2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using System . Reflection ;
5
+ using System . Runtime . InteropServices ;
6
+ using BenchmarkDotNet . Build . Options ;
5
7
using Cake . Frosting ;
6
8
7
9
namespace BenchmarkDotNet . Build ;
@@ -10,6 +12,9 @@ public class CommandLineParser
10
12
{
11
13
private const string ScriptName = "build.cmd" ;
12
14
15
+ private static readonly string CallScriptName =
16
+ ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) ? ScriptName : "./" + ScriptName ;
17
+
13
18
public static readonly CommandLineParser Instance = new ( ) ;
14
19
15
20
public string [ ] ? Parse ( string [ ] ? args )
@@ -53,63 +58,32 @@ public class CommandLineParser
53
58
{
54
59
var arg = argsToProcess . Dequeue ( ) ;
55
60
56
- var matched = false ;
57
- foreach ( var option in options )
58
- {
59
- if ( Is ( arg , option . ShortName , option . FullName ) )
60
- {
61
- matched = true ;
62
- cakeArgs . Add ( option . CakeOption ) ;
63
- if ( option . Arg != "" )
64
- {
65
- if ( ! argsToProcess . Any ( ) )
66
- {
67
- PrintError ( option . FullName + " is not specified" ) ;
68
- return null ;
69
- }
70
-
71
- cakeArgs . Add ( argsToProcess . Dequeue ( ) ) ;
72
- }
73
- }
74
- }
75
-
76
61
if ( arg . StartsWith ( "/p:" ) )
77
62
{
78
- matched = true ;
79
63
cakeArgs . Add ( "--msbuild" ) ;
80
64
cakeArgs . Add ( arg [ 3 ..] ) ;
65
+ continue ;
81
66
}
82
67
83
- if ( ! matched )
68
+ if ( arg . StartsWith ( '-' ) )
84
69
{
85
- PrintError ( "Unknown option: " + arg ) ;
86
- return null ;
70
+ cakeArgs . Add ( arg ) ;
71
+ if ( argsToProcess . Any ( ) && ! argsToProcess . Peek ( ) . StartsWith ( '-' ) )
72
+ cakeArgs . Add ( argsToProcess . Dequeue ( ) ) ;
73
+ continue ;
87
74
}
75
+
76
+ PrintError ( "Unknown option: " + arg ) ;
77
+ return null ;
88
78
}
89
79
90
80
return cakeArgs . ToArray ( ) ;
91
81
}
92
82
93
83
94
- private record Option ( string ShortName , string FullName , string Arg , string Description , string CakeOption ) ;
95
-
96
- private readonly Option [ ] options =
84
+ private readonly IOption [ ] baseOptions =
97
85
{
98
- new ( "-v" ,
99
- "--verbosity" ,
100
- "<LEVEL>" ,
101
- "Specifies the amount of information to be displayed\n (Quiet, Minimal, Normal, Verbose, Diagnostic)" ,
102
- "--verbosity" ) ,
103
- new ( "-e" ,
104
- "--exclusive" ,
105
- "" ,
106
- "Executes the target task without any dependencies" ,
107
- "--exclusive" ) ,
108
- new ( "-h" ,
109
- "--help" ,
110
- "" ,
111
- "Prints help information for the target task" ,
112
- "" )
86
+ KnownOptions . Verbosity , KnownOptions . Exclusive , KnownOptions . Help
113
87
} ;
114
88
115
89
private void PrintHelp ( )
@@ -127,7 +101,7 @@ private void PrintHelp()
127
101
WriteHeader ( "Usage:" ) ;
128
102
129
103
WritePrefix ( ) ;
130
- Write ( ScriptName + " " ) ;
104
+ Write ( CallScriptName + " " ) ;
131
105
WriteTask ( "<TASK> " ) ;
132
106
WriteOption ( "[OPTIONS]" ) ;
133
107
WriteLine ( ) ;
@@ -137,12 +111,12 @@ private void PrintHelp()
137
111
WriteHeader ( "Examples:" ) ;
138
112
139
113
WritePrefix ( ) ;
140
- Write ( ScriptName + " " ) ;
114
+ Write ( CallScriptName + " " ) ;
141
115
WriteTask ( "restore" ) ;
142
116
WriteLine ( ) ;
143
117
144
118
WritePrefix ( ) ;
145
- Write ( ScriptName + " " ) ;
119
+ Write ( CallScriptName + " " ) ;
146
120
WriteTask ( "build " ) ;
147
121
WriteOption ( "/p:" ) ;
148
122
WriteArg ( "Configuration" ) ;
@@ -151,7 +125,7 @@ private void PrintHelp()
151
125
WriteLine ( ) ;
152
126
153
127
WritePrefix ( ) ;
154
- Write ( ScriptName + " " ) ;
128
+ Write ( CallScriptName + " " ) ;
155
129
WriteTask ( "pack " ) ;
156
130
WriteOption ( "/p:" ) ;
157
131
WriteArg ( "VersionPrefix" ) ;
@@ -164,27 +138,29 @@ private void PrintHelp()
164
138
WriteLine ( ) ;
165
139
166
140
WritePrefix ( ) ;
167
- Write ( ScriptName + " " ) ;
141
+ Write ( CallScriptName + " " ) ;
168
142
WriteTask ( "unittests " ) ;
169
143
WriteOption ( "--exclusive --verbosity " ) ;
170
144
WriteArg ( "Diagnostic" ) ;
171
145
WriteLine ( ) ;
172
146
173
147
WritePrefix ( ) ;
174
- Write ( ScriptName + " " ) ;
148
+ Write ( CallScriptName + " " ) ;
175
149
WriteTask ( "docs-update " ) ;
176
- WriteOption ( "/p:" ) ;
177
- WriteArg ( "Depth" ) ;
178
- WriteOption ( "=" ) ;
150
+ WriteOption ( "--depth " ) ;
179
151
WriteArg ( "3" ) ;
180
152
WriteLine ( ) ;
181
153
154
+ WritePrefix ( ) ;
155
+ Write ( CallScriptName + " " ) ;
156
+ WriteTask ( "docs-build " ) ;
157
+ WriteOption ( "--preview " ) ;
182
158
WriteLine ( ) ;
183
159
184
- PrintCommonOptions ( ) ;
185
-
186
160
WriteLine ( ) ;
187
161
162
+ PrintOptions ( baseOptions ) ;
163
+
188
164
WriteHeader ( "Tasks:" ) ;
189
165
var taskWidth = GetTaskNames ( ) . Max ( name => name . Length ) + 3 ;
190
166
foreach ( var ( taskName , taskDescription ) in GetTasks ( ) )
@@ -207,29 +183,47 @@ private void PrintHelp()
207
183
}
208
184
}
209
185
210
- private void PrintCommonOptions ( )
186
+ private void PrintOptions ( IOption [ ] options )
211
187
{
188
+ const string valuePlaceholder = "<VALUE>" ;
189
+
212
190
WriteLine ( "Options:" , ConsoleColor . DarkCyan ) ;
213
191
214
- var shortNameWidth = options . Max ( it => it . ShortName . Length ) ;
215
- var targetWidth = options . Max ( it => it . FullName . Length + it . Arg . Length ) ;
192
+ int GetWidth ( IOption option )
193
+ {
194
+ int width = option . CommandLineName . Length ;
195
+ foreach ( var alias in option . Aliases )
196
+ width += 1 + alias . Length ;
197
+ if ( option is StringOption )
198
+ width += 1 + valuePlaceholder . Length ;
199
+ return width ;
200
+ }
216
201
217
- foreach ( var ( shortName , fullName , arg , description , _) in options )
202
+ const int descriptionGap = 3 ;
203
+ var maxWidth = options . Max ( GetWidth ) + descriptionGap ;
204
+
205
+ foreach ( var option in options )
218
206
{
207
+ var allNames = option . Aliases . Append ( option . CommandLineName ) . OrderBy ( name => name . Length ) ;
208
+ var joinName = string . Join ( ',' , allNames ) ;
209
+
219
210
WritePrefix ( ) ;
220
- WriteOption ( shortName . PadRight ( shortNameWidth ) ) ;
221
- WriteOption ( shortName != "" ? "," : " " ) ;
222
- WriteOption ( fullName ) ;
223
- Write ( " " ) ;
224
- WriteArg ( arg ) ;
225
- Write ( new string ( ' ' , targetWidth - fullName . Length - arg . Length + 3 ) ) ;
226
- var descriptionLines = description . Split ( new [ ] { '\n ' } , StringSplitOptions . RemoveEmptyEntries ) ;
211
+ WriteOption ( joinName ) ;
212
+ if ( option is StringOption )
213
+ {
214
+ Write ( " " ) ;
215
+ WriteArg ( valuePlaceholder ) ;
216
+ }
217
+
218
+ Write ( new string ( ' ' ,
219
+ maxWidth - joinName . Length - ( option is StringOption ? valuePlaceholder . Length + 1 : 0 ) ) ) ;
220
+ var descriptionLines = option . Description . Split ( new [ ] { '\n ' } , StringSplitOptions . RemoveEmptyEntries ) ;
227
221
Write ( descriptionLines . FirstOrDefault ( ) ?? "" ) ;
228
222
for ( int i = 1 ; i < descriptionLines . Length ; i ++ )
229
223
{
230
224
WriteLine ( ) ;
231
225
WritePrefix ( ) ;
232
- Write ( new string ( ' ' , shortNameWidth + 2 + targetWidth + 3 ) ) ;
226
+ Write ( new string ( ' ' , maxWidth ) ) ;
233
227
Write ( descriptionLines [ i ] ) ;
234
228
}
235
229
@@ -240,10 +234,12 @@ private void PrintCommonOptions()
240
234
WriteOption ( "/p:" ) ;
241
235
WriteArg ( "<KEY>" ) ;
242
236
WriteOption ( "=" ) ;
243
- WriteArg ( "<VALUE>" ) ;
244
- Write ( new string ( ' ' , targetWidth + shortNameWidth - 11 ) ) ;
237
+ WriteArg ( valuePlaceholder ) ;
238
+ Write ( new string ( ' ' , maxWidth - "/p:<KEY>=" . Length - valuePlaceholder . Length ) ) ;
245
239
Write ( "Passes custom properties to MSBuild" ) ;
246
240
WriteLine ( ) ;
241
+
242
+ WriteLine ( ) ;
247
243
}
248
244
249
245
private void PrintTaskHelp ( string taskName )
@@ -267,18 +263,19 @@ private void PrintTaskHelp(string taskName)
267
263
WriteLine ( taskDescription ) ;
268
264
}
269
265
270
- foreach ( var line in helpInfo . Description )
271
- {
272
- WritePrefix ( ) ;
273
- WriteLine ( line ) ;
274
- }
266
+ if ( string . IsNullOrWhiteSpace ( helpInfo . Description ) )
267
+ foreach ( var line in helpInfo . Description . Split ( '\n ' , StringSplitOptions . RemoveEmptyEntries ) )
268
+ {
269
+ WritePrefix ( ) ;
270
+ WriteLine ( line . Trim ( ) ) ;
271
+ }
275
272
276
273
WriteLine ( ) ;
277
274
278
275
WriteHeader ( "Usage:" ) ;
279
276
280
277
WritePrefix ( ) ;
281
- Write ( ScriptName + " " ) ;
278
+ Write ( CallScriptName + " " ) ;
282
279
WriteTask ( taskName + " " ) ;
283
280
WriteOption ( "[OPTIONS]" ) ;
284
281
WriteLine ( ) ;
@@ -309,7 +306,19 @@ private void PrintTaskHelp(string taskName)
309
306
310
307
WriteLine ( ) ;
311
308
312
- PrintCommonOptions ( ) ;
309
+ PrintOptions ( helpInfo . Options . Concat ( baseOptions ) . ToArray ( ) ) ;
310
+
311
+ if ( helpInfo . EnvironmentVariables . Any ( ) )
312
+ {
313
+ WriteHeader ( "Environment variables:" ) ;
314
+ foreach ( var variable in helpInfo . EnvironmentVariables )
315
+ {
316
+ WritePrefix ( ) ;
317
+ WriteOption ( variable ) ;
318
+ }
319
+
320
+ WriteLine ( ) ;
321
+ }
313
322
}
314
323
315
324
private static HashSet < string > GetTaskNames ( )
0 commit comments