Skip to content

Migrate from CommandLineParser to System.CommandLine#1941

Merged
tyrielv merged 1 commit intomicrosoft:masterfrom
tyrielv:tyrielv/net10-system-commandline
Apr 15, 2026
Merged

Migrate from CommandLineParser to System.CommandLine#1941
tyrielv merged 1 commit intomicrosoft:masterfrom
tyrielv:tyrielv/net10-system-commandline

Conversation

@tyrielv
Copy link
Copy Markdown
Contributor

@tyrielv tyrielv commented Apr 9, 2026

Migrate from CommandLineParser to System.CommandLine

Summary

Replace reflection-based CommandLineParser 2.6.0 with Microsoft's System.CommandLine latest stable release. This eliminates runtime reflection for CLI parsing, a prerequisite for NativeAOT compilation.

What changed

  • 16 GVFS verb files — Removed [Verb]/[Option]/[Value] attributes, added CreateCommand() with SetAction(ParseResult) pattern
  • 3 standalone programs — FastFetch, GVFS.Mount, LockHolder migrated to RootCommand
  • 4 Program.cs files — Replaced Parser.ParseArguments with RootCommand.Parse(args).Invoke()
  • GVFSVerb.cs — Added shared helpers (SetActionForVerbWithEnlistment<T>, SetActionForNoEnlistment<T>) with per-verb (verb, result) => callback for option binding
  • 4 csproj files — Swapped CommandLineParserSystem.CommandLine
  • Preserved version subcommandgvfs version was handled by CommandLineParser as a built-in pseudo-verb; recreated as explicit subcommand using ProcessHelper.GetCurrentProcessVersion()
  • --version redirects to version — rewritten to args[0] = "version" before parsing, so both use the same code path (AOT-safe, no assembly reflection)
  • Added help subcommandgvfs help [subcmd] for parity with old parser (additive)
  • Case-insensitive verbsargs[0] lowercased before parse, matching old CaseSensitive = false
  • --help/-h/-? handled automatically by System.CommandLine

Review guide

  • Program.cs--version redirect (line ~20), case normalization (line ~28), exit code parity with ReturnCode model
  • GVFSVerb.cs — Shared helpers: verify (verb, result) => callback binds all verb-specific options before Execute()
  • Spot-check a verb (e.g., ServiceVerb, PrefetchVerb) — every Option<T> should have a matching GetValue() assignment
  • CloneVerb.cs / ConfigVerb.cs — Custom handlers (not shared helpers) due to unique dispatch semantics

Verification

  • ✅ Zero C# compilation errors
  • ✅ 793/793 unit tests pass
  • ✅ No remaining using CommandLine; or [Verb]/[Option]/[Value] attributes

Context

Phase 2B of .NET 10 NativeAOT migration.

@tyrielv tyrielv changed the title Migrate from CommandLineParser to System.CommandLine 2.0.3 Migrate from CommandLineParser to System.CommandLine Apr 9, 2026
@tyrielv tyrielv force-pushed the tyrielv/net10-system-commandline branch 3 times, most recently from 4aa10aa to 72ff548 Compare April 14, 2026 16:11
@tyrielv tyrielv marked this pull request as ready for review April 15, 2026 03:38
@tyrielv tyrielv requested a review from KeithIsSleeping April 15, 2026 15:56
Replace reflection-based CommandLineParser 2.6.0 with Microsoft's
System.CommandLine 2.0.5 stable release. This eliminates runtime
reflection for CLI parsing, a prerequisite for NativeAOT compilation.

All 16 GVFS verbs, FastFetch, GVFS.Mount, and LockHolder migrated.
Uses SetAction+ParseResult pattern (2.0.x stable API). Shared helpers
in GVFSVerb reduce boilerplate while preserving per-verb option binding.

Replaces System.CommandLine's built-in --version (assembly reflection,
not AOT-safe) with custom --version option routing to same code as
'gvfs version' subcommand via ProcessHelper.GetCurrentProcessVersion().
Adds 'help' subcommand for backward compatibility with old CLI.
Case-insensitive verb matching preserved via args normalization.

Assisted-by: Claude Opus 4.6
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
@tyrielv tyrielv force-pushed the tyrielv/net10-system-commandline branch from 72ff548 to f0c8cb8 Compare April 15, 2026 16:09
Copy link
Copy Markdown
Contributor

@derrickstolee derrickstolee left a comment

Choose a reason for hiding this comment

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

If this passes functional tests without actually changing how those tests execute the CLI, then I call that a win.

@tyrielv tyrielv enabled auto-merge April 15, 2026 17:35
@tyrielv tyrielv removed the request for review from KeithIsSleeping April 15, 2026 17:38
@tyrielv tyrielv merged commit 7d0389b into microsoft:master Apr 15, 2026
88 of 89 checks passed
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