Skip to content

Pass everything after ktools git -- to git verbatim [patch] - #339

Open
matt-edmondson wants to merge 1 commit into
mainfrom
fix/332-git-passthrough-after-separator
Open

matt-edmondson wants to merge 1 commit into
mainfrom
fix/332-git-passthrough-after-separator

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #332

What was wrong

GitCommand built git's argv from context.Remaining.Raw on the assumption that a literal -- keeps flags verbatim. It doesn't: Spectre.Console.Cli still tokenizes what follows the separator.

  • -- log -1 became git log -. That's the dangerous case, since checkout - and merge - act on the previous branch.
  • -- clean -fdx, -- branch -vv and -- commit -mwip were rejected with "put it after --", even though the user already had.
  • -- grep -C2 foo and -- diff -U5 failed with "Short option does not have a valid name" (exit 255).

The fix

  • New GitPassThrough (KtsuTools/Commands/GitPassThrough.cs). Split takes a command line whose first token is git and cuts it at the first --. Spectre gets everything before the separator, and the tail is kept as Arguments. Any other command line comes back unchanged, along with GitPassThrough.None. Any later -- stays in the tail, because that one belongs to git's own pathspec syntax.
  • Program.Main now calls a new Program.Run(args, services). That method does the split, registers the GitPassThrough as a singleton, and runs the CommandApp on the shortened arguments. It is separate from Main so tests can take exactly the shipped path.
  • GitCommand takes the GitPassThrough in its constructor and appends its Arguments after settings.Args and Remaining.Raw. The forgotten-separator check is unchanged, so ktools git status --short is still rejected instead of silently dropping --short.

This follows the issue's suggestion to read the real argv after the first --. Splitting before CommandApp.Run is necessary rather than optional: Spectre rejects -C2 at parse time, before the command ever runs.

Tests

All new tests are in GitCommandTests:

  • TheRealAppPassesEverythingAfterTheSeparatorToGitVerbatim runs through Program.Run with a real CommandApp, as the issue's acceptance criteria ask. The cases are log -1, log -3 -p, clean -fdx, branch -vv, grep -C2 foo, diff -U5 and log '--format=%an %s' -1, and each checks the exact argument string git receives.
  • TheRealAppKeepsPositionalArgumentsBeforeTheSeparator covers git log --path … -- -1, which should give log -1.
  • TheRealAppStillRejectsAFlagWrittenWithoutTheSeparator covers git status --short, which should exit 1 and run nothing.
  • Three Split unit tests cover a later -- staying in the tail, a non-git command being left alone, and a git command line with no separator being left alone.

With Split turned into a no-op, so that Spectre sees the whole command line as it does on main, all 8 separator cases fail. The rejection test passes either way. The full suite passes: 397/397.

CI note

On main, restore currently fails with NU1903: SixLabors.ImageSharp 3.1.12 has a known high-severity advisory. That failure is unrelated to this change, and it is the same one #334, #337 and #338 report. To run the build and tests above locally, I passed -p:WarningsNotAsErrors=NU1903.


Generated by Claude Code

Spectre.Console.Cli still tokenizes the arguments after a '--', so
`ktools git -- log -1` ran `git log -`, `-- clean -fdx` was rejected as
three ktools options, and `-- grep -C2 foo` failed with "Short option does
not have a valid name".

Program now splits a `git` command line at its first '--' before Spectre
parses it, and hands the tail to GitCommand through a GitPassThrough
service, so git gets exactly the typed tokens. Flags written without the
separator are still caught by the existing forgotten-separator check.

Fixes #332

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW6DQQw6JpYVSCPgTzR

Copy link
Copy Markdown
Contributor Author

The ci / .NET / Test on … checks fail at restore with error NU1903: SixLabors.ImageSharp 3.1.12 has a known high-severity vulnerability (GHSA-v76p-62qx-wwq2).

The same checks are red on main at 3382f1d, and this PR doesn't touch the ImageSharp reference, so the failure isn't caused by this PR.

I don't know of a fix I could bring into this PR. #270, the bump to 3.2.0, is red as well because 3.2.0 needs a Six Labors license in CI (see ktsu-dev/IconHelper#155).

Locally, with -p:WarningsNotAsErrors=NU1903, the full suite passes: 397/397.


Generated by Claude Code

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.

ktools git -- log -1 passes - to git, and -- clean -fdx / -- grep -C2 are rejected: Spectre still tokenizes everything after --

1 participant