CLI: Add Reporter for structured CLI output with VT color and level routing#40798
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new structured output pipeline for the wslc CLI by adding a Reporter abstraction (level-aware output) backed by an OutputWriter/OutputChannel implementation (buffered, atomic flush, optional VT color handling). It integrates the reporter into the CLI execution context and updates Main.cpp error/cancellation reporting to use it, along with unit tests and a new localized cancellation string.
Changes:
- Added
Reporterfor level-gated output (Info/Warn/Error/Debug) with VT-aware formatting behavior. - Added
OutputChannel/OutputWriterfor buffered output accumulation and atomic flush semantics with optional color filtering and SGR reset. - Integrated reporter into the CLI execution context, updated main cancellation/error paths, added unit tests, and added a new en-US localization string.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/windows/wslc/WSLCCLIReporterUnitTests.cpp | Adds unit tests covering routing, VT/color filtering, flush lifecycle, clone semantics, and level gating. |
| src/windows/wslc/core/Reporter.h | Declares the Reporter interface (levels, routing, cloning, console width). |
| src/windows/wslc/core/Reporter.cpp | Implements level gating, formatting selection, and stdout/stderr routing behavior. |
| src/windows/wslc/core/OutputWriter.h | Declares OutputChannel and OutputWriter (buffering + VT/color controls). |
| src/windows/wslc/core/OutputWriter.cpp | Implements buffered flush, VT sequence handling, and OutputChannel console/FILE* backends. |
| src/windows/wslc/core/Main.cpp | Enables VT mode on stdout and switches cancellation/error reporting to use context.Output. |
| src/windows/wslc/core/CLIExecutionContext.h | Adds Reporter Output to the execution context for shared CLI output. |
| localization/strings/en-US/Resources.resw | Adds WSLCCLI_OperationCancelled string for localized cancellation messaging. |
ff1bee9 to
2d1a14f
Compare
- Rename Reporter::GetOutputWriter to GetWriter for brevity; matches the level-targeted call sites that follow it. - Move CapturePipe and CaptureReporter from WSLCCLIReporterUnitTests.cpp into WSLCCLITestHelpers.h so other CLI unit test suites can capture Reporter output without duplicating the pipe plumbing. - Fix the read-pipe handle leak in CapturePipe: hold the read end in a wil::unique_hfile member (declared before m_reader so destruction order joins the reader thread first, then closes the handle). - Open the read pipe with ReadPipeOverlapped=true so PartialHandleRead's InterruptableRead can be interrupted by its exit event during teardown rather than relying on writer-side fclose ordering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
OneBlue
left a comment
There was a problem hiding this comment.
Change looks good, couple minor comments
OneBlue
left a comment
There was a problem hiding this comment.
Approving to unblock, one outstanding comment on how we can simplify / explicit the std::format logic, but this is not blocking
Summary of the Pull Request
Adds a Reporter class for structured, level-aware console output in wslc. Reporter provides a
std::format-style API that routes Output to stdout and Info/Warning/Error to stderr, with automatic SGR color wrapping (yellow for warnings, red for errors) and VT sequence stripping when the destination is redirected or color is disabled.Reporter is backed by OutputChannel, a byte-sink class that owns VT enablement (RAII) on console handles and falls back to
fwprintffor redirected output. Each write is a single kernel call (WriteConsoleW or fwprintf) so concurrent threads cannot interleave.Main.cpp error handling and cancellation output now use Reporter. Other wslc commands can be converted in follow-up PRs.
PR Checklist
Detailed Description of the Pull Request / Additional comments
New files:
OutputChannel.h/.cpp— Byte sink: WriteConsoleW for consoles, fwprintf for redirected output. OwnsEnableVirtualTerminalRAII. ProvidesGetConsoleWidth()(minus one column as an autowrap guard).Reporter.h/.cpp—std::format-style write API withOutput/Info/Warn/Errorconvenience methods. VTSequencearguments are automatically stripped when VT is off; colorSequencearguments are additionally stripped when color is disabled. Level-based SGR prefix/reset wrapping for warnings (yellow) and errors (red).WSLCCLIReporterUnitTests.cpp— 20 unit tests covering OutputChannel writes, Reporter formatting, Sequence stripping, color/no-color behavior, level routing, VT state queries, and console width.WSLCCLITestHelpers.h—CapturePipe(RAII pipe pair for capturing FILE* output) andCaptureReporter/SplitCaptureReportertest helpers.Modified files:
CLIExecutionContext.h— HoldsReporteras a value member.NON_MOVABLE(Reporter owns non-movable OutputChannels).Main.cpp— Error and cancellation output routed throughcontext.Reporter. Removed standaloneEnableVirtualTerminalRAII (now owned by OutputChannel).Validation Steps Performed