feat: add --staged diff scope for pre-commit hook scanning (#18)#53
Open
ChrisJr404 wants to merge 1 commit intoknostic:masterfrom
Open
feat: add --staged diff scope for pre-commit hook scanning (#18)#53ChrisJr404 wants to merge 1 commit intoknostic:masterfrom
ChrisJr404 wants to merge 1 commit intoknostic:masterfrom
Conversation
Adds a --staged flag to `openant scan` and `openant diff` that runs the incremental pipeline against the staged index (`git diff --cached`) instead of a committed ref. This is the workflow described by the DiffGuard project referenced in knostic#18: scan only what's about to be committed, before commit. Implementation: - New BuildStagedManifest, StagedChangedFiles, StagedHunksForFile in internal/git/diff.go. The manifest's base_ref is the literal "STAGED", base_sha is HEAD, and head_sha is a zero placeholder (the index has no SHA). The Python core reads these as opaque strings, so reports show "base=STAGED" without any core changes. - diffOpts grows a staged bool; validate() makes --staged mutually exclusive with --diff-base/--pr. - modeOpts/modeDecision thread the staged choice through selectMode so scan, diff, and the meta.json running state all agree. - README gains a short "Incremental and diff-based scans" section listing the four scopes (--diff-base, --pr, --staged, --incremental). Untracked files are not in the index, so they don't appear in the staged manifest. Pre-commit hooks usually just `git add` first, which is the standard expectation; we don't try to second-guess that. Tests: - 5 new git pkg tests: staged file/hunk extraction, manifest construction for changed_functions and changed_files scopes, empty-index edge case, bad-scope rejection. The hunk extraction test stages two files and edits a third worktree-only to confirm --cached doesn't bleed. - 5 new cmd pkg tests: validateModeFlags coverage for the four new conflict combos, selectMode confirms the Staged decision flag. - New diff_shared_test.go covers diffOpts.validate / isSet for the staged path. Closes knostic#18.
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.
What
Adds a
--stagedflag toopenant scanandopenant diffthat runs theincremental pipeline against the staged index (
git diff --cached) insteadof a committed ref. This is the workflow the DiffGuard project from #18
is built around: scan what is about to be committed, before the commit lands.
The existing
--diff-base/--pr/--incrementalmodes already coverpost-commit and PR-time scanning.
--stagedfills the pre-commit gap, whichmakes the diff-mode pipeline usable from a
pre-commithook or a quick local"scan what I'm about to commit" run without first committing.
Usage
In a
.git/hooks/pre-commit:How
BuildStagedManifest,StagedChangedFiles,StagedHunksForFileininternal/git/diff.go. SameManifestshape as the committed-diff path,with
base_ref="STAGED",base_sha=HEAD, and a zero placeholder forhead_sha(the index has no SHA).base=STAGEDcleanly without any change inlibs/openant-core.diffOptsgrows astaged bool;validate()makes--stagedmutuallyexclusive with
--diff-base/--pr.modeOpts/modeDecisionthread the staged choice throughselectMode,so
scan,diff, and the projectmeta.jsonrunning state agree on thescan kind.
four scopes (
--diff-base,--pr,--staged,--incremental).Notes
Untracked files are not in the index, so they do not appear in the staged
manifest. Pre-commit hooks typically
git addfirst; not second-guessingthat contract here.
git diff --cached --unified=0is the same hunk format the existingcommitted-diff path consumes, so the rest of the pipeline (parser tagging,
diff_filter, reporter) needs no changes.Tests
10 new tests, all passing:
internal/git:TestStagedChangedFilesAndHunks(stages two files plus aworktree-only edit, asserts
--cacheddoes not bleed),TestBuildStagedManifest,TestBuildStagedManifestChangedFilesScopeOmitsHunks,TestBuildStagedManifestEmptyIndex,TestBuildStagedManifestRejectsBadScope.cmd:TestValidateModeFlagsgains five rows for the new conflict combos(
staged + diffBase,staged + pr,staged + incremental,full + staged,staged alone);TestSelectModeStagedSetsStagedFlag.cmd/diff_shared_test.go:TestDiffOptsValidateStaged(7 sub-cases) andTestDiffOptsIsSetStaged.go vet ./...clean.go test ./...green on all packages.Closes #18.