183 lines
4.6 KiB
JavaScript
183 lines
4.6 KiB
JavaScript
'use strict';
|
|
|
|
var exec = require('child_process').exec;
|
|
var spawn = require('child_process').spawn;
|
|
function execute(command, cb){
|
|
let output = '';
|
|
function callback(error, stdout, stderr) {
|
|
cb(stdout);
|
|
}
|
|
exec (command, { maxBuffer: 1024*1024*1024 }, callback)
|
|
};
|
|
|
|
function getDifflines(upto, path, cb) {
|
|
if (typeof upto === 'function') {
|
|
cb = upto;
|
|
path = '';
|
|
upto = '';
|
|
} else if (typeof path === 'function') {
|
|
cb = path;
|
|
path = '';
|
|
}
|
|
execute('git diff '+upto+'..@ '+path, (log) => {
|
|
let o = {
|
|
add: 0,
|
|
del: 0
|
|
};
|
|
for (let line of log.split(/\n/g)) {
|
|
if (line.match(/^\+/)) {
|
|
o.add ++;
|
|
} else if (line.match(/^-/)) {
|
|
o.del ++;
|
|
}
|
|
}
|
|
o.diff = o.add - o.del;
|
|
cb (o);
|
|
});
|
|
}
|
|
|
|
function getChangelog(upto, path, cb) {
|
|
if (typeof upto === 'function') {
|
|
cb = upto;
|
|
path = '';
|
|
upto = '';
|
|
} else if (typeof path === 'function') {
|
|
cb = path;
|
|
path = '';
|
|
}
|
|
execute('git log '+upto+'..@ '+path, (log) => {
|
|
let o = {
|
|
upto: upto,
|
|
path: path,
|
|
authors: {},
|
|
commits: []
|
|
};
|
|
const lines = log.split('\n');
|
|
let date = null;
|
|
let commit = null;
|
|
let message = '';
|
|
for (let line of lines) {
|
|
if (line.match("^Author")) {
|
|
const author = line.substring(8);
|
|
if (o.authors[author] === undefined) {
|
|
o.authors[author] = 1;
|
|
} else o.authors[author]++;
|
|
} else if (line.match("^Date:")) {
|
|
date = line.substring(8);
|
|
} else if (line.match("^commit")) {
|
|
if (commit !== null) {
|
|
var doh = {
|
|
hash: commit,
|
|
date: date,
|
|
msg: message.trim()
|
|
};
|
|
o.commits.push(doh);
|
|
message = '';
|
|
date = '';
|
|
}
|
|
commit = line.substring(7);
|
|
} else if (line[0] == ' ') {
|
|
message += line + '\n';
|
|
}
|
|
}
|
|
cb (o);
|
|
});
|
|
}
|
|
|
|
function countWord(x,y) {
|
|
let count = 0;
|
|
for (let a of x) {
|
|
if (a.msg.match(y)) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
function computeStats(o) {
|
|
return {
|
|
commits: o.commits.length,
|
|
fix: countWord(o.commits, /fix/i),
|
|
crash: countWord(o.commits, /crash/i),
|
|
'new': countWord(o.commits, /new/i),
|
|
add: countWord(o.commits, /add/i),
|
|
anal: countWord(o.commits, /anal/i),
|
|
leak: countWord(o.commits, /leak/i),
|
|
esil: countWord(o.commits, /esil/i),
|
|
enhance: countWord(o.commits, /enhance/i),
|
|
}
|
|
}
|
|
|
|
function computeRanking(o) {
|
|
let r = [];
|
|
for (let a in o.authors) {
|
|
r.push(o.authors[a]+ ' '+a);
|
|
// console.log(a);
|
|
}
|
|
r = r.sort(function(a, b) {
|
|
a = +((a.split(' ')[0]));
|
|
b = +((b.split(' ')[0]));
|
|
return (a < b) ? 1 : -1;
|
|
});
|
|
return {
|
|
count: Object.keys(o.authors).length,
|
|
authors: r
|
|
};
|
|
}
|
|
|
|
String.prototype.repeat = function(times) {
|
|
return (new Array(times + 1)).join(this);
|
|
};
|
|
|
|
function printMdList(md_list, list_level) {
|
|
var elems = Object.keys(md_list);
|
|
elems.forEach(function(elem) {
|
|
if (typeof md_list[elem] === "object") {
|
|
console.log("\t".repeat(list_level) + "- " + elem + ":");
|
|
return printMdList(md_list[elem], list_level + 1);
|
|
} else {
|
|
var elem_name = isNaN(elem) ? (elem + ": ") : "";
|
|
console.log ("\t".repeat(list_level) + "- " + elem_name + md_list[elem]);
|
|
}
|
|
});
|
|
}
|
|
|
|
const last_tag = '0.10.1';
|
|
|
|
const paths = [
|
|
'', // total
|
|
'binr/r2pm/d',
|
|
'libr/debug',
|
|
'libr/bin',
|
|
'libr/core',
|
|
'libr/crypto',
|
|
'libr/cons',
|
|
'libr/anal',
|
|
'libr/asm',
|
|
'man',
|
|
];
|
|
|
|
var count = 0;
|
|
var doner = [];
|
|
var ready = false;
|
|
|
|
for (let one_path of paths) {
|
|
count ++;
|
|
getChangelog(last_tag, one_path, function(o) {
|
|
getDifflines(last_tag, one_path, function(d) {
|
|
let r = computeStats (o);
|
|
r.path = one_path;
|
|
r.rank = computeRanking (o);
|
|
r.diff = d;
|
|
doner.push (r);
|
|
count --;
|
|
if (count == 0 && ready) {
|
|
for(let one_doner of doner) {
|
|
printMdList(one_doner, 0);
|
|
console.log("\n");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
ready = true;
|