The 2.13 release of reposurgeon has in it maybe the coolest new feature I’ve ever implemented in five minutes of programming – graphical visualization of a repository’s commit DAG.
In yet another episode of “The Awesome Power of Combining Unix Tools”, the way this actually works is that the new “graph” command emits to standard output a description of the commit graph in the DOT language used by the open-source graphviz suite. To turn this into an image view, just create the following little reposurgeon script and call it something like “show”:
shell dot </tmp/foo$$ -Tpng | display -; rm /tmp/foo$$
Now you can say “script show”; reposurgeon will call the graph command, redirecting the output to a tempfile (the reposurgeon interpreter knows that $$ in a script should be expanded to the process ID). Then it will spawn a shell and run a pipeline using the main graphviz rendering program, dot, to make an image from the DOT markup. That is then fed to the viewer of your choice, in this case display(1) from the ImageMagick suite.
Oh, and that $% in there? That says “substitute the selection set, if any, given the script command”. So you can use this to view selected subsets of the commit graph – useful for large repositories.
The stupid way to implement this feature would have been to hardwire assumptions about the image renderer and viewer into reposurgeon itself, or (slightly less stupidly) pass them in via environment variables or a dotfile. By using reposurgeon’s script feature I avoid all that sort of nonsense – the only graphics-specific thing reposurgeon itself knows how to do is emit DOT markup, which took me all of about five minutes to write after I read the graphviz documentation.
I added in-script expansion of the $$ and $% cookies once I knew ‘graph’ was a good idea (I already had ‘shell’ and > output redirection for reposurgeon commands). The $$ cookie is of course modeled on how Unix shells expand it – a perfectly reasonable notation that there is no reason not to re-use here, and which will be helpful for any other reposurgeon script in the future that needs to use tempfiles.
This is how it looks when you design your application as a domain-specific language and think in terms of adding simple, combinable, orthogonal primitives to it rather than big lumps implementing idiosyncratic features with code that never gets re-used for anything else. Total lines of code to implement DOT output plus $$ plus $% was certainly less than it would have been had I tried to write the equivalent of that script in Python inside reposurgeon, and this way each of these three little featurelets can pay off its complexity cost in the future by being useful in ways I’m not trying to anticipate now.
This design has one drawback, however. The reposurgeon scripting facility was really designed for writing regression tests and per-project repository-lifting scripts; there is at present no place reposurgeon looks for scripts like this that should be shared among all your projects – for the excellent reason that this is (probably) the first such shareable script ever written. I need to think about that; this will probably turn into another addition to the language.