thomaskekeisen.de

Aus dem Leben eines Bildschirmarbyters

Achtung: Diese Seite enthält Partner- und Werbe-Links. Daher ist diese Seite im Gesamten als Werbeanzeige zu verstehen!

Warum sollte man das tun wollen?

Ich fand es spannend zu wissen, wie viele statische Versionen meines Blogs ich aus den Quelldaten erzeugt habe. Darum pflege ich eine version.json und die dort enthaltene Versionsnummer wird mit gulp-bump entsprechend bei jedem Aufruf meines build -Befehls um "1" erhöht. Aktuell steht diese Zahl bei 1.6.28012.

        
            var plugins = require('gulp-load-plugins')();

            gulp.task('updateVersion', function() {
                return gulp.src('./version.json')
                    .pipe(plugins.bump({ key: 'version', type: 'patch' }))
                    .pipe(gulp.dest('./'))
                ;
            });
        
    

Da ich bei der Entwicklung meiner Seite auf ein komplett statisches Konzept - heißt: kein PHP und kein CMS- setze, habe ich für jeden Artikel, jedes Feature und jeden Bugfix einen entsprechenden git-Branch. Das funktioniert super, hat aber den unangenehmen Nebeneffekt, dass die version.json immer einen Konflikt auslöst, da sich die Versionsnummer natürlich auf jedem Zweig unabhängig von einander verändert. Anfangs habe ich diese Konflikte manuell gelöst, das wurde mir dann aber zu anstrengend. Nicht zuletzt, weil ich die Differenzen der Versionsnummern zum Zeitpunkt der "Abzweigung" herausfinden musste um letztlich die richtige und endgültige Nummer zu berechnen.

gulp-script mit eigener Merge-Logik

Um die für meinen "Rebase" benötigten Informationen überhaupt vorliegen zu haben, musste ich das Format der Konflikte so anpassen, dass alle Zweige und deren Versionen in die version.json geschrieben werden. Hierzu muss die Einstellung merge.conflictstyle auf diff3 gesetzt werden ( git config merge.conflictstyle diff3 ). Im Anschluss kann mein Script die von git veränderte Datei einlesen und weiterverarbeiten.

Screenshot: Drei Konflikte wurden automatisch gelöst.

Die Lösung meines Problems ist das Script anbei. Es kann einen älteren Branch ohne Probleme über auch 20 bis 30 Commits rebasen, wenn nur die version.json im Konflikt steht. Sobald weitere Dateien im Konflikt stehen, hört das Script auf und ich muss weitere Dateien händisch bearbeiten.

        
            var plugins = require('gulp-load-plugins')();

            gulp.task('autoRebase', function() {
                var conflictIsVersionFile = function (stdoutSplitted)
                {
                    for (var i = 0; i < 3; ++i) {
                        var currentLine = stdoutSplitted[i];
        
                        if (!currentLine.endsWith('version.json')) {
                            return false;
                        }
                    }
        
                    return true;
                };
        
                var getBuildNumber = function(fullVersionNumber)
                {
                    var versionSplitted       = fullVersionNumber.split('.');
                    var versionSplittedBuild  = parseInt(versionSplitted[2], 10);
        
                    return versionSplittedBuild;
                };
        
                var getBuildNumberOverviewFromMatches = function (matches)
                {
                    if (matches && matches.length == 7) {
                        var overview = {
                            branch:      getBuildNumber(matches[6]),
                            branchFull:  matches[6],
                            current:     getBuildNumber(matches[4]),
                            currentFull: matches[4],
                            server:      getBuildNumber(matches[2]),
                            serverFull:  matches[2]
                        };
        
                        return overview;
                    }
        
                    return false;
                };
        
                var getBuildVersions = function ()
                {
                    var matches        = parseVersionFile();
                    var buildVersions  = getBuildNumberOverviewFromMatches(matches);
        
                    return buildVersions;
                };
        
                var getDifferenceForBuildVersions = function (buildVersions)
                {
                    var branchDifference = parseInt(Math.abs(buildVersions.current - buildVersions.branch), 10);
                    var serverDifference = parseInt(Math.abs(buildVersions.current - buildVersions.server), 10);
                    var totalDifference  = branchDifference + serverDifference;
        
                    plugins.util.log('> Difference:', branchDifference, serverDifference, totalDifference);
        
                    return totalDifference;
                };
        
                var getFinalBuildVersion = function (buildVersions)
                {
                    var totalDifference   = getDifferenceForBuildVersions(buildVersions);
                    var finalBuildVersion = buildVersions.current + totalDifference;
        
                    return finalBuildVersion;
                };
        
                var getFinalVersion = function (buildVersions)
                {
                    var finalBuildVersion  = getFinalBuildVersion(buildVersions);
                    var versionSplitted    = buildVersions.currentFull.split('.');
                    var finalVersion       = versionSplitted[0] + '.' + versionSplitted[1] + '.' + finalBuildVersion;
        
                    return finalVersion;
                };
        
                var getFinalVersionJson = function (buildVersions)
                {
                    var finalVersion       = getFinalVersion(buildVersions);
                    var finalVersionObject = {
                        version: finalVersion
                    };
                    var finalVersionJSON   = JSON.stringify(finalVersionObject, null, 4);
        
                    return finalVersionJSON;
                };
        
                var parseVersionFile = function ()
                {
                    var fileContent       = fs.readFileSync('version.json', 'utf8');
                    var regularExpression = /<<<<<<<.*?$[\s\S]*?("version": "(.*?)")[\s\S|||||||s\S]*?("version": "(.*?)")[\s\S]*?^=======$[\s\S]*?("version": "(.*?)")[\s\S]*?>>>>>>>.*?$/gm;
                    var matches           = regularExpression.exec(fileContent);
        
                    return matches;
                };
        
                var writeUpdatedVersionFile = function (buildVersions)
                {
                    var finalVersionJSON = getFinalVersionJson(buildVersions);
        
                    fs.writeFileSync('version.json', finalVersionJSON);
                };
        
                return function (done) {
                    plugins.util.log('> Trying to merge version number automatically');
        
                    var mergeVersionFile = function () {
                        var buildVersions = getBuildVersions();
        
                        plugins.util.log('> Found versions:', buildVersions);
        
                        if (buildVersions) {
                            writeUpdatedVersionFile(buildVersions);
        
                            exec('git add version.json', function(error, stdout, stderr) {
                                exec('git rebase --continue', function(error, stdout, stderr) {
                                    exec('git ls-files --unmerged', function(error, stdout, stderr) {
                                        var stdoutSplitted = stdout.trim().split('\n');
        
                                        plugins.util.log('> Result lines', stdoutSplitted.length);
        
                                        if (stdoutSplitted.length == 3) {
                                            if (conflictIsVersionFile(stdoutSplitted)) {
                                                plugins.util.log('> Found another conflict in version.json, starting over');
        
                                                mergeVersionFile();
                                            } else {
                                                plugins.util.log('> Done');
        
                                                done();
                                            }
                                        } else if (stdoutSplitted.length == 0) {
                                            plugins.util.log('> No conflict in version file found');
        
                                            done();
                                        } else {
                                            plugins.util.log('> Non auto-mergable conflicts found, please fix manually and restart this script');
        
                                            done();
                                        }
                                    });
                                });
                            });
                        } else {
                            plugins.util.log('> No conflict in version file found');
        
                            done();
                        }
                    };
        
                    mergeVersionFile();
                };
            });
        
    

Teilen

Kommentare