Skip to content

Instantly share code, notes, and snippets.

@LeeCampbell
Created November 3, 2016 05:41
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeeCampbell/a3e2b7efaa8dbb0dcccd280b7cb521c8 to your computer and use it in GitHub Desktop.
Save LeeCampbell/a3e2b7efaa8dbb0dcccd280b7cb521c8 to your computer and use it in GitHub Desktop.
LinqPad Script that generates the GraphViz file to visualize dependencies.
void Main()
{
//Generates the .gv file content that can be put into GraphViz to vizualize your dependency tree.
// Once in GrpahViz, export to svg to avoid guessing how big you will need it (e.g. compared to PNG/JPG or other raster formats)
var rootPath = @"C:\source\GitHub\Mercury";
var outputPath = @"C:\source\GitHub\Mercury\references.dot";
var limit = 1000;
var projects = Directory.GetFiles(rootPath, "*.csproj", SearchOption.AllDirectories)
.Where(path=>!path.ToLowerInvariant().Contains("test")) //Exclude tests for sanity
.Select(path => CreateProject(path))
.ToArray();
var sb = new StringBuilder();
sb.AppendLine("digraph G {");
sb.AppendLine("size = \"50,50\"; "); //Size in inches.
foreach (var project in projects.Where(p=>p.Index < limit))
{
sb.AppendLine($"{project.Index} [label=\"{project.Name}\", shape=component, style=filled, fillcolor=LightBlue];");
}
sb.AppendLine();
foreach (var project in projects.Where(p=>p.Index < limit))
{
foreach (var refId in project.ReferenceIds().Where(idx=>idx < limit))
{
sb.AppendLine($"{project.Index} -> {refId} [ ];");
}
}
sb.AppendLine("}");
sb.ToString().Dump();
}
// Define other methods and classes here
private static Project CreateProject(string fullPath)
{
XmlReader reader = XmlReader.Create(fullPath);
XElement root = XElement.Load(reader);
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
namespaceManager.AddNamespace("defaultNamespace", "http://schemas.microsoft.com/developer/msbuild/2003");
var elements = root.XPathSelectElements("//defaultNamespace:ProjectReference", namespaceManager);
var relativeReferences = elements.Select(e => e.Attribute("Include").Value);
var currentDir = Path.GetDirectoryName(fullPath);
var absoluteReferences = relativeReferences.Select(r => Path.Combine(currentDir, r))
.Select(p => Path.GetFullPath(p).ToLowerInvariant())
.ToArray();
return new Project(Path.GetFileNameWithoutExtension(fullPath), fullPath.ToLowerInvariant(), absoluteReferences);
}
public class Project
{
private static int NextIndex = 0;
private static Dictionary<string, int> _fullPathToIndexMap = new Dictionary<string, int>();
public Project(string name, string fullPath, string[] fullPathReferences)
{
Index = NextIndex++;
Name = name;
References = fullPathReferences;
_fullPathToIndexMap[fullPath] = Index;
}
public int Index { get; private set; }
public string Name { get; private set; }
public string[] References { get; private set; }
public IEnumerable<int> ReferenceIds()
{
foreach (var fullPath in References)
{
int value;
if (_fullPathToIndexMap.TryGetValue(fullPath, out value))
{
yield return value;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment