Redesign command-line help to meet the needs of WiX v4
Rob Mensching committed
Aug 11, 2022 at 17:40 UTC
a6f8b6fa3903d846cdc2fbe715ca951d83af3107
38 files changed
+685
-363
src/api/wix/WixToolset.Extensibility/BaseCommandLineCommand.cs
new
+40
@@ -0,0 +1,40 @@
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.Extensibility
4
+{
5
+ using System.Threading;
6
+ using System.Threading.Tasks;
7
+ using WixToolset.Extensibility.Data;
8
+ using WixToolset.Extensibility.Services;
9
+
10
+ /// <summary>
11
+ /// Base class for a command-line command.
12
+ /// </summary>
13
+ public abstract class BaseCommandLineCommand : ICommandLineCommand
14
+ {
15
+ /// <summary>
16
+ /// See <see cref="ICommandLineCommand.ShowLogo" />
17
+ /// </summary>
18
+ public virtual bool ShowLogo => false;
19
+
20
+ /// <summary>
21
+ /// See <see cref="ICommandLineCommand.StopParsing" />
22
+ /// </summary>
23
+ public bool StopParsing { get; protected set; }
24
+
25
+ /// <summary>
26
+ /// See <see cref="ICommandLineCommand.ExecuteAsync" />
27
+ /// </summary>
28
+ public abstract Task<int> ExecuteAsync(CancellationToken cancellationToken);
29
+
30
+ /// <summary>
31
+ /// See <see cref="ICommandLineCommand.GetCommandLineHelp" />
32
+ /// </summary>
33
+ public abstract CommandLineHelp GetCommandLineHelp();
34
+
35
+ /// <summary>
36
+ /// See <see cref="ICommandLineCommand.TryParseArgument" />
37
+ /// </summary>
38
+ public abstract bool TryParseArgument(ICommandLineParser parser, string argument);
39
+ }
40
+}
src/api/wix/WixToolset.Extensibility/BaseExtensionCommandLine.cs
+5
-4
@@ -2,8 +2,6 @@
2
3
namespace WixToolset.Extensibility
4
{
5
- using System;
6
- using System.Collections.Generic;
5
using WixToolset.Extensibility.Data;
6
using WixToolset.Extensibility.Services;
7
@@ -13,9 +11,12 @@ namespace WixToolset.Extensibility
11
public abstract class BaseExtensionCommandLine : IExtensionCommandLine
12
{
13
/// <summary>
16
- /// See <see cref="IExtensionCommandLine.CommandLineSwitches" />
14
+ /// See <see cref="IExtensionCommandLine.GetCommandLineHelp" />
15
/// </summary>
18
- public virtual IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => Array.Empty<ExtensionCommandLineSwitch>();
16
+ public virtual CommandLineHelp GetCommandLineHelp()
17
+ {
18
+ return null;
19
+ }
20
21
/// <summary>
22
/// See <see cref="IExtensionCommandLine.PostParse" />
src/api/wix/WixToolset.Extensibility/Data/CommandLineHelp.cs
new
+52
@@ -0,0 +1,52 @@
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.Extensibility.Data
4
+{
5
+ using System.Collections.Generic;
6
+
7
+ /// <summary>
8
+ /// A command line option (switch or command) description.
9
+ /// </summary>
10
+ public class CommandLineHelp
11
+ {
12
+ /// <summary>
13
+ /// Creates command line help.
14
+ /// </summary>
15
+ /// <param name="description">Description for the command line option.</param>
16
+ /// <param name="usage">Optional usage for the command line option.</param>
17
+ /// <param name="switches">Optional list of switches.</param>
18
+ /// <param name="commands">Optional list of commands.</param>
19
+ public CommandLineHelp(string description, string usage = null, IReadOnlyCollection<CommandLineHelpSwitch> switches = null, IReadOnlyCollection<CommandLineHelpCommand> commands = null)
20
+ {
21
+ this.Description = description;
22
+ this.Usage = usage;
23
+ this.Switches = switches;
24
+ this.Commands = commands;
25
+ }
26
+
27
+ /// <summary>
28
+ /// Description for the command line option.
29
+ /// </summary>
30
+ public string Description { get; set; }
31
+
32
+ /// <summary>
33
+ /// Usage for the command line option.
34
+ /// </summary>
35
+ public string Usage { get; set; }
36
+
37
+ /// <summary>
38
+ /// Optional additional notes for the command line option.
39
+ /// </summary>
40
+ public string Notes { get; set; }
41
+
42
+ /// <summary>
43
+ /// Optional list of command line switches.
44
+ /// </summary>
45
+ public IReadOnlyCollection<CommandLineHelpSwitch> Switches { get; set; }
46
+
47
+ /// <summary>
48
+ /// Optional list of command line commands.
49
+ /// </summary>
50
+ public IReadOnlyCollection<CommandLineHelpCommand> Commands { get; set; }
51
+ }
52
+}
src/api/wix/WixToolset.Extensibility/Data/CommandLineHelpCommand.cs
new
+31
@@ -0,0 +1,31 @@
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.Extensibility.Data
4
+{
5
+ /// <summary>
6
+ /// A command line command description.
7
+ /// </summary>
8
+ public class CommandLineHelpCommand
9
+ {
10
+ /// <summary>
11
+ /// Creates help for command line command.
12
+ /// </summary>
13
+ /// <param name="name">Name of command.</param>
14
+ /// <param name="description">Description for command.</param>
15
+ public CommandLineHelpCommand(string name, string description)
16
+ {
17
+ Name = name;
18
+ Description = description;
19
+ }
20
+
21
+ /// <summary>
22
+ /// Name of command.
23
+ /// </summary>
24
+ public string Name { get; set; }
25
+
26
+ /// <summary>
27
+ /// Description of the command.
28
+ /// </summary>
29
+ public string Description { get; set; }
30
+ }
31
+}
src/api/wix/WixToolset.Extensibility/Data/CommandLineHelpSwitch.cs
new
+47
@@ -0,0 +1,47 @@
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.Extensibility.Data
4
+{
5
+ /// <summary>
6
+ /// A command line switch description.
7
+ /// </summary>
8
+ public class CommandLineHelpSwitch
9
+ {
10
+ /// <summary>
11
+ /// Creates help for command line switch.
12
+ /// </summary>
13
+ /// <param name="name">Name of switch.</param>
14
+ /// <param name="description">Description for switch.</param>
15
+ public CommandLineHelpSwitch(string name, string description) : this(name, null, description)
16
+ {
17
+ }
18
+
19
+ /// <summary>
20
+ /// Creates help for command line switch.
21
+ /// </summary>
22
+ /// <param name="name">Name of switch.</param>
23
+ /// <param name="shortName">Optional short name of switch.</param>
24
+ /// <param name="description">Description for switch.</param>
25
+ public CommandLineHelpSwitch(string name, string shortName, string description)
26
+ {
27
+ Name = name;
28
+ ShortName = shortName;
29
+ Description = description;
30
+ }
31
+
32
+ /// <summary>
33
+ /// Name for switch.
34
+ /// </summary>
35
+ public string Name { get; set; }
36
+
37
+ /// <summary>
38
+ /// Optional short name for switch.
39
+ /// </summary>
40
+ public string ShortName { get; set; }
41
+
42
+ /// <summary>
43
+ /// Description of the switch.
44
+ /// </summary>
45
+ public string Description { get; set; }
46
+ }
47
+}
src/api/wix/WixToolset.Extensibility/Data/ExtensionCommandLineSwitch.cs
deleted
-20
@@ -1,20 +0,0 @@
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.Extensibility.Data
4
-{
5
- /// <summary>
6
- /// A command line option.
7
- /// </summary>
8
- public struct ExtensionCommandLineSwitch
9
- {
10
- /// <summary>
11
- ///
12
- /// </summary>
13
- public string Switch { get; set; }
14
-
15
- /// <summary>
16
- ///
17
- /// </summary>
18
- public string Description { get; set; }
19
- }
20
-}
src/api/wix/WixToolset.Extensibility/Data/ICommandLineCommand.cs
+6
-6
@@ -12,19 +12,19 @@ namespace WixToolset.Extensibility.Data
12
public interface ICommandLineCommand
13
{
14
/// <summary>
15
- /// Indicates the command-line should show help for the command.
15
+ /// Indicates the command-line should show the logo.
16
/// </summary>
17
- bool ShowHelp { get; set; }
17
+ bool ShowLogo { get; }
18
19
/// <summary>
20
- /// Indicates the command-line should show the command-line logo.
20
+ /// Indicates the command-line parsing can stop.
21
/// </summary>
22
- bool ShowLogo { get; set; }
22
+ bool StopParsing { get; }
23
24
/// <summary>
25
- /// Indicates the command-line parsing can stop.
25
+ /// Gets the help for this command.
26
/// </summary>
27
- bool StopParsing { get; }
27
+ CommandLineHelp GetCommandLineHelp();
28
29
/// <summary>
30
/// Executes the command.
src/api/wix/WixToolset.Extensibility/IExtensionCommandLine.cs
+2
-4
@@ -2,7 +2,6 @@
2
3
namespace WixToolset.Extensibility
4
{
5
- using System.Collections.Generic;
5
using WixToolset.Extensibility.Data;
6
using WixToolset.Extensibility.Services;
7
@@ -12,10 +11,9 @@ namespace WixToolset.Extensibility
11
public interface IExtensionCommandLine
12
{
13
/// <summary>
15
- /// Gets the supported command line types for this extension.
14
+ /// Gets the help for this extension.
15
/// </summary>
17
- /// <value>The supported command line types for this extension.</value>
18
- IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches { get; }
16
+ CommandLineHelp GetCommandLineHelp();
17
18
/// <summary>
19
/// Called before the command-line is parsed.
src/tools/heat/HeatCommand.cs
+13
-9
@@ -11,13 +11,16 @@ namespace WixToolset.Harvesters
11
using System.Threading.Tasks;
12
using System.Xml;
13
using WixToolset.Data;
14
+ using WixToolset.Extensibility;
15
using WixToolset.Extensibility.Data;
16
using WixToolset.Extensibility.Services;
17
using WixToolset.Harvesters.Extensibility;
18
using Wix = WixToolset.Harvesters.Serialize;
19
19
- internal class HeatCommand : ICommandLineCommand
20
+ internal class HeatCommand : BaseCommandLineCommand
21
{
22
+ private bool showLogo;
23
+
24
public HeatCommand(string harvestType, IList<IHeatExtension> extensions, IServiceProvider serviceProvider)
25
{
26
this.Extensions = extensions;
@@ -28,11 +31,7 @@ namespace WixToolset.Harvesters
31
this.ExtensionOptions.Add(harvestType);
32
}
33
31
- public bool ShowHelp { get; set; }
32
-
33
- public bool ShowLogo { get; set; }
34
-
35
- public bool StopParsing { get; private set; }
34
+ public override bool ShowLogo => this.showLogo;
35
36
private string ExtensionArgument { get; set; }
37
@@ -50,13 +49,18 @@ namespace WixToolset.Harvesters
49
50
private IServiceProvider ServiceProvider { get; }
51
53
- public Task<int> ExecuteAsync(CancellationToken cancellationToken)
52
+ public override CommandLineHelp GetCommandLineHelp()
53
+ {
54
+ return null;
55
+ }
56
+
57
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
58
{
59
var exitCode = this.Harvest();
60
return Task.FromResult(exitCode);
61
}
62
59
- public bool TryParseArgument(ICommandLineParser parser, string arg)
63
+ public override bool TryParseArgument(ICommandLineParser parser, string arg)
64
{
65
if (this.ExtensionArgument == null)
66
{
@@ -67,7 +71,7 @@ namespace WixToolset.Harvesters
71
string parameter = arg.Substring(1);
72
if ("nologo" == parameter)
73
{
70
- this.ShowLogo = false;
74
+ this.showLogo = false;
75
}
76
else if ("o" == parameter || "out" == parameter)
77
{
src/tools/heat/HeatCommandLine.cs
+2
-4
@@ -13,19 +13,17 @@ namespace WixToolset.Harvesters
13
14
internal class HeatCommandLine : IHeatCommandLine
15
{
16
- private readonly List<IHeatExtension> extensions;
17
- private readonly IMessaging messaging;
16
private readonly IServiceProvider serviceProvider;
17
+ private readonly List<IHeatExtension> extensions;
18
19
public HeatCommandLine(IServiceProvider serviceProvider, IEnumerable<IHeatExtension> heatExtensions)
20
{
21
+ this.serviceProvider = serviceProvider;
22
this.extensions = new List<IHeatExtension> { new IIsHeatExtension(), new UtilHeatExtension(serviceProvider), new VSHeatExtension() };
23
if (heatExtensions != null)
24
{
25
this.extensions.AddRange(heatExtensions);
26
}
27
- this.messaging = serviceProvider.GetService<IMessaging>();
28
- this.serviceProvider = serviceProvider;
27
}
28
29
public ICommandLineCommand ParseStandardCommandLine(ICommandLineArguments arguments)
src/tools/heat/HelpCommand.cs
+7
-10
@@ -8,12 +8,13 @@ namespace WixToolset.Harvesters
8
using System.Diagnostics;
9
using System.Threading;
10
using System.Threading.Tasks;
11
+ using WixToolset.Extensibility;
12
using WixToolset.Extensibility.Data;
13
using WixToolset.Extensibility.Services;
14
using WixToolset.Harvesters.Data;
15
using WixToolset.Harvesters.Extensibility;
16
16
- internal class HelpCommand : ICommandLineCommand
17
+ internal class HelpCommand : BaseCommandLineCommand
18
{
19
const string HelpMessageOptionFormat = " {0,-7} {1}";
20
@@ -24,17 +25,12 @@ namespace WixToolset.Harvesters
25
26
private IList<IHeatExtension> Extensions { get; }
27
27
- public bool ShowHelp { get; set; }
28
-
29
- public bool ShowLogo
28
+ public override CommandLineHelp GetCommandLineHelp()
29
{
31
- get => false;
32
- set { }
30
+ return null;
31
}
32
35
- public bool StopParsing => true;
36
-
37
- public Task<int> ExecuteAsync(CancellationToken cancellationToken)
33
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
34
{
35
var exitCode = this.DisplayHelp();
36
return Task.FromResult(exitCode);
@@ -50,8 +46,9 @@ namespace WixToolset.Harvesters
46
Console.WriteLine();
47
}
48
53
- public bool TryParseArgument(ICommandLineParser parser, string argument)
49
+ public override bool TryParseArgument(ICommandLineParser parser, string argument)
50
{
51
+ this.StopParsing = true;
52
return true;
53
}
54
src/wix/WixToolset.Converters/ConvertCommand.cs
+17
-27
@@ -5,27 +5,34 @@ namespace WixToolset.Converters
5
using System;
6
using System.Threading;
7
using System.Threading.Tasks;
8
- using WixToolset.Extensibility.Services;
8
+ using WixToolset.Extensibility.Data;
9
10
internal class ConvertCommand : FixupCommandBase
11
{
12
private const string SettingsFileDefault = "wix.convert.settings.xml";
13
14
- public ConvertCommand(IServiceProvider serviceProvider)
14
+ public ConvertCommand(IServiceProvider serviceProvider) : base(serviceProvider)
15
{
16
- this.Messaging = serviceProvider.GetService<IMessaging>();
16
}
17
19
- private IMessaging Messaging { get; }
20
-
21
- public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
18
+ public override CommandLineHelp GetCommandLineHelp()
19
{
23
- if (this.ShowHelp)
20
+ return new CommandLineHelp("Convert v3 source code to v4 source code.", "convert [options] sourceFile [sourceFile ...]")
21
{
25
- DisplayHelp();
26
- return Task.FromResult(-1);
27
- }
22
+ Switches = new[]
23
+ {
24
+ new CommandLineHelpSwitch("--dry-run", "-n", "Only display errors, do not update files."),
25
+ new CommandLineHelpSwitch("--recurse", "-r", "Search for matching files in current dir and subdirs."),
26
+ new CommandLineHelpSwitch("-set1<file>", "Primary settings file."),
27
+ new CommandLineHelpSwitch("-set2<file>", "Secondary settings file (overrides primary)."),
28
+ new CommandLineHelpSwitch("-indent:<n>", "Indentation multiple (overrides default of 4)."),
29
+ },
30
+ Notes = " sourceFile may use wildcards like *.wxs"
31
+ };
32
+ }
33
34
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
35
+ {
36
this.ParseSettings(SettingsFileDefault);
37
38
var converter = new WixConverter(this.Messaging, this.IndentationAmount, this.ErrorsAsWarnings, this.IgnoreErrors);
@@ -39,22 +46,5 @@ namespace WixToolset.Converters
46
return converter.ConvertFile(file, fix);
47
}
48
}
42
-
43
- private static void DisplayHelp()
44
- {
45
- Console.WriteLine();
46
- Console.WriteLine("Usage: wix convert [options] sourceFile [sourceFile ...]");
47
- Console.WriteLine();
48
- Console.WriteLine("Options:");
49
- Console.WriteLine(" -h|--help Show command line help.");
50
- Console.WriteLine(" --nologo Suppress displaying the logo information.");
51
- Console.WriteLine(" -n|--dry-run Only display errors, do not update files.");
52
- Console.WriteLine(" -r|--recurse Search for matching files in current dir and subdirs.");
53
- Console.WriteLine(" -set1<file> Primary settings file.");
54
- Console.WriteLine(" -set2<file> Secondary settings file (overrides primary).");
55
- Console.WriteLine(" -indent:<n> Indentation multiple (overrides default of 4).");
56
- Console.WriteLine();
57
- Console.WriteLine(" sourceFile may use wildcards like *.wxs");
58
- }
49
}
50
}
src/wix/WixToolset.Converters/ConverterExtensionCommandLine.cs
+10
-5
@@ -3,7 +3,6 @@
3
namespace WixToolset.Converters
4
{
5
using System;
6
- using System.Collections.Generic;
6
using WixToolset.Extensibility;
7
using WixToolset.Extensibility.Data;
8
using WixToolset.Extensibility.Services;
@@ -21,11 +20,17 @@ namespace WixToolset.Converters
20
21
private IServiceProvider ServiceProvider { get; }
22
24
- public override IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => new ExtensionCommandLineSwitch[]
23
+ public override CommandLineHelp GetCommandLineHelp()
24
{
26
- new ExtensionCommandLineSwitch { Switch = "convert", Description = "Convert v3 source code to v4 source code." },
27
- new ExtensionCommandLineSwitch { Switch = "format", Description = "Ensures consistent formatting of source code." },
28
- };
25
+ return new CommandLineHelp("Source code converter and formatter.")
26
+ {
27
+ Commands = new[]
28
+ {
29
+ new CommandLineHelpCommand("convert", "Convert v3 source code to v4 source code."),
30
+ new CommandLineHelpCommand("format", "Ensures consistent formatting of source code."),
31
+ }
32
+ };
33
+ }
34
35
public override bool TryParseCommand(ICommandLineParser parser, string argument, out ICommandLineCommand command)
36
{
src/wix/WixToolset.Converters/FixupCommandBase.cs
+11
-28
@@ -6,15 +6,17 @@ namespace WixToolset.Converters
6
using System.Collections.Generic;
7
using System.IO;
8
using System.Threading;
9
- using System.Threading.Tasks;
9
using System.Xml;
11
- using WixToolset.Extensibility.Data;
10
+ using WixToolset.Data;
11
+ using WixToolset.Extensibility;
12
using WixToolset.Extensibility.Services;
13
14
- internal abstract class FixupCommandBase : ICommandLineCommand
14
+ internal abstract class FixupCommandBase : BaseCommandLineCommand
15
{
16
- protected FixupCommandBase()
16
+ protected FixupCommandBase(IServiceProvider serviceProvider)
17
{
18
+ this.Messaging = serviceProvider.GetService<IMessaging>();
19
+
20
this.IndentationAmount = 4; // default indentation amount
21
this.ErrorsAsWarnings = new HashSet<string>();
22
this.ExemptFiles = new HashSet<string>();
@@ -23,11 +25,7 @@ namespace WixToolset.Converters
25
this.SearchPatterns = new List<string>();
26
}
27
26
- public bool ShowHelp { get; set; }
27
-
28
- public bool ShowLogo { get; set; }
29
-
30
- public bool StopParsing { get; set; }
28
+ protected IMessaging Messaging { get; }
29
30
protected CustomTableTarget CustomTableSetting { get; set; }
31
@@ -43,15 +41,15 @@ namespace WixToolset.Converters
41
42
protected bool Recurse { get; set; }
43
46
- private HashSet<string> SearchPatternResults { get; }
44
+ private HashSet<string> SearchPatternResults { get; }
45
48
- private List<string> SearchPatterns { get; }
46
+ private List<string> SearchPatterns { get; }
47
48
private string SettingsFile1 { get; set; }
49
50
private string SettingsFile2 { get; set; }
51
54
- public bool TryParseArgument(ICommandLineParser parser, string argument)
52
+ public override bool TryParseArgument(ICommandLineParser parser, string argument)
53
{
54
if (!parser.IsSwitch(argument))
55
{
@@ -62,14 +60,6 @@ namespace WixToolset.Converters
60
var parameter = argument.Substring(1);
61
switch (parameter.ToLowerInvariant())
62
{
65
- case "?":
66
- case "h":
67
- case "-help":
68
- this.ShowHelp = true;
69
- this.ShowLogo = true;
70
- this.StopParsing = true;
71
- return true;
72
-
63
case "-custom-table":
64
var customTableSetting = parser.GetNextArgumentOrError(argument);
65
switch (customTableSetting)
@@ -91,11 +81,6 @@ namespace WixToolset.Converters
81
this.DryRun = true;
82
return true;
83
94
- case "nologo":
95
- case "-nologo":
96
- this.ShowLogo = false;
97
- return true;
98
-
84
case "s":
85
case "r":
86
case "-recurse":
@@ -131,8 +116,6 @@ namespace WixToolset.Converters
116
}
117
}
118
134
- public abstract Task<int> ExecuteAsync(CancellationToken cancellationToken);
135
-
119
protected void ParseSettings(string defaultSettingsFile)
120
{
121
// parse the settings if any were specified
@@ -157,7 +140,7 @@ namespace WixToolset.Converters
140
{
141
if (!this.SearchPatternResults.Contains(searchPattern))
142
{
160
- Console.Error.WriteLine("Could not find file \"{0}\"", searchPattern);
143
+ this.Messaging.Write(ErrorMessages.FileNotFound(null, searchPattern));
144
errors++;
145
}
146
}
src/wix/WixToolset.Converters/FormatCommand.cs
+18
-28
@@ -5,31 +5,38 @@ namespace WixToolset.Converters
5
using System;
6
using System.Threading;
7
using System.Threading.Tasks;
8
- using WixToolset.Extensibility.Services;
8
+ using WixToolset.Extensibility.Data;
9
10
internal class FormatCommand : FixupCommandBase
11
{
12
private const string SettingsFileDefault = "wix.format.settings.xml";
13
14
- public FormatCommand(IServiceProvider serviceProvider)
14
+ public FormatCommand(IServiceProvider serviceProvider) : base(serviceProvider)
15
{
16
- this.Messaging = serviceProvider.GetService<IMessaging>();
16
}
17
19
- private IMessaging Messaging { get; }
18
+ public override CommandLineHelp GetCommandLineHelp()
19
+ {
20
+ return new CommandLineHelp("Ensures consistent formatting of source code.", "format [options] sourceFile [sourceFile ...]")
21
+ {
22
+ Switches = new[]
23
+ {
24
+ new CommandLineHelpSwitch("--dry-run", "-n", "Only display errors, do not update files."),
25
+ new CommandLineHelpSwitch("--recurse", "-r", "Search for matching files in current dir and subdirs."),
26
+ new CommandLineHelpSwitch("-set1<file>", "Primary settings file."),
27
+ new CommandLineHelpSwitch("-set2<file>", "Secondary settings file (overrides primary)."),
28
+ new CommandLineHelpSwitch("-indent:<n>", "Indentation multiple (overrides default of 4)."),
29
+ },
30
+ Notes = " sourceFile may use wildcards like *.wxs"
31
+ };
32
+ }
33
34
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
35
{
23
- if (this.ShowHelp)
24
- {
25
- DisplayHelp();
26
- return Task.FromResult(-1);
27
- }
36
+ this.ParseSettings(SettingsFileDefault);
37
38
var converter = new WixConverter(this.Messaging, this.IndentationAmount, this.ErrorsAsWarnings, this.IgnoreErrors);
39
31
- this.ParseSettings(SettingsFileDefault);
32
-
40
var errors = base.Inspect(Inspector, cancellationToken);
41
42
return Task.FromResult(errors);
@@ -39,22 +46,5 @@ namespace WixToolset.Converters
46
return converter.FormatFile(file, fix);
47
}
48
}
42
-
43
- private static void DisplayHelp()
44
- {
45
- Console.WriteLine();
46
- Console.WriteLine("Usage: wix format [options] sourceFile [sourceFile ...]");
47
- Console.WriteLine();
48
- Console.WriteLine("Options:");
49
- Console.WriteLine(" -h|--help Show command line help.");
50
- Console.WriteLine(" --nologo Suppress displaying the logo information.");
51
- Console.WriteLine(" -n|--dry-run Only display errors, do not update files.");
52
- Console.WriteLine(" -r|--recurse Search for matching files in current dir and subdirs.");
53
- Console.WriteLine(" -set1<file> Primary settings file.");
54
- Console.WriteLine(" -set2<file> Secondary settings file (overrides primary).");
55
- Console.WriteLine(" -indent:<n> Indentation multiple (overrides default of 4).");
56
- Console.WriteLine();
57
- Console.WriteLine(" sourceFile may use wildcards like *.wxs");
58
- }
49
}
50
}
src/wix/WixToolset.Core.Burn/BurnExtensionCommandLine.cs
+6
-4
@@ -3,7 +3,6 @@
3
namespace WixToolset.Core.Burn
4
{
5
using System;
6
- using System.Collections.Generic;
6
using WixToolset.Core.Burn.CommandLine;
7
using WixToolset.Extensibility;
8
using WixToolset.Extensibility.Data;
@@ -22,10 +21,13 @@ namespace WixToolset.Core.Burn
21
22
private IServiceProvider ServiceProvider { get; }
23
25
- public override IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => new ExtensionCommandLineSwitch[]
24
+ public override CommandLineHelp GetCommandLineHelp()
25
{
27
- new ExtensionCommandLineSwitch { Switch = "burn", Description = "Burn specialized operations." },
28
- };
26
+ return new CommandLineHelp(null)
27
+ {
28
+ Commands = new[] { new CommandLineHelpCommand("burn", "Specialized operations for manipulating Burn-based bundles.") }
29
+ };
30
+ }
31
32
public override bool TryParseCommand(ICommandLineParser parser, string argument, out ICommandLineCommand command)
33
{
src/wix/WixToolset.Core.Burn/CommandLine/BurnCommand.cs
+20
-26
@@ -5,41 +5,50 @@ namespace WixToolset.Core.Burn.CommandLine
5
using System;
6
using System.Threading;
7
using System.Threading.Tasks;
8
+ using WixToolset.Extensibility;
9
using WixToolset.Extensibility.Data;
10
using WixToolset.Extensibility.Services;
11
12
/// <summary>
13
/// Burn specialized command.
14
/// </summary>
14
- internal class BurnCommand : ICommandLineCommand
15
+ internal class BurnCommand : BaseCommandLineCommand
16
{
17
public BurnCommand(IServiceProvider serviceProvider)
18
{
19
this.ServiceProvider = serviceProvider;
20
}
21
21
- public bool ShowHelp { get; set; }
22
-
23
- public bool ShowLogo { get; set; }
24
-
25
- public bool StopParsing { get; set; }
26
-
22
private IServiceProvider ServiceProvider { get; }
23
24
private BurnSubcommandBase Subcommand { get; set; }
25
31
- public Task<int> ExecuteAsync(CancellationToken cancellationToken)
26
+ public override CommandLineHelp GetCommandLineHelp()
27
{
33
- if (this.ShowHelp || this.Subcommand is null)
28
+ return this.Subcommand?.GetCommandLineHelp() ?? new CommandLineHelp("Specialized operations for manipulating Burn-based bundles.", "burn detach|extract|reattach|remotepayload")
29
{
35
- DisplayHelp();
30
+ Commands = new[]
31
+ {
32
+ new CommandLineHelpCommand("detach", "Detaches the burn engine from a bundle so it can be signed."),
33
+ new CommandLineHelpCommand("extract", "Extracts the internals of a bundle to a folder."),
34
+ new CommandLineHelpCommand("reattach", "Reattaches a signed burn engine to a bundle."),
35
+ new CommandLineHelpCommand("remotepayload", "Extracts the internals of a bundle."),
36
+ }
37
+ };
38
+ }
39
+
40
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
41
+ {
42
+ if (this.Subcommand is null)
43
+ {
44
+ Console.Error.WriteLine("A subcommand is required for the \"burn\" command. Add -h to for help.");
45
return Task.FromResult(1);
46
}
47
48
return this.Subcommand.ExecuteAsync(cancellationToken);
49
}
50
42
- public bool TryParseArgument(ICommandLineParser parser, string argument)
51
+ public override bool TryParseArgument(ICommandLineParser parser, string argument)
52
{
53
if (this.Subcommand is null)
54
{
@@ -67,20 +76,5 @@ namespace WixToolset.Core.Burn.CommandLine
76
77
return this.Subcommand.TryParseArgument(parser, argument);
78
}
70
-
71
- private static void DisplayHelp()
72
- {
73
- Console.WriteLine();
74
- Console.WriteLine("Usage: wix burn detach|reattach bundle.exe -out engine.exe");
75
- Console.WriteLine();
76
- Console.WriteLine("Options:");
77
- Console.WriteLine(" -h|--help Show command line help.");
78
- Console.WriteLine(" --nologo Suppress displaying the logo information.");
79
- Console.WriteLine();
80
- Console.WriteLine("Commands:");
81
- Console.WriteLine();
82
- Console.WriteLine(" detach Detaches the burn engine from a bundle so it can be signed.");
83
- Console.WriteLine(" reattach Reattaches a signed burn engine to a bundle.");
84
- }
79
}
80
}
src/wix/WixToolset.Core.Burn/CommandLine/BurnSubcommandBase.cs
+3
@@ -4,10 +4,13 @@ namespace WixToolset.Core.Burn.CommandLine
4
{
5
using System.Threading;
6
using System.Threading.Tasks;
7
+ using WixToolset.Extensibility.Data;
8
using WixToolset.Extensibility.Services;
9
10
internal abstract class BurnSubcommandBase
11
{
12
+ public abstract CommandLineHelp GetCommandLineHelp();
13
+
14
public abstract bool TryParseArgument(ICommandLineParser parser, string argument);
15
16
public abstract Task<int> ExecuteAsync(CancellationToken cancellationToken);
src/wix/WixToolset.Core.Burn/CommandLine/DetachSubcommand.cs
+10
@@ -7,6 +7,7 @@ namespace WixToolset.Core.Burn.CommandLine
7
using System.Threading;
8
using System.Threading.Tasks;
9
using WixToolset.Core.Burn.Inscribe;
10
+ using WixToolset.Extensibility.Data;
11
using WixToolset.Extensibility.Services;
12
13
internal class DetachSubcommand : BurnSubcommandBase
@@ -27,6 +28,15 @@ namespace WixToolset.Core.Burn.CommandLine
28
29
private string EngineOutputPath { get; set; }
30
31
+ public override CommandLineHelp GetCommandLineHelp()
32
+ {
33
+ return new CommandLineHelp("Detaches the burn engine from a bundle so it can be signed.", "burn detach [options] original.exe -engine engine.exe", new[]
34
+ {
35
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
36
+ new CommandLineHelpSwitch("-engine", "Path to extract bundle's engine file to."),
37
+ });
38
+ }
39
+
40
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
41
{
42
if (String.IsNullOrEmpty(this.InputPath))
src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs
+11
@@ -7,6 +7,7 @@ namespace WixToolset.Core.Burn.CommandLine
7
using System.Threading;
8
using System.Threading.Tasks;
9
using WixToolset.Core.Burn.Bundles;
10
+ using WixToolset.Extensibility.Data;
11
using WixToolset.Extensibility.Services;
12
13
internal class ExtractSubcommand : BurnSubcommandBase
@@ -27,6 +28,15 @@ namespace WixToolset.Core.Burn.CommandLine
28
29
private string ExtractPath { get; set; }
30
31
+ public override CommandLineHelp GetCommandLineHelp()
32
+ {
33
+ return new CommandLineHelp("Extracts the internals of a bundle to a folder.", "burn extract [options] bundle.exe -o outputfolder ", new[]
34
+ {
35
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
36
+ new CommandLineHelpSwitch("-out", "-o", "Folder to extract the bundle contents to."),
37
+ });
38
+ }
39
+
40
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
41
{
42
if (String.IsNullOrEmpty(this.InputPath))
@@ -77,6 +87,7 @@ namespace WixToolset.Core.Burn.CommandLine
87
return true;
88
89
case "o":
90
+ case "out":
91
this.ExtractPath = parser.GetNextArgumentAsDirectoryOrError(argument);
92
return true;
93
}
src/wix/WixToolset.Core.Burn/CommandLine/ReattachSubcommand.cs
+10
@@ -7,6 +7,7 @@ namespace WixToolset.Core.Burn.CommandLine
7
using System.Threading;
8
using System.Threading.Tasks;
9
using WixToolset.Core.Burn.Inscribe;
10
+ using WixToolset.Extensibility.Data;
11
using WixToolset.Extensibility.Services;
12
13
internal class ReattachSubcommand : BurnSubcommandBase
@@ -29,6 +30,15 @@ namespace WixToolset.Core.Burn.CommandLine
30
31
private string OutputPath { get; set; }
32
33
+ public override CommandLineHelp GetCommandLineHelp()
34
+ {
35
+ return new CommandLineHelp("Reattaches a signed burn engine to a bundle.", "burn reattach [options] original.exe signed.exe -o final.exe", new[]
36
+ {
37
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
38
+ new CommandLineHelpSwitch("-out", "-o", "Output bundle with signed engine attached."),
39
+ });
40
+ }
41
+
42
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
43
{
44
if (String.IsNullOrEmpty(this.InputPath))
src/wix/WixToolset.Core.Burn/CommandLine/RemotePayloadSubcommand.cs
+31
@@ -15,6 +15,7 @@ namespace WixToolset.Core.Burn.CommandLine
15
using WixToolset.Data;
16
using WixToolset.Data.Symbols;
17
using WixToolset.Extensibility;
18
+ using WixToolset.Extensibility.Data;
19
using WixToolset.Extensibility.Services;
20
21
internal class RemotePayloadSubcommand : BurnSubcommandBase
@@ -66,6 +67,36 @@ namespace WixToolset.Core.Burn.CommandLine
67
68
private bool UseCertificate { get; set; }
69
70
+ public override CommandLineHelp GetCommandLineHelp()
71
+ {
72
+ return new CommandLineHelp("Generate source code for a remote payload", "burn remotepayload [options] payloadfile [payloadfile ...]", new[]
73
+ {
74
+ new CommandLineHelpSwitch("-basepath", "-bp", "Folder as base to make payloads relative."),
75
+ new CommandLineHelpSwitch("-bundlepayloadgeneration", "Sets the package payload generation option; see the Payload Generation Types below."),
76
+ new CommandLineHelpSwitch("-downloadurl", "-du", "Set the DownloadUrl attribute on the generated payloads."),
77
+ new CommandLineHelpSwitch("-out", "-o", "Path to output the source code file."),
78
+ new CommandLineHelpSwitch("-recurse", "-r", "Indicates to add all payloads in directory recursively."),
79
+ new CommandLineHelpSwitch("-intermediatefolder", "Optional working folder. If not specified %TMP% folder will be created."),
80
+ new CommandLineHelpSwitch("-packagetype", "Explicitly set package type; see the Pacakge Types below."),
81
+ new CommandLineHelpSwitch("-usecertificate", "Use certificate to validate signed payloads. This option is not recommended."),
82
+ })
83
+ {
84
+ Notes = String.Join(Environment.NewLine,
85
+ "Payload Generation Types:",
86
+ " none",
87
+ " externalwithoutdownloadurl",
88
+ " external",
89
+ " all",
90
+ String.Empty,
91
+ "Package Types:",
92
+ " bundle",
93
+ " exe",
94
+ " msi",
95
+ " msp",
96
+ " msu")
97
+ };
98
+ }
99
+
100
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
101
{
102
var inputPaths = this.ExpandInputPaths();
src/wix/WixToolset.Core.ExtensionCache/ExtensionCacheManagerCommand.cs
+25
-44
@@ -7,13 +7,14 @@ namespace WixToolset.Core.ExtensionCache
7
using System.Linq;
8
using System.Threading;
9
using System.Threading.Tasks;
10
+ using WixToolset.Extensibility;
11
using WixToolset.Extensibility.Data;
12
using WixToolset.Extensibility.Services;
13
14
/// <summary>
15
/// Extension cache manager command.
16
/// </summary>
16
- internal class ExtensionCacheManagerCommand : ICommandLineCommand
17
+ internal class ExtensionCacheManagerCommand : BaseCommandLineCommand
18
{
19
private enum CacheSubcommand
20
{
@@ -29,12 +30,6 @@ namespace WixToolset.Core.ExtensionCache
30
this.ExtensionReferences = new List<string>();
31
}
32
32
- public bool ShowHelp { get; set; }
33
-
34
- public bool ShowLogo { get; set; }
35
-
36
- public bool StopParsing { get; set; }
37
-
33
private IMessaging Messaging { get; }
34
35
private IExtensionManager ExtensionManager { get; }
@@ -45,12 +40,30 @@ namespace WixToolset.Core.ExtensionCache
40
41
private List<string> ExtensionReferences { get; }
42
48
- public async Task<int> ExecuteAsync(CancellationToken cancellationToken)
43
+ public override CommandLineHelp GetCommandLineHelp()
44
+ {
45
+ return new CommandLineHelp("Manage the extension cache.", "extension add|remove|list [options] [extensionRef]")
46
+ {
47
+ Switches = new[]
48
+ {
49
+ new CommandLineHelpSwitch("--global", "-g", "Add/remove the extension for the current user."),
50
+ },
51
+ Commands = new[]
52
+ {
53
+ new CommandLineHelpCommand("add", "Add extension to the cache."),
54
+ new CommandLineHelpCommand("list", "List extensions in the cache."),
55
+ new CommandLineHelpCommand("remove", "Remove extension from the cache."),
56
+ },
57
+ Notes = " extensionRef format: extensionId/version (the version is optional)"
58
+ };
59
+ }
60
+
61
+ public override async Task<int> ExecuteAsync(CancellationToken cancellationToken)
62
{
50
- if (this.ShowHelp || !this.Subcommand.HasValue)
63
+ if (!this.Subcommand.HasValue)
64
{
52
- DisplayHelp();
53
- return 1;
65
+ Console.Error.WriteLine("A subcommand is required for the \"extension\" command. Use -h to for help.");
66
+ return -1;
67
}
68
69
var success = false;
@@ -74,7 +87,7 @@ namespace WixToolset.Core.ExtensionCache
87
return success ? 0 : 2;
88
}
89
77
- public bool TryParseArgument(ICommandLineParser parser, string argument)
90
+ public override bool TryParseArgument(ICommandLineParser parser, string argument)
91
{
92
if (!parser.IsSwitch(argument))
93
{
@@ -98,19 +111,6 @@ namespace WixToolset.Core.ExtensionCache
111
var parameter = argument.Substring(1);
112
switch (parameter.ToLowerInvariant())
113
{
101
- case "?":
102
- case "h":
103
- case "-help":
104
- this.ShowHelp = true;
105
- this.ShowLogo = true;
106
- this.StopParsing = true;
107
- return true;
108
-
109
- case "nologo":
110
- case "-nologo":
111
- this.ShowLogo = false;
112
- return true;
113
-
114
case "g":
115
case "-global":
116
this.Global = true;
@@ -161,24 +161,5 @@ namespace WixToolset.Core.ExtensionCache
161
162
return found;
163
}
164
-
165
- private static void DisplayHelp()
166
- {
167
- Console.WriteLine();
168
- Console.WriteLine("Usage: wix extension add|remove|list [extensionRef]");
169
- Console.WriteLine();
170
- Console.WriteLine("Options:");
171
- Console.WriteLine(" -h|--help Show command line help.");
172
- Console.WriteLine(" -g|--global Add/remove the extension for the current user.");
173
- Console.WriteLine(" --nologo Suppress displaying the logo information.");
174
- Console.WriteLine();
175
- Console.WriteLine("Commands:");
176
- Console.WriteLine();
177
- Console.WriteLine(" add Add extension to the cache.");
178
- Console.WriteLine(" list List extensions in the cache.");
179
- Console.WriteLine(" remove Remove extension from the cache.");
180
- Console.WriteLine();
181
- Console.WriteLine(" extensionRef format: extensionId/version (the version is optional)");
182
- }
164
}
165
}
src/wix/WixToolset.Core.ExtensionCache/ExtensionCacheManagerExtensionCommandLine.cs
+6
-4
@@ -3,7 +3,6 @@
3
namespace WixToolset.Core.ExtensionCache
4
{
5
using System;
6
- using System.Collections.Generic;
6
using WixToolset.Extensibility;
7
using WixToolset.Extensibility.Data;
8
using WixToolset.Extensibility.Services;
@@ -21,10 +20,13 @@ namespace WixToolset.Core.ExtensionCache
20
21
private IServiceProvider ServiceProvider { get; }
22
24
- public override IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => new ExtensionCommandLineSwitch[]
23
+ public override CommandLineHelp GetCommandLineHelp()
24
{
26
- new ExtensionCommandLineSwitch { Switch = "extension", Description = "Manage extension cache." },
27
- };
25
+ return new CommandLineHelp("Manage the extension cache.")
26
+ {
27
+ Commands = new[] { new CommandLineHelpCommand("extension", "Manage extension cache.") }
28
+ };
29
+ }
30
31
public override bool TryParseCommand(ICommandLineParser parser, string argument, out ICommandLineCommand command)
32
{
src/wix/WixToolset.Core.WindowsInstaller/CommandLine/DecompilerSubcommand.cs
+16
@@ -42,6 +42,22 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
42
43
private bool SuppressUI { get; set; }
44
45
+ public override CommandLineHelp GetCommandLineHelp()
46
+ {
47
+ return new CommandLineHelp("Converts a Windows Installer database back into source code.", "msi decompile [options] inputfile", new[]
48
+ {
49
+ new CommandLineHelpSwitch("-cub", "Optional path to a custom validation .CUBe file."),
50
+ new CommandLineHelpSwitch("-sct", "Suppress decompiling custom tables."),
51
+ new CommandLineHelpSwitch("-sdet", "Suppress dropping empty tables."),
52
+ new CommandLineHelpSwitch("-sras", "Suppress relative action sequencing."),
53
+ new CommandLineHelpSwitch("-sui", "Suppress decompiling UI tables."),
54
+ new CommandLineHelpSwitch("-type", "Optional specify the input file type: msi or msm. If not specified, type will be inferred by file extension."),
55
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
56
+ new CommandLineHelpSwitch("-out", "-o", "Path to output the decompiled .wxs file. If not specified, outputs next to inputfile"),
57
+ new CommandLineHelpSwitch("-x", "Folder to export embedded binaries and icons to."),
58
+ });
59
+ }
60
+
61
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
62
{
63
if (String.IsNullOrEmpty(this.InputPath))
src/wix/WixToolset.Core.WindowsInstaller/CommandLine/InscribeSubcommand.cs
+10
@@ -7,6 +7,7 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
7
using System.Threading;
8
using System.Threading.Tasks;
9
using WixToolset.Core.WindowsInstaller.Inscribe;
10
+ using WixToolset.Extensibility.Data;
11
using WixToolset.Extensibility.Services;
12
13
internal class InscribeSubcommand : WindowsInstallerSubcommandBase
@@ -27,6 +28,15 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
28
29
private string OutputPath { get; set; }
30
31
+ public override CommandLineHelp GetCommandLineHelp()
32
+ {
33
+ return new CommandLineHelp("Updates MSI database with cabinet signature information.", "msi inscribe [options] input.msi [-out inscribed.msi]", new[]
34
+ {
35
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
36
+ new CommandLineHelpSwitch("-out", "-o", "Path to output the inscribed MSI. If not provided, the input MSI is updated in place."),
37
+ });
38
+ }
39
+
40
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
41
{
42
if (String.IsNullOrEmpty(this.InputPath))
src/wix/WixToolset.Core.WindowsInstaller/CommandLine/TransformSubcommand.cs
+47
@@ -12,6 +12,7 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
12
using WixToolset.Data.Symbols;
13
using WixToolset.Data.WindowsInstaller;
14
using WixToolset.Extensibility;
15
+ using WixToolset.Extensibility.Data;
16
using WixToolset.Extensibility.Services;
17
18
internal class TransformSubcommand : WindowsInstallerSubcommandBase
@@ -51,6 +52,52 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
52
53
private TransformFlags ValidationFlags { get; set; }
54
55
+ public override CommandLineHelp GetCommandLineHelp()
56
+ {
57
+ return new CommandLineHelp("Creates an MST transform file.", "msi transform [options] target.msi [updated.msi] -out output.mst")
58
+ {
59
+ Switches = new[]
60
+ {
61
+ new CommandLineHelpSwitch("-a", "Admin image, generates source file information in the transform."),
62
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
63
+ new CommandLineHelpSwitch("-p", "Preserve unchanged rows."),
64
+ new CommandLineHelpSwitch("-pedantic", "Show pedantic messages."),
65
+ new CommandLineHelpSwitch("-serr <flags>", "Suppress error when applying transform; see Error flags below"),
66
+ new CommandLineHelpSwitch("-t <type>", "Use default validation flags for the transform type; see Transform types below"),
67
+ new CommandLineHelpSwitch("-val <flags>", "Validation flags for the transform; see Validation flags below"),
68
+ new CommandLineHelpSwitch("-x", "Folder to extract binaries."),
69
+ new CommandLineHelpSwitch("-xo", "Output transfrom as a WiX output instead of an MST file."),
70
+ new CommandLineHelpSwitch("-out", "-o", "Path to output the transform file."),
71
+ },
72
+ Notes = String.Join(Environment.NewLine,
73
+ "Error flags:",
74
+ " a Ignore errors when adding an existing row",
75
+ " b Ignore errors when deleting a missing row",
76
+ " c Ignore errors when adding an existing table",
77
+ " d Ignore errors when deleting a missing table",
78
+ " e Ignore errors when modifying a missing row",
79
+ " f Ignore errors when changing the code page",
80
+ String.Empty,
81
+ "Validation flags:",
82
+ " g UpgradeCode must match",
83
+ " l Language must match",
84
+ " r Product ID must match",
85
+ " s Check major version only",
86
+ " t Check major and minor versions",
87
+ " u Check major, minor, and upgrade versions",
88
+ " v Upgrade version < target version",
89
+ " w Upgrade version <= target version",
90
+ " x Upgrade version = target version",
91
+ " y Upgrade version > target version",
92
+ " z Upgrade version >= target version",
93
+ String.Empty,
94
+ "Transform types:",
95
+ " language Default flags for a language transform",
96
+ " instance Default flags for an instance transform",
97
+ " patch Default flags for a patch transform")
98
+ };
99
+ }
100
+
101
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
102
{
103
if (String.IsNullOrEmpty(this.TargetPath))
src/wix/WixToolset.Core.WindowsInstaller/CommandLine/ValidateSubcommand.cs
+13
@@ -9,6 +9,7 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
9
using System.Threading.Tasks;
10
using WixToolset.Core.WindowsInstaller.Validate;
11
using WixToolset.Data.WindowsInstaller;
12
+ using WixToolset.Extensibility.Data;
13
using WixToolset.Extensibility.Services;
14
15
internal class ValidateSubcommand : WindowsInstallerSubcommandBase
@@ -35,6 +36,18 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
36
37
private List<string> SuppressIces { get; } = new List<string>();
38
39
+ public override CommandLineHelp GetCommandLineHelp()
40
+ {
41
+ return new CommandLineHelp("Validates MSI database using standard or custom ICEs.", "msi validate [options] inputfile", new[]
42
+ {
43
+ new CommandLineHelpSwitch("-cub", "Optional path to a custom validation .CUBe file."),
44
+ new CommandLineHelpSwitch("-ice", "Validates only with the specified ICE. May be provided multiple times."),
45
+ new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
46
+ new CommandLineHelpSwitch("-pdb", "Optional path to .wixpdb for source line information. If not provided, will check next to the input file."),
47
+ new CommandLineHelpSwitch("-sice", "Suppresses an ICE validator."),
48
+ });
49
+ }
50
+
51
public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
52
{
53
WindowsInstallerData data = null;
src/wix/WixToolset.Core.WindowsInstaller/CommandLine/WindowsInstallerCommand.cs
+20
-27
@@ -5,41 +5,50 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
5
using System;
6
using System.Threading;
7
using System.Threading.Tasks;
8
+ using WixToolset.Extensibility;
9
using WixToolset.Extensibility.Data;
10
using WixToolset.Extensibility.Services;
11
12
/// <summary>
13
/// Windows Installer specialized command.
14
/// </summary>
14
- internal class WindowsInstallerCommand : ICommandLineCommand
15
+ internal class WindowsInstallerCommand : BaseCommandLineCommand
16
{
17
public WindowsInstallerCommand(IServiceProvider serviceProvider)
18
{
19
this.ServiceProvider = serviceProvider;
20
}
21
21
- public bool ShowHelp { get; set; }
22
-
23
- public bool ShowLogo { get; set; }
24
-
25
- public bool StopParsing { get; set; }
26
-
22
private IServiceProvider ServiceProvider { get; }
23
24
private WindowsInstallerSubcommandBase Subcommand { get; set; }
25
31
- public Task<int> ExecuteAsync(CancellationToken cancellationToken)
26
+ public override CommandLineHelp GetCommandLineHelp()
27
{
33
- if (this.ShowHelp || this.Subcommand is null)
28
+ return this.Subcommand?.GetCommandLineHelp() ?? new CommandLineHelp("Specialized operations for manipulating Windows Installer databases.", "msi decompile|inscribe|transform|validate")
29
{
35
- DisplayHelp();
30
+ Commands = new[]
31
+ {
32
+ new CommandLineHelpCommand("decompile", "Converts a Windows Installer database back into source code."),
33
+ new CommandLineHelpCommand("inscribe", "Updates MSI database with cabinet signature information."),
34
+ new CommandLineHelpCommand("transform", "Creates an MST transform file."),
35
+ new CommandLineHelpCommand("validate", "Validates MSI database using standard or custom ICEs."),
36
+ }
37
+ };
38
+ }
39
+
40
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
41
+ {
42
+ if (this.Subcommand is null)
43
+ {
44
+ Console.Error.WriteLine("A subcommand is required for the \"msi\" command. Add -h to for help.");
45
return Task.FromResult(1);
46
}
47
48
return this.Subcommand.ExecuteAsync(cancellationToken);
49
}
50
42
- public bool TryParseArgument(ICommandLineParser parser, string argument)
51
+ public override bool TryParseArgument(ICommandLineParser parser, string argument)
52
{
53
if (this.Subcommand is null)
54
{
@@ -67,21 +76,5 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
76
77
return this.Subcommand.TryParseArgument(parser, argument);
78
}
70
-
71
- private static void DisplayHelp()
72
- {
73
- Console.WriteLine();
74
- Console.WriteLine("Usage: wix msi inscribe input.msi [-intermedidateFolder folder] [-out output.msi]");
75
- Console.WriteLine();
76
- Console.WriteLine("Options:");
77
- Console.WriteLine(" -h|--help Show command line help.");
78
- Console.WriteLine(" --nologo Suppress displaying the logo information.");
79
- Console.WriteLine();
80
- Console.WriteLine("Commands:");
81
- Console.WriteLine();
82
- Console.WriteLine(" inscribe Updates MSI database with cabinet signature information.");
83
- Console.WriteLine(" transform Creates an MST transform file.");
84
- Console.WriteLine(" validate Validates MSI database using standard or custom ICEs.");
85
- }
79
}
80
}
src/wix/WixToolset.Core.WindowsInstaller/CommandLine/WindowsInstallerSubcommandBase.cs
+3
@@ -4,10 +4,13 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
4
{
5
using System.Threading;
6
using System.Threading.Tasks;
7
+ using WixToolset.Extensibility.Data;
8
using WixToolset.Extensibility.Services;
9
10
internal abstract class WindowsInstallerSubcommandBase
11
{
12
+ public abstract CommandLineHelp GetCommandLineHelp();
13
+
14
public abstract bool TryParseArgument(ICommandLineParser parser, string argument);
15
16
public abstract Task<int> ExecuteAsync(CancellationToken cancellationToken);
src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerExtensionCommandLine.cs
+9
-4
@@ -3,7 +3,6 @@
3
namespace WixToolset.Core.WindowsInstaller
4
{
5
using System;
6
- using System.Collections.Generic;
6
using WixToolset.Core.WindowsInstaller.CommandLine;
7
using WixToolset.Extensibility;
8
using WixToolset.Extensibility.Data;
@@ -22,10 +21,16 @@ namespace WixToolset.Core.WindowsInstaller
21
22
private IServiceProvider ServiceProvider { get; }
23
25
- public override IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => new ExtensionCommandLineSwitch[]
24
+ public override CommandLineHelp GetCommandLineHelp()
25
{
27
- new ExtensionCommandLineSwitch { Switch = "msi", Description = "Windows Installer specialized operations." },
28
- };
26
+ return new CommandLineHelp("Specialized operations for manipulating Windows Installer databases.")
27
+ {
28
+ Commands = new[]
29
+ {
30
+ new CommandLineHelpCommand("msi", "Windows Installer specialized operations."),
31
+ }
32
+ };
33
+ }
34
35
public override bool TryParseCommand(ICommandLineParser parser, string argument, out ICommandLineCommand command)
36
{
src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
+37
-29
@@ -14,7 +14,7 @@ namespace WixToolset.Core.CommandLine
14
using WixToolset.Extensibility.Data;
15
using WixToolset.Extensibility.Services;
16
17
- internal class BuildCommand : ICommandLineCommand
17
+ internal class BuildCommand : BaseCommandLineCommand
18
{
19
private readonly CommandLine commandLine;
20
@@ -26,21 +26,6 @@ namespace WixToolset.Core.CommandLine
26
this.commandLine = new CommandLine(this.ServiceProvider, this.Messaging);
27
}
28
29
- public bool ShowHelp
30
- {
31
- get { return this.commandLine.ShowHelp; }
32
- set { this.commandLine.ShowHelp = value; }
33
- }
34
-
35
- public bool ShowLogo
36
- {
37
- get { return this.commandLine.ShowLogo; }
38
- set { this.commandLine.ShowLogo = value; }
39
- }
40
-
41
- // Stop parsing when we've decided to show help.
42
- public bool StopParsing => this.commandLine.ShowHelp;
43
-
29
private IServiceProvider ServiceProvider { get; }
30
31
private IMessaging Messaging { get; }
@@ -57,14 +42,40 @@ namespace WixToolset.Core.CommandLine
42
43
private string TrackingFile { get; set; }
44
60
- public Task<int> ExecuteAsync(CancellationToken cancellationToken)
45
+ public override CommandLineHelp GetCommandLineHelp()
46
{
62
- if (this.commandLine.ShowHelp)
47
+ return new CommandLineHelp("", "build [options] sourcevile [sourcefile ...] -out output.ext", new[]
48
{
64
- Console.WriteLine("TODO: Show build command help");
65
- return Task.FromResult(-1);
66
- }
49
+ new CommandLineHelpSwitch("-arch", "Set the architecture of the output."),
50
+ new CommandLineHelpSwitch("-bindfiles", "-bf", "Bind files into an output .wixlib. Ignored if not building a .wixlib."),
51
+ new CommandLineHelpSwitch("-bindpath", "Bind path to search for content files."),
52
+ new CommandLineHelpSwitch("-cabcache", "-cc", "Set a folder to cache cabinets across builds."),
53
+ new CommandLineHelpSwitch("-culture", "Adds a culture to filter localization files."),
54
+ new CommandLineHelpSwitch("-define", "-d", "Sets a preprocessor variable."),
55
+ new CommandLineHelpSwitch("-defaultcompressionlevel", "-dcl", "Default compression level; see Compression levels below."),
56
+ new CommandLineHelpSwitch("-include", "-i", "Folder to search for include files."),
57
+ new CommandLineHelpSwitch("-intermediatefolder", "Optional working folder. If not specified a folder in %TMP% will be created."),
58
+ new CommandLineHelpSwitch("-loc", "Localization file to use in the build. By default, .wxl files are recognized as localization."),
59
+ new CommandLineHelpSwitch("-lib", "Library file to use in the build. By default, .wixlb files are recognized as libraries."),
60
+ new CommandLineHelpSwitch("-src", "Source file to use in the build. By default, .wxs files are recognized as source code."),
61
+ new CommandLineHelpSwitch("-out", "-o", "Path to output the build to."),
62
+ new CommandLineHelpSwitch("-outputtype", "Explicitly set the output type if it cannot be determined from the output."),
63
+ new CommandLineHelpSwitch("-pdb", "Optional path to output .wixpdb. Default will write .wixpdb beside output path."),
64
+ new CommandLineHelpSwitch("-pdbtype", "Switch to disable creation of .wixpdb. Types: full or none."),
65
+ })
66
+ {
67
+ Notes = String.Join(Environment.NewLine,
68
+ "Compression levels:",
69
+ " none Use no compression",
70
+ " low Use low compression",
71
+ " medium Use medium compression",
72
+ " high Use high compression",
73
+ " mszip Use ms-zip compression")
74
+ };
75
+ }
76
77
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
78
+ {
79
this.IntermediateFolder = this.commandLine.CalculateIntermedateFolder();
80
81
this.Platform = this.commandLine.Platform;
@@ -144,7 +155,7 @@ namespace WixToolset.Core.CommandLine
155
return Task.FromResult(this.Messaging.LastErrorNumber);
156
}
157
147
- public bool TryParseArgument(ICommandLineParser parser, string argument)
158
+ public override bool TryParseArgument(ICommandLineParser parser, string argument)
159
{
160
return this.commandLine.TryParseArgument(argument, parser);
161
}
@@ -465,7 +476,7 @@ namespace WixToolset.Core.CommandLine
476
477
public List<string> SourceFilePaths { get; } = new List<string>();
478
468
- public List<string> UnevaluatedInputFilePaths { get; } = new List<string>();
479
+ public List<string> UnclassifiedInputFilePaths { get; } = new List<string>();
480
481
public Platform Platform { get; private set; }
482
@@ -473,10 +484,6 @@ namespace WixToolset.Core.CommandLine
484
485
public PdbType PdbType { get; private set; }
486
476
- public bool ShowLogo { get; set; }
477
-
478
- public bool ShowHelp { get; set; }
479
-
487
public string IntermediateFolder { get; private set; }
488
489
public string OutputFile { get; private set; }
@@ -535,6 +542,7 @@ namespace WixToolset.Core.CommandLine
542
}
543
544
case "cc":
545
+ case "cabcache":
546
this.CabCachePath = parser.GetNextArgumentOrError(arg);
547
return true;
548
@@ -617,7 +625,7 @@ namespace WixToolset.Core.CommandLine
625
}
626
else
627
{
620
- parser.GetArgumentAsFilePathOrError(arg, "input file", this.UnevaluatedInputFilePaths);
628
+ parser.GetArgumentAsFilePathOrError(arg, "input file", this.UnclassifiedInputFilePaths);
629
return true;
630
}
631
}
@@ -737,7 +745,7 @@ namespace WixToolset.Core.CommandLine
745
var outputPath = this.OutputFile;
746
var outputType = this.CalculateOutputType();
747
740
- foreach (var path in this.UnevaluatedInputFilePaths)
748
+ foreach (var path in this.UnclassifiedInputFilePaths)
749
{
750
var extension = Path.GetExtension(path);
751
src/wix/WixToolset.Core/CommandLine/CommandLine.cs
+32
-18
@@ -21,6 +21,10 @@ namespace WixToolset.Core.CommandLine
21
22
private IMessaging Messaging { get; }
23
24
+ private bool ShowHelp { get; set; }
25
+
26
+ private bool SuppressLogo { get; set; }
27
+
28
public ICommandLineCommand CreateCommand(string[] args)
29
{
30
var arguments = this.ServiceProvider.GetService<ICommandLineArguments>();
@@ -49,11 +53,12 @@ namespace WixToolset.Core.CommandLine
53
54
var command = this.Parse(context);
55
52
- if (command.ShowLogo)
56
+ if (!this.SuppressLogo && command?.ShowLogo == true)
57
{
58
var branding = this.ServiceProvider.GetService<IWixBranding>();
59
Console.WriteLine(branding.ReplacePlaceholders("[AssemblyProduct] [AssemblyDescription] version [ProductVersion]"));
60
Console.WriteLine(branding.ReplacePlaceholders("[AssemblyCopyright]"));
61
+ Console.WriteLine();
62
}
63
64
return command;
@@ -71,7 +76,6 @@ namespace WixToolset.Core.CommandLine
76
77
private ICommandLineCommand Parse(ICommandLineContext context)
78
{
74
- var branding = context.ServiceProvider.GetService<IWixBranding>();
79
var extensions = context.ExtensionManager.GetServices<IExtensionCommandLine>();
80
81
foreach (var extension in extensions)
@@ -86,28 +90,31 @@ namespace WixToolset.Core.CommandLine
90
String.IsNullOrEmpty(parser.ErrorArgument) &&
91
parser.TryGetNextSwitchOrArgument(out var arg))
92
{
89
- if (String.IsNullOrWhiteSpace(arg)) // skip blank arguments.
90
- {
91
- continue;
92
- }
93
-
94
- // First argument must be the command or global switch (that creates a command).
93
+ // If we don't have a command yet, try to parse for a command or a global switch.
94
if (command == null)
95
{
97
- if (!this.TryParseCommand(arg, parser, extensions, out command))
96
+ if (this.TryParseCommand(arg, parser, extensions, out command))
97
{
98
+ // Found our command, all good.
99
+ }
100
+ else if (!parser.IsSwitch(arg) || !TryParseCommandLineArgumentWithExtension(arg, parser, extensions))
101
+ {
102
+ // Not a global switch handled by an extension, so failure.
103
parser.ReportErrorArgument(arg);
104
}
105
}
106
else if (parser.IsSwitch(arg))
107
{
104
- if (!command.TryParseArgument(parser, arg) && !TryParseCommandLineArgumentWithExtension(arg, parser, extensions) &&
105
- !this.TryParseStandardCommandLineSwitch(command, parser, arg))
108
+ // Commands get first crack at parsing switches then extensions then the standard.
109
+ if (!command.TryParseArgument(parser, arg) &&
110
+ !TryParseCommandLineArgumentWithExtension(arg, parser, extensions) &&
111
+ !this.TryParseStandardCommandLineSwitch(parser, arg))
112
{
113
parser.ReportErrorArgument(arg);
114
}
115
}
110
- else if (!TryParseCommandLineArgumentWithExtension(arg, parser, extensions) && !command.TryParseArgument(parser, arg))
116
+ else if (!TryParseCommandLineArgumentWithExtension(arg, parser, extensions) &&
117
+ !command.TryParseArgument(parser, arg))
118
{
119
parser.ReportErrorArgument(arg);
120
}
@@ -121,10 +128,15 @@ namespace WixToolset.Core.CommandLine
128
// If we hit an error, do not return a command.
129
if (!String.IsNullOrEmpty(parser.ErrorArgument))
130
{
124
- return null;
131
+ command = null;
132
+ }
133
+ else if (this.ShowHelp || command == null)
134
+ {
135
+ var branding = context.ServiceProvider.GetService<IWixBranding>();
136
+ command = new HelpCommand(extensions, branding, command);
137
}
138
127
- return command ?? new HelpCommand(extensions, branding);
139
+ return command;
140
}
141
142
private bool TryParseCommand(string arg, ICommandLineParser parser, IEnumerable<IExtensionCommandLine> extensions, out ICommandLineCommand command)
@@ -141,7 +153,7 @@ namespace WixToolset.Core.CommandLine
153
case "help":
154
case "-help":
155
var branding = this.ServiceProvider.GetService<IWixBranding>();
144
- command = new HelpCommand(extensions, branding);
156
+ command = new HelpCommand(extensions, branding, null);
157
break;
158
159
case "version":
@@ -184,7 +196,7 @@ namespace WixToolset.Core.CommandLine
196
return false;
197
}
198
187
- private bool TryParseStandardCommandLineSwitch(ICommandLineCommand command, ICommandLineParser parser, string arg)
199
+ private bool TryParseStandardCommandLineSwitch(ICommandLineParser parser, string arg)
200
{
201
var parameter = arg.Substring(1).ToLowerInvariant();
202
@@ -193,11 +205,13 @@ namespace WixToolset.Core.CommandLine
205
case "?":
206
case "h":
207
case "help":
196
- command.ShowHelp = true;
208
+ case "-help":
209
+ this.ShowHelp = true;
210
return true;
211
212
case "nologo":
200
- command.ShowLogo = false;
213
+ case "-nologo":
214
+ this.SuppressLogo = true;
215
return true;
216
217
case "v":
src/wix/WixToolset.Core/CommandLine/CommandLineParser.cs
+11
-10
@@ -5,6 +5,7 @@ namespace WixToolset.Core.CommandLine
5
using System;
6
using System.Collections.Generic;
7
using System.IO;
8
+ using System.Linq;
9
using WixToolset.Data;
10
using WixToolset.Extensibility.Services;
11
@@ -12,19 +13,19 @@ namespace WixToolset.Core.CommandLine
13
{
14
private const string ExpectedArgument = "expected argument";
15
15
- public string ErrorArgument { get; private set; }
16
-
17
- private Queue<string> RemainingArguments { get; }
18
-
19
- private IMessaging Messaging { get; }
20
-
16
public CommandLineParser(IMessaging messaging, string[] arguments, string errorArgument)
17
{
18
this.Messaging = messaging;
24
- this.RemainingArguments = new Queue<string>(arguments);
19
+ this.RemainingArguments = new Queue<string>(arguments.Where(a => !String.IsNullOrWhiteSpace(a))); // skip blank arguments.
20
this.ErrorArgument = errorArgument;
21
}
22
23
+ public string ErrorArgument { get; private set; }
24
+
25
+ private Queue<string> RemainingArguments { get; }
26
+
27
+ private IMessaging Messaging { get; }
28
+
29
public bool IsSwitch(string arg)
30
{
31
return !String.IsNullOrEmpty(arg) && '-' == arg[0];
@@ -132,15 +133,15 @@ namespace WixToolset.Core.CommandLine
133
this.ErrorArgument = argument;
134
}
135
135
- public bool TryGetNextSwitchOrArgument(out string arg)
136
+ public bool TryGetNextSwitchOrArgument(out string argument)
137
{
138
if (this.RemainingArguments.Count > 0)
139
{
139
- arg = this.RemainingArguments.Dequeue();
140
+ argument = this.RemainingArguments.Dequeue();
141
return true;
142
}
143
143
- arg = null;
144
+ argument = null;
145
return false;
146
}
147
src/wix/WixToolset.Core/CommandLine/HelpCommand.cs
+87
-39
@@ -11,67 +11,115 @@ namespace WixToolset.Core.CommandLine
11
using WixToolset.Extensibility.Data;
12
using WixToolset.Extensibility.Services;
13
14
- internal class HelpCommand : ICommandLineCommand
14
+ internal class HelpCommand : BaseCommandLineCommand
15
{
16
- private static readonly ExtensionCommandLineSwitch[] BuiltInSwitches = new ExtensionCommandLineSwitch[]
17
- {
18
- new ExtensionCommandLineSwitch { Switch = "build", Description = "Build a wixlib, package or bundle." },
19
- new ExtensionCommandLineSwitch { Switch = "decompile", Description = "Decompile a package or bundle into source code." },
20
- };
21
-
22
- public HelpCommand(IEnumerable<IExtensionCommandLine> extensions, IWixBranding branding)
16
+ public HelpCommand(IEnumerable<IExtensionCommandLine> extensions, IWixBranding branding, ICommandLineCommand command)
17
{
18
this.Extensions = extensions;
19
this.Branding = branding;
20
+ this.Command = command;
21
}
22
28
- public bool ShowHelp
23
+ public override bool ShowLogo => true;
24
+
25
+ private IEnumerable<IExtensionCommandLine> Extensions { get; }
26
+
27
+ private IWixBranding Branding { get; }
28
+
29
+ private ICommandLineCommand Command { get; }
30
+
31
+ public override CommandLineHelp GetCommandLineHelp()
32
{
30
- get => true;
31
- set { }
33
+ return new CommandLineHelp(null, "[command] [options]")
34
+ {
35
+ Switches = new[]
36
+ {
37
+ new CommandLineHelpSwitch("--help", "-h", "Show command line help."),
38
+ new CommandLineHelpSwitch("--version", "-v", "Display WiX Toolset version in use."),
39
+ new CommandLineHelpSwitch("--nologo", "Suppress displaying the logo information."),
40
+ },
41
+ Commands = new[]
42
+ {
43
+ new CommandLineHelpCommand("build", "Build a wixlib, package or bundle.")
44
+ },
45
+ Notes = "Run 'wix [command] -h' for more information on a command."
46
+ };
47
}
48
34
- public bool ShowLogo
49
+ public override Task<int> ExecuteAsync(CancellationToken _)
50
{
36
- get => true;
37
- set { }
38
- }
51
+ var extensionsHelp = this.Extensions.Select(e => e.GetCommandLineHelp()).Where(h => h != null).ToList();
52
40
- public bool StopParsing => true;
53
+ var help = this.Command?.GetCommandLineHelp() ?? this.GetCommandLineHelp();
54
42
- private IEnumerable<IExtensionCommandLine> Extensions { get; }
55
+ var switches = new List<CommandLineHelpSwitch>();
56
+ if (help.Switches != null)
57
+ {
58
+ switches.AddRange(help.Switches);
59
+ }
60
44
- private IWixBranding Branding { get; }
61
+ switches.AddRange(extensionsHelp.Where(e => e.Switches != null).SelectMany(e => e.Switches));
62
46
- public Task<int> ExecuteAsync(CancellationToken _)
47
- {
48
- var commandLineSwitches = new List<ExtensionCommandLineSwitch>(BuiltInSwitches);
49
- commandLineSwitches.AddRange(this.Extensions.SelectMany(e => e.CommandLineSwitches).OrderBy(s => s.Switch, StringComparer.Ordinal));
50
-
51
- Console.WriteLine();
52
- Console.WriteLine("Usage: wix [option]");
53
- Console.WriteLine("Usage: wix [command]");
54
- Console.WriteLine();
55
- Console.WriteLine("Options:");
56
- Console.WriteLine(" -h|--help Show command line help.");
57
- Console.WriteLine(" --version Display WiX Toolset version in use.");
58
- Console.WriteLine();
59
-
60
- Console.WriteLine("Commands:");
61
- foreach (var commandLineSwitch in commandLineSwitches)
63
+ var commands = new List<CommandLineHelpCommand>();
64
+ if (help.Commands != null)
65
+ {
66
+ commands.AddRange(help.Commands);
67
+ }
68
+
69
+ if (this.Command == null)
70
+ {
71
+ commands.AddRange(extensionsHelp.Where(e => e.Commands != null).SelectMany(e => e.Commands));
72
+ }
73
+
74
+ if (!String.IsNullOrEmpty(help.Description))
75
+ {
76
+ Console.WriteLine("Description:");
77
+ Console.WriteLine(" {0}", help.Description);
78
+ Console.WriteLine();
79
+ }
80
+
81
+ if (!String.IsNullOrEmpty(help.Usage))
82
+ {
83
+ Console.WriteLine("Usage:");
84
+ Console.WriteLine(" wix {0}", help.Usage);
85
+ Console.WriteLine();
86
+ }
87
+
88
+ if (switches.Count > 0)
89
+ {
90
+ Console.WriteLine("Options:");
91
+ foreach (var commandLineSwitch in help.Switches)
92
+ {
93
+ var switchName = String.IsNullOrEmpty(commandLineSwitch.ShortName) ? commandLineSwitch.Name : $"{commandLineSwitch.ShortName}|{commandLineSwitch.Name}";
94
+ Console.WriteLine(" {0,-17} {1}", switchName, commandLineSwitch.Description);
95
+ }
96
+
97
+ Console.WriteLine();
98
+ }
99
+
100
+ if (commands.Count > 0)
101
+ {
102
+ Console.WriteLine("Commands:");
103
+ foreach (var command in commands)
104
+ {
105
+ Console.WriteLine(" {0,-17} {1}", command.Name, command.Description);
106
+ }
107
+
108
+ Console.WriteLine();
109
+ }
110
+
111
+ if (!String.IsNullOrEmpty(help.Notes))
112
{
63
- Console.WriteLine(" {0,-17} {1}", commandLineSwitch.Switch, commandLineSwitch.Description);
113
+ Console.WriteLine(help.Notes);
114
+ Console.WriteLine();
115
}
116
66
- Console.WriteLine();
67
- Console.WriteLine("Run 'wix [command] -h[elp]' for more information on a command.");
68
- Console.WriteLine();
117
Console.WriteLine(this.Branding.ReplacePlaceholders("For more information see: [SupportUrl]"));
118
119
return Task.FromResult(-1);
120
}
121
74
- public bool TryParseArgument(ICommandLineParser parseHelper, string argument)
122
+ public override bool TryParseArgument(ICommandLineParser parseHelper, string argument)
123
{
124
return true; // eat any arguments
125
}
src/wix/WixToolset.Core/CommandLine/VersionCommand.cs
+8
-8
@@ -5,18 +5,18 @@ namespace WixToolset.Core.CommandLine
5
using System;
6
using System.Threading;
7
using System.Threading.Tasks;
8
+ using WixToolset.Extensibility;
9
using WixToolset.Extensibility.Data;
10
using WixToolset.Extensibility.Services;
11
11
- internal class VersionCommand : ICommandLineCommand
12
+ internal class VersionCommand : BaseCommandLineCommand
13
{
13
- public bool ShowHelp { get; set; }
14
-
15
- public bool ShowLogo { get; set; }
16
-
17
- public bool StopParsing => true;
14
+ public override CommandLineHelp GetCommandLineHelp()
15
+ {
16
+ return null;
17
+ }
18
19
- public Task<int> ExecuteAsync(CancellationToken cancellationToken)
19
+ public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
20
{
21
// $(GitBaseVersionMajor).$(GitBaseVersionMinor).$(GitBaseVersionPatch)$(GitSemVerDashLabel)+$(Commit)
22
Console.WriteLine("{0}.{1}.{2}{3}+{4}", ThisAssembly.Git.BaseVersion.Major
@@ -27,7 +27,7 @@ namespace WixToolset.Core.CommandLine
27
return Task.FromResult(0);
28
}
29
30
- public bool TryParseArgument(ICommandLineParser parseHelper, string argument)
30
+ public override bool TryParseArgument(ICommandLineParser parseHelper, string argument)
31
{
32
return true; // eat any arguments
33
}
src/wix/test/Example.Extension/ExamplePreprocessorExtensionAndCommandLine.cs
+7
-2
@@ -3,7 +3,6 @@
3
namespace Example.Extension
4
{
5
using System;
6
- using System.Collections.Generic;
6
using WixToolset.Extensibility;
7
using WixToolset.Extensibility.Data;
8
using WixToolset.Extensibility.Services;
@@ -12,7 +11,13 @@ namespace Example.Extension
11
{
12
private string exampleValueFromCommandLine;
13
15
- public IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => throw new NotImplementedException();
14
+ public CommandLineHelp GetCommandLineHelp()
15
+ {
16
+ return new CommandLineHelp("Example command line extension", "example value", new[]
17
+ {
18
+ new CommandLineHelpSwitch("-example", "Sets an example value")
19
+ });
20
+ }
21
22
public ExamplePreprocessorExtensionAndCommandLine()
23
{
src/wix/test/WixToolsetTest.CoreIntegration/CommandLineFixture.cs
+2
-3
@@ -22,10 +22,9 @@ namespace WixToolsetTest.CoreIntegration
22
WixAssert.CompareLineByLine(new[]
23
{
24
"-bindpath is expected to be followed by a value. See -? for additional detail.",
25
- "Additional argument '-bindpath' was unexpected. Remove the argument and add the '-?' switch for more information.",
26
- "No source files specified."
25
+ "Additional argument '-bindpath' was unexpected. Remove the argument and add the '-?' switch for more information."
26
}, result.Messages.Select(m => m.ToString()).ToArray());
28
- Assert.Equal(391, result.ExitCode);
27
+ Assert.Equal(1, result.ExitCode);
28
}
29
30
[Fact]