1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Linq ;
5+ using System . Runtime . InteropServices ;
6+ using System . Text ;
7+ using Microsoft . CodeAnalysis . CSharp ;
8+ using Microsoft . CodeAnalysis . Text ;
9+ using PlantUmlClassDiagramGenerator . Library ;
10+ using PlantUmlClassDiagramGenerator . Library . ClassDiagramGenerator ;
11+
12+ namespace PlantUmlClassDiagramGenerator . Generator ;
13+
14+ public class PlantUmlFromDirGenerator : IPlantUmlGenerator
15+ {
16+ public bool GeneratePlantUml ( Dictionary < string , string > parameters )
17+ {
18+ var inputRoot = parameters [ "in" ] ;
19+ if ( ! Directory . Exists ( inputRoot ) )
20+ {
21+ Console . WriteLine ( $ "Directory \" { inputRoot } \" does not exist.") ;
22+ return false ;
23+ }
24+
25+ // Use GetFullPath to fully support relative paths.
26+ var outputRoot = Path . GetFullPath ( inputRoot ) ;
27+ if ( parameters . TryGetValue ( "out" , out string outValue ) )
28+ {
29+ outputRoot = outValue ;
30+ try
31+ {
32+ Directory . CreateDirectory ( outputRoot ) ;
33+ }
34+ catch ( Exception e )
35+ {
36+ Console . WriteLine ( e ) ;
37+ return false ;
38+ }
39+ }
40+
41+ var excludePaths = new List < string > ( ) ;
42+ var pumlexclude = PathHelper . CombinePath ( inputRoot , ".pumlexclude" ) ;
43+ if ( File . Exists ( pumlexclude ) )
44+ {
45+ excludePaths = File
46+ . ReadAllLines ( pumlexclude )
47+ . Where ( path => ! string . IsNullOrWhiteSpace ( path ) )
48+ . Select ( path => path . Trim ( ) )
49+ . ToList ( ) ;
50+ }
51+ if ( parameters . TryGetValue ( "-excludePaths" , out string excludePathValue ) )
52+ {
53+ var splitOptions = StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ;
54+ excludePaths . AddRange ( excludePathValue . Split ( ',' , splitOptions ) ) ;
55+ }
56+
57+ var excludeUmlBeginEndTags = parameters . ContainsKey ( "-excludeUmlBeginEndTags" ) ;
58+ var files = Directory . EnumerateFiles ( inputRoot , "*.cs" , SearchOption . AllDirectories ) ;
59+
60+ var includeRefs = new StringBuilder ( ) ;
61+ if ( ! excludeUmlBeginEndTags ) includeRefs . AppendLine ( "@startuml" ) ;
62+
63+ var error = false ;
64+ var filesToProcess = ExcludeFileFilter . GetFilesToProcess ( files , excludePaths , inputRoot ) ;
65+ RelationshipCollection relationships = new ( ) ;
66+ foreach ( var inputFile in filesToProcess )
67+ {
68+ Console . WriteLine ( $ "Processing \" { inputFile } \" ...") ;
69+ try
70+ {
71+ var outputDir = PathHelper . CombinePath ( outputRoot , Path . GetDirectoryName ( inputFile ) . Replace ( inputRoot , "" ) ) ;
72+ Directory . CreateDirectory ( outputDir ) ;
73+ var outputFile = PathHelper . CombinePath ( outputDir , Path . GetFileNameWithoutExtension ( inputFile ) + ".puml" ) ;
74+
75+ using ( var stream = new FileStream ( inputFile , FileMode . Open , FileAccess . Read ) )
76+ {
77+ var tree = CSharpSyntaxTree . ParseText ( SourceText . From ( stream ) ) ;
78+ var root = tree . GetRoot ( ) ;
79+ Accessibilities ignoreAcc = IPlantUmlGenerator . GetIgnoreAccessibilities ( parameters ) ;
80+
81+ using var filestream = new FileStream ( outputFile , FileMode . Create , FileAccess . Write ) ;
82+ using var writer = new StreamWriter ( filestream ) ;
83+ var gen = new ClassDiagramGenerator (
84+ writer ,
85+ " " ,
86+ ignoreAcc ,
87+ parameters . ContainsKey ( "-createAssociation" ) ,
88+ parameters . ContainsKey ( "-attributeRequired" ) ,
89+ excludeUmlBeginEndTags ,
90+ parameters . ContainsKey ( "-addPackageTags" ) ) ;
91+ gen . Generate ( root ) ;
92+ relationships . AddAll ( gen . relationships ) ;
93+ }
94+
95+ if ( parameters . ContainsKey ( "-allInOne" ) )
96+ {
97+ var lines = File . ReadAllLines ( outputFile ) ;
98+ if ( ! excludeUmlBeginEndTags )
99+ {
100+ lines = lines . Skip ( 1 ) . SkipLast ( 1 ) . ToArray ( ) ;
101+ }
102+ foreach ( string line in lines )
103+ {
104+ includeRefs . AppendLine ( line ) ;
105+ }
106+ }
107+ else
108+ {
109+ var newRoot = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? @".\" : @"." ;
110+ includeRefs . AppendLine ( "!include " + outputFile . Replace ( outputRoot , newRoot ) ) ;
111+ }
112+ }
113+ catch ( Exception e )
114+ {
115+ Console . WriteLine ( e ) ;
116+ error = true ;
117+ }
118+ }
119+
120+ if ( parameters . ContainsKey ( "-addPackageTags" ) )
121+ {
122+ var lines = ClassDiagramGenerator . GenerateRelationships ( relationships ) ;
123+ foreach ( string line in lines . Distinct ( ) )
124+ {
125+ includeRefs . AppendLine ( line ) ;
126+ }
127+ }
128+
129+ if ( ! excludeUmlBeginEndTags ) includeRefs . AppendLine ( "@enduml" ) ;
130+ File . WriteAllText ( PathHelper . CombinePath ( outputRoot , "include.puml" ) , includeRefs . ToString ( ) ) ;
131+
132+ if ( error )
133+ {
134+ Console . WriteLine ( "There were files that could not be processed." ) ;
135+ return false ;
136+ }
137+ return true ;
138+ }
139+ }
0 commit comments