diff options
| author | Rob Mensching <rob@firegiant.com> | 2018-07-12 22:27:09 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2018-07-12 22:38:12 -0700 |
| commit | fc92b28f87599ac25d35399dc2df2f356a285960 (patch) | |
| tree | 0a775850ec5b4ff580b949700b51f5eee3182325 /src/light/LightCommandLine.cs | |
| parent | 1a2d7994764060dc6f8936fab1c03e255f2671c5 (diff) | |
| download | wix-fc92b28f87599ac25d35399dc2df2f356a285960.tar.gz wix-fc92b28f87599ac25d35399dc2df2f356a285960.tar.bz2 wix-fc92b28f87599ac25d35399dc2df2f356a285960.zip | |
Refactor command line parsing to enable extensions there in light.exe
Fixes wixtoolset/issues#5845
Diffstat (limited to 'src/light/LightCommandLine.cs')
| -rw-r--r-- | src/light/LightCommandLine.cs | 196 |
1 files changed, 66 insertions, 130 deletions
diff --git a/src/light/LightCommandLine.cs b/src/light/LightCommandLine.cs index 9a90b9ce..2aa9ea59 100644 --- a/src/light/LightCommandLine.cs +++ b/src/light/LightCommandLine.cs | |||
| @@ -6,8 +6,8 @@ namespace WixToolset.Tools | |||
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.Globalization; | 7 | using System.Globalization; |
| 8 | using System.IO; | 8 | using System.IO; |
| 9 | using WixToolset.Core.CommandLine; | ||
| 10 | using WixToolset.Data; | 9 | using WixToolset.Data; |
| 10 | using WixToolset.Extensibility; | ||
| 11 | using WixToolset.Extensibility.Services; | 11 | using WixToolset.Extensibility.Services; |
| 12 | 12 | ||
| 13 | public class LightCommandLine | 13 | public class LightCommandLine |
| @@ -22,7 +22,6 @@ namespace WixToolset.Tools | |||
| 22 | this.SuppressIces = new List<string>(); | 22 | this.SuppressIces = new List<string>(); |
| 23 | this.Ices = new List<string>(); | 23 | this.Ices = new List<string>(); |
| 24 | this.BindPaths = new List<BindPath>(); | 24 | this.BindPaths = new List<BindPath>(); |
| 25 | this.Extensions = new List<string>(); | ||
| 26 | this.Files = new List<string>(); | 25 | this.Files = new List<string>(); |
| 27 | this.LocalizationFiles = new List<string>(); | 26 | this.LocalizationFiles = new List<string>(); |
| 28 | this.Variables = new Dictionary<string, string>(); | 27 | this.Variables = new Dictionary<string, string>(); |
| @@ -80,8 +79,6 @@ namespace WixToolset.Tools | |||
| 80 | 79 | ||
| 81 | public List<BindPath> BindPaths { get; private set; } | 80 | public List<BindPath> BindPaths { get; private set; } |
| 82 | 81 | ||
| 83 | public List<string> Extensions { get; private set; } | ||
| 84 | |||
| 85 | public List<string> Files { get; private set; } | 82 | public List<string> Files { get; private set; } |
| 86 | 83 | ||
| 87 | public List<string> LocalizationFiles { get; private set; } | 84 | public List<string> LocalizationFiles { get; private set; } |
| @@ -96,35 +93,40 @@ namespace WixToolset.Tools | |||
| 96 | /// Parse the commandline arguments. | 93 | /// Parse the commandline arguments. |
| 97 | /// </summary> | 94 | /// </summary> |
| 98 | /// <param name="args">Commandline arguments.</param> | 95 | /// <param name="args">Commandline arguments.</param> |
| 99 | public string[] Parse(string[] args) | 96 | public string[] Parse(ICommandLineContext context) |
| 100 | { | 97 | { |
| 101 | List<string> unprocessed = new List<string>(); | 98 | var unprocessed = new List<string>(); |
| 99 | |||
| 100 | var extensions = context.ExtensionManager.Create<IExtensionCommandLine>(); | ||
| 101 | |||
| 102 | foreach (var extension in extensions) | ||
| 103 | { | ||
| 104 | extension.PreParse(context); | ||
| 105 | } | ||
| 106 | |||
| 107 | var parser = context.Arguments.Parse(); | ||
| 102 | 108 | ||
| 103 | for (int i = 0; i < args.Length; ++i) | 109 | while (!this.ShowHelp && |
| 110 | String.IsNullOrEmpty(parser.ErrorArgument) && | ||
| 111 | parser.TryGetNextSwitchOrArgument(out var arg)) | ||
| 104 | { | 112 | { |
| 105 | string arg = args[i]; | 113 | if (String.IsNullOrWhiteSpace(arg)) // skip blank arguments. |
| 106 | if (String.IsNullOrEmpty(arg)) // skip blank arguments | ||
| 107 | { | 114 | { |
| 108 | continue; | 115 | continue; |
| 109 | } | 116 | } |
| 110 | 117 | ||
| 111 | if (1 == arg.Length) // treat '-' and '@' as filenames when by themselves. | 118 | if (parser.IsSwitch(arg)) |
| 112 | { | 119 | { |
| 113 | unprocessed.Add(arg); | 120 | var parameter = arg.Substring(1); |
| 114 | } | ||
| 115 | else if ('-' == arg[0] || '/' == arg[0]) | ||
| 116 | { | ||
| 117 | string parameter = arg.Substring(1); | ||
| 118 | if (parameter.Equals("b", StringComparison.Ordinal)) | 121 | if (parameter.Equals("b", StringComparison.Ordinal)) |
| 119 | { | 122 | { |
| 120 | if (!CommandLineHelper.IsValidArg(args, ++i)) | 123 | var result = parser.GetNextArgumentOrError(arg); |
| 124 | if (!String.IsNullOrEmpty(result)) | ||
| 121 | { | 125 | { |
| 122 | break; | 126 | var bindPath = BindPath.Parse(result); |
| 123 | } | ||
| 124 | 127 | ||
| 125 | var bindPath = BindPath.Parse(args[i]); | 128 | this.BindPaths.Add(bindPath); |
| 126 | 129 | } | |
| 127 | this.BindPaths.Add(bindPath); | ||
| 128 | } | 130 | } |
| 129 | else if (parameter.StartsWith("cultures:", StringComparison.Ordinal)) | 131 | else if (parameter.StartsWith("cultures:", StringComparison.Ordinal)) |
| 130 | { | 132 | { |
| @@ -184,25 +186,9 @@ namespace WixToolset.Tools | |||
| 184 | this.Variables.Add(value[0], value[1]); | 186 | this.Variables.Add(value[0], value[1]); |
| 185 | } | 187 | } |
| 186 | } | 188 | } |
| 187 | else if (parameter.Equals("ext", StringComparison.Ordinal)) | ||
| 188 | { | ||
| 189 | if (!CommandLineHelper.IsValidArg(args, ++i)) | ||
| 190 | { | ||
| 191 | this.Messaging.Write(ErrorMessages.TypeSpecificationForExtensionRequired("-ext")); | ||
| 192 | break; | ||
| 193 | } | ||
| 194 | |||
| 195 | this.Extensions.Add(args[i]); | ||
| 196 | } | ||
| 197 | else if (parameter.Equals("loc", StringComparison.Ordinal)) | 189 | else if (parameter.Equals("loc", StringComparison.Ordinal)) |
| 198 | { | 190 | { |
| 199 | string locFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 191 | parser.GetNextArgumentAsFilePathOrError(arg, "localization files", this.LocalizationFiles); |
| 200 | if (String.IsNullOrEmpty(locFile)) | ||
| 201 | { | ||
| 202 | break; | ||
| 203 | } | ||
| 204 | |||
| 205 | this.LocalizationFiles.Add(locFile); | ||
| 206 | } | 192 | } |
| 207 | else if (parameter.Equals("nologo", StringComparison.Ordinal)) | 193 | else if (parameter.Equals("nologo", StringComparison.Ordinal)) |
| 208 | { | 194 | { |
| @@ -214,11 +200,7 @@ namespace WixToolset.Tools | |||
| 214 | } | 200 | } |
| 215 | else if ("o" == parameter || "out" == parameter) | 201 | else if ("o" == parameter || "out" == parameter) |
| 216 | { | 202 | { |
| 217 | this.OutputFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 203 | this.OutputFile = parser.GetNextArgumentAsFilePathOrError(arg); |
| 218 | if (String.IsNullOrEmpty(this.OutputFile)) | ||
| 219 | { | ||
| 220 | break; | ||
| 221 | } | ||
| 222 | } | 204 | } |
| 223 | else if (parameter.Equals("pedantic", StringComparison.Ordinal)) | 205 | else if (parameter.Equals("pedantic", StringComparison.Ordinal)) |
| 224 | { | 206 | { |
| @@ -230,12 +212,7 @@ namespace WixToolset.Tools | |||
| 230 | } | 212 | } |
| 231 | else if (parameter.Equals("usf", StringComparison.Ordinal)) | 213 | else if (parameter.Equals("usf", StringComparison.Ordinal)) |
| 232 | { | 214 | { |
| 233 | this.UnreferencedSymbolsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 215 | this.UnreferencedSymbolsFile = parser.GetNextArgumentAsDirectoryOrError(arg); |
| 234 | |||
| 235 | if (String.IsNullOrEmpty(this.UnreferencedSymbolsFile)) | ||
| 236 | { | ||
| 237 | break; | ||
| 238 | } | ||
| 239 | } | 216 | } |
| 240 | else if (parameter.Equals("xo", StringComparison.Ordinal)) | 217 | else if (parameter.Equals("xo", StringComparison.Ordinal)) |
| 241 | { | 218 | { |
| @@ -243,41 +220,27 @@ namespace WixToolset.Tools | |||
| 243 | } | 220 | } |
| 244 | else if (parameter.Equals("cc", StringComparison.Ordinal)) | 221 | else if (parameter.Equals("cc", StringComparison.Ordinal)) |
| 245 | { | 222 | { |
| 246 | this.CabCachePath = CommandLineHelper.GetDirectory(parameter, this.Messaging, args, ++i); | 223 | this.CabCachePath = parser.GetNextArgumentAsDirectoryOrError(arg); |
| 247 | |||
| 248 | if (String.IsNullOrEmpty(this.CabCachePath)) | ||
| 249 | { | ||
| 250 | break; | ||
| 251 | } | ||
| 252 | } | 224 | } |
| 253 | else if (parameter.Equals("ct", StringComparison.Ordinal)) | 225 | else if (parameter.Equals("ct", StringComparison.Ordinal)) |
| 254 | { | 226 | { |
| 255 | if (!CommandLineHelper.IsValidArg(args, ++i)) | 227 | var result = parser.GetNextArgumentOrError(arg); |
| 228 | if (!String.IsNullOrEmpty(result)) | ||
| 256 | { | 229 | { |
| 257 | this.Messaging.Write(ErrorMessages.IllegalCabbingThreadCount(String.Empty)); | 230 | if (!Int32.TryParse(result, out var ct) || 0 >= ct) |
| 258 | break; | 231 | { |
| 259 | } | 232 | this.Messaging.Write(ErrorMessages.IllegalCabbingThreadCount(result)); |
| 233 | parser.ErrorArgument = arg; | ||
| 234 | break; | ||
| 235 | } | ||
| 260 | 236 | ||
| 261 | int ct = 0; | 237 | this.CabbingThreadCount = ct; |
| 262 | if (!Int32.TryParse(args[i], out ct) || 0 >= ct) | 238 | this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString())); |
| 263 | { | ||
| 264 | this.Messaging.Write(ErrorMessages.IllegalCabbingThreadCount(args[i])); | ||
| 265 | break; | ||
| 266 | } | 239 | } |
| 267 | |||
| 268 | this.CabbingThreadCount = ct; | ||
| 269 | this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString())); | ||
| 270 | } | 240 | } |
| 271 | else if (parameter.Equals("cub", StringComparison.Ordinal)) | 241 | else if (parameter.Equals("cub", StringComparison.Ordinal)) |
| 272 | { | 242 | { |
| 273 | string cubeFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 243 | parser.GetNextArgumentAsFilePathOrError(arg, "static validation files", this.CubeFiles); |
| 274 | |||
| 275 | if (String.IsNullOrEmpty(cubeFile)) | ||
| 276 | { | ||
| 277 | break; | ||
| 278 | } | ||
| 279 | |||
| 280 | this.CubeFiles.Add(cubeFile); | ||
| 281 | } | 244 | } |
| 282 | else if (parameter.StartsWith("ice:", StringComparison.Ordinal)) | 245 | else if (parameter.StartsWith("ice:", StringComparison.Ordinal)) |
| 283 | { | 246 | { |
| @@ -285,57 +248,27 @@ namespace WixToolset.Tools | |||
| 285 | } | 248 | } |
| 286 | else if (parameter.Equals("intermediatefolder", StringComparison.OrdinalIgnoreCase)) | 249 | else if (parameter.Equals("intermediatefolder", StringComparison.OrdinalIgnoreCase)) |
| 287 | { | 250 | { |
| 288 | this.IntermediateFolder = CommandLineHelper.GetDirectory(parameter, this.Messaging, args, ++i); | 251 | this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(arg); |
| 289 | |||
| 290 | if (String.IsNullOrEmpty(this.IntermediateFolder)) | ||
| 291 | { | ||
| 292 | break; | ||
| 293 | } | ||
| 294 | } | 252 | } |
| 295 | else if (parameter.Equals("contentsfile", StringComparison.Ordinal)) | 253 | else if (parameter.Equals("contentsfile", StringComparison.Ordinal)) |
| 296 | { | 254 | { |
| 297 | this.ContentsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 255 | this.ContentsFile = parser.GetNextArgumentAsFilePathOrError(arg); |
| 298 | |||
| 299 | if (String.IsNullOrEmpty(this.ContentsFile)) | ||
| 300 | { | ||
| 301 | break; | ||
| 302 | } | ||
| 303 | } | 256 | } |
| 304 | else if (parameter.Equals("outputsfile", StringComparison.Ordinal)) | 257 | else if (parameter.Equals("outputsfile", StringComparison.Ordinal)) |
| 305 | { | 258 | { |
| 306 | this.OutputsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 259 | this.OutputsFile = parser.GetNextArgumentAsFilePathOrError(arg); |
| 307 | |||
| 308 | if (String.IsNullOrEmpty(this.OutputsFile)) | ||
| 309 | { | ||
| 310 | break; | ||
| 311 | } | ||
| 312 | } | 260 | } |
| 313 | else if (parameter.Equals("builtoutputsfile", StringComparison.Ordinal)) | 261 | else if (parameter.Equals("builtoutputsfile", StringComparison.Ordinal)) |
| 314 | { | 262 | { |
| 315 | this.BuiltOutputsFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 263 | this.BuiltOutputsFile = parser.GetNextArgumentAsFilePathOrError(arg); |
| 316 | |||
| 317 | if (String.IsNullOrEmpty(this.BuiltOutputsFile)) | ||
| 318 | { | ||
| 319 | break; | ||
| 320 | } | ||
| 321 | } | 264 | } |
| 322 | else if (parameter.Equals("wixprojectfile", StringComparison.Ordinal)) | 265 | else if (parameter.Equals("wixprojectfile", StringComparison.Ordinal)) |
| 323 | { | 266 | { |
| 324 | this.WixprojectFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 267 | this.WixprojectFile = parser.GetNextArgumentAsFilePathOrError(arg); |
| 325 | |||
| 326 | if (String.IsNullOrEmpty(this.WixprojectFile)) | ||
| 327 | { | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | } | 268 | } |
| 331 | else if (parameter.Equals("pdbout", StringComparison.Ordinal)) | 269 | else if (parameter.Equals("pdbout", StringComparison.Ordinal)) |
| 332 | { | 270 | { |
| 333 | this.PdbFile = CommandLineHelper.GetFile(parameter, this.Messaging, args, ++i); | 271 | this.PdbFile = parser.GetNextArgumentAsFilePathOrError(arg); |
| 334 | |||
| 335 | if (String.IsNullOrEmpty(this.PdbFile)) | ||
| 336 | { | ||
| 337 | break; | ||
| 338 | } | ||
| 339 | } | 272 | } |
| 340 | else if (parameter.StartsWith("sice:", StringComparison.Ordinal)) | 273 | else if (parameter.StartsWith("sice:", StringComparison.Ordinal)) |
| 341 | { | 274 | { |
| @@ -410,45 +343,35 @@ namespace WixToolset.Tools | |||
| 410 | this.ShowHelp = true; | 343 | this.ShowHelp = true; |
| 411 | break; | 344 | break; |
| 412 | } | 345 | } |
| 413 | else | 346 | else if (!this.TryParseCommandLineArgumentWithExtension(arg, parser, extensions)) |
| 414 | { | 347 | { |
| 415 | unprocessed.Add(arg); | 348 | unprocessed.Add(arg); |
| 416 | } | 349 | } |
| 417 | } | 350 | } |
| 418 | else if ('@' == arg[0]) | 351 | else if (!this.TryParseCommandLineArgumentWithExtension(arg, parser, extensions)) |
| 419 | { | ||
| 420 | string[] parsedArgs = CommandLineResponseFile.Parse(arg.Substring(1)); | ||
| 421 | string[] unparsedArgs = this.Parse(parsedArgs); | ||
| 422 | unprocessed.AddRange(unparsedArgs); | ||
| 423 | } | ||
| 424 | else | ||
| 425 | { | 352 | { |
| 426 | unprocessed.Add(arg); | 353 | unprocessed.Add(arg); |
| 427 | } | 354 | } |
| 428 | } | 355 | } |
| 429 | 356 | ||
| 430 | return unprocessed.ToArray(); | 357 | return this.ParsePostExtensions(parser, unprocessed.ToArray()); |
| 431 | } | 358 | } |
| 432 | 359 | ||
| 433 | public string[] ParsePostExtensions(string[] remaining) | 360 | private string[] ParsePostExtensions(IParseCommandLine parser, string[] remaining) |
| 434 | { | 361 | { |
| 435 | List<string> unprocessed = new List<string>(); | 362 | var unprocessed = new List<string>(); |
| 436 | 363 | ||
| 437 | for (int i = 0; i < remaining.Length; ++i) | 364 | for (int i = 0; i < remaining.Length; ++i) |
| 438 | { | 365 | { |
| 439 | string arg = remaining[i]; | 366 | var arg = remaining[i]; |
| 440 | if (String.IsNullOrEmpty(arg)) // skip blank arguments | ||
| 441 | { | ||
| 442 | continue; | ||
| 443 | } | ||
| 444 | 367 | ||
| 445 | if (1 < arg.Length && ('-' == arg[0] || '/' == arg[0])) | 368 | if (parser.IsSwitch(arg)) |
| 446 | { | 369 | { |
| 447 | unprocessed.Add(arg); | 370 | unprocessed.Add(arg); |
| 448 | } | 371 | } |
| 449 | else | 372 | else |
| 450 | { | 373 | { |
| 451 | this.Files.AddRange(CommandLineHelper.GetFiles(arg, "Source")); | 374 | parser.GetArgumentAsFilePathOrError(arg, "source files", this.Files); |
| 452 | } | 375 | } |
| 453 | } | 376 | } |
| 454 | 377 | ||
| @@ -469,7 +392,7 @@ namespace WixToolset.Tools | |||
| 469 | // Add the directories of the input files as unnamed bind paths. | 392 | // Add the directories of the input files as unnamed bind paths. |
| 470 | foreach (string file in this.Files) | 393 | foreach (string file in this.Files) |
| 471 | { | 394 | { |
| 472 | BindPath bindPath = new BindPath(Path.GetDirectoryName(Path.GetFullPath(file))); | 395 | var bindPath = new BindPath(Path.GetDirectoryName(Path.GetFullPath(file))); |
| 473 | this.BindPaths.Add(bindPath); | 396 | this.BindPaths.Add(bindPath); |
| 474 | } | 397 | } |
| 475 | } | 398 | } |
| @@ -481,5 +404,18 @@ namespace WixToolset.Tools | |||
| 481 | 404 | ||
| 482 | return unprocessed.ToArray(); | 405 | return unprocessed.ToArray(); |
| 483 | } | 406 | } |
| 407 | |||
| 408 | private bool TryParseCommandLineArgumentWithExtension(string arg, IParseCommandLine parser, IEnumerable<IExtensionCommandLine> extensions) | ||
| 409 | { | ||
| 410 | foreach (var extension in extensions) | ||
| 411 | { | ||
| 412 | if (extension.TryParseArgument(parser, arg)) | ||
| 413 | { | ||
| 414 | return true; | ||
| 415 | } | ||
| 416 | } | ||
| 417 | |||
| 418 | return false; | ||
| 419 | } | ||
| 484 | } | 420 | } |
| 485 | } | 421 | } |
