mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-01-12 22:45:52 +08:00
169 lines
3.7 KiB
JavaScript
Executable File
169 lines
3.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
var util = require('util');
|
|
var cp = require('child_process');
|
|
|
|
var Q = require('q');
|
|
var _ = require('lodash');
|
|
var semver = require('semver');
|
|
|
|
var exec = function (cmd) {
|
|
return function () {
|
|
var args = Array.prototype.slice.call(arguments, 0);
|
|
args.unshift(cmd);
|
|
var fullCmd = util.format.apply(util, args);
|
|
return Q.nfcall(cp.exec, fullCmd).then(function (out) {
|
|
return out[0].split('\n');
|
|
});
|
|
};
|
|
};
|
|
|
|
var andThen = function (fn, after) {
|
|
return function () {
|
|
return fn.apply(this, arguments).then(after);
|
|
};
|
|
};
|
|
|
|
var oneArg = function (fn) {
|
|
return function (arg) {
|
|
return fn(arg);
|
|
};
|
|
};
|
|
|
|
var oneLine = function (lines) {
|
|
return lines[0].trim();
|
|
};
|
|
|
|
var noArgs = function (fn) {
|
|
return function () {
|
|
return fn();
|
|
};
|
|
};
|
|
|
|
var identity = function (i) { return i; };
|
|
|
|
// like Q.all, but runs the comands in series
|
|
// useful for ensuring env state (like which branch is checked out)
|
|
var allInSeries = function (fn) {
|
|
return function (args) {
|
|
var results = [];
|
|
var def;
|
|
while (args.length > 0) {
|
|
(function (arg) {
|
|
if (def) {
|
|
def = def.then(function () {
|
|
return fn(arg);
|
|
});
|
|
} else {
|
|
def = fn(arg);
|
|
}
|
|
def = def.then(function (res) {
|
|
results.push(res);
|
|
});
|
|
}(args.pop()));
|
|
}
|
|
return def.then(function () {
|
|
return results;
|
|
});
|
|
};
|
|
};
|
|
|
|
var compareBranches = function (left, right) {
|
|
console.log('# These commits are in ' + left.name + ' but not in ' + right.name + '\n');
|
|
console.log(_(left.log).
|
|
difference(right.log).
|
|
map(function (line) {
|
|
return left.full[left.log.indexOf(line)]; // lol O(n^2)
|
|
}).
|
|
value().
|
|
join('\n'));
|
|
};
|
|
|
|
var checkout = oneArg(exec('git checkout %s'));
|
|
|
|
var getCurrentBranch = andThen(noArgs(exec('git rev-parse --abbrev-ref HEAD')), oneLine);
|
|
var getTags = noArgs(exec('git tag'));
|
|
var getShaOfTag = oneArg(exec('git rev-list %s | head -n 1'));
|
|
var getTheLog = oneArg(exec('git log --pretty=oneline %s..HEAD | cat'));
|
|
|
|
// remember this so we can restore state
|
|
var currentBranch;
|
|
|
|
getCurrentBranch().
|
|
then(function (branch) {
|
|
currentBranch = branch;
|
|
}).
|
|
then(getTags).
|
|
then(function (tags) {
|
|
return tags.
|
|
filter(semver.valid).
|
|
map(semver.clean).
|
|
sort(semver.rcompare);
|
|
}).
|
|
then(function (tags) {
|
|
var major = tags[0].split('.')[0] + '.x';
|
|
return tags.
|
|
filter(function (ver) {
|
|
return semver.satisfies(ver, major);
|
|
});
|
|
}).
|
|
then(function (tags) {
|
|
return _(tags).
|
|
groupBy(function (tag) {
|
|
return tag.split('.')[1];
|
|
}).
|
|
map(function (group) {
|
|
return _.first(group);
|
|
}).
|
|
map(function (tag) {
|
|
return 'v' + tag;
|
|
}).
|
|
value();
|
|
}).
|
|
then(function (tags) {
|
|
var master = tags.pop();
|
|
var stable = tags.pop();
|
|
|
|
return [
|
|
{ name: stable.replace(/\d+$/, 'x'), tag: stable },
|
|
{ name: 'master', tag: master}
|
|
];
|
|
}).
|
|
then(allInSeries(function (branch) {
|
|
return checkout(branch.name).
|
|
then(function () {
|
|
return getTheLog(branch.tag);
|
|
}).
|
|
then(function (log) {
|
|
return log.
|
|
filter(identity);
|
|
}).
|
|
then(function (log) {
|
|
branch.full = log.map(function (line) {
|
|
line = line.split(' ');
|
|
var sha = line.shift();
|
|
var msg = line.join(' ');
|
|
return sha + (msg.toLowerCase().indexOf('fix') === -1 ? ' ' : ' * ') + msg;
|
|
});
|
|
branch.log = log.map(function (line) {
|
|
return line.substr(41);
|
|
});
|
|
return branch;
|
|
});
|
|
})).
|
|
then(function (pairs) {
|
|
compareBranches(pairs[0], pairs[1]);
|
|
console.log('\n');
|
|
compareBranches(pairs[1], pairs[0]);
|
|
return pairs;
|
|
}).
|
|
then(function () {
|
|
return checkout(currentBranch);
|
|
}).
|
|
catch(function (e) {
|
|
console.log(e.stack);
|
|
});
|
|
|