Commit 29582b2
Add --repo/--left/--right/--file CLI flags (closes #5)
DiffViewer is GUI-launch-only today. Add a named-flag command-line form
so terminals, shell aliases, and other tools can drive the app into a
specific (repo, left, right, [file]) context without going through the
launch-context picker.
Parser:
- CommandLineParser.Parse branches into a new flag-form path when the
first positional arg begins with "--". The existing positional grammar
(working-tree path, commit-vs-commit, two-commit, PR URL) is untouched.
- Required flags: --repo, --left, --right. Optional: --file.
- "WORKING" (case-insensitive) maps to DiffSide.WorkingTree; any other
value is treated as a commit-ish and resolved through the existing
RefResolver path.
- New CommandLineErrorKind values: MissingRequiredFlag, MissingFlagValue,
UnexpectedPositionalArgument. Unknown flags fail loud (silent ignore
would hide difftool-style misconfiguration).
- --file is normalized to Path.DirectorySeparatorChar with leading
separators trimmed and stored on ParsedCommandLine.InitialFile.
File pre-selection:
- FileListViewModel.LoadFromChanges takes an optional preferredInitialPath
and selects the matching entry by RepoRelativePath
(OrdinalIgnoreCase) when there is no prior selection. Doing the
selection inside LoadFromChanges keeps it within the IsReloading=true
gate window, so the DiffPane reload still fires exactly once from the
consolidated PropertyChanged at the end of the load.
- MainViewModel accepts an initialFile ctor param and threads it through.
- CompositionRoot passes parsed.InitialFile into the MainViewModel ctor.
Console / stderr:
- New Utility/ConsoleAttacher wraps AttachConsole(ATTACH_PARENT_PROCESS),
idempotent, with cached IsAttached state. Best-effort: a double-click
launch with no parent console just returns false.
- App.OnStartup calls AttachToParent() at the top, then wires a
Console.Error.WriteLine-based stderrWriter into MainWindowCoordinator
only when attachment succeeded.
- MainWindowCoordinator.HandleColdLaunchFailure invokes the writer
(try/catch wrapped — best-effort) before the existing dialog and
empty-state fallback paths. When launched from Explorer the dialog
path is identical to before.
README + CHANGELOG:
- New "Command-line launch" section documenting the flag grammar plus a
working `git` alias recipe (`git config --global alias.dv ...`).
- Honest note on why `git difftool` itself does not fit: it passes
temp snapshot file paths as \/\, not commit-ish refs, so
DiffViewer's flag form (which needs a real repo + refs to drive
hunk staging, history, recents) cannot plug into difftool's slots.
- `[Unreleased]` "Added" entry covering the new flags and the error
behavior.
Tests:
- CommandLineParserFlagFormTests: 26 tests covering required flags,
WORKING sentinel (both sides, case-insensitive), --file
normalization, mixed positional+flag rejection, unknown flag,
unresolvable refs, missing repo, subdir discovery, ParseLaunch
routing.
- FileListViewModelInitialPathTests: 7 tests for preferredInitialPath
(match, case-insensitive, unmatched, null, empty, prior-selection-wins,
commit-vs-commit layout).
- ConsoleAttacherTests: 2 tests for idempotency + IsAttached contract.
- MainWindowCoordinatorTests: 3 new tests for stderr writer
(writes on parse failure, optional/null is still backward-compat,
throwing writer does not derail dialog/shutdown).
Final state: dotnet build -c Release => 0 warnings, 0 errors.
dotnet test => 1199 passed, 1 skipped (unchanged live-network skip),
up from the 1161-passing baseline.
AI-Local-Session: d30f85c9-a0a8-47d4-8312-c1823ad4c3ec
AI-Cloud-Session: 8a8a3c25-8fc8-474f-8993-ac4289b7d964
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent fbfbf53 commit 29582b2
14 files changed
Lines changed: 1084 additions & 7 deletions
File tree
- DiffViewer.Tests
- Services
- Utility
- ViewModels
- DiffViewer
- Models
- Services
- Utility
- ViewModels
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
17 | 32 | | |
18 | 33 | | |
19 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
| 3 | + | |
2 | 4 | | |
3 | 5 | | |
4 | 6 | | |
| |||
38 | 40 | | |
39 | 41 | | |
40 | 42 | | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
41 | 111 | | |
42 | 112 | | |
43 | 113 | | |
| |||
0 commit comments