diff

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package diff parses unified diffs into a structured DiffFile model and maps (file, post-image line) pairs back to added, modified, context, or out-of-hunk locations.

Parsing delegates to sourcegraph/go-diff (ADR 0006); this package adds classification, line-position bookkeeping, and the validator-facing Index.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DiffFile

type DiffFile struct {
	Path    string
	OldPath string
	Kind    FileKind
	Hunks   []Hunk
}

DiffFile is one changed file extracted from a unified diff.

Path holds the post-change path (per the schema: findings address files by their post-change path). OldPath is set when Kind is a rename variant.

func Exclude added in v0.2.2

func Exclude(files []*DiffFile, rawDiff string, patterns []string) (kept []*DiffFile, keptRaw string, excluded []string, err error)

Exclude drops files matching any of the gitignore-lite patterns from both the parsed file list and the raw unified diff, returning the kept files, the rebuilt raw diff, and the excluded paths (in diff order). With no patterns it returns its inputs unchanged.

Pattern rules (documented on the --exclude flag):

  • trailing "/" — directory tree, at any depth ("vendor/", "gen/")
  • no "/" — basename glob via path.Match ("*.lock")
  • otherwise — full-path glob via path.Match ("internal/gen/*.go")

Renamed files are excluded when either their old or new path matches, so `--exclude '*.lock'` cannot be dodged by a rename in the diff.

Raw-segment correspondence is positional: rawDiff must contain exactly one `diff --git` segment per entry in files (the invariant Parse guarantees for its own output). A mismatch is an error, never a guess.

func Include added in v0.3.0

func Include(files []*DiffFile, rawDiff string, patterns []string) (kept []*DiffFile, keptRaw string, dropped []string, err error)

Include is the allowlist inverse of Exclude: it keeps only the files matching at least one of the gitignore-lite patterns, dropping the rest from both the parsed file list and the raw unified diff. It returns the kept files, the rebuilt raw diff, and the dropped paths (in diff order). With no patterns it returns its inputs unchanged — an absent --include means "review everything", not "review nothing".

Pattern rules are identical to Exclude (see matchPattern):

  • trailing "/" — directory tree, at any depth ("internal/", "auth/")
  • no "/" — basename glob via path.Match ("*.go")
  • otherwise — full-path glob via path.Match ("internal/app/*.go")

A renamed file is kept when either its old or new path matches, the same OldPath/Path union Exclude uses — so a rename can't smuggle a file out of an allowlist any more than it can dodge a blocklist.

Raw-segment correspondence is positional, exactly as in Exclude: a segment/file count mismatch is an error, never a guess.

func Parse

func Parse(unified string) ([]*DiffFile, error)

Parse turns a unified diff into a slice of DiffFile.

Parsing delegates to sourcegraph/go-diff (per ADR 0006); this layer adds path normalization, file-kind classification, and per-line bookkeeping for the line-position oracle.

type FileKind

type FileKind int

FileKind classifies a changed file for prompt construction. The provider adapter uses this to decide what reaches the model.

const (
	// FileText is a text file with reviewable hunks. Include in prompt.
	FileText FileKind = iota
	// FileRenameWithHunks was renamed and also modified. Include under
	// the post-rename path; preserve the old path as metadata.
	FileRenameWithHunks
	// FilePureRename was renamed without content changes. Metadata only.
	FilePureRename
	// FileDelete was deleted. Metadata only by default; the v1 schema does
	// not accept deleted-line comments.
	FileDelete
	// FileBinary is a binary file change. Metadata only; unsupported by
	// the model prompt.
	FileBinary
	// FileModeOnly changed file mode without content changes. Metadata only.
	FileModeOnly
)

func (FileKind) IncludeInPrompt

func (k FileKind) IncludeInPrompt() bool

IncludeInPrompt reports whether this file's hunks should reach the model. Mirrors the classification rule in docs/provider-adapters.md § Diff Edge Cases.

func (FileKind) String

func (k FileKind) String() string

String returns a short human-readable label for the kind.

type Hunk

type Hunk struct {
	OldStart int
	OldLines int
	NewStart int
	NewLines int
	Lines    []HunkLine
}

Hunk is one contiguous block of changes within a file, corresponding to a `@@ -a,b +c,d @@` section of the unified diff.

Lines are kept in source order; each carries its post-image line number (zero for deleted lines, which have no post-image position).

type HunkLine

type HunkLine struct {
	Side    LineSide
	NewLine int    // post-image line number; zero when Side == LineDeleted
	Content string // line content, without the leading +/-/space marker
}

HunkLine is one line within a hunk.

type Index

type Index struct {
	// contains filtered or unexported fields
}

Index answers (file, post-image line) → LineClassification queries against a parsed set of DiffFiles. The validator uses it to enforce the v1 schema invariant that findings target only added or modified lines.

func NewIndex

func NewIndex(files []*DiffFile) *Index

NewIndex builds an Index from a parsed diff. Files whose Kind excludes them from the prompt (binary, mode-only, pure-rename, delete) are kept in the index so callers can still distinguish "not in diff" from "in diff but unaddressable"; this distinction matters in M3 when reporting why a finding was quarantined.

func (*Index) Classify

func (i *Index) Classify(file string, line int) LineClassification

Classify resolves a (file, post-image line) pair to a LineClassification. The first return value is the line's role inside the diff; callers that need the underlying file should use Lookup.

func (*Index) Lookup

func (i *Index) Lookup(file string) *DiffFile

Lookup returns the DiffFile for a path, or nil if the file isn't in the diff. Useful for callers that need more than a single classification.

type LineClassification

type LineClassification int

LineClassification labels what a post-image line number resolves to in a changed file. The validator uses this to enforce the v1 finding schema invariant: only added/modified lines are valid finding targets.

const (
	// LineAdded is a brand-new line introduced by the diff (a "+" line in
	// a hunk where the deleted counterpart, if any, is absent).
	LineAdded LineClassification = iota
	// LineModified is an added line that replaces a deleted line in the
	// same hunk position. Distinguished from LineAdded so the TUI can
	// render edit highlights differently in M4.
	LineModified
	// LineContext is an unchanged context line shown for surrounding
	// readability. The v1 finding schema disallows context-line comments,
	// so the validator quarantines findings landing here.
	LineContext
	// LineOutsideHunk is a line number that falls outside every hunk in
	// the file. The schema disallows comments here; quarantine.
	LineOutsideHunk
	// LineFileNotFound is returned when the file isn't part of the diff
	// at all, or has a kind that excludes it from prompting.
	LineFileNotFound
)

type LineSide

type LineSide int

LineSide names whether a hunk line was added, deleted, or context.

const (
	SideContext LineSide = iota
	SideAdded
	SideDeleted
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL