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
}