At $DAYJOB I work on a very large Go application; hundreds and hundreds of packages. Recently I’ve been trying to untangle some code that has inadvertently grown huge trunks of dependencies. I suspect this is what is causing the time taken to link our tests to become the subject of ridicule.
I’ve tried previously to visualise the dependency graph of a package, and found the results unsatisfying. This time around I decided to write something simpler, and was pleased with the results. I present prdeps
.
In traditional unix style, prdeps
does very little, and expects to be part of a larger text processing pipeline.
% prdeps github.com/pkg/sftp github.com/pkg/sftp: github.com/kr/fs: golang.org/x/crypto/ssh: golang.org/x/crypto/curve25519:
Because Go packages are not a DAG, but a graph not a tree, but a directed graph, the output of running prdeps
on any non trivial package is going to be verbose–be prepared for this.
prdeps
, like go list
takes a -f
flag to modify its output. In this example we alter the output format from the usual indented version (which is presented to the template as .Indent
) and disable suppression of the stdlib with the -s
flag.
% prdeps -s -f {{.ImportPath}} github.com/pkg/sftp | head -n5 github.com/pkg/sftp bytes errors io errors
Note that errors
appears twice in the first five lines of output. errors
actually appears 763 times in the output because almost every package either imports it directly and imports a package which also imports errors.
% prdeps -s -f {{.ImportPath}} github.com/pkg/sftp | grep -c errors 763
Another prdeps feature is to print the import graph from the perspective of a test (-t
is for internal tests, -T
is for external):
% prdeps -T github.com/pkg/sftp github.com/pkg/sftp: github.com/pkg/sftp: github.com/kr/fs: golang.org/x/crypto/ssh: golang.org/x/crypto/curve25519: golang.org/x/crypto/ssh: golang.org/x/crypto/curve25519:
Compare this to the previous non test output above. This feature was why I built prdeps
as I wanted to track down reason the linker was taking so long to link the tests for some of our packages.
prdeps
took about 30 minutes to write, and another hour to address the performance issues from several million lines of output that are produced by a non trivial invocation. I’m sure the same result could be done with the right amount of go list
, but the pleasure of being able to write exactly the tool I wanted for the job at hand was reason enough for me.