Skip to content

smourier/Melusyn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Melusyn

A command-line tool that generates Mermaid diagrams (as Markdown) from Visual Studio solutions and MSBuild C# projects.

Point it at a .slnx, .sln, or .csproj and it emits markdown containing:

  • Class diagrams: classes, interfaces, structs, records, enums and delegates with their properties, methods, fields and inheritance/implementation edges.
  • Project references: a flowchart of projects with their project, package and assembly references.
  • Namespace dependencies: a flowchart of namespaces linked by derivations across them.
  • Inheritance: a solution-wide base → derived / interface realization graph, including external (framework/package) base types.

Parsing is done with Roslyn: the solution/project graph is loaded through MSBuildWorkspace when possible (giving resolved references and accurate documents), and any project that will not load falls back to a purely syntactic .cs sweep, so projects do not need to compile or restore.

Usage

Melusyn <input> [options]
Option Description
-o, --output <path> output .md file (or a directory when --split)
--split write one file per project plus an overview README.md
-d, --diagrams <list> which diagrams to emit: Classes, References, Namespaces, Inheritance (default: all)
-m, --members <level> member visibility in class diagrams: None, Public, NonPrivate, All (default: Public)
--no-properties omit properties from class diagrams
--no-methods omit methods from class diagrams
--fields include fields in class diagrams
--constructors include constructors in class diagrams
--group-by-namespace one class diagram per namespace
--direction <dir> flowchart direction TB, LR, BT, RL (default: TB)
--title <text> document title
--max-members <n> cap members shown per type (0 = unlimited)
--include-generated include generated / obj output

Examples

# whole solution, all diagrams, next to the input file
Melusyn MySolution.slnx

# a single project, everything including fields, to a chosen file
Melusyn src/App.csproj -o docs/model.md --members All --fields

# one Markdown file per project, only class and inheritance diagrams
Melusyn MySolution.sln --split -o docs/ -d Classes,Inheritance

Here is the output for Melusyn running on itself:

Project references

flowchart TB
    proj_Melusyn["Melusyn"]:::project
    pkg_Microsoft_Build_Framework(["Microsoft.Build.Framework@18.7.1"]):::package
    proj_Melusyn -.-> pkg_Microsoft_Build_Framework
    pkg_Microsoft_Build_Locator(["Microsoft.Build.Locator@1.11.2"]):::package
    proj_Melusyn -.-> pkg_Microsoft_Build_Locator
    pkg_Microsoft_NET_StringTools(["Microsoft.NET.StringTools@18.7.1"]):::package
    proj_Melusyn -.-> pkg_Microsoft_NET_StringTools
    pkg_System_CommandLine(["System.CommandLine@2.0.9"]):::package
    proj_Melusyn -.-> pkg_System_CommandLine
    pkg_Microsoft_CodeAnalysis_CSharp(["Microsoft.CodeAnalysis.CSharp@5.6.0"]):::package
    proj_Melusyn -.-> pkg_Microsoft_CodeAnalysis_CSharp
    pkg_Microsoft_CodeAnalysis_CSharp_Workspaces(["Microsoft.CodeAnalysis.CSharp.Workspaces@5.6.0"]):::package
    proj_Melusyn -.-> pkg_Microsoft_CodeAnalysis_CSharp_Workspaces
    pkg_Microsoft_CodeAnalysis_Workspaces_MSBuild(["Microsoft.CodeAnalysis.Workspaces.MSBuild@5.6.0"]):::package
    proj_Melusyn -.-> pkg_Microsoft_CodeAnalysis_Workspaces_MSBuild
    classDef project fill:#dae8fc,stroke:#6c8ebf,color:#000;
    classDef package fill:#d5e8d4,stroke:#82b366,color:#000;
    classDef assembly fill:#ffe6cc,stroke:#d79b00,color:#000;
Loading

Namespace dependencies

flowchart TB
    ns_Melusyn["Melusyn"]
    ns_Melusyn_Analysis["Melusyn.Analysis"]
    ns_Melusyn_Cli["Melusyn.Cli"]
    ns_Melusyn_Loading["Melusyn.Loading"]
    ns_Melusyn_Mermaid["Melusyn.Mermaid"]
    ns_Melusyn_Model["Melusyn.Model"]
    ns_Melusyn_Output["Melusyn.Output"]
