Skip to content

Commit e712372

Browse files
benhillisBen Hillis
andauthored
Localize all user-facing wslc.exe CLI strings (#40089)
* Localize all user-facing wslc.exe CLI strings Add localization entries for all hardcoded user-facing strings in the WSLC CLI tool: - 38 command description strings (Short + Long for all commands) - 30 argument description strings in ArgumentDefinitions.h - Settings reset confirmation string - All entries added to en-US/Resources.resw with {Locked=...} comments for CLI flags, product names, and technical terms E2E tests updated to use Localization:: calls and dynamic column formatting instead of hardcoded string copies, so they won't go stale when descriptions change. * formatting --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
1 parent d7828e8 commit e712372

44 files changed

Lines changed: 607 additions & 183 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

localization/strings/en-US/Resources.resw

Lines changed: 356 additions & 0 deletions
Large diffs are not rendered by default.

src/windows/wslc/arguments/ArgumentDefinitions.h

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -33,53 +33,53 @@ Module Name:
3333
// Format: ARGUMENT(EnumName, Name, Alias, Kind, Desc)
3434
// clang-format off
3535
#define WSLC_ARGUMENTS(_) \
36-
_(All, "all", L"a", Kind::Flag, L"Show all regardless of state.") \
36+
_(All, "all", L"a", Kind::Flag, Localization::WSLCCLI_AllArgDescription()) \
3737
_(Attach, "attach", L"a", Kind::Flag, Localization::WSLCCLI_AttachArgDescription()) \
38-
_(BuildArg, "build-arg", NO_ALIAS, Kind::Value, L"Set build-time variables (KEY=VALUE)") \
39-
/*_(CIDFile, "cidfile", NO_ALIAS, Kind::Value, L"Write the container ID to the provided path.")*/ \
40-
_(Command, "command", NO_ALIAS, Kind::Positional, L"The command to run") \
38+
_(BuildArg, "build-arg", NO_ALIAS, Kind::Value, Localization::WSLCCLI_BuildArgDescription()) \
39+
/*_(CIDFile, "cidfile", NO_ALIAS, Kind::Value, Localization::WSLCCLI_CIDFileArgDescription())*/ \
40+
_(Command, "command", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_CommandArgDescription()) \
4141
_(ContainerId, "container-id", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_ContainerIdArgDescription()) \
42-
_(Force, "force", L"f", Kind::Flag, L"Delete containers even if they are running") \
43-
_(Detach, "detach", L"d", Kind::Flag, L"Run container in detached mode") \
44-
/*_(DNS, "dns", NO_ALIAS, Kind::Value, L"IP address of the DNS nameserver in resolv.conf")*/ \
45-
/*_(DNSDomain, "dns-domain", NO_ALIAS, Kind::Value, L"Set the default DNS Domain")*/ \
46-
/*_(DNSOption, "dns-option", NO_ALIAS, Kind::Value, L"Set DNS options")*/ \
47-
/*_(DNSSearch, "dns-search", NO_ALIAS, Kind::Value, L"Set DNS search domains")*/ \
48-
_(Entrypoint, "entrypoint", NO_ALIAS, Kind::Value, L"Specifies the container init process executable") \
49-
_(Env, "env", L"e", Kind::Value, L"Key=Value pairs for environment variables") \
50-
_(EnvFile, "env-file", NO_ALIAS, Kind::Value, L"File containing key=value pairs of env variables") \
51-
_(File, "file", L"f", Kind::Value, L"Path to the Dockerfile (use \"-\" to read from stdin)") \
52-
_(Follow, "follow", L"f", Kind::Flag, L"Follow log output") \
53-
_(Format, "format", NO_ALIAS, Kind::Value, L"Output formatting (json or table) (Default:table)") \
54-
_(ForwardArgs, "arguments", NO_ALIAS, Kind::Forward, L"Arguments to pass to container's init process") \
55-
/*_(GroupId, "groupid", NO_ALIAS, Kind::Value, L"Group Id for the process")*/ \
42+
_(Force, "force", L"f", Kind::Flag, Localization::WSLCCLI_ForceArgDescription()) \
43+
_(Detach, "detach", L"d", Kind::Flag, Localization::WSLCCLI_DetachArgDescription()) \
44+
/*_(DNS, "dns", NO_ALIAS, Kind::Value, Localization::WSLCCLI_DNSArgDescription())*/ \
45+
/*_(DNSDomain, "dns-domain", NO_ALIAS, Kind::Value, Localization::WSLCCLI_DNSDomainArgDescription())*/ \
46+
/*_(DNSOption, "dns-option", NO_ALIAS, Kind::Value, Localization::WSLCCLI_DNSOptionArgDescription())*/ \
47+
/*_(DNSSearch, "dns-search", NO_ALIAS, Kind::Value, Localization::WSLCCLI_DNSSearchArgDescription())*/ \
48+
_(Entrypoint, "entrypoint", NO_ALIAS, Kind::Value, Localization::WSLCCLI_EntrypointArgDescription()) \
49+
_(Env, "env", L"e", Kind::Value, Localization::WSLCCLI_EnvArgDescription()) \
50+
_(EnvFile, "env-file", NO_ALIAS, Kind::Value, Localization::WSLCCLI_EnvFileArgDescription()) \
51+
_(File, "file", L"f", Kind::Value, Localization::WSLCCLI_FileArgDescription()) \
52+
_(Follow, "follow", L"f", Kind::Flag, Localization::WSLCCLI_FollowArgDescription()) \
53+
_(Format, "format", NO_ALIAS, Kind::Value, Localization::WSLCCLI_FormatArgDescription()) \
54+
_(ForwardArgs, "arguments", NO_ALIAS, Kind::Forward, Localization::WSLCCLI_ForwardArgsDescription()) \
55+
/*_(GroupId, "groupid", NO_ALIAS, Kind::Value, Localization::WSLCCLI_GroupIdArgDescription())*/ \
5656
_(Help, "help", WSLC_CLI_HELP_ARG, Kind::Flag, Localization::WSLCCLI_HelpArgDescription()) \
57-
_(ImageForce, "force", L"f", Kind::Flag, L"Delete images even if they are being used") \
58-
_(ImageId, "image", NO_ALIAS, Kind::Positional, L"Image name") \
59-
_(Input, "input", L"i", Kind::Value, L"Provides path to the tar archive file containing the image") \
57+
_(ImageForce, "force", L"f", Kind::Flag, Localization::WSLCCLI_ImageForceArgDescription()) \
58+
_(ImageId, "image", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_ImageIdArgDescription()) \
59+
_(Input, "input", L"i", Kind::Value, Localization::WSLCCLI_InputArgDescription()) \
6060
_(Interactive, "interactive", L"i", Kind::Flag, Localization::WSLCCLI_InteractiveArgDescription()) \
61-
_(Name, "name", NO_ALIAS, Kind::Value, L"Name of the container") \
62-
/*_(NoDNS, "no-dns", NO_ALIAS, Kind::Flag, L"No configuration of DNS in the container")*/ \
63-
_(NoPrune, "no-prune", NO_ALIAS, Kind::Flag, L"Do not delete untagged parents") \
64-
_(NoTrunc, "no-trunc", NO_ALIAS, Kind::Flag, L"Do not truncate output") \
65-
_(Output, "output", L"o", Kind::Value, L"Path for the saved image") \
66-
_(Path, "path", NO_ALIAS, Kind::Positional, L"Path to the build context directory") \
67-
/*_(Progress, "progress", NO_ALIAS, Kind::Value, L"Progress type (format: none|ansi) (default: ansi)")*/ \
68-
_(Publish, "publish", L"p", Kind::Value, L"Publish a port from a container to host") \
69-
/*_(Pull, "pull", NO_ALIAS, Kind::Value, L"Image pull policy (always|missing|never) (default:never)")*/ \
70-
_(Quiet, "quiet", L"q", Kind::Flag, L"Outputs the container IDs only") \
71-
_(Remove, "rm", NO_ALIAS, Kind::Flag, L"Remove the container after it stops") \
72-
/*_(Scheme, "scheme", NO_ALIAS, Kind::Value, L"Use this scheme for registry connection")*/ \
61+
_(Name, "name", NO_ALIAS, Kind::Value, Localization::WSLCCLI_NameArgDescription()) \
62+
/*_(NoDNS, "no-dns", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoDNSArgDescription())*/ \
63+
_(NoPrune, "no-prune", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoPruneArgDescription()) \
64+
_(NoTrunc, "no-trunc", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_NoTruncArgDescription()) \
65+
_(Output, "output", L"o", Kind::Value, Localization::WSLCCLI_OutputArgDescription()) \
66+
_(Path, "path", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_PathArgDescription()) \
67+
/*_(Progress, "progress", NO_ALIAS, Kind::Value, Localization::WSLCCLI_ProgressArgDescription())*/ \
68+
_(Publish, "publish", L"p", Kind::Value, Localization::WSLCCLI_PublishArgDescription()) \
69+
/*_(Pull, "pull", NO_ALIAS, Kind::Value, Localization::WSLCCLI_PullArgDescription())*/ \
70+
_(Quiet, "quiet", L"q", Kind::Flag, Localization::WSLCCLI_QuietArgDescription()) \
71+
_(Remove, "rm", NO_ALIAS, Kind::Flag, Localization::WSLCCLI_RemoveArgDescription()) \
72+
/*_(Scheme, "scheme", NO_ALIAS, Kind::Value, Localization::WSLCCLI_SchemeArgDescription())*/ \
7373
_(Session, "session", NO_ALIAS, Kind::Value, Localization::WSLCCLI_SessionIdArgDescription()) \
74-
_(SessionId, "session-id", NO_ALIAS, Kind::Positional, L"Session ID") \
75-
_(Signal, "signal", L"s", Kind::Value, L"Signal to send (default: SIGKILL)") \
76-
_(Tag, "tag", L"t", Kind::Value, L"Tag for the built image") \
77-
_(Time, "time", L"t", Kind::Value, L"Time in seconds to wait before executing (default 5)") \
78-
/*_(TMPFS, "tmpfs", NO_ALIAS, Kind::Value, L"Mount tmpfs to the container at the given path")*/ \
79-
_(TTY, "tty", L"t", Kind::Flag, L"Open a TTY with the container process.") \
80-
/*_(User, "user", L"u", Kind::Value, L"User ID for the process (name|uid|uid:gid)")*/ \
81-
_(Verbose, "verbose", L"v", Kind::Flag, L"Output verbose details") \
82-
_(Version, "version", L"v", Kind::Flag, L"Show version information for this tool") \
83-
/*_(Virtual, "virtualization", NO_ALIAS, Kind::Value, L"Expose virtualization capabilities to the container")*/ \
84-
_(Volume, "volume", L"v", Kind::Value, L"Bind mount a volume to the container") \
74+
_(SessionId, "session-id", NO_ALIAS, Kind::Positional, Localization::WSLCCLI_SessionIdPositionalArgDescription()) \
75+
_(Signal, "signal", L"s", Kind::Value, Localization::WSLCCLI_SignalArgDescription(L"SIGKILL")) \
76+
_(Tag, "tag", L"t", Kind::Value, Localization::WSLCCLI_TagArgDescription()) \
77+
_(Time, "time", L"t", Kind::Value, Localization::WSLCCLI_TimeArgDescription()) \
78+
/*_(TMPFS, "tmpfs", NO_ALIAS, Kind::Value, Localization::WSLCCLI_TMPFSArgDescription())*/ \
79+
_(TTY, "tty", L"t", Kind::Flag, Localization::WSLCCLI_TTYArgDescription()) \
80+
/*_(User, "user", L"u", Kind::Value, Localization::WSLCCLI_UserArgDescription())*/ \
81+
_(Verbose, "verbose", L"v", Kind::Flag, Localization::WSLCCLI_VerboseArgDescription()) \
82+
_(Version, "version", L"v", Kind::Flag, Localization::WSLCCLI_VersionArgDescription()) \
83+
/*_(Virtual, "virtualization", NO_ALIAS, Kind::Value, Localization::WSLCCLI_VirtualArgDescription())*/ \
84+
_(Volume, "volume", L"v", Kind::Value, Localization::WSLCCLI_VolumeArgDescription()) \
8585
// clang-format on

src/windows/wslc/arguments/ArgumentValidation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Module Name:
2222
#include <wslc.h>
2323

2424
using namespace wsl::windows::common;
25+
using namespace wsl::shared;
2526
using namespace wsl::shared::string;
2627

2728
namespace wsl::windows::wslc {
@@ -121,13 +122,12 @@ WSLCSignal GetWSLCSignalFromString(const std::wstring& input, const std::wstring
121122
// failure since we also know it failed to be found in the map.
122123
catch (ArgumentException)
123124
{
124-
throw ArgumentException(std::format(
125-
L"Invalid {} value: {} is not a recognized signal name or number (Example: SIGKILL, kill, or 9).", argName, input));
125+
throw ArgumentException(Localization::WSLCCLI_InvalidSignalError(argName, input));
126126
}
127127

128128
if (signalValue < MIN_SIGNAL || signalValue > MAX_SIGNAL)
129129
{
130-
throw ArgumentException(std::format(L"Invalid {} value: {} is out of valid range ({}-{}).", argName, input, MIN_SIGNAL, MAX_SIGNAL));
130+
throw ArgumentException(Localization::WSLCCLI_SignalOutOfRangeError(argName, input, MIN_SIGNAL, MAX_SIGNAL));
131131
}
132132

133133
return static_cast<WSLCSignal>(signalValue);

src/windows/wslc/commands/ContainerAttachCommand.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Module Name:
2020

2121
using namespace wsl::windows::wslc::execution;
2222
using namespace wsl::windows::wslc::task;
23+
using namespace wsl::shared;
2324

2425
namespace wsl::windows::wslc {
2526
// Container Attach Command
@@ -33,12 +34,12 @@ std::vector<Argument> ContainerAttachCommand::GetArguments() const
3334

3435
std::wstring ContainerAttachCommand::ShortDescription() const
3536
{
36-
return {L"Attach to a container."};
37+
return Localization::WSLCCLI_ContainerAttachDesc();
3738
}
3839

3940
std::wstring ContainerAttachCommand::LongDescription() const
4041
{
41-
return {L"Attaches to a container."};
42+
return Localization::WSLCCLI_ContainerAttachLongDesc();
4243
}
4344

4445
void ContainerAttachCommand::ExecuteInternal(CLIExecutionContext& context) const

src/windows/wslc/commands/ContainerCommand.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Module Name:
1515
#include "ContainerCommand.h"
1616

1717
using namespace wsl::windows::wslc::execution;
18+
using namespace wsl::shared;
1819

1920
namespace wsl::windows::wslc {
2021
// Container Root Command
@@ -42,12 +43,12 @@ std::vector<Argument> ContainerCommand::GetArguments() const
4243

4344
std::wstring ContainerCommand::ShortDescription() const
4445
{
45-
return {L"Container command."};
46+
return Localization::WSLCCLI_ContainerCommandDesc();
4647
}
4748

4849
std::wstring ContainerCommand::LongDescription() const
4950
{
50-
return {L"Container command for demonstration purposes."};
51+
return Localization::WSLCCLI_ContainerCommandLongDesc();
5152
}
5253

5354
void ContainerCommand::ExecuteInternal(CLIExecutionContext& context) const

src/windows/wslc/commands/ContainerCreateCommand.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Module Name:
2020

2121
using namespace wsl::windows::wslc::execution;
2222
using namespace wsl::windows::wslc::task;
23+
using namespace wsl::shared;
2324

2425
namespace wsl::windows::wslc {
2526
// Container Create Command
@@ -58,12 +59,12 @@ std::vector<Argument> ContainerCreateCommand::GetArguments() const
5859

5960
std::wstring ContainerCreateCommand::ShortDescription() const
6061
{
61-
return {L"Create a container."};
62+
return Localization::WSLCCLI_ContainerCreateDesc();
6263
}
6364

6465
std::wstring ContainerCreateCommand::LongDescription() const
6566
{
66-
return {L"Creates a container."};
67+
return Localization::WSLCCLI_ContainerCreateLongDesc();
6768
}
6869

6970
// clang-format off

src/windows/wslc/commands/ContainerExecCommand.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Module Name:
2020

2121
using namespace wsl::windows::wslc::execution;
2222
using namespace wsl::windows::wslc::task;
23+
using namespace wsl::shared;
2324

2425
namespace wsl::windows::wslc {
2526
// Container Exec Command
@@ -28,11 +29,7 @@ std::vector<Argument> ContainerExecCommand::GetArguments() const
2829
return {
2930
Argument::Create(ArgType::ContainerId, true),
3031
Argument::Create(ArgType::Command, true),
31-
Argument::Create(
32-
ArgType::ForwardArgs,
33-
std::nullopt,
34-
std::nullopt,
35-
L"Arguments to pass to the command being executed inside the container"),
32+
Argument::Create(ArgType::ForwardArgs, std::nullopt, std::nullopt, Localization::WSLCCLI_ContainerExecForwardArgsDescription()),
3633
Argument::Create(ArgType::Detach),
3734
Argument::Create(ArgType::Env, false, NO_LIMIT),
3835
Argument::Create(ArgType::EnvFile, false, NO_LIMIT),
@@ -45,12 +42,12 @@ std::vector<Argument> ContainerExecCommand::GetArguments() const
4542

4643
std::wstring ContainerExecCommand::ShortDescription() const
4744
{
48-
return {L"Execute a command in a running container."};
45+
return Localization::WSLCCLI_ContainerExecDesc();
4946
}
5047

5148
std::wstring ContainerExecCommand::LongDescription() const
5249
{
53-
return {L"Executes a command in a running container."};
50+
return Localization::WSLCCLI_ContainerExecLongDesc();
5451
}
5552
// clang-format off
5653
void ContainerExecCommand::ExecuteInternal(CLIExecutionContext& context) const

src/windows/wslc/commands/ContainerInspectCommand.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Module Name:
2020

2121
using namespace wsl::windows::wslc::execution;
2222
using namespace wsl::windows::wslc::task;
23+
using namespace wsl::shared;
2324

2425
namespace wsl::windows::wslc {
2526
// Container Inspect Command
@@ -33,12 +34,12 @@ std::vector<Argument> ContainerInspectCommand::GetArguments() const
3334

3435
std::wstring ContainerInspectCommand::ShortDescription() const
3536
{
36-
return {L"Inspect a container."};
37+
return Localization::WSLCCLI_ContainerInspectDesc();
3738
}
3839

3940
std::wstring ContainerInspectCommand::LongDescription() const
4041
{
41-
return {L"Display detailed information about a container."};
42+
return Localization::WSLCCLI_ContainerInspectLongDesc();
4243
}
4344

4445
// clang-format off

src/windows/wslc/commands/ContainerKillCommand.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Module Name:
2020

2121
using namespace wsl::windows::wslc::execution;
2222
using namespace wsl::windows::wslc::task;
23+
using namespace wsl::shared;
2324

2425
namespace wsl::windows::wslc {
2526
// Container Kill Command
@@ -28,18 +29,18 @@ std::vector<Argument> ContainerKillCommand::GetArguments() const
2829
return {
2930
Argument::Create(ArgType::ContainerId, true, NO_LIMIT),
3031
Argument::Create(ArgType::Session),
31-
Argument::Create(ArgType::Signal, std::nullopt, std::nullopt, L"Signal to send (default: SIGKILL)"),
32+
Argument::Create(ArgType::Signal),
3233
};
3334
}
3435

3536
std::wstring ContainerKillCommand::ShortDescription() const
3637
{
37-
return {L"Kill containers."};
38+
return Localization::WSLCCLI_ContainerKillDesc();
3839
}
3940

4041
std::wstring ContainerKillCommand::LongDescription() const
4142
{
42-
return {L"Kills containers."};
43+
return Localization::WSLCCLI_ContainerKillLongDesc();
4344
}
4445

4546
// clang-format off

src/windows/wslc/commands/ContainerListCommand.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Module Name:
2020

2121
using namespace wsl::windows::wslc::execution;
2222
using namespace wsl::windows::wslc::task;
23+
using namespace wsl::shared;
2324
using namespace wsl::shared::string;
2425

2526
namespace wsl::windows::wslc {
@@ -37,12 +38,12 @@ std::vector<Argument> ContainerListCommand::GetArguments() const
3738

3839
std::wstring ContainerListCommand::ShortDescription() const
3940
{
40-
return {L"List containers."};
41+
return Localization::WSLCCLI_ContainerListDesc();
4142
}
4243

4344
std::wstring ContainerListCommand::LongDescription() const
4445
{
45-
return {L"Lists containers. By default, only running containers are shown; use --all to include all containers."};
46+
return Localization::WSLCCLI_ContainerListLongDesc();
4647
}
4748

4849
void ContainerListCommand::ValidateArgumentsInternal(const ArgMap& execArgs) const
@@ -52,7 +53,7 @@ void ContainerListCommand::ValidateArgumentsInternal(const ArgMap& execArgs) con
5253
auto format = execArgs.Get<ArgType::Format>();
5354
if (!IsEqual(format, L"json") && !IsEqual(format, L"table"))
5455
{
55-
throw CommandException(L"Invalid format type specified. Supported format types are: json, table");
56+
throw CommandException(Localization::WSLCCLI_InvalidFormatError());
5657
}
5758
}
5859
}

0 commit comments

Comments
 (0)