Created
May 5, 2014 18:03
-
-
Save usefulthink/7fad0d23ab2054a50c18 to your computer and use it in GitHub Desktop.
practicing node streams – script generates a git commit-log, parses it and reformats into a day-by-day-log useful for time-tracking.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
var fs = require('fs'), | |
util = require('util'), | |
spawn = require('child_process').spawn, | |
stream = require('stream'); | |
function dateString(date) { return date.toISOString().split('T')[0]; } | |
function timeString(date) { return date.toTimeString().slice(0,5); } | |
var logParser = (function() { | |
var s=new stream.Transform({objectMode:true}); | |
s._transform = function(chunk, encoding, callback) { | |
var buf = chunk.toString('utf-8'), | |
lines = buf.trim().split("\n"); | |
lines = lines.map(function(line) { | |
// note: this of course correlates with git's log-format | |
var parts = line.split('|'); | |
var ts = new Date(parts[0]), | |
date = dateString(ts), | |
time = timeString(ts); | |
return { timestamp: ts.getTime(), date: date, time: time, author: parts[1], msg: parts[2] }; | |
}); | |
lines.forEach(this.push.bind(this)); | |
callback(); | |
}; | |
return s; | |
} ()); | |
var dayAggregator = (function() { | |
var s = new stream.Transform({objectMode:true}); | |
var aggregate; | |
function _reset() { | |
aggregate = { date: '', firstCommitAt: null, lastCommitAt: null, msgs: [] }; | |
} | |
_reset(); | |
s._transform = function(o, encoding, callback) { | |
if(o.date !== aggregate.date && aggregate.msgs.length > 0) { | |
aggregate.msgs = aggregate.msgs.sort(function(a,b) { return a.timestamp - b.timestamp; }); | |
this.push(aggregate); | |
_reset(); | |
} | |
if(!aggregate.firstCommitAt) { | |
aggregate.firstCommitAt = new Date(o.timestamp); | |
} | |
aggregate.date = o.date; | |
aggregate.lastCommitAt = new Date(o.timestamp); | |
aggregate.msgs.push(o); | |
callback(); | |
}; | |
return s; | |
} ()); | |
var dayLogWriter = (function() { | |
var s = new stream.Transform({objectMode:true}); | |
s._write = function(o, encoding, callback) { | |
this.push('\n\033[1;32m---- '+o.date+' ----\033[0m\n'); | |
var msgs = o.msgs.map(function(msg) { | |
return '\033[36m['+msg.time+']\033[0m \033[34m' + msg.author + '\033[0m: ' + msg.msg; | |
}); | |
this.push(' '+(msgs.join('\n '))+'\n\n'); | |
this.push('First commit: '+timeString(o.firstCommitAt) + '\n'); | |
this.push('Last commit: '+timeString(o.lastCommitAt) + '\n'); | |
callback(); | |
}; | |
return s; | |
} ()); | |
var dumpObjectStream = (function() { | |
var s = new stream.Writable({objectMode:true}); | |
s._write = function(chunk, encoding, callback) { | |
console.log('dumpObjectStream:', util.inspect(chunk, {colors:true})); | |
callback(); | |
}; | |
return s; | |
}()); | |
// now fetch the data and format it... | |
var cp = spawn('git', ['log', '--reverse', '--date-order', '--format=%ai|%ae|%s'].concat(process.argv.slice(2))); | |
cp.stdout.pipe(logParser).pipe(dayAggregator).pipe(dayLogWriter).pipe(process.stdout); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment