Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dotnet publish --configuration Release --output ./staging

Tests live in `ProjectDirector.Test` (MSTest, via `MSTest.Sdk` + `ktsu.Sdk`). The app exposes its internals to the test project through `InternalsVisibleTo` in `ProjectDirector/AssemblyInfo.cs`. `GitCliTests` drives `GitCli` against throwaway repositories under the temp directory; the ImGui layer is not unit-tested.

That last point is why the repository actions are shaped the way they are: the part of each with a rule in it is pulled out into a plain method so it can be driven without a live ImGui context or a display. `ProjectDirector.DecidePull` decides whether pulling interrupts the user first (`PullDecisionTests`), and `GitCli.ListPendingChanges` plus `ProjectDirector.DescribePendingChanges` decide what a commit will sweep up and how that is shown (`CommitTests`). Anything genuinely worth testing that is still tangled up with drawing is usually worth extracting the same way.

```powershell
dotnet test --configuration Release
```
Expand Down Expand Up @@ -52,6 +54,9 @@ dotnet test --configuration Release
- Arguments are passed as a list rather than as a command string, so paths containing spaces need no quoting
- `RunIn` uses `git -C <repo>`, which never touches the process working directory and so stays safe while repositories are fetched concurrently
- Queries answer from git's exit code rather than by searching its output for "fatal"
- `StageAllAndCommit` returns a null commit result when staging failed, so a caller can tell "never attempted" from "git refused". A clean tree is the second kind: git exits non-zero and that refusal is passed through rather than being pre-empted here
- `Push` sends no refspec and no force, so a branch with no upstream and a diverged branch are both refused by git, with its own explanation, rather than guessed at or overwritten
- `ListPendingChanges` parses `status --porcelain -z` by *consuming* a rename's trailing source entry rather than by testing each entry for a status prefix. A source path such as `ab cd.txt` has a space in the third position and is indistinguishable from a record by inspection, so a prefix test would list a file that no longer exists

### Why the git command line rather than a library

Expand Down
Loading