Loading

Inheritance

Nothing to show.

Class diagrams

Melusyn

classDiagram
    class Melusyn_Program["Program"] {
        <<static>>
    }
    class Melusyn_Analysis_SymbolFormatting["SymbolFormatting"] {
        <<static>>
        +Display(ITypeSymbol) string$
        +FullName(INamedTypeSymbol) string$
        +NamespaceOf(INamedTypeSymbol) string$
    }
    class Melusyn_Analysis_TypeAnalyzer["TypeAnalyzer"] {
        <<static>>
        +Analyze(LoadedProject, CliOptions) ProjectModel$
    }
    class Melusyn_Cli_AppRunner["AppRunner"] {
        <<static>>
        +RunAsync(CliOptions, CancellationToken) Task~int~$
    }
    class Melusyn_Cli_CliOptions["CliOptions"] {
        +string InputPath
        +string? OutputPath
        +bool Split
        +IReadOnlySet~DiagramKind~ Diagrams
        +MemberFilter Members
        +bool IncludeProperties
        +bool IncludeMethods
        +bool IncludeFields
        +bool IncludeConstructors
        +bool GroupByNamespace
        +string Direction
        +string? Title
        +int MaxMembersPerType
        +bool ExcludeGenerated
        +IncludeMember(Accessibility) bool
    }
    class Melusyn_Cli_CommandFactory["CommandFactory"] {
        <<static>>
        +Create() RootCommand$
    }
    class Melusyn_Cli_DiagramKind["DiagramKind"] {
        <<enumeration>>
        Classes
        References
        Namespaces
        Inheritance
    }
    class Melusyn_Cli_MemberFilter["MemberFilter"] {
        <<enumeration>>
        None
        Public
        NonPrivate
        All
    }
    class Melusyn_Loading_CsprojFileParser["CsprojFileParser"] {
        <<static>>
        +ParseMeta(string) ProjectModel$
    }
    class Melusyn_Loading_GeneratedFile["GeneratedFile"] {
        <<static>>
        +IsInBuildOutput(string?) bool$
        +IsGenerated(string?) bool$
    }
    class Melusyn_Loading_LoadedProject["LoadedProject"] {
        +ProjectModel Meta
        +IReadOnlyList~SyntaxTree~ SyntaxTrees
        +IReadOnlyList~MetadataReference~ MetadataReferences
    }
    class Melusyn_Loading_MSBuildLoader["MSBuildLoader"] {
        <<static>>
        +TryLoadAsync(string, string, TextWriter, CancellationToken) Task~IReadOnlyDictionary~string, ProjectData~?~$
    }
    class Melusyn_Loading_MSBuildLoader_ProjectData["ProjectData"] {
        <<record>>
        +IReadOnlyList~SyntaxTree~ SyntaxTrees
        +IReadOnlyList~MetadataReference~ References
    }
    class Melusyn_Loading_ProjectSetLoader["ProjectSetLoader"] {
        <<static>>
        +LoadAsync(string, CliOptions, TextWriter, CancellationToken) Task~SolutionModel~$
    }
    class Melusyn_Loading_SolutionFileParser["SolutionFileParser"] {
        <<static>>
        +GetProjectPaths(string) IReadOnlyList~string~$
    }
    class Melusyn_Loading_SyntacticProjectReader["SyntacticProjectReader"] {
        <<static>>
        +ReadTrees(string, CliOptions) IReadOnlyList~SyntaxTree~$
    }
    class Melusyn_Mermaid_ClassDiagramGenerator["ClassDiagramGenerator"] {
        <<static>>
        +Generate(IReadOnlyList~TypeModel~, CliOptions) IReadOnlyList~DiagramSection~$
    }
    class Melusyn_Mermaid_DiagramSection["DiagramSection"] {
        <<record>>
        +string Title
        +string Mermaid
    }
    class Melusyn_Mermaid_IdAllocator["IdAllocator"] {
        +Get(string) string
        +Contains(string) bool
    }
    class Melusyn_Mermaid_InheritanceGraphGenerator["InheritanceGraphGenerator"] {
        <<static>>
        +Generate(SolutionModel) DiagramSection$
    }
    class Melusyn_Mermaid_MermaidText["MermaidText"] {
        <<static>>
        +Label(string) string$
        +Type(string) string$
    }
    class Melusyn_Mermaid_NamespaceGraphGenerator["NamespaceGraphGenerator"] {
        <<static>>
        +Generate(SolutionModel, CliOptions) DiagramSection$
    }
    class Melusyn_Mermaid_ReferenceGraphGenerator["ReferenceGraphGenerator"] {
        <<static>>
        +Generate(SolutionModel, CliOptions) DiagramSection$
    }
    class Melusyn_Mermaid_VisibilityGlyph["VisibilityGlyph"] {
        <<static>>
        +For(Accessibility) string$
    }
    class Melusyn_Model_FieldModel["FieldModel"] {
        <<record>>
        +string Name
        +string Type
        +Accessibility Accessibility
        +bool IsStatic
        +bool IsConst
    }
    class Melusyn_Model_MethodModel["MethodModel"] {
        <<record>>
        +string Name
        +string ReturnType
        +IReadOnlyList~ParameterModel~ Parameters
        +Accessibility Accessibility
        +bool IsStatic
        +bool IsAbstract
        +bool IsConstructor
    }
    class Melusyn_Model_PackageReferenceModel["PackageReferenceModel"] {
        <<record>>
        +string Name
        +string? Version
    }
    class Melusyn_Model_ParameterModel["ParameterModel"] {
        <<record>>
        +string Name
        +string Type
    }
    class Melusyn_Model_ProjectModel["ProjectModel"] {
        <<record>>
        +string Name
        +string AssemblyName
        +string Path
        +string? TargetFrameworks
        +IReadOnlyList~string~ ProjectReferences
        +IReadOnlyList~PackageReferenceModel~ PackageReferences
        +IReadOnlyList~string~ AssemblyReferences
        +IReadOnlyList~TypeModel~ Types
    }
    class Melusyn_Model_PropertyModel["PropertyModel"] {
        <<record>>
        +string Name
        +string Type
        +Accessibility Accessibility
        +bool IsStatic
        +bool HasGetter
        +bool HasSetter
    }
    class Melusyn_Model_SolutionModel["SolutionModel"] {
        <<record>>
        +string Name
        +string Path
        +IReadOnlyList~ProjectModel~ Projects
    }
    class Melusyn_Model_TypeModel["TypeModel"] {
        <<record>>
        +string Name
        +string FullName
        +string Namespace
        +TypeModelKind Kind
        +string ProjectName
        +Accessibility Accessibility
        +bool IsStatic
        +bool IsAbstract
        +bool IsSealed
        +IReadOnlyList~string~ TypeParameters
        +IReadOnlyList~TypeReferenceModel~ BaseTypes
        +IReadOnlyList~PropertyModel~ Properties
        +IReadOnlyList~MethodModel~ Methods
        +IReadOnlyList~FieldModel~ Fields
        +IReadOnlyList~string~ EnumMembers
    }
    class Melusyn_Model_TypeModelKind["TypeModelKind"] {
        <<enumeration>>
        Class
        Interface
        Struct
        Record
        RecordStruct
        Enum
        Delegate
    }
    class Melusyn_Model_TypeReferenceModel["TypeReferenceModel"] {
        <<record>>
        +string Display
        +string FullName
        +bool IsInterface
        +bool IsResolved
    }
    class Melusyn_Output_DocumentWriter["DocumentWriter"] {
        <<static>>
        +WriteAsync(SolutionModel, CliOptions) Task~IReadOnlyList~string~~$
    }
    class Melusyn_Output_MarkdownComposer["MarkdownComposer"] {
        <<static>>
        +ComposeSingle(SolutionModel, CliOptions) string$
        +ComposeOverview(SolutionModel, CliOptions) string$
        +ComposeProject(ProjectModel, CliOptions) string$
        +FileNameFor(ProjectModel) string$
    }
Loading

About

A tool that creates mermaid markdown files from Visual Studio solution and/or MsBuild projects.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages