Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created October 7, 2022 05:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufcpp/daf471cde450bb38d1e667419ddcdcb0 to your computer and use it in GitHub Desktop.
Save ufcpp/daf471cde450bb38d1e667419ddcdcb0 to your computer and use it in GitHub Desktop.
GetProjectDependencyGraph を mermaid 記法出力
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
class DependencyAnalyzer
{
public static async ValueTask WriteMermaidGraph(string path)
{
MSBuildLocator.RegisterDefaults();
var workspace = MSBuildWorkspace.Create();
var sln = await workspace.OpenSolutionAsync(path);
WriteMermaidGraph(GetProjectDependencies(sln));
}
private static IEnumerable<(string from, string to)> GetProjectDependencies(Solution sln)
{
var graph = sln.GetProjectDependencyGraph();
foreach (var pid in graph.GetTopologicallySortedProjects())
{
var p = sln.GetProject(pid)!;
var pn = name(p);
foreach (var rid in GetDirectDependecy(graph, p))
{
var rp = sln.GetProject(rid)!;
var rpn = name(rp);
yield return (pn, rpn);
}
}
static string name(Project p) => p.Name.Replace('(', '_').Replace(')', ' ');
}
// なんか、GetProjectsThatThisProjectDirectlyDependsOn が返す内容が direct じゃない…
// よくわからないし解決方法見つからず。
// しょうがないんで、逆に、 transitive なのが帰ってくる想定で ExceptFor しまくる。
private static IEnumerable<ProjectId> GetDirectDependecy(ProjectDependencyGraph graph, Project p)
{
var deps = graph.GetProjectsThatThisProjectDirectlyDependsOn(p.Id).AsEnumerable();
foreach (var d in deps.ToArray())
{
deps = deps.Except(graph.GetProjectsThatThisProjectDirectlyDependsOn(d));
}
return deps.ToArray();
}
/// <summary>
/// 依存関係を mermaid graph で <see cref="Console"/> に出力。
/// </summary>
/// <param name="dependencies"></param>
private static void WriteMermaidGraph(IEnumerable<(string from, string to)> dependencies)
{
Console.WriteLine("""
```mermaid
graph LR
""");
foreach (var (from, to) in dependencies)
{
Console.WriteLine($"{from} --> {to}");
}
Console.WriteLine("""
```
""");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment