CLI: Add explicit per-command argument overrides (#41478)
David Bennett committed
Sep 1, 2026 at 11:15 UTC
2dbe9953723e03f987b34bd1f5138dbf39238012
48 files changed
+193
-146
src/windows/wslc/arguments/Argument.cpp
+9
-15
@@ -28,28 +28,22 @@ using namespace std::literals;
28
namespace wsl::windows::wslc {
29
using namespace wsl::windows::wslc::execution;
30
31
-// This is the main Argument creation method, allowing overrides of the default properties of arguments.
32
-// The ArgType has some core characteristic, such as the Kind, Name, and Alias. If these
33
-// need to be changed, it is recommended to create a new ArgType in ArgumentDefinitions.h. If the argument
34
-// just needs a different description, it can be overridden in the desc, or if you need it to be required,
35
-// or to allow multiple uses within a command, then those properties can be set using the Create
36
-// function below inside the command. In this way all arguments default to "1" use and not required, and
37
-// this can only be changed in the command's GetArguments function, so the defaults are always clear and
38
-// consistent. Visibility can also be overridden and is defaulted to "Help".
39
-Argument Argument::Create(ArgType type, std::optional<bool> required, std::optional<argument::Limit> limit, std::optional<std::wstring> desc)
31
+Argument Argument::Create(ArgType type, ArgumentOverrides overrides)
32
{
33
+ WI_ASSERT(!overrides.Name.has_value() || overrides.Name->size() >= 2);
34
+
35
switch (type)
36
{
43
-#define WSLC_ARG_CREATE_CASE(EnumName, Name, Alias, ArgumentKind, ConvertedType, Desc) \
37
+#define WSLC_ARG_CREATE_CASE(EnumName, DefaultName, DefaultAlias, ArgumentKind, ConvertedType, DefaultDesc) \
38
case ArgType::EnumName: \
39
return Argument{ \
40
type, \
47
- L##Name, \
48
- Alias, \
49
- desc.has_value() ? std::move(desc.value()) : std::wstring(Desc), \
41
+ overrides.Name.has_value() ? std::move(overrides.Name.value()) : std::wstring{L##DefaultName}, \
42
+ overrides.Alias.has_value() ? std::move(overrides.Alias.value()) : std::wstring{DefaultAlias}, \
43
+ overrides.Desc.has_value() ? std::move(overrides.Desc.value()) : std::wstring(DefaultDesc), \
44
ArgumentKind, \
51
- required.value_or(DefaultRequired), \
52
- limit.value_or(DefaultLimit)};
45
+ overrides.Required.value_or(Argument::DefaultRequired), \
46
+ overrides.Limit.value_or(Argument::DefaultLimit)};
47
48
WSLC_ARGUMENTS(WSLC_ARG_CREATE_CASE)
49
#undef WSLC_ARG_CREATE_CASE
src/windows/wslc/arguments/Argument.h
+17
-10
@@ -14,7 +14,9 @@ Abstract:
14
#pragma once
15
#include "ArgMap.h"
16
17
+#include <optional>
18
#include <string>
19
+#include <utility>
20
21
#define WSLC_CLI_ARG_ID_CHAR L'-'
22
#define WSLC_CLI_ARG_ID_STRING L"-"
@@ -26,6 +28,15 @@ Abstract:
28
using namespace wsl::windows::wslc::argument;
29
30
namespace wsl::windows::wslc {
31
+struct ArgumentOverrides
32
+{
33
+ std::optional<std::wstring> Name;
34
+ std::optional<std::wstring> Alias;
35
+ std::optional<bool> Required;
36
+ std::optional<argument::Limit> Limit;
37
+ std::optional<std::wstring> Desc;
38
+};
39
+
40
// An argument to a command.
41
struct Argument
42
{
@@ -37,13 +48,13 @@ struct Argument
48
// Full constructor with all parameters
49
Argument(
50
ArgType argType,
40
- const std::wstring& name,
41
- const std::wstring& alias,
42
- const std::wstring& desc,
51
+ std::wstring name,
52
+ std::wstring alias,
53
+ std::wstring desc,
54
argument::Kind kind = DefaultKind,
55
bool required = DefaultRequired,
56
argument::Limit limit = DefaultLimit) :
46
- m_argType(argType), m_name(name), m_alias(alias), m_desc(desc), m_type(kind), m_required(required), m_limit(limit)
57
+ m_argType(argType), m_name(std::move(name)), m_desc(std::move(desc)), m_alias(std::move(alias)), m_required(required), m_type(kind), m_limit(limit)
58
{
59
}
60
@@ -53,12 +64,8 @@ struct Argument
64
Argument(Argument&&) = default;
65
Argument& operator=(Argument&&) = default;
66
56
- // Creates an argument with optional overrides for table defaults
57
- static Argument Create(
58
- ArgType type,
59
- std::optional<bool> required = std::nullopt,
60
- std::optional<argument::Limit> limit = std::nullopt,
61
- std::optional<std::wstring> desc = std::nullopt);
67
+ // Creates an argument using its table defaults and any command-specific overrides.
68
+ static Argument Create(ArgType type, ArgumentOverrides overrides = {});
69
70
// Gets the argument usage string in the format of "-alias,--name" or just "--name" if no alias.
71
std::wstring GetUsageString() const;
src/windows/wslc/arguments/ArgumentDefinitions.h
+5
-6
@@ -13,12 +13,11 @@ Abstract:
13
--*/
14
#pragma once
15
16
-// Here is where base argument types are defined, with their name, alias, kind, and default description.
17
-// The description can be overridden by commands if a particular command needs a different description but otherwise the
18
-// same argument type definition. The ArgType enum and the mapping of ArgType to data type are generated from this X-Macro, so all
19
-// arguments must be defined here to be used in the system. The arguments defined here are the basis for all commands,
20
-// but not all arguments need to be used by all commands, and additional properties of the arguments can be set in the command's
21
-// GetArguments function when creating the Argument with Argument::Create.
16
+// Here is where base argument types are defined, with their default name, default alias, kind, conversion type, and
17
+// default description. Commands can override the name, alias, required state, limit, and description. The ArgType enum,
18
+// kind, and conversion type remain fixed. The ArgType enum and the mapping of ArgType to data type are generated from
19
+// this X-Macro, so all arguments must be defined here to be used in the system. The arguments defined here are the basis
20
+// for all commands, but not all arguments need to be used by all commands.
21
22
// The Kind determines the data type:
23
// - Kind::Flag -> bool
src/windows/wslc/commands/ContainerAttachCommand.cpp
+1
-1
@@ -28,7 +28,7 @@ namespace wsl::windows::wslc {
28
std::vector<Argument> ContainerAttachCommand::GetArguments() const
29
{
30
return {
31
- Argument::Create(ArgType::ContainerId, true),
31
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
32
};
33
}
34
src/windows/wslc/commands/ContainerCpCommand.cpp
+2
-2
@@ -16,8 +16,8 @@ std::vector<Argument> ContainerCpCommand::GetArguments() const
16
{
17
return {
18
Argument::Create(ArgType::Archive),
19
- Argument::Create(ArgType::Source, true, std::nullopt, Localization::WSLCCLI_CpSourceArgDescription()),
20
- Argument::Create(ArgType::Target, true, std::nullopt, Localization::WSLCCLI_CpTargetArgDescription()),
19
+ Argument::Create(ArgType::Source, {.Required = true, .Desc = Localization::WSLCCLI_CpSourceArgDescription()}),
20
+ Argument::Create(ArgType::Target, {.Required = true, .Desc = Localization::WSLCCLI_CpTargetArgDescription()}),
21
};
22
}
23
src/windows/wslc/commands/ContainerCreateCommand.cpp
+15
-15
@@ -28,19 +28,19 @@ std::vector<Argument> ContainerCreateCommand::GetArguments() const
28
{
29
// clang-format off
30
return {
31
- Argument::Create(ArgType::ImageId, true),
31
+ Argument::Create(ArgType::ImageId, {.Required = true}),
32
Argument::Create(ArgType::Command),
33
Argument::Create(ArgType::ForwardArgs),
34
Argument::Create(ArgType::CIDFile),
35
Argument::Create(ArgType::Cpus),
36
- Argument::Create(ArgType::DNS, false, Limit::Unlimited),
36
+ Argument::Create(ArgType::DNS, {.Limit = Limit::Unlimited}),
37
// Argument::Create(ArgType::DNSDomain),
38
- Argument::Create(ArgType::DNSOption, false, Limit::Unlimited),
39
- Argument::Create(ArgType::DNSSearch, false, Limit::Unlimited),
38
+ Argument::Create(ArgType::DNSOption, {.Limit = Limit::Unlimited}),
39
+ Argument::Create(ArgType::DNSSearch, {.Limit = Limit::Unlimited}),
40
Argument::Create(ArgType::Domainname),
41
Argument::Create(ArgType::Entrypoint),
42
- Argument::Create(ArgType::Env, false, Limit::Unlimited),
43
- Argument::Create(ArgType::EnvFile, false, Limit::Unlimited),
42
+ Argument::Create(ArgType::Env, {.Limit = Limit::Unlimited}),
43
+ Argument::Create(ArgType::EnvFile, {.Limit = Limit::Unlimited}),
44
// Argument::Create(ArgType::GroupId),
45
Argument::Create(ArgType::Gpus),
46
Argument::Create(ArgType::HealthCmd),
@@ -50,17 +50,17 @@ std::vector<Argument> ContainerCreateCommand::GetArguments() const
50
Argument::Create(ArgType::HealthTimeout),
51
Argument::Create(ArgType::Hostname),
52
Argument::Create(ArgType::Interactive),
53
- Argument::Create(ArgType::IpAddress, false),
54
- Argument::Create(ArgType::Label, false, Limit::Unlimited),
53
+ Argument::Create(ArgType::IpAddress),
54
+ Argument::Create(ArgType::Label, {.Limit = Limit::Unlimited}),
55
Argument::Create(ArgType::Memory),
56
- Argument::Create(ArgType::Mount, false, Limit::Unlimited),
56
+ Argument::Create(ArgType::Mount, {.Limit = Limit::Unlimited}),
57
Argument::Create(ArgType::Name),
58
- Argument::Create(ArgType::Network, false, Limit::Unlimited),
59
- Argument::Create(ArgType::NetworkAlias, false, Limit::Unlimited),
58
+ Argument::Create(ArgType::Network, {.Limit = Limit::Unlimited}),
59
+ Argument::Create(ArgType::NetworkAlias, {.Limit = Limit::Unlimited}),
60
// Argument::Create(ArgType::NoDNS),
61
// Argument::Create(ArgType::Progress),
62
Argument::Create(ArgType::NoHealthcheck),
63
- Argument::Create(ArgType::Publish, false, Limit::Unlimited),
63
+ Argument::Create(ArgType::Publish, {.Limit = Limit::Unlimited}),
64
Argument::Create(ArgType::PublishAll),
65
Argument::Create(ArgType::Pull),
66
Argument::Create(ArgType::Remove),
@@ -68,11 +68,11 @@ std::vector<Argument> ContainerCreateCommand::GetArguments() const
68
Argument::Create(ArgType::ShmSize),
69
Argument::Create(ArgType::StopSignal),
70
Argument::Create(ArgType::StopTimeout),
71
- Argument::Create(ArgType::TMPFS, false, Limit::Unlimited),
71
+ Argument::Create(ArgType::TMPFS, {.Limit = Limit::Unlimited}),
72
Argument::Create(ArgType::TTY),
73
- Argument::Create(ArgType::Ulimit, false, Limit::Unlimited),
73
+ Argument::Create(ArgType::Ulimit, {.Limit = Limit::Unlimited}),
74
Argument::Create(ArgType::User),
75
- Argument::Create(ArgType::Volume, false, Limit::Unlimited),
75
+ Argument::Create(ArgType::Volume, {.Limit = Limit::Unlimited}),
76
// Argument::Create(ArgType::Virtual),
77
Argument::Create(ArgType::WorkDir),
78
};
src/windows/wslc/commands/ContainerExecCommand.cpp
+5
-5
@@ -27,12 +27,12 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerExecCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true),
31
- Argument::Create(ArgType::Command, true),
32
- Argument::Create(ArgType::ForwardArgs, std::nullopt, std::nullopt, Localization::WSLCCLI_ContainerExecForwardArgsDescription()),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
31
+ Argument::Create(ArgType::Command, {.Required = true}),
32
+ Argument::Create(ArgType::ForwardArgs, {.Desc = Localization::WSLCCLI_ContainerExecForwardArgsDescription()}),
33
Argument::Create(ArgType::Detach),
34
- Argument::Create(ArgType::Env, false, Limit::Unlimited),
35
- Argument::Create(ArgType::EnvFile, false, Limit::Unlimited),
34
+ Argument::Create(ArgType::Env, {.Limit = Limit::Unlimited}),
35
+ Argument::Create(ArgType::EnvFile, {.Limit = Limit::Unlimited}),
36
Argument::Create(ArgType::Interactive),
37
Argument::Create(ArgType::TTY),
38
Argument::Create(ArgType::User),
src/windows/wslc/commands/ContainerExportCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerExportCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true),
31
- Argument::Create(ArgType::Output, std::nullopt, std::nullopt, Localization::WSLCCLI_ContainerExportOutputArgDescription()),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
31
+ Argument::Create(ArgType::Output, {.Desc = Localization::WSLCCLI_ContainerExportOutputArgDescription()}),
32
};
33
}
34
src/windows/wslc/commands/ContainerInspectCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerInspectCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true, Limit::Unlimited),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true, .Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::InspectFormat),
32
};
33
}
src/windows/wslc/commands/ContainerKillCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerKillCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true, Limit::Unlimited),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true, .Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::Signal),
32
};
33
}
src/windows/wslc/commands/ContainerListCommand.cpp
+1
-1
@@ -29,7 +29,7 @@ std::vector<Argument> ContainerListCommand::GetArguments() const
29
{
30
return {
31
Argument::Create(ArgType::All),
32
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
32
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
33
Argument::Create(ArgType::Format),
34
Argument::Create(ArgType::Last),
35
Argument::Create(ArgType::Latest),
src/windows/wslc/commands/ContainerLogsCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerLogsCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
31
Argument::Create(ArgType::Follow),
32
Argument::Create(ArgType::Tail),
33
Argument::Create(ArgType::Timestamps),
src/windows/wslc/commands/ContainerRemoveCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerRemoveCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true, Limit::Unlimited),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true, .Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::Force),
32
Argument::Create(ArgType::Volumes),
33
};
src/windows/wslc/commands/ContainerRunCommand.cpp
+15
-15
@@ -28,20 +28,20 @@ std::vector<Argument> ContainerRunCommand::GetArguments() const
28
{
29
// clang-format off
30
return {
31
- Argument::Create(ArgType::ImageId, true),
31
+ Argument::Create(ArgType::ImageId, {.Required = true}),
32
Argument::Create(ArgType::Command),
33
Argument::Create(ArgType::ForwardArgs),
34
Argument::Create(ArgType::CIDFile),
35
Argument::Create(ArgType::Cpus),
36
Argument::Create(ArgType::Detach),
37
- Argument::Create(ArgType::DNS, false, Limit::Unlimited),
37
+ Argument::Create(ArgType::DNS, {.Limit = Limit::Unlimited}),
38
// Argument::Create(ArgType::DNSDomain),
39
- Argument::Create(ArgType::DNSOption, false, Limit::Unlimited),
40
- Argument::Create(ArgType::DNSSearch, false, Limit::Unlimited),
39
+ Argument::Create(ArgType::DNSOption, {.Limit = Limit::Unlimited}),
40
+ Argument::Create(ArgType::DNSSearch, {.Limit = Limit::Unlimited}),
41
Argument::Create(ArgType::Domainname),
42
Argument::Create(ArgType::Entrypoint),
43
- Argument::Create(ArgType::Env, false, Limit::Unlimited),
44
- Argument::Create(ArgType::EnvFile, false, Limit::Unlimited),
43
+ Argument::Create(ArgType::Env, {.Limit = Limit::Unlimited}),
44
+ Argument::Create(ArgType::EnvFile, {.Limit = Limit::Unlimited}),
45
Argument::Create(ArgType::Gpus),
46
Argument::Create(ArgType::HealthCmd),
47
Argument::Create(ArgType::HealthInterval),
@@ -50,17 +50,17 @@ std::vector<Argument> ContainerRunCommand::GetArguments() const
50
Argument::Create(ArgType::HealthTimeout),
51
Argument::Create(ArgType::Hostname),
52
Argument::Create(ArgType::Interactive),
53
- Argument::Create(ArgType::IpAddress, false),
54
- Argument::Create(ArgType::Label, false, Limit::Unlimited),
53
+ Argument::Create(ArgType::IpAddress),
54
+ Argument::Create(ArgType::Label, {.Limit = Limit::Unlimited}),
55
Argument::Create(ArgType::Memory),
56
- Argument::Create(ArgType::Mount, false, Limit::Unlimited),
56
+ Argument::Create(ArgType::Mount, {.Limit = Limit::Unlimited}),
57
Argument::Create(ArgType::Name),
58
- Argument::Create(ArgType::Network, false, Limit::Unlimited),
59
- Argument::Create(ArgType::NetworkAlias, false, Limit::Unlimited),
58
+ Argument::Create(ArgType::Network, {.Limit = Limit::Unlimited}),
59
+ Argument::Create(ArgType::NetworkAlias, {.Limit = Limit::Unlimited}),
60
// Argument::Create(ArgType::NoDNS),
61
// Argument::Create(ArgType::Progress),
62
Argument::Create(ArgType::NoHealthcheck),
63
- Argument::Create(ArgType::Publish, false, Limit::Unlimited),
63
+ Argument::Create(ArgType::Publish, {.Limit = Limit::Unlimited}),
64
Argument::Create(ArgType::PublishAll),
65
Argument::Create(ArgType::Pull),
66
Argument::Create(ArgType::Remove),
@@ -68,11 +68,11 @@ std::vector<Argument> ContainerRunCommand::GetArguments() const
68
Argument::Create(ArgType::ShmSize),
69
Argument::Create(ArgType::StopSignal),
70
Argument::Create(ArgType::StopTimeout),
71
- Argument::Create(ArgType::TMPFS, false, Limit::Unlimited),
71
+ Argument::Create(ArgType::TMPFS, {.Limit = Limit::Unlimited}),
72
Argument::Create(ArgType::TTY),
73
- Argument::Create(ArgType::Ulimit, false, Limit::Unlimited),
73
+ Argument::Create(ArgType::Ulimit, {.Limit = Limit::Unlimited}),
74
Argument::Create(ArgType::User),
75
- Argument::Create(ArgType::Volume, false, Limit::Unlimited),
75
+ Argument::Create(ArgType::Volume, {.Limit = Limit::Unlimited}),
76
// Argument::Create(ArgType::Virtual),
77
Argument::Create(ArgType::WorkDir),
78
};
src/windows/wslc/commands/ContainerStartCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerStartCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
31
Argument::Create(ArgType::Attach),
32
Argument::Create(ArgType::Interactive), // NYI
33
};
src/windows/wslc/commands/ContainerStatsCommand.cpp
+1
-1
@@ -26,7 +26,7 @@ namespace wsl::windows::wslc {
26
std::vector<Argument> ContainerStatsCommand::GetArguments() const
27
{
28
return {
29
- Argument::Create(ArgType::ContainerId, false, Limit::Unlimited),
29
+ Argument::Create(ArgType::ContainerId, {.Limit = Limit::Unlimited}),
30
Argument::Create(ArgType::All),
31
Argument::Create(ArgType::Format),
32
Argument::Create(ArgType::NoTrunc),
src/windows/wslc/commands/ContainerStopCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ContainerStopCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ContainerId, true, Limit::Unlimited),
31
- Argument::Create(ArgType::Signal, std::nullopt, std::nullopt, Localization::WSLCCLI_ContainerStopSignalArgDescription()),
30
+ Argument::Create(ArgType::ContainerId, {.Required = true, .Limit = Limit::Unlimited}),
31
+ Argument::Create(ArgType::Signal, {.Desc = Localization::WSLCCLI_ContainerStopSignalArgDescription()}),
32
Argument::Create(ArgType::Time),
33
};
34
}
src/windows/wslc/commands/ImageBuildCommand.cpp
+6
-6
@@ -27,18 +27,18 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ImageBuildCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::Path, true),
31
- Argument::Create(ArgType::BuildArg, false, Limit::Unlimited),
30
+ Argument::Create(ArgType::Path, {.Required = true}),
31
+ Argument::Create(ArgType::BuildArg, {.Limit = Limit::Unlimited}),
32
Argument::Create(ArgType::BuildPull),
33
Argument::Create(ArgType::BuildTarget),
34
Argument::Create(ArgType::File),
35
Argument::Create(ArgType::IidFile),
36
- Argument::Create(ArgType::BuildLabel, false, Limit::Unlimited),
36
+ Argument::Create(ArgType::BuildLabel, {.Limit = Limit::Unlimited}),
37
Argument::Create(ArgType::NoCache),
38
- Argument::Create(ArgType::BuildOutput, false, std::nullopt, Localization::WSLCCLI_BuildOutputArgDescription()),
38
+ Argument::Create(ArgType::BuildOutput, {.Desc = Localization::WSLCCLI_BuildOutputArgDescription()}),
39
Argument::Create(ArgType::Progress),
40
- Argument::Create(ArgType::Secret, false, Limit::Unlimited),
41
- Argument::Create(ArgType::Tag, false, Limit::Unlimited),
40
+ Argument::Create(ArgType::Secret, {.Limit = Limit::Unlimited}),
41
+ Argument::Create(ArgType::Tag, {.Limit = Limit::Unlimited}),
42
Argument::Create(ArgType::Verbose),
43
};
44
}
src/windows/wslc/commands/ImageImportCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ImageImportCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ImportFile, true),
30
+ Argument::Create(ArgType::ImportFile, {.Required = true}),
31
Argument::Create(ArgType::ImageId),
32
Argument::Create(ArgType::NoTrunc),
33
};
src/windows/wslc/commands/ImageInspectCommand.cpp
+1
-1
@@ -28,7 +28,7 @@ namespace wsl::windows::wslc {
28
std::vector<Argument> ImageInspectCommand::GetArguments() const
29
{
30
return {
31
- Argument::Create(ArgType::ImageId, true, Limit::Unlimited),
31
+ Argument::Create(ArgType::ImageId, {.Required = true, .Limit = Limit::Unlimited}),
32
Argument::Create(ArgType::InspectFormat),
33
};
34
}
src/windows/wslc/commands/ImageListCommand.cpp
+1
-1
@@ -28,7 +28,7 @@ namespace wsl::windows::wslc {
28
std::vector<Argument> ImageListCommand::GetArguments() const
29
{
30
return {
31
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
31
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
32
Argument::Create(ArgType::Format),
33
Argument::Create(ArgType::NoTrunc),
34
Argument::Create(ArgType::Quiet),
src/windows/wslc/commands/ImagePruneCommand.cpp
+2
-2
@@ -28,8 +28,8 @@ namespace wsl::windows::wslc {
28
std::vector<Argument> ImagePruneCommand::GetArguments() const
29
{
30
return {
31
- Argument::Create(ArgType::All, std::nullopt, std::nullopt, Localization::WSLCCLI_ImagePruneAllArgDescription()),
32
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
31
+ Argument::Create(ArgType::All, {.Desc = Localization::WSLCCLI_ImagePruneAllArgDescription()}),
32
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
33
};
34
}
35
src/windows/wslc/commands/ImagePullCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ImagePullCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ImageId, true),
31
- Argument::Create(ArgType::Quiet, std::nullopt, std::nullopt, Localization::WSLCCLI_PullQuietArgDescription()),
30
+ Argument::Create(ArgType::ImageId, {.Required = true}),
31
+ Argument::Create(ArgType::Quiet, {.Desc = Localization::WSLCCLI_PullQuietArgDescription()}),
32
// Argument::Create(ArgType::Scheme),
33
// Argument::Create(ArgType::Progress),
34
};
src/windows/wslc/commands/ImagePushCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ImagePushCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ImageId, true),
30
+ Argument::Create(ArgType::ImageId, {.Required = true}),
31
};
32
}
33
src/windows/wslc/commands/ImageRemoveCommand.cpp
+1
-1
@@ -28,7 +28,7 @@ namespace wsl::windows::wslc {
28
std::vector<Argument> ImageRemoveCommand::GetArguments() const
29
{
30
return {
31
- Argument::Create(ArgType::ImageId, true, Limit::Unlimited),
31
+ Argument::Create(ArgType::ImageId, {.Required = true, .Limit = Limit::Unlimited}),
32
Argument::Create(ArgType::ImageForce),
33
Argument::Create(ArgType::NoPrune),
34
};
src/windows/wslc/commands/ImageSaveCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ImageSaveCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::ImageId, true, Limit::Unlimited),
30
+ Argument::Create(ArgType::ImageId, {.Required = true, .Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::Output),
32
};
33
}
src/windows/wslc/commands/ImageTagCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> ImageTagCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::Source, true),
31
- Argument::Create(ArgType::Target, true),
30
+ Argument::Create(ArgType::Source, {.Required = true}),
31
+ Argument::Create(ArgType::Target, {.Required = true}),
32
};
33
}
34
src/windows/wslc/commands/InspectCommand.cpp
+1
-1
@@ -22,7 +22,7 @@ namespace wsl::windows::wslc {
22
std::vector<Argument> InspectCommand::GetArguments() const
23
{
24
return {
25
- Argument::Create(ArgType::ObjectId, true, Limit::Unlimited),
25
+ Argument::Create(ArgType::ObjectId, {.Required = true, .Limit = Limit::Unlimited}),
26
Argument::Create(ArgType::Type),
27
Argument::Create(ArgType::InspectFormat),
28
};
src/windows/wslc/commands/NetworkConnectCommand.cpp
+7
-7
@@ -27,13 +27,13 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkConnectCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::NetworkName, true),
31
- Argument::Create(ArgType::ContainerId, true),
32
- Argument::Create(ArgType::DriverOpt, false, Limit::Unlimited),
33
- Argument::Create(ArgType::IpAddress, false),
34
- Argument::Create(ArgType::Link, false, Limit::Unlimited),
35
- Argument::Create(ArgType::LinkLocalIp, false, Limit::Unlimited),
36
- Argument::Create(ArgType::NetworkAlias, false, Limit::Unlimited),
30
+ Argument::Create(ArgType::NetworkName, {.Required = true}),
31
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
32
+ Argument::Create(ArgType::DriverOpt, {.Limit = Limit::Unlimited}),
33
+ Argument::Create(ArgType::IpAddress),
34
+ Argument::Create(ArgType::Link, {.Limit = Limit::Unlimited}),
35
+ Argument::Create(ArgType::LinkLocalIp, {.Limit = Limit::Unlimited}),
36
+ Argument::Create(ArgType::NetworkAlias, {.Limit = Limit::Unlimited}),
37
};
38
}
39
src/windows/wslc/commands/NetworkCreateCommand.cpp
+4
-4
@@ -27,10 +27,10 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkCreateCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::NetworkName, true),
31
- Argument::Create(ArgType::Driver, std::nullopt, std::nullopt, Localization::WSLCCLI_NetworkDriverOptionDescription()),
32
- Argument::Create(ArgType::Options, false, Limit::Unlimited),
33
- Argument::Create(ArgType::Label, false, Limit::Unlimited, Localization::WSLCCLI_NetworkLabelArgDescription()),
30
+ Argument::Create(ArgType::NetworkName, {.Required = true}),
31
+ Argument::Create(ArgType::Driver, {.Desc = Localization::WSLCCLI_NetworkDriverOptionDescription()}),
32
+ Argument::Create(ArgType::Options, {.Limit = Limit::Unlimited}),
33
+ Argument::Create(ArgType::Label, {.Limit = Limit::Unlimited, .Desc = Localization::WSLCCLI_NetworkLabelArgDescription()}),
34
Argument::Create(ArgType::Gateway),
35
Argument::Create(ArgType::Internal),
36
Argument::Create(ArgType::IpRange),
src/windows/wslc/commands/NetworkDisconnectCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkDisconnectCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::NetworkName, true),
31
- Argument::Create(ArgType::ContainerId, true),
30
+ Argument::Create(ArgType::NetworkName, {.Required = true}),
31
+ Argument::Create(ArgType::ContainerId, {.Required = true}),
32
};
33
}
34
src/windows/wslc/commands/NetworkInspectCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkInspectCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::NetworkName, true, Limit::Unlimited),
30
+ Argument::Create(ArgType::NetworkName, {.Required = true, .Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::InspectFormat),
32
};
33
}
src/windows/wslc/commands/NetworkListCommand.cpp
+2
-2
@@ -27,10 +27,10 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkListCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
30
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::Format),
32
Argument::Create(ArgType::NoTrunc),
33
- Argument::Create(ArgType::Quiet, false, std::nullopt, Localization::WSLCCLI_NetworkListQuietArgDesc()),
33
+ Argument::Create(ArgType::Quiet, {.Desc = Localization::WSLCCLI_NetworkListQuietArgDesc()}),
34
};
35
}
36
src/windows/wslc/commands/NetworkPruneCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkPruneCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
30
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
31
};
32
}
33
src/windows/wslc/commands/NetworkRemoveCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> NetworkRemoveCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::NetworkName, true, Limit::Unlimited),
31
- Argument::Create(ArgType::Force, std::nullopt, std::nullopt, Localization::WSLCCLI_NetworkForceArgDescription()),
30
+ Argument::Create(ArgType::NetworkName, {.Required = true, .Limit = Limit::Unlimited}),
31
+ Argument::Create(ArgType::Force, {.Desc = Localization::WSLCCLI_NetworkForceArgDescription()}),
32
};
33
}
34
src/windows/wslc/commands/SessionEnterCommand.cpp
+2
-2
@@ -26,8 +26,8 @@ namespace wsl::windows::wslc {
26
std::vector<Argument> SessionEnterCommand::GetArguments() const
27
{
28
return {
29
- Argument::Create(ArgType::StoragePath, true),
30
- Argument::Create(ArgType::Name, std::nullopt, std::nullopt, Localization::WSLCCLI_SessionEnterNameArgDescription()),
29
+ Argument::Create(ArgType::StoragePath, {.Required = true}),
30
+ Argument::Create(ArgType::Name, {.Desc = Localization::WSLCCLI_SessionEnterNameArgDescription()}),
31
};
32
}
33
src/windows/wslc/commands/SessionListCommand.cpp
+1
-1
@@ -25,7 +25,7 @@ namespace wsl::windows::wslc {
25
std::vector<Argument> SessionListCommand::GetArguments() const
26
{
27
return {
28
- Argument::Create(ArgType::Verbose, std::nullopt, std::nullopt, Localization::WSLCCLI_SessionListVerboseArgDescription()),
28
+ Argument::Create(ArgType::Verbose, {.Desc = Localization::WSLCCLI_SessionListVerboseArgDescription()}),
29
};
30
}
31
src/windows/wslc/commands/SessionRunCommand.cpp
+2
-2
@@ -25,8 +25,8 @@ namespace wsl::windows::wslc {
25
std::vector<Argument> SessionRunCommand::GetArguments() const
26
{
27
return {
28
- Argument::Create(ArgType::Command, true),
29
- Argument::Create(ArgType::ForwardArgs, std::nullopt, std::nullopt, Localization::WSLCCLI_SessionRunForwardArgsDescription()),
28
+ Argument::Create(ArgType::Command, {.Required = true}),
29
+ Argument::Create(ArgType::ForwardArgs, {.Desc = Localization::WSLCCLI_SessionRunForwardArgsDescription()}),
30
};
31
}
32
src/windows/wslc/commands/VolumeCreateCommand.cpp
+2
-2
@@ -29,8 +29,8 @@ std::vector<Argument> VolumeCreateCommand::GetArguments() const
29
return {
30
Argument::Create(ArgType::VolumeName),
31
Argument::Create(ArgType::Driver),
32
- Argument::Create(ArgType::Options, false, Limit::Unlimited),
33
- Argument::Create(ArgType::Label, false, Limit::Unlimited),
32
+ Argument::Create(ArgType::Options, {.Limit = Limit::Unlimited}),
33
+ Argument::Create(ArgType::Label, {.Limit = Limit::Unlimited}),
34
};
35
}
36
src/windows/wslc/commands/VolumeInspectCommand.cpp
+1
-1
@@ -27,7 +27,7 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> VolumeInspectCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::VolumeName, true, Limit::Unlimited),
30
+ Argument::Create(ArgType::VolumeName, {.Required = true, .Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::InspectFormat),
32
};
33
}
src/windows/wslc/commands/VolumeListCommand.cpp
+2
-2
@@ -27,9 +27,9 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> VolumeListCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
30
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
31
Argument::Create(ArgType::Format),
32
- Argument::Create(ArgType::Quiet, false, std::nullopt, Localization::WSLCCLI_VolumeListQuietArgDesc()),
32
+ Argument::Create(ArgType::Quiet, {.Desc = Localization::WSLCCLI_VolumeListQuietArgDesc()}),
33
};
34
}
35
src/windows/wslc/commands/VolumePruneCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> VolumePruneCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::All, std::nullopt, std::nullopt, Localization::WSLCCLI_VolumePruneAllArgDescription()),
31
- Argument::Create(ArgType::Filter, false, Limit::Unlimited),
30
+ Argument::Create(ArgType::All, {.Desc = Localization::WSLCCLI_VolumePruneAllArgDescription()}),
31
+ Argument::Create(ArgType::Filter, {.Limit = Limit::Unlimited}),
32
};
33
}
34
src/windows/wslc/commands/VolumeRemoveCommand.cpp
+2
-2
@@ -27,8 +27,8 @@ namespace wsl::windows::wslc {
27
std::vector<Argument> VolumeRemoveCommand::GetArguments() const
28
{
29
return {
30
- Argument::Create(ArgType::VolumeName, true, Limit::Unlimited),
31
- Argument::Create(ArgType::Force, std::nullopt, std::nullopt, Localization::WSLCCLI_VolumeForceArgDescription()),
30
+ Argument::Create(ArgType::VolumeName, {.Required = true, .Limit = Limit::Unlimited}),
31
+ Argument::Create(ArgType::Force, {.Desc = Localization::WSLCCLI_VolumeForceArgDescription()}),
32
};
33
}
34
test/windows/wslc/ParserTestCases.h
+10
-10
@@ -55,21 +55,21 @@ inline std::vector<wsl::windows::wslc::Argument> GetArgumentsForSet(ArgumentSet
55
{
56
case ArgumentSet::Run:
57
return {
58
- Argument::Create(ArgType::ImageId, true), // Required positional argument
59
- Argument::Create(ArgType::Command, false), // Optional positional argument
60
- Argument::Create(ArgType::ForwardArgs, false),
58
+ Argument::Create(ArgType::ImageId, {.Required = true}), // Required positional argument
59
+ Argument::Create(ArgType::Command), // Optional positional argument
60
+ Argument::Create(ArgType::ForwardArgs),
61
Argument::Create(ArgType::Help),
62
Argument::Create(ArgType::Interactive),
63
Argument::Create(ArgType::Verbose),
64
Argument::Create(ArgType::Remove),
65
Argument::Create(ArgType::Signal),
66
Argument::Create(ArgType::Time),
67
- Argument::Create(ArgType::Publish, false, Limit::Unlimited), // Not required, unlimited.
67
+ Argument::Create(ArgType::Publish, {.Limit = Limit::Unlimited}), // Not required, unlimited.
68
};
69
70
case ArgumentSet::List:
71
return {
72
- Argument::Create(ArgType::ContainerId, false, Limit::Unlimited), // Optional positional
72
+ Argument::Create(ArgType::ContainerId, {.Limit = Limit::Unlimited}), // Optional positional
73
Argument::Create(ArgType::Help),
74
Argument::Create(ArgType::Verbose),
75
};
@@ -78,17 +78,17 @@ inline std::vector<wsl::windows::wslc::Argument> GetArgumentsForSet(ArgumentSet
78
// Mirrors ImageBuildCommand::GetArguments() so the parser tests exercise the
79
// real `wslc build` option set (notably the --progress value option).
80
return {
81
- Argument::Create(ArgType::Path, true), // Required positional (build context path)
82
- Argument::Create(ArgType::BuildArg, false, Limit::Unlimited),
81
+ Argument::Create(ArgType::Path, {.Required = true}), // Required positional (build context path)
82
+ Argument::Create(ArgType::BuildArg, {.Limit = Limit::Unlimited}),
83
Argument::Create(ArgType::BuildPull),
84
Argument::Create(ArgType::BuildTarget),
85
Argument::Create(ArgType::File),
86
- Argument::Create(ArgType::Label, false, Limit::Unlimited),
86
+ Argument::Create(ArgType::Label, {.Limit = Limit::Unlimited}),
87
Argument::Create(ArgType::NoCache),
88
Argument::Create(ArgType::Output),
89
Argument::Create(ArgType::Progress),
90
- Argument::Create(ArgType::Secret, false, Limit::Unlimited),
91
- Argument::Create(ArgType::Tag, false, Limit::Unlimited),
90
+ Argument::Create(ArgType::Secret, {.Limit = Limit::Unlimited}),
91
+ Argument::Create(ArgType::Tag, {.Limit = Limit::Unlimited}),
92
Argument::Create(ArgType::Verbose),
93
Argument::Create(ArgType::Help),
94
};
test/windows/wslc/WSLCCLIArgumentUnitTests.cpp
+19
@@ -69,6 +69,25 @@ class WSLCCLIArgumentUnitTests
69
VERIFY_ARE_EQUAL(ArgType::Verbose, withArgument.Arguments().front().Type());
70
}
71
72
+ TEST_METHOD(ArgumentCreate_DefaultsAndOverrides)
73
+ {
74
+ const auto defaults = Argument::Create(ArgType::Quiet);
75
+ VERIFY_ARE_EQUAL(std::wstring{L"quiet"}, defaults.Name());
76
+ VERIFY_ARE_EQUAL(std::wstring{L"q"}, defaults.Alias());
77
+
78
+ const auto noAlias = Argument::Create(ArgType::Quiet, {.Alias = NO_ALIAS});
79
+ VERIFY_IS_TRUE(noAlias.Alias().empty());
80
+ VERIFY_ARE_EQUAL(defaults.Description(), noAlias.Description());
81
+
82
+ const auto overrides = Argument::Create(
83
+ ArgType::Filter, {.Name = L"where", .Alias = L"x", .Required = true, .Limit = Limit::Unlimited, .Desc = L"Custom description"});
84
+ VERIFY_ARE_EQUAL(std::wstring{L"where"}, overrides.Name());
85
+ VERIFY_ARE_EQUAL(std::wstring{L"x"}, overrides.Alias());
86
+ VERIFY_IS_TRUE(overrides.Required());
87
+ VERIFY_ARE_EQUAL(Limit::Unlimited, overrides.Limit());
88
+ VERIFY_ARE_EQUAL(std::wstring{L"Custom description"}, overrides.Description());
89
+ }
90
+
91
// Test: Verify Argument::Create() successfully creates arguments for all ArgType enum values
92
TEST_METHOD(ArgumentCreate_AllArguments)
93
{
test/windows/wslc/WSLCCLICommandUnitTests.cpp
+7
@@ -316,6 +316,13 @@ class WSLCCLICommandUnitTests
316
317
// Check name collision between distinct ArgTypes.
318
const auto& name = arg.Name();
319
+ if (name.size() < 2)
320
+ {
321
+ VERIFY_FAIL(
322
+ std::format(L"Command '{}' uses invalid long-form name '--{}' for ArgType '{}'", commandFullName, name, ArgTypeName(arg.Type()))
323
+ .c_str());
324
+ }
325
+
326
auto [nameIt, nameInserted] = seenNames.emplace(name, arg.Type());
327
if (!nameInserted)
328
{
test/windows/wslc/WSLCCLIExecutionUnitTests.cpp
+1
-1
@@ -58,7 +58,7 @@ class WSLCCLIExecutionUnitTests
58
{
59
RootCommand command;
60
ArgMap args;
61
- const std::vector<Argument> definitions{Argument::Create(ArgType::Password, true)};
61
+ const std::vector<Argument> definitions{Argument::Create(ArgType::Password, {.Required = true})};
62
63
try
64
{
test/windows/wslc/WSLCCLIParserUnitTests.cpp
+24
-3
@@ -361,7 +361,7 @@ class WSLCCLIParserUnitTests
361
362
// Pass 2: full mode with the subcommand's argument set.
363
std::vector<Argument> subDefs = {
364
- Argument::Create(ArgType::ImageId, true),
364
+ Argument::Create(ArgType::ImageId, {.Required = true}),
365
Argument::Create(ArgType::Signal),
366
};
367
ArgMap subArgs;
@@ -558,7 +558,8 @@ class WSLCCLIParserUnitTests
558
// Unlimited value args are exempt from last-wins: every CLI occurrence accumulates.
559
TEST_METHOD(UnlimitedValueOnCli_Accumulates)
560
{
561
- ArgMap args = ParseFlags(L"wslc --publish 80:80 --publish 443:443", {Argument::Create(ArgType::Publish, false, Limit::Unlimited)});
561
+ ArgMap args =
562
+ ParseFlags(L"wslc --publish 80:80 --publish 443:443", {Argument::Create(ArgType::Publish, {.Limit = Limit::Unlimited})});
563
564
VERIFY_ARE_EQUAL(2u, args.Count(ArgType::Publish));
565
}
@@ -653,7 +654,8 @@ class WSLCCLIParserUnitTests
654
TEST_METHOD(Flag_SpaceSeparatedValue_StaysPositional)
655
{
656
ArgMap args = ParseFlags(
656
- L"wslc --verbose true", {Argument::Create(ArgType::Verbose), Argument::Create(ArgType::ContainerId, false, Limit::Unlimited)});
657
+ L"wslc --verbose true",
658
+ {Argument::Create(ArgType::Verbose), Argument::Create(ArgType::ContainerId, {.Limit = Limit::Unlimited})});
659
660
VERIFY_IS_TRUE(args.Contains(ArgType::Verbose));
661
VERIFY_IS_TRUE(args.GetValue<ArgType::Verbose>());
@@ -684,6 +686,25 @@ class WSLCCLIParserUnitTests
686
VERIFY_IS_FALSE(ParseFlags(L"wslc -q=false", {Argument::Create(ArgType::Quiet)}).GetValue<ArgType::Quiet>());
687
}
688
689
+ TEST_METHOD(AliasOverride_ControlsCommandAlias)
690
+ {
691
+ const std::vector<Argument> customAlias{Argument::Create(ArgType::Quiet, {.Alias = L"x"})};
692
+ VERIFY_IS_TRUE(ParseFlags(L"wslc -x", customAlias).GetValue<ArgType::Quiet>());
693
+ VERIFY_THROWS(ParseFlags(L"wslc -q", customAlias), ArgumentException);
694
+
695
+ const std::vector<Argument> noAlias{Argument::Create(ArgType::Quiet, {.Alias = NO_ALIAS})};
696
+ VERIFY_IS_TRUE(ParseFlags(L"wslc --quiet", noAlias).GetValue<ArgType::Quiet>());
697
+ VERIFY_THROWS(ParseFlags(L"wslc -q", noAlias), ArgumentException);
698
+ }
699
+
700
+ TEST_METHOD(NameOverride_ControlsCommandName)
701
+ {
702
+ const std::vector<Argument> definitions{Argument::Create(ArgType::Quiet, {.Name = L"silent"})};
703
+ VERIFY_IS_TRUE(ParseFlags(L"wslc --silent", definitions).GetValue<ArgType::Quiet>());
704
+ VERIFY_IS_TRUE(ParseFlags(L"wslc -q", definitions).GetValue<ArgType::Quiet>());
705
+ VERIFY_THROWS(ParseFlags(L"wslc --quiet", definitions), ArgumentException);
706
+ }
707
+
708
// Docker-parity single-letter forms ("t"/"T"/"f"/"F") are honored on the alias form too.
709
TEST_METHOD(Flag_AliasShortBooleanForms)
710
{