Created
October 27, 2010 14:39
-
-
Save robfe/649146 to your computer and use it in GitHub Desktop.
Analyses all the csproj files in a directory and generates a dot (www.graphviz.com) graph of the project references, including silverlight application references
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
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Xml.Linq; | |
namespace ReferenceReader | |
{ | |
class CsProjReferencesToDot | |
{ | |
static void Main(string[] args) | |
{ | |
var foregroundColor = Console.ForegroundColor; | |
if (!args.Any()) | |
{ | |
args = new[] { Environment.CurrentDirectory }; | |
} | |
var dict = args.SelectMany(dir => Directory.EnumerateFiles(dir, "*.csproj", SearchOption.AllDirectories)).ToDictionary(x => x, x => new Project(x)); | |
dict.Values.AsParallel().ForAll(project => project.Link(dict)); | |
Console.ForegroundColor = ConsoleColor.DarkGray; | |
Console.WriteLine("digraph g{"); | |
Console.WriteLine(" rankdir=LR"); | |
Console.WriteLine(" node[fontname=calibri]"); | |
var projects = dict.Values.ToList(); | |
int projectCount = 0; | |
int projectReferences = 0; | |
int silverlightReferences = 0; | |
int brokenReferences = 0; | |
foreach (Project project in projects) | |
{ | |
projectCount++; | |
Console.ForegroundColor = ConsoleColor.Gray; | |
Console.WriteLine(" {0}[label=\"{1} ({2})\"]", project.Id, project.Name, project.CsFiles); | |
foreach (Project r in project.ProjectReferences) | |
{ | |
Console.ForegroundColor = ConsoleColor.Green; | |
Console.WriteLine(" {0}->{1}[color=darkgreen]", project.Id, r.Id); | |
projectReferences++; | |
} | |
foreach (Project r in project.SilverlightReferences) | |
{ | |
Console.ForegroundColor = ConsoleColor.Blue; | |
Console.WriteLine(" {0}->{1}[color=blue]", project.Id, r.Id); | |
silverlightReferences++; | |
} | |
foreach (string r in project.BrokenReferences) | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
var id = r.Replace('.', '_').Replace('\\', '_'); | |
Console.WriteLine(" {0}[label=\"{1}\"]", id, r.Replace("\\", "\\\\")); | |
Console.WriteLine(" {0}->{1}[color=red]", project.Id, id); | |
brokenReferences++; | |
} | |
} | |
Console.ForegroundColor = ConsoleColor.DarkGray; | |
StringBuilder sb = new StringBuilder("Project Reference analysis: "); | |
sb.AppendFormat("path = [{0}], ", string.Join(", ", args).Replace("\\", "\\\\")); | |
sb.AppendFormat("projects = {0}, ", projectCount); | |
sb.AppendFormat("project references = {0}, ", projectReferences); | |
sb.AppendFormat("silverlight references = {0}, ", silverlightReferences); | |
sb.AppendFormat("external/broken references = {0}", brokenReferences); | |
Console.WriteLine(" graph[label=\"{0}\", fontsize=30]", sb); | |
Console.WriteLine("}"); | |
Console.ForegroundColor = foregroundColor; | |
} | |
} | |
class Project | |
{ | |
static readonly XNamespace Ns = "http://schemas.microsoft.com/developer/msbuild/2003"; | |
public Project(string file) | |
{ | |
Name = Path.GetFileNameWithoutExtension(file); | |
FullPath = file; | |
} | |
protected string FullPath { get; set; } | |
public List<Project> ProjectReferences { get; set; } | |
public List<Project> SilverlightReferences { get; set; } | |
public List<string> BrokenReferences { get; set; } | |
public int CsFiles { get; set; } | |
public string Name { get; set; } | |
public string Id { get { return Name.Replace('.', '_'); } } | |
public void Link(Dictionary<string, Project> projects) | |
{ | |
ProjectReferences = new List<Project>(); | |
SilverlightReferences = new List<Project>(); | |
BrokenReferences = new List<string>(); | |
var xml = XDocument.Load(FullPath).Root; | |
Debug.Assert(xml != null); | |
//<Compile Include="Program.cs" /> | |
CsFiles = xml.Descendants(Ns + "Compile").Where(x => ((string) x.Attribute("Include")).EndsWith(".cs")).Count(); | |
foreach (XElement element in xml.Descendants(Ns + "ProjectReference")) | |
{ | |
var rel = (string)element.Attribute("Include"); | |
var path = new Uri(Path.Combine(Path.GetDirectoryName(FullPath), rel)).AbsolutePath.Replace("%20", " "); | |
path = new FileInfo(path).FullName; | |
if (projects.ContainsKey(path)) | |
{ | |
ProjectReferences.Add(projects[path]); | |
} | |
else | |
{ | |
BrokenReferences.Add(rel); | |
} | |
} | |
foreach (var item in xml.Descendants(Ns + "SilverlightApplicationList").SelectMany(x => x.Value.Split(','))) | |
{ | |
var cells = item.Split('|'); | |
var rel = cells[1]; | |
var path = new Uri(Path.Combine(Path.GetDirectoryName(FullPath), rel)).AbsolutePath; | |
path = new FileInfo(path).FullName; | |
if (projects.ContainsKey(path)) | |
{ | |
SilverlightReferences.Add(projects[path]); | |
} | |
else | |
{ | |
BrokenReferences.Add(rel); | |
} | |
} | |
} | |
public override string ToString() | |
{ | |
return string.Format("Name: {0}, ProjectReferences [{1}]", Name, String.Join(", ", ProjectReferences.Select(x => x.Name))); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
usage: