Skip to content

Replace System.CommandLine with a custom argument parser#749

Merged
tannergooding merged 3 commits into
dotnet:mainfrom
tannergooding:tannergooding-fix-remap-value-with-spaces
Jul 13, 2026
Merged

Replace System.CommandLine with a custom argument parser#749
tannergooding merged 3 commits into
dotnet:mainfrom
tannergooding:tannergooding-fix-remap-value-with-spaces

Conversation

@tannergooding

Copy link
Copy Markdown
Member

Replaces the System.CommandLine dependency in ClangSharpPInvokeGenerator with a small, hand-rolled, reflection-free (AOT-friendly) argument parser.

System.CommandLine beta4 tokenizes each response-file line by splitting on whitespace before option matching, so a name=value argument whose value contains spaces (e.g. __arglist=@params string[] args) was split into multiple tokens and rejected with Invalid key/value pair argument. beta3 kept each line intact, which is why the repo has been pinned there as a workaround. Rather than chase the dependency, this rolls our own parser: each non-empty, non-# response-file line is read as exactly one token and never whitespace-split, so spaced values are preserved. A token is treated as an option only when it exactly equals a known alias, or (for the --opt=value inline form) the text before the first = is a known alias -- so bare name=value values and -m64 stay intact.

Fixes #554


Also folds in two cleanups:

  • Version is derived from the assembly (Major.Minor.Build) instead of a hardcoded string, so it tracks VersionPrefix automatically.
  • The repeated (string[])[.. opt.Values] casts collapse into a single CommandLineOption.GetValues().

Adds tests/ClangSharpPInvokeGenerator.UnitTests exercising the parser directly, including the #554 regression three ways (bare, inline --opt=, and via a response file), multi-pair tokens, single/flag arity, -m64-as-value, AllowedValues, and unknown-option/missing-response-file errors. The exe exposes its internals to the test project via InternalsVisibleTo.

Verified: full generator suite 3742/3742 and the new parser suite 11/11 pass with 0 warnings; --help/--version/config-help and the #554 repro all check out. System.CommandLine is removed from the csproj and Directory.Packages.props, and the README help blocks are regenerated from actual output.

tannergooding and others added 3 commits July 13, 2026 09:10
System.CommandLine has repeatedly broken the CLI, most recently in dotnet#554 where
the beta4 response-file tokenizer splits each line on whitespace before options
are matched, corrupting `name=value` values that contain spaces (such as a
`--remap` to a type with a space in it). The stable package also changed too
much to adopt cleanly, so roll a small parser we control instead.

The new parser is a plain, reflection-free (AOT-friendly) implementation that
reads each response-file line as a single token, preserving embedded spaces,
while still supporting multiple pairs across separate tokens, the inline
`--opt=value` form, and `#` comments. Drop the System.CommandLine package
reference and the CustomHelpBuilder, and regenerate the README help blocks to
match the new output.

Fixes dotnet#554

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The version shown by --version was a hardcoded "21.1.8" that had to be manually
kept in sync with VersionPrefix and the targeted clang release. Read it from the
assembly version (major.minor.build) so it tracks VersionPrefix automatically
and stays aligned with the clang/clangsharp version lines printed alongside it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Cover the custom `CommandLineParser` directly, including the dotnet#554
regression: a `name=value` token whose value contains spaces (bare, inline `--opt=`,
and via a response file) is preserved as a single value rather than split on whitespace.
Also cover multi-pair tokens, single/flag arity, `AllowedValues`, unknown options, and
response-file handling. Wire the exe up with `InternalsVisibleTo` so the internal parser
types are testable.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@tannergooding tannergooding merged commit 8a1e511 into dotnet:main Jul 13, 2026
14 checks passed
@tannergooding tannergooding deleted the tannergooding-fix-remap-value-with-spaces branch July 13, 2026 16:40
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.

Latest 18.1.0 release breaks type remapping for args with spaces in them

1 participant