Skip to content

CLI: Help improvements - Table output with color and routing support#40848

Draft
dkbennett wants to merge 6 commits into
masterfrom
user/dkbennett/betterhelp
Draft

CLI: Help improvements - Table output with color and routing support#40848
dkbennett wants to merge 6 commits into
masterfrom
user/dkbennett/betterhelp

Conversation

@dkbennett

@dkbennett dkbennett commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary of the Pull Request

image

Help improvements

  • Reformats help to be closer to Docker and draws inspiration from cargo and other popular CLIs.
  • Uses TableOutput for rendering args and options, keeping consistent table row spacing, and aligning options and aliases and descriptions.
  • Help now has a bit of color/emphasis. Copyright is dimmed to de-emphasize. Errors are colored. Usage has some cyan for drawing attention. Headings and option args are brightened.
  • Help is on stdout if using the --help flag, and stderr if printed as part of a usage error.
  • Now shows the executable name (so if you launch with container.exe you'll get container as the command name for the help, not wslc)
  • Shows Global options at the bottom (like Docker)
  • Descriptions for arguments now word-wraps so long descriptions are OK and display well, or when the console is not as wide.

TableOutput Improvements (extends beyond just help, any table can utilize these benefits, though no other ones have yet)

  • Colored cells and naturally handles VT and color disable. Cells now have FormattedCell (which can be a simple string) for easy color or VT introduction that are stripped when no color or VT is disabled.

  • Whole-line writing possible within the table output.

  • Columns can support word-wrap

  • TableOutput now uses the Reporter for writing output and has a cleaner API.

  • It was original intent to separate fixing up dead tests but the review bot was complaining about that loudly, so this is a one-shot that fixes up all the tests and removes unused test code. The main changes to the tests are around the routing change (help output for argument errors is now in stderr, not stdout) and because of that we now search for the specific error in the stderr instead of trying to match exact help output. The help output tests now verify help is output on stdout but does not explicitly verify the exact format of the help.

PR Checklist

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Tests

  • TableOutputCapture rewritten to use pipe-based CaptureReporter (old SetOutputFunction callback removed)
  • Added unit tests for WriteRow, WriteLine, VT rendering/stripping, column width measurement
  • E2E tests updated with Reporter context setup

Validation Steps Performed

  • E2E tests, many unit tests for table output
  • Manual validation

Copilot AI review requested due to automatic review settings June 18, 2026 21:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The updated table-output unit tests introduce dangling references via cap.lines() temporaries, and a large amount of existing help E2E coverage is disabled by SKIP_TEST_UNSTABLE() rather than being updated to validate the new help behavior.

Pull request overview

This PR modernizes the WSLC CLI help experience by reworking help rendering to use the shared TableOutput infrastructure (including word-wrap and VT formatting), while also improving help output routing (stdout vs stderr) and making usage reflect the invoked executable name.

Changes:

  • Refactors TableOutput to write via Reporter, adds FormattedCell support, and introduces whole-line output plus word-wrapping columns.
  • Reworks command help generation to use table rendering, VT emphasis, global options grouping, and correct output routing on errors; sets executable name from argv[0].
  • Updates/extends unit and E2E tests for the new rendering/routing behavior (with many existing help-output E2E tests currently skipped).
File summaries
File Description
test/windows/wslc/WSLCCLITestHelpers.h Refactors TableOutputCapture to capture output via Reporter/pipe for new table rendering.
test/windows/wslc/WSLCCLITableOutputUnitTests.cpp Updates/adds extensive unit coverage for wrapping, FormattedCell, and WriteLine behavior.
test/windows/wslc/e2e/WSLCExecutor.h Adds stderr substring helper for new help-routing assertions.
test/windows/wslc/e2e/WSLCExecutor.cpp Implements stderr substring helper; switches header expectation to localized API.
test/windows/wslc/e2e/WSLCE2EVolumeTests.cpp Skips legacy help-output E2E tests for volume command.
test/windows/wslc/e2e/WSLCE2EVolumeRemoveTests.cpp Skips legacy help-output E2E tests for volume remove.
test/windows/wslc/e2e/WSLCE2EVolumePruneTests.cpp Skips legacy help-output E2E tests for volume prune help/error paths.
test/windows/wslc/e2e/WSLCE2EVolumeListTests.cpp Skips legacy help-output E2E test for volume list --help.
test/windows/wslc/e2e/WSLCE2EVolumeInspectTests.cpp Skips legacy help-output E2E tests for volume inspect help/error paths.
test/windows/wslc/e2e/WSLCE2EVolumeCreateTests.cpp Skips legacy help-output E2E test for volume create --help.
test/windows/wslc/e2e/WSLCE2ERegistryTests.cpp Skips legacy help-output E2E tests for registry login/logout --help.
test/windows/wslc/e2e/WSLCE2EPushPullTests.cpp Skips legacy help-output E2E tests for image push/pull (and root aliases).
test/windows/wslc/e2e/WSLCE2ENetworkTests.cpp Skips legacy help-output E2E tests for network command.
test/windows/wslc/e2e/WSLCE2ENetworkRemoveTests.cpp Skips legacy help-output E2E tests for network remove.
test/windows/wslc/e2e/WSLCE2ENetworkListTests.cpp Skips legacy help-output E2E test for network list --help.
test/windows/wslc/e2e/WSLCE2ENetworkInspectTests.cpp Skips legacy help-output E2E tests for network inspect help/error paths.
test/windows/wslc/e2e/WSLCE2ENetworkCreateTests.cpp Skips legacy help-output E2E tests for network create help/error paths.
test/windows/wslc/e2e/WSLCE2EInspectTests.cpp Skips legacy help-output E2E tests for inspect help/error paths.
test/windows/wslc/e2e/WSLCE2EImageTests.cpp Skips legacy help-output E2E tests for image command.
test/windows/wslc/e2e/WSLCE2EImageTagTests.cpp Skips legacy help-output E2E tests for image tag help/error paths.
test/windows/wslc/e2e/WSLCE2EImageSaveTests.cpp Skips legacy help-output E2E tests for image save help/error paths.
test/windows/wslc/e2e/WSLCE2EImagePruneTests.cpp Skips legacy help-output E2E tests for image prune help/error paths.
test/windows/wslc/e2e/WSLCE2EImageListTests.cpp Skips legacy help-output E2E tests for image list help/error paths.
test/windows/wslc/e2e/WSLCE2EImageInspectTests.cpp Skips legacy help-output E2E tests for image inspect help/error paths.
test/windows/wslc/e2e/WSLCE2EImageImportTests.cpp Skips legacy help-output E2E tests for image import help/error paths.
test/windows/wslc/e2e/WSLCE2EImageDeleteTests.cpp Skips legacy help-output E2E tests for image delete help/error paths.
test/windows/wslc/e2e/WSLCE2EContainerTests.cpp Skips legacy help-output E2E tests for container command.
test/windows/wslc/e2e/WSLCE2EContainerStopTests.cpp Skips legacy help-output E2E test for container stop --help.
test/windows/wslc/e2e/WSLCE2EContainerRunTests.cpp Skips legacy help-output E2E test for container run --help.
test/windows/wslc/e2e/WSLCE2EContainerRemoveTests.cpp Skips legacy help-output E2E test for container remove --help.
test/windows/wslc/e2e/WSLCE2EContainerPruneTests.cpp Skips legacy help-output E2E test for container prune --help.
test/windows/wslc/e2e/WSLCE2EContainerListTests.cpp Skips legacy help-output E2E tests for container list help/error paths.
test/windows/wslc/e2e/WSLCE2EContainerKillTests.cpp Skips legacy help-output E2E test for container kill --help.
test/windows/wslc/e2e/WSLCE2EContainerInspectTests.cpp Skips legacy help-output E2E tests for container inspect help/error paths.
test/windows/wslc/e2e/WSLCE2EContainerExecTests.cpp Skips legacy help-output E2E tests for container exec help/error paths.
test/windows/wslc/e2e/WSLCE2EContainerCreateTests.cpp Skips legacy help-output E2E tests for container create help/error paths.
test/windows/wslc/e2e/WSLCE2EContainerAttachTests.cpp Skips legacy help-output E2E test for container attach --help.
test/windows/wslc/e2e/WSLCE2EGlobalTests.cpp Adds new help routing/color tests; skips legacy “exact help output” tests.
src/windows/wslc/tasks/VolumeTasks.cpp Updates table output usage to pass Reporter and WriteRow.
src/windows/wslc/tasks/SessionTasks.cpp Updates session listing to use new TableOutput constructor and WriteRow.
src/windows/wslc/tasks/NetworkTasks.cpp Updates network listing to pass Reporter and use WriteRow.
src/windows/wslc/tasks/ImageTasks.cpp Updates image listing to use new column config shape and Reporter-backed table output.
src/windows/wslc/tasks/ContainerTasks.cpp Updates container list/stats tables to new config shape and Reporter/WriteRow.
src/windows/wslc/core/TableOutput.h Major refactor: FormattedCell, wrapping, standalone lines, Reporter integration, new overflow modes.
src/windows/wslc/core/Main.cpp Extracts executable name from argv[0]; routes help-on-error via Reporter.
src/windows/wslc/core/Command.h Switches executable name to runtime global; updates OutputHelp signature to accept Reporter.
src/windows/wslc/core/Command.cpp Reimplements help output using table rendering, VT emphasis, and stdout/stderr routing.
src/windows/wslc/commands/VolumeCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/SystemCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/SessionCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/RootCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/RegistryCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/NetworkCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/ImageCommand.cpp Routes help output through context.Reporter.
src/windows/wslc/commands/ContainerCommand.cpp Routes help output through context.Reporter.
localization/strings/en-US/Resources.resw Adds localized headings used by the new help layout (Commands/Options/Global Options/etc.).

Copilot's findings

  • Files reviewed: 56/56 changed files
  • Comments generated: 46

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread test/windows/wslc/WSLCCLITableOutputUnitTests.cpp Outdated
Comment thread test/windows/wslc/WSLCCLITableOutputUnitTests.cpp Outdated
Comment thread test/windows/wslc/WSLCCLITableOutputUnitTests.cpp Outdated
Comment thread test/windows/wslc/WSLCCLITableOutputUnitTests.cpp Outdated
Comment thread test/windows/wslc/WSLCCLITableOutputUnitTests.cpp Outdated
Comment thread test/windows/wslc/e2e/WSLCE2EGlobalTests.cpp Outdated
Comment thread test/windows/wslc/e2e/WSLCE2EVolumePruneTests.cpp Outdated
Comment thread test/windows/wslc/e2e/WSLCE2EImagePruneTests.cpp Outdated
Comment thread test/windows/wslc/e2e/WSLCE2EImageListTests.cpp Outdated
Comment thread test/windows/wslc/e2e/WSLCE2EContainerListTests.cpp Outdated
Copilot AI review requested due to automatic review settings June 19, 2026 14:12
@dkbennett dkbennett force-pushed the user/dkbennett/betterhelp branch from 13cee59 to d72c536 Compare June 19, 2026 14:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

TableOutput currently gates all FormattedCell sequences on IsColorEnabled(), which can incorrectly suppress non-color VT sequences under --no-color and conflicts with the intended Reporter/VT behavior.

Copilot's findings
  • Files reviewed: 59/59 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread test/windows/wslc/e2e/WSLCE2EAliasTests.cpp
Comment thread src/windows/wslc/core/TableOutput.h
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 14:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

There are confirmed formatting/correctness issues in the new table/help rendering logic (notably FormattedCell::VisibleWidth() behavior) that should be fixed before approval.

Copilot's findings
  • Files reviewed: 59/59 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment on lines +74 to +90
// Visible width: count characters that are not part of {} placeholders.
size_t VisibleWidth() const
{
size_t width = 0;
for (size_t i = 0; i < fmt.size(); ++i)
{
if (i + 1 < fmt.size() && fmt[i] == L'{' && fmt[i + 1] == L'}')
{
++i; // skip the pair
}
else
{
++width;
}
}
return width;
}
Comment on lines +123 to 125
std::wstring usageText = Localization::WSLCCLI_Usage(s_ExecutableName, std::wstring_view{commandChain});
reporter.Write(helpLevel, L"{}{}{}", HelpHeadingEmphasis, usageText, Format::Default);

dkbennett and others added 3 commits June 19, 2026 08:15
… set

Render() and RenderTruncated() now take both vtEnabled and colorEnabled
flags, matching Reporter's contract: VT off strips all sequences, color
off strips only color sequences (non-color sequences pass through).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 15:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

TableOutput.h now uses THROW_HR_IF but does not include the WIL header that defines it, making the header non-self-contained and potentially breaking builds depending on include order.

Copilot's findings
  • Files reviewed: 59/59 changed files
  • Comments generated: 1

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment on lines 19 to 23
#include <algorithm>
#include <array>
#include <cwchar>
#include <functional>
#include <sstream>
#include <initializer_list>
#include <optional>
#include <string>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants