Skip to content

CLI: Unify interactive input and output in Reporter - #41215

Merged
dkbennett merged 6 commits into
masterfrom
user/dkbennett/reporterinput
Aug 3, 2026
Merged

CLI: Unify interactive input and output in Reporter#41215
dkbennett merged 6 commits into
masterfrom
user/dkbennett/reporterinput

Conversation

@dkbennett

Copy link
Copy Markdown
Member

Summary of the Pull Request

Unifies interactive user input with user-facing output under the WSLC CLI's Reporter. Previously Reporter only handled output, and interactive input (prompting, echo masking) was handled ad hoc inside commands like wslc registry login, where console handling does not belong. This moves that logic into a single, testable owner so commands can prompt consistently instead of reimplementing console handling, and registry login is simplified to just ask the Reporter for input. Prompts for input were changed from stderr to stdout intentionally (see detailed description for reasoning).

Note that Reporter is planned to be renamed in a follow-up PR to reflect that it now provides unified input/output management for the CLI; the current name is kept here to keep the diff focused and does not yet fully describe the expanded responsibility.

Sample output from manual testing with stderr redirected to show prompts still function as expected consistent with other CLIs:
image
(note these commands failed expectedly but the purpose was to verify the input behavior on a real console; the tests verify the command)

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

  • New InputChannel: reads a line at a time from the console or a redirected file/pipe. On an interactive console it can mask echo (for password entry) and report whether input is interactive; it distinguishes an empty line from end of input.
  • Reporter now owns an input channel alongside its output channels and exposes:
    • IsInputInteractive() to check whether a prompt can be shown.
    • ReadLine(mask) to read a single line, optionally masking echo.
    • PromptForLine(label, mask) to write a label and read the response in one call.
  • wslc registry login now uses PromptForLine for the username and (masked) password prompts, replacing the previous inline prompting.
  • Updated the interactive-login E2E assertions from stderr to stdout to match the new prompt stream.
  • Unit tests and test helpers covering the input channel and the reporter's prompt/read paths.

Prompt default output stream

Interactive login prompts now write to stdout. Previously they were emitted at Info level, which routes to stderr; this PR moves them to stdout (Level::Output). This is an intentional behavior change, not a regression.

For most CLIs stderr is arguably the more correct target for prompts, since it keeps stdout clean for piped or captured output. Two practical reasons favor stdout here:

  1. The container CLI ecosystem prompts on stdout: Docker (cli.Out()), containerd/nerdctl (cmd.OutOrStdout()), and Apple container all prompt there, so WSLC matches the tools its users expect.
  2. Redirecting stderr to a log file (command 2> file) is common; with prompts on stderr that redirect would send the prompt to the file and leave the user at an apparently blank line. Keeping prompts on stdout avoids that.

The interactive-login E2E assertions were updated from stderr to stdout to match.

Validation Steps Performed

  • Unit tests, including the new input tests that were added, pass.
  • E2E Registry tests pass, including the ones for interactive input testing.
  • Manual invocation of deployed CLI of the registry login command to verify behavior on a real console.

Copilot AI review requested due to automatic review settings July 30, 2026 23:44

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.

Pull request overview

This PR centralizes interactive input (prompting and optional echo masking) under the WSLC CLI Reporter, replacing ad hoc console handling in commands (notably wslc registry login). It introduces a new InputChannel abstraction and updates tests to validate prompt behavior and the stdout prompt-stream change.

Changes:

  • Added InputChannel and extended Reporter to support IsInputInteractive(), ReadLine(), and PromptForLine() (with optional masking).
  • Updated RegistryLoginCommand to use Reporter for username/password prompting and stdin password reads.
  • Added/updated unit and E2E tests, including a new InputPipe test helper, and moved interactive prompt assertions from stderr to stdout.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/windows/wslc/WSLCCLITestHelpers.h Adds InputPipe RAII helper to feed UTF-8 input into tests via a pipe and background writer thread.
test/windows/wslc/WSLCCLIReporterUnitTests.cpp Adds InputChannel and Reporter prompt/read unit tests and a helper InputCaptureReporter.
test/windows/wslc/e2e/WSLCE2ERegistryTests.cpp Updates interactive login prompt expectations from stderr to stdout.
src/windows/wslc/core/Reporter.h Extends Reporter API to include input-related methods and stores an InputChannel.
src/windows/wslc/core/Reporter.cpp Initializes InputChannel and implements Reporter::PromptForLine() with label + flush + read behavior.
src/windows/wslc/core/OutputChannel.h Adds Flush() to ensure prompts are visible before blocking reads when output is redirected.
src/windows/wslc/core/OutputChannel.cpp Implements OutputChannel::Flush() with best-effort logging on failure.
src/windows/wslc/core/InputChannel.h New abstraction for line-oriented input with optional console echo masking and interactivity detection.
src/windows/wslc/core/InputChannel.cpp Implements console-mode probing, echo masking via SetConsoleMode, and line reading via fgetwc.
src/windows/wslc/commands/RegistryCommand.cpp Removes inline prompting logic and switches login to Reporter::PromptForLine() / Reporter::ReadLine().

Comment thread src/windows/wslc/core/InputChannel.h
Comment thread src/windows/wslc/core/InputChannel.cpp
Comment thread src/windows/wslc/core/InputChannel.cpp
Copilot AI review requested due to automatic review settings July 30, 2026 23:54

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.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/windows/wslc/core/InputChannel.cpp:80

  • InputChannel::ReadLine treats fgetwc() returning WEOF as end-of-input, but WEOF can also indicate a read/encoding error. Consider detecting ferror() and failing explicitly so unexpected input/encoding errors don’t get silently treated as EOF (which can lead to confusing empty credentials, etc.).
        const wint_t ch = fgetwc(m_file);
        if (ch == WEOF)
        {
            break;
        }

src/windows/wslc/core/Reporter.cpp:72

  • Reporter::PromptForLine computes willMask but calls InputChannel::ReadLine with the original mask flag. If the console-mode probe differs between the IsInteractive() call and the later ReadLine() call, the code can emit (or omit) the trailing newline inconsistently with whether echo was actually masked. Passing willMask into ReadLine keeps the newline behavior consistent with the masking decision.
    const bool willMask = mask && m_in.IsInteractive();
    auto line = m_in.ReadLine(mask);

@dkbennett
dkbennett marked this pull request as ready for review July 31, 2026 05:37
@dkbennett
dkbennett requested review from a team as code owners July 31, 2026 05:37
Comment thread src/windows/wslc/core/InputChannel.cpp
@dkbennett
dkbennett merged commit 05c2387 into master Aug 3, 2026
12 checks passed
@dkbennett
dkbennett deleted the user/dkbennett/reporterinput branch August 3, 2026 20:27
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.

3 participants