Skip to content

Refresh command-line parsing with per-call options - #15220

Open
baronfel wants to merge 2 commits into
mainfrom
baronfel-command-line-parsing-refresh
Open

baronfel wants to merge 2 commits into
mainfrom
baronfel-command-line-parsing-refresh

Conversation

@baronfel

@baronfel baronfel commented Oct 6, 2026

Copy link
Copy Markdown
Member

Related issue(s):

Fixes #15218
Fixes #15219
Related SDK integration: dotnet/sdk#56123

Context

The .NET SDK needs to distinguish MSBuild switches from application arguments without failing on unknown switches or reading response files. The existing experimental parser always throws for unknown switches and gathers response-file and environment inputs.

Changes Made

Add Parse(IReadOnlyList<string>, CommandLineParsingOptions) to the internal experimental API. Options control unknown-switch exceptions, response-file reading, and inclusion of MSBUILD_LOGGING_ARGS.

When unknown-switch exceptions are disabled, return the original tokens in UnrecognizedArguments. When response-file reading is disabled, return explicit @file tokens separately in UnexpandedResponseFileArguments. Both collections preserve quoting, order, and duplicates. Options apply to one call and do not affect later calls or earlier results.

Add regression coverage and document the API in documentation/specs/command-line-parsing.md.

Compatibility

All options default to the existing behavior. Preserve the IEnumerable<string> overload and the existing accessor constructor. The CLI continues strict parsing with unchanged response-file handling. Other errors, including malformed known switches, duplicate project arguments, and unreadable or repeated response files, still throw. No new diagnostics or ChangeWave are required because the behavior changes are opt-in. The API remains internal and available to the SDK through the existing friend assembly.

Testing

Commands ran on Windows with the repository-local SDK/runtime configured:

  • .\build.cmd -v quiet /bl:7.binlog — passed, zero warnings and errors.
  • .\.dotnet\dotnet.exe test --project "$PWD\src\MSBuild.UnitTests\Microsoft.Build.CommandLine.UnitTests.csproj" --no-restore /bl:5.binlog -- --no-progress — passed on both target frameworks: 1,460 passed, 16 existing platform/issue skips, zero failures.
  • .\.dotnet\dotnet.exe test --project "$PWD\src\MSBuild.UnitTests\Microsoft.Build.CommandLine.UnitTests.csproj" --no-build --no-restore /bl:9.binlog -- --filter-class "Microsoft.Build.CommandLine.UnitTests.CommandLineParserTests" --no-progress — final parser regressions passed: 38 cases across both frameworks, no skips.
  • dotnet --version in the bootstrap environment — returned 11.0.100-rc.1.26420.103.
  • dotnet build src\Samples\Dependency\Dependency.csproj -v:q /bl:8.binlog in the bootstrap environment — passed, zero warnings and errors.
  • dotnet msbuild -help in the bootstrap environment — passed.
  • git --no-pager diff --check — passed.

Linux/macOS and the full repository test suite were not run. Initial validation encountered local runtime resolution and bootstrap compiler-lock issues; those were resolved before the successful runs above.

Dependencies and Follow-up

The SDK can adopt these options for token classification in dotnet/sdk#56123 after this API is available. No companion PR is required to merge this change.

Support IReadOnlyList tokens, unknown-switch collection, unexpanded response-file arguments, and token-only parsing while preserving CLI defaults.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: da6ccb4c-52f9-4389-a389-914271a74a6d
Copilot AI balanced review requested due to automatic review settings October 6, 2026 20:40
@baronfel
baronfel deployed to copilot-pat-pool October 6, 2026 20:40 — with GitHub Actions Active
@baronfel
baronfel deployed to copilot-pat-pool October 6, 2026 20:40 — with GitHub Actions Active
@baronfel
baronfel deployed to copilot-pat-pool October 6, 2026 20:41 — with GitHub Actions Active

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.

Copilot review overview

🟡 Changes recommended

The preserved enumerable overload can now enumerate list-backed input twice, regressing its prior one-pass behavior.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds configurable MSBuild command-line parsing for SDK token classification.

Changes:

  • Adds per-call controls for unknown switches, response files, and environment logging arguments.
  • Returns unrecognized and unexpanded tokens while preserving order and quoting.
  • Adds regression tests and API documentation.
File Description
src/​MSBuild/​MSBuild.csproj Includes the new options source.
src/​MSBuild/​CommandLine/​CommandLineSwitchesAccessor.cs Exposes unrecognized and unexpanded tokens.
src/​MSBuild/​CommandLine/​CommandLineParsingOptions.cs Defines parsing controls.
src/​MSBuild/​CommandLine/​CommandLineParser.cs Implements per-call parsing behavior.
src/​MSBuild.UnitTests/​CommandLineParserTests.cs Covers options, errors, and parser reuse.
documentation/​specs/​command-line-parsing.md Documents the experimental API.

Comment thread src/MSBuild/CommandLine/CommandLineParser.cs Outdated
@baronfel
baronfel deployed to copilot-pat-pool October 6, 2026 20:58 — with GitHub Actions Active
@baronfel
baronfel deployed to copilot-pat-pool October 6, 2026 20:59 — with GitHub Actions Active
@baronfel
baronfel deployed to copilot-pat-pool October 6, 2026 20:59 — with GitHub Actions Active
Snapshot enumerable inputs even when they implement IReadOnlyList, add regression coverage, and document the list overload's stable-input contract.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: da6ccb4c-52f9-4389-a389-914271a74a6d
@baronfel
baronfel requested a review from a team October 7, 2026 14:03

This branch was successfully deployed

1 active (outdated) deployment
copilot-pat-pool — a4f140bd Deployed Oct 6, 2026 by baronfel via conclusion #971
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.

Allow command-line parsing without reading response files Provide non-throwing command-line parsing for unknown switches

2 participants