Skip to content

Commit 09ed31d

Browse files
authored
Generate Mermaid HTML diagrammer from input assembly via ilspycmd (#3324)
* added mermaid class diagrammer contributed from https://github.com/h0lg/netAmermaid - find earlier git history there * reading from embedded resource instead of file * swapped out icon to brand diagrammers as an ILSpy product reusing linked ..\ILSpy\Images\ILSpy.ico from UI project * added required ilspycmd options and routed call * adjusted VS Code task to generate model.json required by the JS/CSS/HTML dev loop * added debug launchSettings * updated help command output * using ILSpyX build info in generated diagrammers removing unused code * using explicit type where it's not obvious * outputting in to a folder next to and named after the input assembly + " diagrammer" by default * renamed diagrammer output to index.html to support default web server configs in the wild * improved instructions for creating an off-line diagrammer * added developer-facing doco for how to edit the HTML/JS/CSS parts * renamed to remove netAmermaid branding * updated repo URL and doco link to new Wiki page * copied over doco * removed obsolete parts * moved CLI doco into ILSpyCmd README * removed end-user facing chapters that go into the Wiki from dev-facing doco * updated to ilspycmd API and rebranded to ILSpy * removed doco that's now in https://github.com/icsharpcode/ILSpy/wiki/Diagramming * added tasks
1 parent b4d85a5 commit 09ed31d

28 files changed

+3967
-26
lines changed

ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using ICSharpCode.Decompiler.Metadata;
1919
using ICSharpCode.Decompiler.Solution;
2020
using ICSharpCode.Decompiler.TypeSystem;
21+
using ICSharpCode.ILSpyX.MermaidDiagrammer;
2122
using ICSharpCode.ILSpyX.PdbProvider;
2223

2324
using McMaster.Extensions.CommandLineUtils;
@@ -44,6 +45,13 @@ Decompile assembly to destination directory (single C# file).
4445
Decompile assembly to destination directory, create a project file, one source file per type,
4546
into nicely nested directories.
4647
ilspycmd --nested-directories -p -o c:\decompiled sample.dll
48+
49+
Generate a HTML diagrammer containing all type info into a folder next to the input assembly
50+
ilspycmd sample.dll --generate-diagrammer
51+
52+
Generate a HTML diagrammer containing filtered type info into a custom output folder
53+
(including types in the LightJson namespace while excluding types in nested LightJson.Serialization namespace)
54+
ilspycmd sample.dll --generate-diagrammer -o c:\diagrammer --generate-diagrammer-include LightJson\\..+ --generate-diagrammer-exclude LightJson\\.Serialization\\..+
4755
")]
4856
[HelpOption("-h|--help")]
4957
[ProjectOptionRequiresOutputDirectoryValidation]
@@ -114,6 +122,46 @@ class ILSpyCmdProgram
114122
[Option("--disable-updatecheck", "If using ilspycmd in a tight loop or fully automated scenario, you might want to disable the automatic update check.", CommandOptionType.NoValue)]
115123
public bool DisableUpdateCheck { get; }
116124

125+
#region MermaidDiagrammer options
126+
127+
// reused or quoted commands
128+
private const string generateDiagrammerCmd = "--generate-diagrammer",
129+
exclude = generateDiagrammerCmd + "-exclude",
130+
include = generateDiagrammerCmd + "-include";
131+
132+
[Option(generateDiagrammerCmd, "Generates an interactive HTML diagrammer app from selected types in the target assembly" +
133+
" - to the --outputdir or in a 'diagrammer' folder next to to the assembly by default.", CommandOptionType.NoValue)]
134+
public bool GenerateDiagrammer { get; }
135+
136+
[Option(include, "An optional regular expression matching Type.FullName used to whitelist types to include in the generated diagrammer.", CommandOptionType.SingleValue)]
137+
public string Include { get; set; }
138+
139+
[Option(exclude, "An optional regular expression matching Type.FullName used to blacklist types to exclude from the generated diagrammer.", CommandOptionType.SingleValue)]
140+
public string Exclude { get; set; }
141+
142+
[Option(generateDiagrammerCmd + "-report-excluded", "Outputs a report of types excluded from the generated diagrammer" +
143+
$" - whether by default because compiler-generated, explicitly by '{exclude}' or implicitly by '{include}'." +
144+
" You may find this useful to develop and debug your regular expressions.", CommandOptionType.NoValue)]
145+
public bool ReportExludedTypes { get; set; }
146+
147+
[Option(generateDiagrammerCmd + "-docs", "The path or file:// URI of the XML file containing the target assembly's documentation comments." +
148+
" You only need to set this if a) you want your diagrams annotated with them and b) the file name differs from that of the assmbly." +
149+
" To enable XML documentation output for your assmbly, see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/#create-xml-documentation-output",
150+
CommandOptionType.SingleValue)]
151+
public string XmlDocs { get; set; }
152+
153+
/// <inheritdoc cref="ILSpyX.MermaidDiagrammer.GenerateHtmlDiagrammer.StrippedNamespaces" />
154+
[Option(generateDiagrammerCmd + "-strip-namespaces", "Optional space-separated namespace names that are removed for brevity from XML documentation comments." +
155+
" Note that the order matters: e.g. replace 'System.Collections' before 'System' to remove both of them completely.", CommandOptionType.MultipleValue)]
156+
public string[] StrippedNamespaces { get; set; }
157+
158+
[Option(generateDiagrammerCmd + "-json-only",
159+
"Whether to generate a model.json file instead of baking it into the HTML template." +
160+
" This is useful for the HTML/JS/CSS development loop.", CommandOptionType.NoValue,
161+
ShowInHelpText = false)] // developer option, output is really only useful in combination with the corresponding task in html/gulpfile.js
162+
public bool JsonOnly { get; set; }
163+
#endregion
164+
117165
private readonly IHostEnvironment _env;
118166
public ILSpyCmdProgram(IHostEnvironment env)
119167
{
@@ -157,6 +205,26 @@ private async Task<int> OnExecuteAsync(CommandLineApplication app)
157205
SolutionCreator.WriteSolutionFile(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(outputDirectory) + ".sln"), projects);
158206
return 0;
159207
}
208+
else if (GenerateDiagrammer)
209+
{
210+
foreach (var file in InputAssemblyNames)
211+
{
212+
var command = new GenerateHtmlDiagrammer {
213+
Assembly = file,
214+
OutputFolder = OutputDirectory,
215+
Include = Include,
216+
Exclude = Exclude,
217+
ReportExludedTypes = ReportExludedTypes,
218+
JsonOnly = JsonOnly,
219+
XmlDocs = XmlDocs,
220+
StrippedNamespaces = StrippedNamespaces
221+
};
222+
223+
command.Run();
224+
}
225+
226+
return 0;
227+
}
160228
else
161229
{
162230
foreach (var file in InputAssemblyNames)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"profiles": {
3+
"no args": {
4+
"commandName": "Project",
5+
"commandLineArgs": ""
6+
},
7+
"print help": {
8+
"commandName": "Project",
9+
"commandLineArgs": "--help"
10+
},
11+
"generate diagrammer": {
12+
"commandName": "Project",
13+
// containing all types
14+
15+
// full diagrammer (~6.3 Mb!)
16+
//"commandLineArgs": "ICSharpCode.Decompiler.dll --generate-diagrammer"
17+
18+
// including types in LightJson namespace while excluding types in nested LightJson.Serialization namespace, matched by what returns System.Type.FullName
19+
//"commandLineArgs": "ICSharpCode.Decompiler.dll --generate-diagrammer --generate-diagrammer-include LightJson\\..+ --generate-diagrammer-exclude LightJson\\.Serialization\\..+"
20+
21+
// including types in Decompiler.TypeSystem namespace while excluding types in nested Decompiler.TypeSystem.Implementation namespace
22+
"commandLineArgs": "ICSharpCode.Decompiler.dll --generate-diagrammer --generate-diagrammer-include Decompiler\\.TypeSystem\\..+ --generate-diagrammer-exclude Decompiler\\.TypeSystem\\.Implementation\\..+"
23+
},
24+
"generate diagrammer model.json": {
25+
"commandName": "Project",
26+
"commandLineArgs": "ICSharpCode.Decompiler.dll --generate-diagrammer --generate-diagrammer-json-only"
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)