@joebigelow / wix-1 / commits / 04b8976c

Make commands async and internal processes cancelable

Rob Mensching committed Jun 8, 2020 at 16:25 UTC 04b8976ca565ce95cf32a58c8725843618724383
13 files changed +75 -45
src/WixToolset.Core.TestPackage/WixRunner.cs
+7 -4
@@ -4,6 +4,8 @@ namespace WixToolset.Core.TestPackage
4 {
5 using System;
6 using System.Collections.Generic;
7 + using System.Threading;
8 + using System.Threading.Tasks;
9 using WixToolset.Data;
10 using WixToolset.Extensibility.Data;
11 using WixToolset.Extensibility.Services;
@@ -13,17 +15,18 @@ namespace WixToolset.Core.TestPackage
15 public static int Execute(string[] args, out List<Message> messages)
16 {
17 var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider();
16 - return Execute(args, serviceProvider, out messages);
18 + var task = Execute(args, serviceProvider, out messages);
19 + return task.Result;
20 }
21
22 public static WixRunnerResult Execute(params string[] args)
23 {
24 var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider();
25 var exitCode = Execute(args, serviceProvider, out var messages);
23 - return new WixRunnerResult { ExitCode = exitCode, Messages = messages.ToArray() };
26 + return new WixRunnerResult { ExitCode = exitCode.Result, Messages = messages.ToArray() };
27 }
28
26 - public static int Execute(string[] args, IWixToolsetServiceProvider serviceProvider, out List<Message> messages)
29 + public static Task<int> Execute(string[] args, IWixToolsetServiceProvider serviceProvider, out List<Message> messages)
30 {
31 var listener = new TestMessageListener();
32
@@ -39,7 +42,7 @@ namespace WixToolset.Core.TestPackage
42 commandLine.ExtensionManager = CreateExtensionManagerWithStandardBackends(serviceProvider, arguments.Extensions);
43 commandLine.Arguments = arguments;
44 var command = commandLine.ParseStandardCommandLine();
42 - return command?.Execute() ?? 1;
45 + return command?.ExecuteAsync(CancellationToken.None) ?? Task.FromResult(1);
46 }
47
48 private static IExtensionManager CreateExtensionManagerWithStandardBackends(IWixToolsetServiceProvider serviceProvider, string[] extensions)
src/WixToolset.Core/BindContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Data;
@@ -55,5 +55,7 @@ namespace WixToolset.Core
55 public bool SuppressValidation { get; set; }
56
57 public bool SuppressLayout { get; set; }
58 +
59 + public CancellationToken CancellationToken { get; set; }
60 }
61 }
src/WixToolset.Core/CommandLine/BuildCommand.cs
+27 -18
@@ -6,6 +6,8 @@ namespace WixToolset.Core.CommandLine
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 + using System.Threading;
10 + using System.Threading.Tasks;
11 using System.Xml.Linq;
12 using WixToolset.Data;
13 using WixToolset.Extensibility;
@@ -54,12 +56,12 @@ namespace WixToolset.Core.CommandLine
56
57 private string BuiltOutputsFile { get; set; }
58
57 - public int Execute()
59 + public Task<int> ExecuteAsync(CancellationToken cancellationToken)
60 {
61 if (this.commandLine.ShowHelp)
62 {
63 Console.WriteLine("TODO: Show build command help");
62 - return -1;
64 + return Task.FromResult(-1);
65 }
66
67 this.IntermediateFolder = this.commandLine.CalculateIntermedateFolder();
@@ -107,23 +109,23 @@ namespace WixToolset.Core.CommandLine
109
110 if (this.Messaging.EncounteredError)
111 {
110 - return this.Messaging.LastErrorNumber;
112 + return Task.FromResult(this.Messaging.LastErrorNumber);
113 }
114
113 - var wixobjs = this.CompilePhase(preprocessorVariables, codeFiles);
115 + var wixobjs = this.CompilePhase(preprocessorVariables, codeFiles, cancellationToken);
116
115 - var wxls = this.LoadLocalizationFiles(this.commandLine.LocalizationFilePaths, preprocessorVariables);
117 + var wxls = this.LoadLocalizationFiles(this.commandLine.LocalizationFilePaths, preprocessorVariables, cancellationToken);
118
119 if (this.Messaging.EncounteredError)
120 {
119 - return this.Messaging.LastErrorNumber;
121 + return Task.FromResult(this.Messaging.LastErrorNumber);
122 }
123
124 if (this.OutputType == OutputType.Library)
125 {
126 using (new IntermediateFieldContext("wix.lib"))
127 {
126 - var wixlib = this.LibraryPhase(wixobjs, wxls, this.commandLine.BindFiles, this.commandLine.BindPaths);
128 + var wixlib = this.LibraryPhase(wixobjs, wxls, this.commandLine.BindFiles, this.commandLine.BindPaths, cancellationToken);
129
130 if (!this.Messaging.EncounteredError)
131 {
@@ -137,7 +139,7 @@ namespace WixToolset.Core.CommandLine
139 {
140 if (wixipl == null)
141 {
140 - wixipl = this.LinkPhase(wixobjs, this.commandLine.LibraryFilePaths, creator);
142 + wixipl = this.LinkPhase(wixobjs, this.commandLine.LibraryFilePaths, creator, cancellationToken);
143 }
144
145 if (!this.Messaging.EncounteredError)
@@ -157,14 +159,14 @@ namespace WixToolset.Core.CommandLine
159 {
160 using (new IntermediateFieldContext("wix.bind"))
161 {
160 - this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths);
162 + this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths, cancellationToken);
163 }
164 }
165 }
166 }
167 }
168
167 - return this.Messaging.LastErrorNumber;
169 + return Task.FromResult(this.Messaging.LastErrorNumber);
170 }
171
172 public bool TryParseArgument(ICommandLineParser parser, string argument)
@@ -210,13 +212,13 @@ namespace WixToolset.Core.CommandLine
212 }
213 }
214
213 - private IEnumerable<Intermediate> CompilePhase(IDictionary<string, string> preprocessorVariables, IEnumerable<SourceFile> sourceFiles)
215 + private IEnumerable<Intermediate> CompilePhase(IDictionary<string, string> preprocessorVariables, IEnumerable<SourceFile> sourceFiles, CancellationToken cancellationToken)
216 {
217 var intermediates = new List<Intermediate>();
218
219 foreach (var sourceFile in sourceFiles)
220 {
219 - var document = this.Preprocess(preprocessorVariables, sourceFile.SourcePath);
221 + var document = this.Preprocess(preprocessorVariables, sourceFile.SourcePath, cancellationToken);
222
223 if (this.Messaging.EncounteredError)
224 {
@@ -228,6 +230,7 @@ namespace WixToolset.Core.CommandLine
230 context.OutputPath = sourceFile.OutputPath;
231 context.Platform = this.Platform;
232 context.Source = document;
233 + context.CancellationToken = cancellationToken;
234
235 Intermediate intermediate = null;
236 try
@@ -251,7 +254,7 @@ namespace WixToolset.Core.CommandLine
254 return intermediates;
255 }
256
254 - private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates, IEnumerable<Localization> localizations, bool bindFiles, IEnumerable<IBindPath> bindPaths)
257 + private Intermediate LibraryPhase(IEnumerable<Intermediate> intermediates, IEnumerable<Localization> localizations, bool bindFiles, IEnumerable<IBindPath> bindPaths, CancellationToken cancellationToken)
258 {
259 var context = this.ServiceProvider.GetService<ILibraryContext>();
260 context.BindFiles = bindFiles;
@@ -259,6 +262,7 @@ namespace WixToolset.Core.CommandLine
262 context.Extensions = this.ExtensionManager.GetServices<ILibrarianExtension>();
263 context.Localizations = localizations;
264 context.Intermediates = intermediates;
265 + context.CancellationToken = cancellationToken;
266
267 Intermediate library = null;
268 try
@@ -274,7 +278,7 @@ namespace WixToolset.Core.CommandLine
278 return library;
279 }
280
277 - private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates, IEnumerable<string> libraryFiles, ITupleDefinitionCreator creator)
281 + private Intermediate LinkPhase(IEnumerable<Intermediate> intermediates, IEnumerable<string> libraryFiles, ITupleDefinitionCreator creator, CancellationToken cancellationToken)
282 {
283 var libraries = this.LoadLibraries(libraryFiles, creator);
284
@@ -289,12 +293,13 @@ namespace WixToolset.Core.CommandLine
293 context.ExpectedOutputType = this.OutputType;
294 context.Intermediates = intermediates.Concat(libraries).ToList();
295 context.TupleDefinitionCreator = creator;
296 + context.CancellationToken = cancellationToken;
297
298 var linker = this.ServiceProvider.GetService<ILinker>();
299 return linker.Link(context);
300 }
301
297 - private void BindPhase(Intermediate output, IEnumerable<Localization> localizations, IEnumerable<string> filterCultures, string cabCachePath, IEnumerable<IBindPath> bindPaths)
302 + private void BindPhase(Intermediate output, IEnumerable<Localization> localizations, IEnumerable<string> filterCultures, string cabCachePath, IEnumerable<IBindPath> bindPaths, CancellationToken cancellationToken)
303 {
304 var intermediateFolder = this.IntermediateFolder;
305 if (String.IsNullOrEmpty(intermediateFolder))
@@ -312,6 +317,7 @@ namespace WixToolset.Core.CommandLine
317 context.IntermediateFolder = intermediateFolder;
318 context.IntermediateRepresentation = output;
319 context.Localizations = localizations;
320 + context.CancellationToken = cancellationToken;
321
322 var resolver = this.ServiceProvider.GetService<IResolver>();
323 resolveResult = resolver.Resolve(context);
@@ -343,6 +349,7 @@ namespace WixToolset.Core.CommandLine
349 context.PdbPath = this.PdbType == PdbType.None ? null : this.PdbFile ?? Path.ChangeExtension(this.OutputFile, ".wixpdb");
350 context.SuppressIces = Array.Empty<string>(); // TODO: set this correctly
351 context.SuppressValidation = true; // TODO: set this correctly
352 + context.CancellationToken = cancellationToken;
353
354 var binder = this.ServiceProvider.GetService<IBinder>();
355 bindResult = binder.Bind(context);
@@ -363,6 +370,7 @@ namespace WixToolset.Core.CommandLine
370 context.OutputsFile = this.OutputsFile;
371 context.BuiltOutputsFile = this.BuiltOutputsFile;
372 context.SuppressAclReset = false; // TODO: correctly set SuppressAclReset
373 + context.CancellationToken = cancellationToken;
374
375 var layout = this.ServiceProvider.GetService<ILayoutCreator>();
376 layout.Layout(context);
@@ -392,14 +400,14 @@ namespace WixToolset.Core.CommandLine
400 return Array.Empty<Intermediate>();
401 }
402
395 - private IEnumerable<Localization> LoadLocalizationFiles(IEnumerable<string> locFiles, IDictionary<string, string> preprocessorVariables)
403 + private IEnumerable<Localization> LoadLocalizationFiles(IEnumerable<string> locFiles, IDictionary<string, string> preprocessorVariables, CancellationToken cancellationToken)
404 {
405 var localizations = new List<Localization>();
406 var parser = this.ServiceProvider.GetService<ILocalizationParser>();
407
408 foreach (var loc in locFiles)
409 {
402 - var document = this.Preprocess(preprocessorVariables, loc);
410 + var document = this.Preprocess(preprocessorVariables, loc, cancellationToken);
411
412 if (this.Messaging.EncounteredError)
413 {
@@ -413,7 +421,7 @@ namespace WixToolset.Core.CommandLine
421 return localizations;
422 }
423
416 - private XDocument Preprocess(IDictionary<string, string> preprocessorVariables, string sourcePath)
424 + private XDocument Preprocess(IDictionary<string, string> preprocessorVariables, string sourcePath, CancellationToken cancellationToken)
425 {
426 var context = this.ServiceProvider.GetService<IPreprocessContext>();
427 context.Extensions = this.ExtensionManager.GetServices<IPreprocessorExtension>();
@@ -421,6 +429,7 @@ namespace WixToolset.Core.CommandLine
429 context.IncludeSearchPaths = this.IncludeSearchPaths;
430 context.SourcePath = sourcePath;
431 context.Variables = preprocessorVariables;
432 + context.CancellationToken = cancellationToken;
433
434 IPreprocessResult result = null;
435 try
src/WixToolset.Core/CommandLine/CompileCommand.cs
+5 -7
@@ -4,7 +4,8 @@ namespace WixToolset.Core.CommandLine
4 {
5 using System;
6 using System.Collections.Generic;
7 - using System.Xml.Linq;
7 + using System.Threading;
8 + using System.Threading.Tasks;
9 using WixToolset.Data;
10 using WixToolset.Extensibility;
11 using WixToolset.Extensibility.Data;
@@ -47,12 +48,9 @@ namespace WixToolset.Core.CommandLine
48
49 public bool StopParsing => throw new NotImplementedException();
50
50 - public bool TryParseArgument(ICommandLineParser parseHelper, string argument)
51 - {
52 - throw new NotImplementedException();
53 - }
51 + public bool TryParseArgument(ICommandLineParser parseHelper, string argument) => throw new NotImplementedException();
52
55 - public int Execute()
53 + public Task<int> ExecuteAsync(CancellationToken _)
54 {
55 foreach (var sourceFile in this.SourceFiles)
56 {
@@ -91,7 +89,7 @@ namespace WixToolset.Core.CommandLine
89 intermediate.Save(sourceFile.OutputPath);
90 }
91
94 - return 0;
92 + return Task.FromResult(0);
93 }
94 }
95 }
src/WixToolset.Core/CommandLine/DecompileCommand.cs
+6 -4
@@ -4,6 +4,8 @@ namespace WixToolset.Core.CommandLine
4 {
5 using System;
6 using System.IO;
7 + using System.Threading;
8 + using System.Threading.Tasks;
9 using System.Xml.Linq;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
@@ -29,12 +31,12 @@ namespace WixToolset.Core.CommandLine
31
32 public IMessaging Messaging { get; }
33
32 - public int Execute()
34 + public Task<int> ExecuteAsync(CancellationToken _)
35 {
36 if (this.commandLine.ShowHelp)
37 {
38 Console.WriteLine("TODO: Show decompile command help");
37 - return -1;
39 + return Task.FromResult(-1);
40 }
41
42 var context = this.ServiceProvider.GetService<IDecompileContext>();
@@ -61,10 +63,10 @@ namespace WixToolset.Core.CommandLine
63
64 if (this.Messaging.EncounteredError)
65 {
64 - return 1;
66 + return Task.FromResult(1);
67 }
68
67 - return 0;
69 + return Task.FromResult(0);
70 }
71
72 public bool TryParseArgument(ICommandLineParser parser, string argument)
src/WixToolset.Core/CommandLine/HelpCommand.cs
+5 -3
@@ -1,8 +1,10 @@
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
3 namespace WixToolset.Core.CommandLine
4 {
5 using System;
6 + using System.Threading;
7 + using System.Threading.Tasks;
8 using WixToolset.Extensibility.Data;
9 using WixToolset.Extensibility.Services;
10
@@ -12,11 +14,11 @@ namespace WixToolset.Core.CommandLine
14
15 public bool StopParsing => true;
16
15 - public int Execute()
17 + public Task<int> ExecuteAsync(CancellationToken _)
18 {
19 Console.WriteLine("TODO: Show list of available commands");
20
19 - return -1;
21 + return Task.FromResult(-1);
22 }
23
24 public bool TryParseArgument(ICommandLineParser parseHelper, string argument)
src/WixToolset.Core/CommandLine/VersionCommand.cs
+4 -2
@@ -3,6 +3,8 @@
3 namespace WixToolset.Core.CommandLine
4 {
5 using System;
6 + using System.Threading;
7 + using System.Threading.Tasks;
8 using WixToolset.Extensibility.Data;
9 using WixToolset.Extensibility.Services;
10
@@ -12,12 +14,12 @@ namespace WixToolset.Core.CommandLine
14
15 public bool StopParsing => true;
16
15 - public int Execute()
17 + public Task<int> ExecuteAsync(CancellationToken cancellationToken)
18 {
19 Console.WriteLine("wix version {0}", ThisAssembly.AssemblyInformationalVersion);
20 Console.WriteLine();
21
20 - return 0;
22 + return Task.FromResult(0);
23 }
24
25 public bool TryParseArgument(ICommandLineParser parseHelper, string argument) => true; // eat any arguments
src/WixToolset.Core/CompileContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
@@ -28,5 +28,7 @@ namespace WixToolset.Core
28 public Platform Platform { get; set; }
29
30 public XDocument Source { get; set; }
31 +
32 + public CancellationToken CancellationToken { get; set; }
33 }
34 }
src/WixToolset.Core/LayoutContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using WixToolset.Extensibility;
8 using WixToolset.Extensibility.Data;
9 using WixToolset.Extensibility.Services;
@@ -34,5 +34,7 @@ namespace WixToolset.Core
34 public string BuiltOutputsFile { get; set; }
35
36 public bool SuppressAclReset { get; set; }
37 +
38 + public CancellationToken CancellationToken { get; set; }
39 }
40 }
src/WixToolset.Core/LibraryContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Data;
@@ -31,5 +31,7 @@ namespace WixToolset.Core
31 public IEnumerable<Localization> Localizations { get; set; }
32
33 public IEnumerable<Intermediate> Intermediates { get; set; }
34 +
35 + public CancellationToken CancellationToken { get; set; }
36 }
37 }
src/WixToolset.Core/LinkContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Data;
@@ -27,5 +27,7 @@ namespace WixToolset.Core
27 public IEnumerable<Intermediate> Intermediates { get; set; }
28
29 public ITupleDefinitionCreator TupleDefinitionCreator { get; set; }
30 +
31 + public CancellationToken CancellationToken { get; set; }
32 }
33 }
src/WixToolset.Core/PreprocessContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Data;
@@ -29,5 +29,7 @@ namespace WixToolset.Core
29 public IDictionary<string, string> Variables { get; set; }
30
31 public SourceLineNumber CurrentSourceLineNumber { get; set; }
32 +
33 + public CancellationToken CancellationToken { get; set; }
34 }
35 }
src/WixToolset.Core/ResolveContext.cs
+3 -1
@@ -2,8 +2,8 @@
2
3 namespace WixToolset.Core
4 {
5 - using System;
5 using System.Collections.Generic;
6 + using System.Threading;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9 using WixToolset.Extensibility.Data;
@@ -35,5 +35,7 @@ namespace WixToolset.Core
35 public IVariableResolver VariableResolver { get; set; }
36
37 public bool AllowUnresolvedVariables { get; set; }
38 +
39 + public CancellationToken CancellationToken { get; set; }
40 }
41 }