wslc: alias -f to --format on inspect commands for docker parity (#41463)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ggarzia-MSFT committed
Sep 1, 2026 at 10:31 UTC
8544b7b0b23163df3e05d08c5e822f088328c3d5
4 files changed
+56
-1
src/windows/wslc/arguments/ArgumentDefinitions.h
+1
-1
@@ -82,7 +82,7 @@ _(ImageId, "image", NO_ALIAS, Kind::Positional,
82
_(ImportFile, "file", NO_ALIAS, Kind::Positional, NoConversion, Localization::WSLCCLI_ImportFileArgDescription()) \
83
_(IidFile, "iidfile", NO_ALIAS, Kind::Value, NoConversion, Localization::WSLCCLI_IidFileArgDescription()) \
84
_(Input, "input", L"i", Kind::Value, NoConversion, Localization::WSLCCLI_InputArgDescription()) \
85
-_(InspectFormat, "format", NO_ALIAS, Kind::Value, JsonIndent, Localization::WSLCCLI_InspectFormatArgDescription()) \
85
+_(InspectFormat, "format", L"f", Kind::Value, JsonIndent, Localization::WSLCCLI_InspectFormatArgDescription()) \
86
_(Interactive, "interactive", L"i", Kind::Flag, NoConversion, Localization::WSLCCLI_InteractiveArgDescription()) \
87
_(Internal, "internal", NO_ALIAS, Kind::Flag, NoConversion, Localization::WSLCCLI_NetworkInternalArgDescription()) \
88
_(IpAddress, "ip", NO_ALIAS, Kind::Value, NoConversion, Localization::WSLCCLI_IpAddressArgDescription()) \
test/windows/wslc/CommandLineTestCases.h
+16
@@ -199,6 +199,16 @@ COMMAND_LINE_TEST_CASE(L"inspect --format badformat cont1", L"inspect", false)
199
COMMAND_LINE_TEST_CASE(L"container inspect --format json cont1", L"inspect", true)
200
COMMAND_LINE_TEST_CASE(L"container inspect --format table cont1", L"inspect", false)
201
COMMAND_LINE_TEST_CASE(L"container inspect --format badformat cont1", L"inspect", false)
202
+// The inspect family aliases -f to --format, matching `docker inspect -f`. The alias accepts the
203
+// same values as the long name and rejects the same ones.
204
+COMMAND_LINE_TEST_CASE(L"inspect -f json cont1", L"inspect", true)
205
+COMMAND_LINE_TEST_CASE(L"inspect -f=json cont1", L"inspect", true)
206
+COMMAND_LINE_TEST_CASE(L"inspect -f table cont1", L"inspect", false)
207
+COMMAND_LINE_TEST_CASE(L"inspect -f badformat cont1", L"inspect", false)
208
+COMMAND_LINE_TEST_CASE(L"inspect -f", L"inspect", false) // Missing value for -f
209
+COMMAND_LINE_TEST_CASE(L"inspect --type container -f json cont1", L"inspect", true)
210
+COMMAND_LINE_TEST_CASE(L"container inspect -f json cont1", L"inspect", true)
211
+COMMAND_LINE_TEST_CASE(L"container inspect -f table cont1", L"inspect", false)
212
COMMAND_LINE_TEST_CASE(L"remove cont1", L"remove", true)
213
COMMAND_LINE_TEST_CASE(L"container remove cont1 cont2", L"remove", true)
214
COMMAND_LINE_TEST_CASE(L"rm cont1", L"remove", true)
@@ -336,6 +346,12 @@ COMMAND_LINE_TEST_CASE(L"network inspect --format badformat net1", L"inspect", f
346
COMMAND_LINE_TEST_CASE(L"volume inspect --format json vol1", L"inspect", true)
347
COMMAND_LINE_TEST_CASE(L"volume inspect --format table vol1", L"inspect", false)
348
COMMAND_LINE_TEST_CASE(L"volume inspect --format badformat vol1", L"inspect", false)
349
+COMMAND_LINE_TEST_CASE(L"image inspect -f json img1", L"inspect", true)
350
+COMMAND_LINE_TEST_CASE(L"image inspect -f table img1", L"inspect", false)
351
+COMMAND_LINE_TEST_CASE(L"network inspect -f json net1", L"inspect", true)
352
+COMMAND_LINE_TEST_CASE(L"network inspect -f table net1", L"inspect", false)
353
+COMMAND_LINE_TEST_CASE(L"volume inspect -f json vol1", L"inspect", true)
354
+COMMAND_LINE_TEST_CASE(L"volume inspect -f table vol1", L"inspect", false)
355
356
// Version command tests
357
COMMAND_LINE_TEST_CASE(L"version", L"version", true)
test/windows/wslc/WSLCCLICommandUnitTests.cpp
+24
@@ -21,9 +21,13 @@ Abstract:
21
#include "Command.h"
22
#include "RootCommand.h"
23
#include "ContainerCommand.h"
24
+#include "ImageCommand.h"
25
+#include "InspectCommand.h"
26
+#include "NetworkCommand.h"
27
#include "SessionCommand.h"
28
#include "SystemCommand.h"
29
#include "VersionCommand.h"
30
+#include "VolumeCommand.h"
31
#include "EnvironmentOptions.h"
32
33
using namespace wsl::windows::wslc;
@@ -245,6 +249,26 @@ class WSLCCLICommandUnitTests
249
}
250
}
251
252
+ // Every command in the inspect family exposes docker's `-f` alias for --format
253
+ // (docker/cli cli/command/system/inspect.go: flags.StringVarP(&opts.format, "format", "f", ...)).
254
+ TEST_METHOD(InspectCommands_FormatArgumentHasDockerAlias)
255
+ {
256
+ const auto VerifyFormatAlias = [](const Command& command) {
257
+ const auto args = command.GetArguments();
258
+ const auto found = std::ranges::find_if(args, [](const auto& arg) { return arg.Type() == ArgType::InspectFormat; });
259
+
260
+ VERIFY_IS_TRUE(found != args.end(), std::format(L"Command '{}' does not register --format", command.FullName()).c_str());
261
+ VERIFY_ARE_EQUAL(std::wstring(L"format"), found->Name());
262
+ VERIFY_ARE_EQUAL(std::wstring(L"f"), found->Alias());
263
+ };
264
+
265
+ VerifyFormatAlias(InspectCommand(L""));
266
+ VerifyFormatAlias(ContainerInspectCommand(L"container"));
267
+ VerifyFormatAlias(ImageInspectCommand(L"image"));
268
+ VerifyFormatAlias(NetworkInspectCommand(L"network"));
269
+ VerifyFormatAlias(VolumeInspectCommand(L"volume"));
270
+ }
271
+
272
// Walk every command in the root tree and verify no argument collisions.
273
TEST_METHOD(AllCommands_NoAmbiguousArgumentNamesOrAliases)
274
{
test/windows/wslc/WSLCCLIParserUnitTests.cpp
+15
@@ -661,6 +661,21 @@ class WSLCCLIParserUnitTests
661
VERIFY_ARE_EQUAL(std::wstring(L"true"), args.GetValue<ArgType::ContainerId>());
662
}
663
664
+ // A value argument's alias carries its value exactly like the long name, including the
665
+ // adjoined form. The inspect family depends on this for docker's `-f json`.
666
+ TEST_METHOD(Value_AliasCarriesValue)
667
+ {
668
+ std::vector<Argument> defs = {Argument::Create(ArgType::InspectFormat), Argument::Create(ArgType::ObjectId, false, Limit::Unlimited)};
669
+
670
+ VERIFY_ARE_EQUAL(wsl::shared::c_jsonCompactIndent, ParseFlags(L"wslc -f json cont1", defs).GetValue<ArgType::InspectFormat>());
671
+ VERIFY_ARE_EQUAL(wsl::shared::c_jsonCompactIndent, ParseFlags(L"wslc -f=json cont1", defs).GetValue<ArgType::InspectFormat>());
672
+
673
+ // The positional still lands where it belongs once the alias has taken its value.
674
+ auto args = ParseFlags(L"wslc -f json cont1", defs);
675
+ VERIFY_ARE_EQUAL(1u, args.Count(ArgType::ObjectId));
676
+ VERIFY_ARE_EQUAL(std::wstring(L"cont1"), args.GetValue<ArgType::ObjectId>());
677
+ }
678
+
679
// Alias forms honor adjoined booleans just like the long name.
680
TEST_METHOD(Flag_AliasAdjoinedBoolean)
681
{