Created
November 3, 2016 05:41
-
-
Save LeeCampbell/a3e2b7efaa8dbb0dcccd280b7cb521c8 to your computer and use it in GitHub Desktop.
LinqPad Script that generates the GraphViz file to visualize dependencies.
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
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