Repository navigation
Replace McMaster with CliFx in ilspycmd - #4306
Draft
christophwille wants to merge 3 commits into
Draft
christophwille wants to merge 3 commits into
christophwille wants to merge 3 commits into
Conversation
The command-line libraries evaluated as McMaster replacements differ from it in exactly these spots: a bare -usepdb must not consume the following token, a multi-value option takes one value per occurrence so the next bare token stays an input file, and -pd is not -p -d. None of them was pinned by the existing contract tests. Assisted-by: Claude:claude-fable-5-1:Claude Code
McMaster binds options by reflection, which is what the trimmer root and the value-parser warm-up in the csproj existed for, and its hosting integration pulled in Microsoft.Extensions.Hosting for an environment object nothing read. CliFx 3 is source-generated and AOT-clean, but its parser is position-based: input files are read only up to the first option, an option collects every following bare token, every single-dash token is split into one-letter options, and ':' or '=' do not attach a value. The verb-less command line needs the opposite of each, so a rewriter in front of CliFx reorders the tokens into the form it parses and rejects what it would misread; CliFx then does the typed binding, help and version. The engine keeps its options as plain properties on ILSpyCmdProgram and validates their combination itself; LegacyCommand (CliFx's default command) and LegacyArgumentRewriter are the only files that know the parser, so verbs can be added as named commands later and the verb-less form can be retired by deleting those two. CliFx answers its own usage errors with exit code 1, which this tool never used, so the host maps 1 to EX_USAGE; its console opens the raw standard handles, so the host routes it through Console.Out and Console.Error instead. Assisted-by: Claude:claude-fable-5-1:Claude Code
Taken from the Release build's --help output, so the Debug-only ILAst options stay out of it. Assisted-by: Claude:claude-fable-5-1:Claude Code
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft: one of three candidate ports of
ilspycmdoff McMaster.Extensions.CommandLineUtils (System.CommandLine in #4305, ConsoleAppFramework, CliFx), to be compared side by side. This one uses CliFx 3.0.1 (source-generated since 3.0; no runtime dependencies on net10.0).The contract tests from #4303 are the oracle:
ICSharpCode.ILSpyCmd.Testsis green (111 tests, the 108 existing ones plus three rows added here that pin spellings the evaluated libraries would otherwise change: a bare-usepdbfollowed by a file name, a multi-value option followed by a file name, and-pdbeing an error rather than-p -d). Error and help wording changed; option and argument behavior did not.Shape (the same in all three drafts)
ILSpyCmdProgramis now the engine with plain settable properties; it validates the option combination itself (ValidateUsage: input files,-rdirectories,-usepdb/settings files exist,-p/-dneed-o) and runs the request. It no longer knows a parser.ValidationAttributes.csand the unusedIHostEnvironmentare gone, soMicrosoft.Extensions.Hostingleaves the project too.LegacyCommandis the file that knows the library. It defines the verb-less command line and binds it into anILSpyCmdProgram. Retiring the verb-less form later means deleting it (here: together withLegacyArgumentRewriter).How CliFx fits
LegacyCommandis CliFx's default command ([Command]without a name, apartial classwith[CommandOption]/[CommandParameter]properties and a generatedDescriptor). Verbs become named commands ([Command("dump table")], multi-word names nest by prefix) registered next to it; routing takes the longest leading token sequence that names a command, otherwise the default command. A file literally named like a verb needs./verb.-r dir sample.dllwould make the assembly a reference path), splits every single-dash token into one-letter options (-ilis-i -l, short names are onechar), and has no:/=delimiters.LegacyArgumentRewritertherefore turns the raw arguments into[input files..., --name value ...]first, using the generated descriptor for arity and short names plus a five-entry table for the multi-letter aliases (-il -lv -ds -genpdb -usepdb). It also rejects what CliFx would misread (unknown options,-pd,--) with the old exit code.EX_USAGE. The command's own exit code is read back from the instance, which is handed to CliFx throughUseTypeInstantiator.-lvvalue escape as an exception with a stack trace; a smallScalarInputConverterthrowsCommandException(..., 64)instead, which CliFx prints as a one-line error.SystemConsoleopens the raw standard handles and bypassesConsole.SetOut; the host passes aFakeConsoleover two tiny write-only streams that hand the bytes back toConsole.Out/Console.Error(this is also what lets the in-process tests see the output). Ctrl+C registration is lost; the tool never registered one.--generate-diagrammer-json-onlyis taken out of the arguments by the rewriter and set on the command directly.Behavioral differences left (none pinned by the contract)
USAGE/DESCRIPTION/PARAMETERS/OPTIONS,Default: <false>.on every flag, aChoices:list for--languageversion, the Remarks/Examples under DESCRIPTION, the version in the header); the README block was regenerated from the Release build.AOT
CliFx 3 binds through generated typed descriptors, so
<TrimmerRootAssembly Include="ilspycmd" />and the McMaster value-parser warm-up are gone.IlcTreatWarningsAsErrors=falsestays for Mono.Cecil. Not run locally: the Native AOT publish. TheIlspyCmdRidPackagesCI job (win-x64/linux-x64 publish plus smoke test) is the gate for this PR.Assisted-by: Claude:claude-fable-5-1:Claude Code