Due to the complexity in the codebase and development processes at a current client of mine, I have had to extend NuGet in some interesting ways recently. This has resulted in an open source command line extension set called NuGet.Extensions (snappy name, huh?) and an additional library that NuGet.Extensions depends on called NuGet.Extras (on fire with these names) that deal with some of these complexities.

Some of these extensions address issues in either the implementation of NuGet or extend it in ways that could be reused elsewhere, and others have very particular uses that might be interesting in other organisations but require a specific problem to really provide value. Its a mixed bag, and all I can say is even if they seem crazy, you should see the problem they were trying to fix!

So I thought I would try and spend a bit of time writing up these commands over the next few weeks, and the first that I wanted to look at is a NuGet.Extensions command called “graph“.

graph” was built out of the need to ensure that a feed was acyclic. With the ability for anyone to add packages to a feed, and no governance around package dependencies at publish time, there is a real possibility that you could (if you were either stupid enough or so inclined) implement a cycle in a NuGet package dependency. This of course would show up when consumed (either a stack overflow traversing the install graph or by a clever error message), but ideally it would be caught before then. Due to the astonishing dependency complexity where I currently work, there is also a need to provide a view over the package dependencies so that a comparison can be done against runtime and build time dependency closure (more on that later).

So what does “graph” do? In a nutshell, you point it at a NuGet feed, and it creates a graph of all the packages and their dependencies using QuickGraph, and then outputs this graph as a DGML for consumption within Visual Studio. It will also tell you as part of the output whether the graph is cyclic.

So, examples right? First of all, you have to install the extensions…this is typically achieved by grabbing the extension (there is a download here) and dropping it into %LocalAppData%\NuGet\Commands. There are other ways, but I couldn’t find a link (seems to be a hole in the documentation).

From there, to get the command line options:

C:\>nuget graph -help
usage: NuGet graph

Provides a DGML graph of either a package and all its dependencies, or an entire feed.

options:

 -Source +           A list of sources to search
 -DAGCheck           Check whether there are any cycles in the graph.
 -NoLoners           Cull any disconnected vertices from the graph.
 -Output             Output file name.
 -Help          (?)  help

For more information, visit http://docs.nuget.org/docs/reference/command-line-reference

To reduce noise, we want to ignore packages that have no dependencies as they really don’t add to our understanding of dependencies (and they clutter the graph). We can run this against the NuGet.org using the command line below:

C:\temp>nuget graph -source http://nuget.org/api/v2 -dagcheck -noloners -output nuget.org.dgml
Adding package and dependencies: 20120510003
Adding package and dependencies: 20120510007
Adding package and dependencies: 20120510008
Adding package and dependencies: 32feet.NET
Adding package and dependencies: 51Degrees.mobi
Adding package and dependencies: 51Degrees.mobi-WebMatrix
Adding package and dependencies: abc
Adding package and dependencies: Abc.Client.Collector
....
Adding package and dependencies: ZXing
Adding package and dependencies: ZXing.Net
Adding package and dependencies: ZXing.WP7
Adding package and dependencies: Zyan
Adding package and dependencies: ?????
Removing loner: 20120510003
Removing loner: 20120510007
Removing loner: 20120510008
Removing loner: 32feet.net
Removing loner: abc
....
Removing loner: zoomtextboxphone
Removing loner: zxing
Removing loner: zxing.wp7
Removing loner: zyan

Graph is a DAG.

Completed graph in 190.7365271 seconds

C:\temp>

So, as you can imagine “….” in the above output is just for brevity….I probably should add a quiet mode. Also note that NuGet.Org feed is currently a DAG, and this is good!

So, what does this look like when done? It takes a while to render in VS 2010. Actually, who am I kidding. It takes ages. Get a coffee or two. Eventually you will see a resultant image similar to the one below (you can also find the .dgml output here).

Pretty, huh? :)