1
+ using Spectre . Console ;
2
+ using DevConfigGenerator ;
3
+ using System . Runtime . InteropServices . Marshalling ;
4
+
5
+ var devConfig = new DevConfigFile ( ) ;
6
+
7
+ try
8
+ {
9
+ while ( true )
10
+ {
11
+ if ( devConfig . Core != null || devConfig . Services . Any ( ) )
12
+ {
13
+ var table = new Table ( ) ;
14
+ table . ShowRowSeparators = true ;
15
+ table . AddColumn ( "Package" ) ;
16
+ table . AddColumn ( "Type" ) ;
17
+ table . AddColumn ( "Change Messages" ) ;
18
+
19
+ if ( devConfig . Core != null )
20
+ {
21
+ table . AddRow ( devConfig . Core . FormattedNameColumn ( ) , devConfig . Core . Type , devConfig . Core . FormattedMessagesColumn ( ) ) ;
22
+ }
23
+
24
+ foreach ( var service in devConfig . Services )
25
+ {
26
+ table . AddRow ( service . FormattedNameColumn ( ) , service . Type , service . FormattedMessagesColumn ( ) ) ;
27
+ }
28
+
29
+ AnsiConsole . Write ( table ) ;
30
+ }
31
+
32
+ var changeType = AnsiConsole . Prompt (
33
+ new SelectionPrompt < string > ( )
34
+ . Title ( "What type of change was made?" )
35
+ . AddChoices ( new [ ] {
36
+ "Core" , "Generator" , "Service" , "Save DevConfigFile" , "Exit Without Saving"
37
+ } ) ) ;
38
+
39
+ switch ( changeType )
40
+ {
41
+ case "Core" :
42
+ CoreChange ( ) ;
43
+ break ;
44
+ case "Generator" :
45
+ GeneratorChange ( ) ;
46
+ break ;
47
+ case "Service" :
48
+ ServiceChange ( ) ;
49
+ break ;
50
+ case "Save DevConfigFile" :
51
+ WriteDevConfigFile ( ) ;
52
+ return ;
53
+ case "Exit Without Saving" :
54
+ return ;
55
+ }
56
+ }
57
+
58
+ }
59
+ catch ( Exception e )
60
+ {
61
+ Console . WriteLine ( "Unhandled exception while generating dev config file" ) ;
62
+ Console . WriteLine ( e . Message ) ;
63
+ }
64
+
65
+ void WriteDevConfigFile ( )
66
+ {
67
+ if ( devConfig . Core == null && ! devConfig . Services . Any ( ) )
68
+ {
69
+ AnsiConsole . Markup ( "[yellow]Skipped writing dev config since the config is empty[/]\n " ) ;
70
+ }
71
+
72
+ var devConfigDirectory = Path . Combine ( FindRepoRoot ( ) , "generator" , ".DevConfigs" ) ;
73
+ if ( ! Directory . Exists ( devConfigDirectory ) )
74
+ {
75
+ Directory . CreateDirectory ( devConfigDirectory ) ;
76
+ }
77
+
78
+ var devConfigFilePath = Path . Combine ( devConfigDirectory , Guid . NewGuid ( ) . ToString ( ) + ".json" ) ;
79
+ DevConfigWriter . Write ( devConfig , devConfigFilePath ) ;
80
+
81
+ AnsiConsole . Markup ( $ "DevConfig file written to: [green]{ devConfigFilePath } [/]\n ") ;
82
+ AnsiConsole . WriteLine ( File . ReadAllText ( devConfigFilePath ) ) ;
83
+ }
84
+
85
+
86
+ void CoreChange ( )
87
+ {
88
+ var change = AnsiConsole . Prompt ( new TextPrompt < string > ( "Enter the change message for the [green]core[/] change:" ) ) ;
89
+
90
+ var newCoreConfig = false ;
91
+ if ( devConfig . Core == null )
92
+ {
93
+ newCoreConfig = true ;
94
+ devConfig . Core = new CoreChange ( ) ;
95
+ }
96
+
97
+ devConfig . Core . Messages . Add ( change ) ;
98
+
99
+ devConfig . Core . Type = AskChangeType ( devConfig . Core . Type ) ;
100
+
101
+ var textPrompt = new TextPrompt < bool > ( "Should service packages be updated to use new Core?" )
102
+ . AddChoice ( true )
103
+ . AddChoice ( false )
104
+ . WithConverter ( choice => choice ? "y" : "n" ) ;
105
+
106
+ // If added a second change message to core then default the update service minimum to the value choosen for the previous entry.
107
+ if ( ! newCoreConfig )
108
+ {
109
+ textPrompt . DefaultValue ( devConfig . Core . UpdateServiceMinimum ) ;
110
+ }
111
+
112
+ var updateServiceMinimum = AnsiConsole . Prompt ( textPrompt ) ;
113
+
114
+ devConfig . Core . UpdateServiceMinimum = updateServiceMinimum ;
115
+ }
116
+
117
+ void GeneratorChange ( )
118
+ {
119
+ AnsiConsole . Markup ( "Generator changes are saved as [green]Core changes[/] with update service minimum set to [green]true[/].\n " ) ;
120
+ var change = AnsiConsole . Prompt ( new TextPrompt < string > ( "Enter the change message for the [green]generator[/] change:" ) ) ;
121
+
122
+ if ( devConfig . Core == null )
123
+ {
124
+ devConfig . Core = new CoreChange ( ) ;
125
+ }
126
+
127
+ devConfig . Core . Messages . Add ( change ) ;
128
+ devConfig . Core . UpdateServiceMinimum = true ;
129
+
130
+ devConfig . Core . Type = AskChangeType ( devConfig . Core . Type ) ;
131
+ }
132
+
133
+ void ServiceChange ( )
134
+ {
135
+ var serviceNames = new List < string > ( ) ;
136
+ foreach ( var serviceDirectory in Directory . GetDirectories ( Path . Combine ( FindRepoRoot ( ) , "sdk" , "src" , "Services" ) ) )
137
+ {
138
+ serviceNames . Add ( new DirectoryInfo ( serviceDirectory ) . Name ) ;
139
+ }
140
+
141
+ var searchQuery = AnsiConsole . Ask < string > ( "What service was changed (The name should match directory name in the sdk/src/Services parent directory)?" ) ;
142
+
143
+
144
+ string serviceName ;
145
+ if ( serviceNames . FirstOrDefault ( x => string . Equals ( x , searchQuery , StringComparison . OrdinalIgnoreCase ) ) != null )
146
+ {
147
+ serviceName = serviceNames . FirstOrDefault ( x => string . Equals ( x , searchQuery , StringComparison . OrdinalIgnoreCase ) ) ! ;
148
+ }
149
+ else
150
+ {
151
+ var topMatches = FuzzySharp . Process . ExtractTop ( searchQuery , serviceNames )
152
+ . Select ( result => result . Value )
153
+ . ToList ( ) ;
154
+
155
+ serviceName = AnsiConsole . Prompt (
156
+ new SelectionPrompt < string > ( )
157
+ . PageSize ( 10 )
158
+ . AddChoices ( topMatches ) ) ;
159
+ }
160
+
161
+
162
+ var service = devConfig . Services . FirstOrDefault ( x => x . Name == serviceName ) ;
163
+
164
+ // Check to see if this is the first change log entry for this service being added to the dev config.
165
+ // If so add the service to the list of services being changed.
166
+ if ( service == null )
167
+ {
168
+ service = new Service { Name = serviceName } ;
169
+ devConfig . Services . Add ( service ) ;
170
+ }
171
+
172
+ var change = AnsiConsole . Prompt ( new TextPrompt < string > ( $ "Enter the change message for [green]{ serviceName } [/] change:") ) ;
173
+ service . Messages . Add ( change ) ;
174
+
175
+ service . Type = AskChangeType ( service . Type ) ;
176
+ }
177
+
178
+ static string AskChangeType ( string defaultValue )
179
+ {
180
+ string [ ] choices ;
181
+ if ( defaultValue == "patch" )
182
+ {
183
+ choices = new [ ] { "patch" , "minor" } ;
184
+ }
185
+ else
186
+ {
187
+ choices = new [ ] { "minor" , "patch" } ;
188
+ }
189
+
190
+ var changeType = AnsiConsole . Prompt (
191
+ new SelectionPrompt < string > ( )
192
+ . Title ( "Type of change?" )
193
+ . AddChoices ( choices ) ) ;
194
+
195
+ return changeType ;
196
+ }
197
+
198
+ static string FindRepoRoot ( )
199
+ {
200
+ var directory = Directory . GetParent ( typeof ( Program ) . Assembly . Location ) ? . FullName ;
201
+ while ( directory != null )
202
+ {
203
+ if ( File . Exists ( Path . Combine ( directory , "SDK.CHANGELOG.MD" ) ) )
204
+ {
205
+ return directory ;
206
+ }
207
+
208
+ directory = Directory . GetParent ( directory ) ? . FullName ;
209
+ }
210
+
211
+ throw new ApplicationException ( "Failed to resolve SDK's repository root. The tool must be run within the SDK's repository" ) ;
212
+ }
0 commit comments