aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/CommandLine/BuildCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/CommandLine/BuildCommand.cs')
-rw-r--r--src/WixToolset.Core/CommandLine/BuildCommand.cs478
1 files changed, 390 insertions, 88 deletions
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs
index 6052d979..87a3cd30 100644
--- a/src/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -1,4 +1,4 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. 1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2 2
3namespace WixToolset.Core.CommandLine 3namespace WixToolset.Core.CommandLine
4{ 4{
@@ -14,83 +14,84 @@ namespace WixToolset.Core.CommandLine
14 14
15 internal class BuildCommand : ICommandLineCommand 15 internal class BuildCommand : ICommandLineCommand
16 { 16 {
17 public BuildCommand(IServiceProvider serviceProvider, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, IEnumerable<string> libraryFiles, IEnumerable<string> filterCultures, string outputPath, OutputType outputType, Platform platform, string cabCachePath, bool bindFiles, IEnumerable<BindPath> bindPaths, IEnumerable<string> includeSearchPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile) 17 private readonly CommandLine commandLine;
18
19 public BuildCommand(IServiceProvider serviceProvider)
18 { 20 {
19 this.ServiceProvider = serviceProvider; 21 this.ServiceProvider = serviceProvider;
20 this.Messaging = serviceProvider.GetService<IMessaging>(); 22 this.Messaging = serviceProvider.GetService<IMessaging>();
21 this.ExtensionManager = serviceProvider.GetService<IExtensionManager>(); 23 this.ExtensionManager = serviceProvider.GetService<IExtensionManager>();
22 this.LocFiles = locFiles; 24 this.commandLine = new CommandLine(this.Messaging);
23 this.LibraryFiles = libraryFiles;
24 this.FilterCultures = filterCultures;
25 this.PreprocessorVariables = preprocessorVariables;
26 this.SourceFiles = sources;
27 this.OutputPath = outputPath;
28 this.OutputType = outputType;
29 this.Platform = platform;
30
31 this.CabCachePath = cabCachePath;
32 this.BindFiles = bindFiles;
33 this.BindPaths = bindPaths;
34 this.IncludeSearchPaths = includeSearchPaths;
35
36 this.IntermediateFolder = intermediateFolder ?? Path.GetTempPath();
37 this.ContentsFile = contentsFile;
38 this.OutputsFile = outputsFile;
39 this.BuiltOutputsFile = builtOutputsFile;
40 } 25 }
41 26
42 public IServiceProvider ServiceProvider { get; } 27 public bool ShowLogo => this.commandLine.ShowLogo;
43 28
44 public IMessaging Messaging { get; } 29 public bool StopParsing => this.commandLine.ShowHelp;
45 30
46 public IExtensionManager ExtensionManager { get; } 31 private IServiceProvider ServiceProvider { get; }
47 32
48 public IEnumerable<string> FilterCultures { get; } 33 private IMessaging Messaging { get; }
49 34
50 public IEnumerable<string> IncludeSearchPaths { get; } 35 private IExtensionManager ExtensionManager { get; }
51 36
52 public IEnumerable<string> LocFiles { get; } 37 private string IntermediateFolder { get; set; }
53 38
54 public IEnumerable<string> LibraryFiles { get; } 39 private OutputType OutputType { get; set; }
55 40
56 private IEnumerable<SourceFile> SourceFiles { get; } 41 private List<string> IncludeSearchPaths { get; set; }
57 42
58 private IDictionary<string, string> PreprocessorVariables { get; } 43 private Platform Platform { get; set; }
59 44
60 private string OutputPath { get; } 45 private string OutputFile { get; set; }
61 46
62 private OutputType OutputType { get; } 47 private string ContentsFile { get; set; }
63 48
64 private Platform Platform { get; } 49 private string OutputsFile { get; set; }
65 50
66 public string CabCachePath { get; } 51 private string BuiltOutputsFile { get; set; }
67 52
68 public bool BindFiles { get; } 53 public int Execute()
54 {
55 if (this.commandLine.ShowHelp)
56 {
57 Console.WriteLine("TODO: Show build command help");
58 return -1;
59 }
69 60
70 public IEnumerable<BindPath> BindPaths { get; } 61 this.IntermediateFolder = this.commandLine.CalculateIntermedateFolder();
71 62
72 public string IntermediateFolder { get; } 63 this.OutputType = this.commandLine.CalculateOutputType();
73 64
74 public string ContentsFile { get; } 65 this.IncludeSearchPaths = this.commandLine.IncludeSearchPaths;
75 66
76 public string OutputsFile { get; } 67 this.Platform = this.commandLine.Platform;
77 68
78 public string BuiltOutputsFile { get; } 69 this.OutputFile = this.commandLine.OutputFile;
70
71 this.ContentsFile = this.commandLine.ContentsFile;
72
73 this.OutputsFile = this.commandLine.OutputsFile;
74
75 this.BuiltOutputsFile = this.commandLine.BuiltOutputsFile;
76
77 var preprocessorVariables = this.commandLine.GatherPreprocessorVariables();
78
79 var sourceFiles = this.commandLine.GatherSourceFiles(this.IntermediateFolder);
80
81 var filterCultures = this.commandLine.CalculateFilterCultures();
79 82
80 public int Execute()
81 {
82 var creator = this.ServiceProvider.GetService<ITupleDefinitionCreator>(); 83 var creator = this.ServiceProvider.GetService<ITupleDefinitionCreator>();
83 84
84 this.EvaluateSourceFiles(creator, out var codeFiles, out var wixipl); 85 this.EvaluateSourceFiles(sourceFiles, creator, out var codeFiles, out var wixipl);
85 86
86 if (this.Messaging.EncounteredError) 87 if (this.Messaging.EncounteredError)
87 { 88 {
88 return this.Messaging.LastErrorNumber; 89 return this.Messaging.LastErrorNumber;
89 } 90 }
90 91
91 var wixobjs = this.CompilePhase(codeFiles); 92 var wixobjs = this.CompilePhase(preprocessorVariables, codeFiles);
92 93
93 var wxls = this.LoadLocalizationFiles().ToList(); 94 var wxls = this.LoadLocalizationFiles(this.commandLine.LocalizationFilePaths, preprocessorVariables);
94 95
95 if (this.Messaging.EncounteredError) 96 if (this.Messaging.EncounteredError)
96 { 97 {
@@ -99,29 +100,29 @@ namespace WixToolset.Core.CommandLine
99 100
100 if (this.OutputType == OutputType.Library) 101 if (this.OutputType == OutputType.Library)
101 { 102 {
102 var wixlib = this.LibraryPhase(wixobjs, wxls); 103 var wixlib = this.LibraryPhase(wixobjs, wxls, this.commandLine.BindFiles, this.commandLine.BindPaths);
103 104
104 if (!this.Messaging.EncounteredError) 105 if (!this.Messaging.EncounteredError)
105 { 106 {
106 wixlib.Save(this.OutputPath); 107 wixlib.Save(this.commandLine.OutputFile);
107 } 108 }
108 } 109 }
109 else 110 else
110 { 111 {
111 if (wixipl == null) 112 if (wixipl == null)
112 { 113 {
113 wixipl = this.LinkPhase(wixobjs, creator); 114 wixipl = this.LinkPhase(wixobjs, this.commandLine.LibraryFilePaths, creator);
114 } 115 }
115 116
116 if (!this.Messaging.EncounteredError) 117 if (!this.Messaging.EncounteredError)
117 { 118 {
118 if (this.OutputType == OutputType.IntermediatePostLink) 119 if (this.OutputType == OutputType.IntermediatePostLink)
119 { 120 {
120 wixipl.Save(this.OutputPath); 121 wixipl.Save(this.commandLine.OutputFile);
121 } 122 }
122 else 123 else
123 { 124 {
124 this.BindPhase(wixipl, wxls); 125 this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths);
125 } 126 }
126 } 127 }
127 } 128 }
@@ -129,13 +130,18 @@ namespace WixToolset.Core.CommandLine
129 return this.Messaging.LastErrorNumber; 130 return this.Messaging.LastErrorNumber;
130 } 131 }
131 132
132 private void EvaluateSourceFiles(ITupleDefinitionCreator creator, out List<SourceFile> codeFiles, out Intermediate wixipl) 133 public bool TryParseArgument(ICommandLineParser parser, string argument)
134 {
135 return this.commandLine.TryParseArgument(argument, parser);
136 }
137
138 private void EvaluateSourceFiles(IEnumerable<SourceFile> sourceFiles, ITupleDefinitionCreator creator, out List<SourceFile> codeFiles, out Intermediate wixipl)
133 { 139 {
134 codeFiles = new List<SourceFile>(); 140 codeFiles = new List<SourceFile>();
135 141
136 wixipl = null; 142 wixipl = null;
137 143
138 foreach (var sourceFile in this.SourceFiles) 144 foreach (var sourceFile in sourceFiles)
139 { 145 {
140 var extension = Path.GetExtension(sourceFile.SourcePath); 146 var extension = Path.GetExtension(sourceFile.SourcePath);
141 147
@@ -167,13 +173,13 @@ namespace WixToolset.Core.CommandLine
167 } 173 }
168 } 174 }
169 175
170 private IEnumerable<Intermediate> CompilePhase(IEnumerable<SourceFile> sourceFiles) 176 private IEnumerable<Intermediate> CompilePhase(IDictionary<string, string> preprocessorVariables, IEnumerable<SourceFile> sourceFiles)
171 { 177 {
172 var intermediates = new List<Intermediate>(); 178 var intermediates = new List<Intermediate>();
173 179
174 foreach (var sourceFile in sourceFiles) 180 foreach (var sourceFile in sourceFiles)
175 { 181 {
176 var document = this.Preprocess(sourceFile.SourcePath); 182 var document = this.Preprocess(preprocessorVariables, sourceFile.SourcePath);
177 183
178 if (this.Messaging.EncounteredError) 184 if (this.Messaging.EncounteredError)
179 { 185 {
@@ -208,11 +214,11 @@ namespace WixToolset.Core.CommandLine
208 return intermediates; 214 return intermediates;
209 } 215 }
210 216
211 private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates, IEnumerable<Localization> localizations) 217 private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates, IEnumerable<Localization> localizations, bool bindFiles, IEnumerable<BindPath> bindPaths)
212 { 218 {
213 var context = this.ServiceProvider.GetService<ILibraryContext>(); 219 var context = this.ServiceProvider.GetService<ILibraryContext>();
214 context.BindFiles = this.BindFiles; 220 context.BindFiles = bindFiles;
215 context.BindPaths = this.BindPaths; 221 context.BindPaths = bindPaths;
216 context.Extensions = this.ExtensionManager.Create<ILibrarianExtension>(); 222 context.Extensions = this.ExtensionManager.Create<ILibrarianExtension>();
217 context.Localizations = localizations; 223 context.Localizations = localizations;
218 context.Intermediates = intermediates; 224 context.Intermediates = intermediates;
@@ -230,10 +236,10 @@ namespace WixToolset.Core.CommandLine
230 236
231 return library; 237 return library;
232 } 238 }
233 239
234 private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates, ITupleDefinitionCreator creator) 240 private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates, IEnumerable<string> libraryFiles, ITupleDefinitionCreator creator)
235 { 241 {
236 var libraries = this.LoadLibraries(creator); 242 var libraries = this.LoadLibraries(libraryFiles, creator);
237 243
238 if (this.Messaging.EncounteredError) 244 if (this.Messaging.EncounteredError)
239 { 245 {
@@ -251,7 +257,7 @@ namespace WixToolset.Core.CommandLine
251 return linker.Link(context); 257 return linker.Link(context);
252 } 258 }
253 259
254 private void BindPhase(Intermediate output, IEnumerable<Localization> localizations) 260 private void BindPhase(Intermediate output, IEnumerable<Localization> localizations, IEnumerable<string> filterCultures, string cabCachePath, IEnumerable<BindPath> bindPaths)
255 { 261 {
256 var intermediateFolder = this.IntermediateFolder; 262 var intermediateFolder = this.IntermediateFolder;
257 if (String.IsNullOrEmpty(intermediateFolder)) 263 if (String.IsNullOrEmpty(intermediateFolder))
@@ -262,10 +268,10 @@ namespace WixToolset.Core.CommandLine
262 ResolveResult resolveResult; 268 ResolveResult resolveResult;
263 { 269 {
264 var context = this.ServiceProvider.GetService<IResolveContext>(); 270 var context = this.ServiceProvider.GetService<IResolveContext>();
265 context.BindPaths = this.BindPaths; 271 context.BindPaths = bindPaths;
266 context.Extensions = this.ExtensionManager.Create<IResolverExtension>(); 272 context.Extensions = this.ExtensionManager.Create<IResolverExtension>();
267 context.ExtensionData = this.ExtensionManager.Create<IExtensionData>(); 273 context.ExtensionData = this.ExtensionManager.Create<IExtensionData>();
268 context.FilterCultures = this.FilterCultures; 274 context.FilterCultures = filterCultures;
269 context.IntermediateFolder = intermediateFolder; 275 context.IntermediateFolder = intermediateFolder;
270 context.IntermediateRepresentation = output; 276 context.IntermediateRepresentation = output;
271 context.Localizations = localizations; 277 context.Localizations = localizations;
@@ -284,7 +290,7 @@ namespace WixToolset.Core.CommandLine
284 { 290 {
285 var context = this.ServiceProvider.GetService<IBindContext>(); 291 var context = this.ServiceProvider.GetService<IBindContext>();
286 //context.CabbingThreadCount = this.CabbingThreadCount; 292 //context.CabbingThreadCount = this.CabbingThreadCount;
287 context.CabCachePath = this.CabCachePath; 293 context.CabCachePath = cabCachePath;
288 context.Codepage = resolveResult.Codepage; 294 context.Codepage = resolveResult.Codepage;
289 //context.DefaultCompressionLevel = this.DefaultCompressionLevel; 295 //context.DefaultCompressionLevel = this.DefaultCompressionLevel;
290 context.DelayedFields = resolveResult.DelayedFields; 296 context.DelayedFields = resolveResult.DelayedFields;
@@ -293,8 +299,8 @@ namespace WixToolset.Core.CommandLine
293 context.Ices = Array.Empty<string>(); // TODO: set this correctly 299 context.Ices = Array.Empty<string>(); // TODO: set this correctly
294 context.IntermediateFolder = intermediateFolder; 300 context.IntermediateFolder = intermediateFolder;
295 context.IntermediateRepresentation = resolveResult.IntermediateRepresentation; 301 context.IntermediateRepresentation = resolveResult.IntermediateRepresentation;
296 context.OutputPath = this.OutputPath; 302 context.OutputPath = this.OutputFile;
297 context.OutputPdbPath = Path.ChangeExtension(this.OutputPath, ".wixpdb"); 303 context.OutputPdbPath = Path.ChangeExtension(this.OutputFile, ".wixpdb");
298 context.SuppressIces = Array.Empty<string>(); // TODO: set this correctly 304 context.SuppressIces = Array.Empty<string>(); // TODO: set this correctly
299 context.SuppressValidation = true; // TODO: set this correctly 305 context.SuppressValidation = true; // TODO: set this correctly
300 306
@@ -323,41 +329,39 @@ namespace WixToolset.Core.CommandLine
323 } 329 }
324 } 330 }
325 331
326 private IEnumerable<Intermediate> LoadLibraries(ITupleDefinitionCreator creator) 332 private IEnumerable<Intermediate> LoadLibraries(IEnumerable<string> libraryFiles, ITupleDefinitionCreator creator)
327 { 333 {
328 var libraries = new List<Intermediate>(); 334 var libraries = new List<Intermediate>();
329 335
330 if (this.LibraryFiles != null) 336 foreach (var libraryFile in libraryFiles)
331 { 337 {
332 foreach (var libraryFile in this.LibraryFiles) 338 try
333 { 339 {
334 try 340 var library = Intermediate.Load(libraryFile, creator);
335 {
336 var library = Intermediate.Load(libraryFile, creator);
337 341
338 libraries.Add(library); 342 libraries.Add(library);
339 } 343 }
340 catch (WixCorruptFileException e) 344 catch (WixCorruptFileException e)
341 { 345 {
342 this.Messaging.Write(e.Error); 346 this.Messaging.Write(e.Error);
343 } 347 }
344 catch (WixUnexpectedFileFormatException e) 348 catch (WixUnexpectedFileFormatException e)
345 { 349 {
346 this.Messaging.Write(e.Error); 350 this.Messaging.Write(e.Error);
347 }
348 } 351 }
349 } 352 }
350 353
351 return libraries; 354 return libraries;
352 } 355 }
353 356
354 private IEnumerable<Localization> LoadLocalizationFiles() 357 private IEnumerable<Localization> LoadLocalizationFiles(IEnumerable<string> locFiles, IDictionary<string, string> preprocessorVariables)
355 { 358 {
356 var localizer = new Localizer(this.ServiceProvider); 359 var localizations = new List<Localization>();
360 var localizer = this.ServiceProvider.GetService<ILocalizer>();
357 361
358 foreach (var loc in this.LocFiles) 362 foreach (var loc in locFiles)
359 { 363 {
360 var document = this.Preprocess(loc); 364 var document = this.Preprocess(preprocessorVariables, loc);
361 365
362 if (this.Messaging.EncounteredError) 366 if (this.Messaging.EncounteredError)
363 { 367 {
@@ -365,18 +369,20 @@ namespace WixToolset.Core.CommandLine
365 } 369 }
366 370
367 var localization = localizer.ParseLocalizationFile(document); 371 var localization = localizer.ParseLocalizationFile(document);
368 yield return localization; 372 localizations.Add(localization);
369 } 373 }
374
375 return localizations;
370 } 376 }
371 377
372 private XDocument Preprocess(string sourcePath) 378 private XDocument Preprocess(IDictionary<string, string> preprocessorVariables, string sourcePath)
373 { 379 {
374 var context = this.ServiceProvider.GetService<IPreprocessContext>(); 380 var context = this.ServiceProvider.GetService<IPreprocessContext>();
375 context.Extensions = this.ExtensionManager.Create<IPreprocessorExtension>(); 381 context.Extensions = this.ExtensionManager.Create<IPreprocessorExtension>();
376 context.Platform = this.Platform; 382 context.Platform = this.Platform;
377 context.IncludeSearchPaths = this.IncludeSearchPaths; 383 context.IncludeSearchPaths = this.IncludeSearchPaths;
378 context.SourcePath = sourcePath; 384 context.SourcePath = sourcePath;
379 context.Variables = this.PreprocessorVariables; 385 context.Variables = preprocessorVariables;
380 386
381 XDocument document = null; 387 XDocument document = null;
382 try 388 try
@@ -391,5 +397,301 @@ namespace WixToolset.Core.CommandLine
391 397
392 return document; 398 return document;
393 } 399 }
400
401 private class CommandLine
402 {
403 private static readonly char[] BindPathSplit = { '=' };
404
405 public bool BindFiles { get; private set; }
406
407 public List<BindPath> BindPaths { get; } = new List<BindPath>();
408
409 public string CabCachePath { get; private set; }
410
411 public List<string> Cultures { get; } = new List<string>();
412
413 public List<string> Defines { get; } = new List<string>();
414
415 public List<string> IncludeSearchPaths { get; } = new List<string>();
416
417 public List<string> LocalizationFilePaths { get; } = new List<string>();
418
419 public List<string> LibraryFilePaths { get; } = new List<string>();
420
421 public List<string> SourceFilePaths { get; } = new List<string>();
422
423 public Platform Platform { get; private set; }
424
425 public bool ShowLogo { get; private set; }
426
427 public bool ShowHelp { get; private set; }
428
429 public string IntermediateFolder { get; private set; }
430
431 public string OutputFile { get; private set; }
432
433 public string OutputType { get; private set; }
434
435 public string ContentsFile { get; private set; }
436
437 public string OutputsFile { get; private set; }
438
439 public string BuiltOutputsFile { get; private set; }
440
441 public CommandLine(IMessaging messaging)
442 {
443 this.Messaging = messaging;
444 }
445
446 private IMessaging Messaging { get; }
447
448 public bool TryParseArgument(string arg, ICommandLineParser parser)
449 {
450 if (parser.IsSwitch(arg))
451 {
452 var parameter = arg.Substring(1);
453 switch (parameter.ToLowerInvariant())
454 {
455 case "?":
456 case "h":
457 case "help":
458 this.ShowHelp = true;
459 return true;
460
461 case "arch":
462 case "platform":
463 {
464 var value = parser.GetNextArgumentOrError(arg);
465 if (Enum.TryParse(value, true, out Platform platform))
466 {
467 this.Platform = platform;
468 return true;
469 }
470 break;
471 }
472
473 case "bindfiles":
474 this.BindFiles = true;
475 return true;
476
477 case "bindpath":
478 {
479 var value = parser.GetNextArgumentOrError(arg);
480 if (this.TryParseBindPath(value, out var bindPath))
481 {
482 this.BindPaths.Add(bindPath);
483 return true;
484 }
485 break;
486 }
487 case "cc":
488 this.CabCachePath = parser.GetNextArgumentOrError(arg);
489 return true;
490
491 case "culture":
492 parser.GetNextArgumentOrError(arg, this.Cultures);
493 return true;
494
495 case "contentsfile":
496 this.ContentsFile = parser.GetNextArgumentAsFilePathOrError(arg);
497 return true;
498 case "outputsfile":
499 this.OutputsFile = parser.GetNextArgumentAsFilePathOrError(arg);
500 return true;
501 case "builtoutputsfile":
502 this.BuiltOutputsFile = parser.GetNextArgumentAsFilePathOrError(arg);
503 return true;
504
505 case "d":
506 case "define":
507 parser.GetNextArgumentOrError(arg, this.Defines);
508 return true;
509
510 case "i":
511 case "includepath":
512 parser.GetNextArgumentOrError(arg, this.IncludeSearchPaths);
513 return true;
514
515 case "intermediatefolder":
516 this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(arg);
517 return true;
518
519 case "loc":
520 parser.GetNextArgumentAsFilePathOrError(arg, "localization files", this.LocalizationFilePaths);
521 return true;
522
523 case "lib":
524 parser.GetNextArgumentAsFilePathOrError(arg, "library files", this.LibraryFilePaths);
525 return true;
526
527 case "o":
528 case "out":
529 this.OutputFile = parser.GetNextArgumentAsFilePathOrError(arg);
530 return true;
531
532 case "outputtype":
533 this.OutputType = parser.GetNextArgumentOrError(arg);
534 return true;
535
536 case "nologo":
537 this.ShowLogo = false;
538 return true;
539
540 case "v":
541 case "verbose":
542 this.Messaging.ShowVerboseMessages = true;
543 return true;
544
545 case "sval":
546 // todo: implement
547 return true;
548
549 case "sw":
550 case "suppresswarning":
551 var warning = parser.GetNextArgumentOrError(arg);
552 if (!String.IsNullOrEmpty(warning))
553 {
554 var warningNumber = Convert.ToInt32(warning);
555 this.Messaging.SuppressWarningMessage(warningNumber);
556 }
557 return true;
558 }
559
560 return false;
561 }
562 else
563 {
564 parser.GetArgumentAsFilePathOrError(arg, "source code", this.SourceFilePaths);
565 return true;
566 }
567 }
568
569 public string CalculateIntermedateFolder()
570 {
571 return String.IsNullOrEmpty(this.IntermediateFolder) ? Path.GetTempPath() : this.IntermediateFolder;
572 }
573
574 public OutputType CalculateOutputType()
575 {
576 if (String.IsNullOrEmpty(this.OutputType))
577 {
578 this.OutputType = Path.GetExtension(this.OutputFile);
579 }
580
581 switch (this.OutputType.ToLowerInvariant())
582 {
583 case "bundle":
584 case ".exe":
585 return Data.OutputType.Bundle;
586
587 case "library":
588 case ".wixlib":
589 return Data.OutputType.Library;
590
591 case "module":
592 case ".msm":
593 return Data.OutputType.Module;
594
595 case "patch":
596 case ".msp":
597 return Data.OutputType.Patch;
598
599 case ".pcp":
600 return Data.OutputType.PatchCreation;
601
602 case "product":
603 case "package":
604 case ".msi":
605 return Data.OutputType.Product;
606
607 case "transform":
608 case ".mst":
609 return Data.OutputType.Transform;
610
611 case "intermediatepostlink":
612 case ".wixipl":
613 return Data.OutputType.IntermediatePostLink;
614 }
615
616 return Data.OutputType.Unknown;
617 }
618
619 public IEnumerable<string> CalculateFilterCultures()
620 {
621 var result = new List<string>();
622
623 if (this.Cultures == null)
624 {
625 }
626 else if (this.Cultures.Count == 1 && this.Cultures[0].Equals("null", StringComparison.OrdinalIgnoreCase))
627 {
628 // When null is used treat it as if cultures wasn't specified. This is
629 // needed for batching in the MSBuild task since MSBuild doesn't support
630 // empty items.
631 }
632 else
633 {
634 foreach (var culture in this.Cultures)
635 {
636 // Neutral is different from null. For neutral we still want to do culture filtering.
637 // Set the culture to the empty string = identifier for the invariant culture.
638 var filter = (culture.Equals("neutral", StringComparison.OrdinalIgnoreCase)) ? String.Empty : culture;
639 result.Add(filter);
640 }
641 }
642
643 return result;
644 }
645
646 public IDictionary<string, string> GatherPreprocessorVariables()
647 {
648 var variables = new Dictionary<string, string>();
649
650 foreach (var pair in this.Defines)
651 {
652 var value = pair.Split(new[] { '=' }, 2);
653
654 if (variables.ContainsKey(value[0]))
655 {
656 this.Messaging.Write(ErrorMessages.DuplicateVariableDefinition(value[0], (1 == value.Length) ? String.Empty : value[1], variables[value[0]]));
657 continue;
658 }
659
660 variables.Add(value[0], (1 == value.Length) ? String.Empty : value[1]);
661 }
662
663 return variables;
664 }
665
666
667 public IEnumerable<SourceFile> GatherSourceFiles(string intermediateDirectory)
668 {
669 var files = new List<SourceFile>();
670
671 foreach (var item in this.SourceFilePaths)
672 {
673 var sourcePath = item;
674 var outputPath = Path.Combine(intermediateDirectory, Path.GetFileNameWithoutExtension(sourcePath) + ".wir");
675
676 files.Add(new SourceFile(sourcePath, outputPath));
677 }
678
679 return files;
680 }
681
682 private bool TryParseBindPath(string bindPath, out BindPath bp)
683 {
684 var namedPath = bindPath.Split(BindPathSplit, 2);
685 bp = (1 == namedPath.Length) ? new BindPath(namedPath[0]) : new BindPath(namedPath[0], namedPath[1]);
686
687 if (File.Exists(bp.Path))
688 {
689 this.Messaging.Write(ErrorMessages.ExpectedDirectoryGotFile("-bindpath", bp.Path));
690 return false;
691 }
692
693 return true;
694 }
695 }
394 } 696 }
395} 697}