Documentation
¶
Overview ¶
Package git provides repository checkouts for scanners that operate on source trees.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsLocalPath ¶ added in v0.55.0
IsLocalPath reports whether url names a directory on this machine rather than a remote.
Deliberately a filesystem question rather than a URL-parsing one: "." and "../service" and an absolute path are all local, and anything with a scheme or an scp-style host is not.
func UncommittedFiles ¶ added in v0.55.0
UncommittedFiles counts a local repository's uncommitted changes, or 0 when there are none, the path is not local, or git cannot say.
Exists because a local path is cloned like any other source: the scan sees the *committed* state, not the files on disk. That is right — a scan has to describe a revision someone else can reproduce — and it is invisible, so a change that introduces a finding passes until it is committed. Best-effort: a scan must not fail because git could not answer a courtesy question.
Types ¶
type Scope ¶ added in v0.52.0
type Scope struct {
// Paths restricts the checkout to these directories. Empty means the whole repository.
//
// Directory prefixes, not general globs: `services/web` and `services/web/**` both mean the
// same subtree. That is what sparse checkout can express, and expressing it any other way
// would mean downloading the repository to throw most of it away.
Paths []string
// Ignore removes matching paths after checkout, applied last so it can carve out of Paths.
// Gitignore-style: a trailing `/` matches a directory and everything under it, `*` matches
// within a path segment, `**` matches across them.
Ignore []string
}
Scope restricts which of a repository's files a checkout materialises.
Shaping the tree rather than passing flags to each tool is deliberate. Every repository scanner is handed the checkout directory and points its tool at it — Trivy, Semgrep, Gitleaks and gosec all take a root and walk it. Translating a descriptor's scope into each tool's own include and exclude syntax would be a mapping per tool, wrong in a different way for each, and absent for the next scanner someone adds. A tree that already contains what was asked for needs no translation and cannot be forgotten.
type Tree ¶ added in v0.64.0
type Tree struct {
// Dir is the checkout on disk.
Dir string
// Revision is the SHA that was materialised, as `git rev-parse HEAD` reports it. Empty only
// when git could not be asked, which is not worth failing a scan over.
Revision string
// Dirty counts uncommitted files in the source. For a clone they are what the tree is
// missing; for a working-tree copy they are what it uniquely contains. WorkingTree says
// which, so nothing has to infer it from a count.
Dirty int
// WorkingTree reports that this copy came from a checkout on disk, uncommitted work included,
// rather than from a commit — so it is not reproducible.
WorkingTree bool
}
Tree is a materialised copy of a repository, and the revision it actually holds.
The resolved revision matters because a descriptor usually does not name one: `revision` is empty far more often than not, meaning "the default branch", which is a moving answer. A report that cannot say which commit it describes cannot be reproduced or compared, and that is the entire justification for scanning a committed revision in the first place.
func Checkout ¶
func Checkout(ctx context.Context, url, revision string, scope Scope) (tree Tree, cleanup func(), err error)
Checkout clones url into a fresh temporary directory, materialising only what scope allows. With an empty revision it does a shallow clone of the default branch; otherwise it clones and checks out revision. The returned cleanup removes the directory (call it even on error paths that returned a dir).
func CheckoutWorkingTree ¶ added in v0.64.0
CheckoutWorkingTree copies a local checkout — including uncommitted work — into a temporary directory and scopes it exactly as Checkout does.
A copy rather than the path itself, which is the whole point. Scanning in place would mean a tool writing its caches into somebody's repository, and `paths`/`ignore` are applied by deleting what is not wanted — against a real checkout that is not scoping, it is data loss.
The file list comes from `git ls-files -co --exclude-standard`: tracked files plus untracked ones that are not ignored. That is git's own answer to "what is in this working tree", so a build artifact directory or a local .env is left behind for the same reason a commit would leave it behind, rather than by a rule Draugr invented.