Documentation
¶
Overview ¶
Package match holds the Rewriter seam (Locate + Render -> edit-set) and its dispatch table: the smart rewriter plus the action-pin rewriter for SHA-pinned uses: lines. Pure.
Index ¶
- func LookupTool(name string) (string, string, bool)
- func MiseFile(path string) bool
- func PythonVersionFile(path string) bool
- func Shaped(s string) bool
- func SwiftVersionFile(path string) bool
- func ToolNames() []string
- type ActionPin
- type ActionTag
- type ActionTrack
- type Context
- type DockerPin
- type DockerTag
- type DockerTrack
- type FindReplace
- type Guarded
- type Hash
- type Inference
- type Location
- type PythonTag
- type Renderer
- type Requirement
- type Rewriter
- type SecurePin
- type Smart
- type Span
- type Table
- type Token
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func LookupTool ¶
LookupTool resolves a mise tool name to the GitHub repository whose tags carry its releases and the tag prefix those tags wear, consulting the curated [miseGithubTools] map then the generated registry map.
func MiseFile ¶
MiseFile reports whether path is a file mise reads tool pins from (its own configuration or asdf's .tool-versions), where a bare single-number pin (node = "24") means major precision rather than a calendar tag, so selection may relax its scheme guard.
func PythonVersionFile ¶ added in v0.3.6
PythonVersionFile reports whether path is a pyenv .python-version file, the comment-less plain-text target annotate proposes a sidecar for.
func Shaped ¶
Shaped reports whether s carries a version-shaped token, i.e. Find locates one. A restyling rewriter re-dresses a resolved version onto the current token's shape, and a value with no version-shaped token (a leading-zero component like 19.0614, a four-component core) has no shape to re-dress - rendering it would fabricate a version, so such a candidate must not be selected.
func SwiftVersionFile ¶ added in v0.3.12
SwiftVersionFile reports whether path is a swiftly .swift-version file, the comment-less plain-text target annotate proposes a sidecar for.
func ToolNames ¶
func ToolNames() []string
ToolNames returns every tool name LookupTool resolves, naturally sorted, so a mistyped name can be met with a suggestion. It covers the GitHub-released tools only, the ones a `tool=` key names; an ecosystem tool is reached by its package name, not this map.
Types ¶
type ActionPin ¶
type ActionPin struct{}
ActionPin rewrites a GitHub Actions secure pin, where one resolved candidate drives two spans on the same line:
uses: owner/repo@<40-hex-sha> # v1.2.3
the commit SHA (from Candidate.Commit) and the trailing version comment (from Candidate.Version, restyled). The version comment is the current-version anchor - a SHA cannot anchor a semver constraint - so when it is present it fixes the version and its style. A pin with no comment is still a valid target: it has no current version to anchor a relative constraint, so run resolves it per the directive (latest unless a range constrains it) and Render appends a fresh comment, documenting the version the SHA now points at. Render relies on the provider storing the peeled target commit, not an annotated-tag object SHA.
func NewActionPin ¶
func NewActionPin() ActionPin
NewActionPin returns the action-pin rewriter (stateless value, like Smart).
func (ActionPin) Locate ¶
Locate parses the action reference, requiring a full 40-hex SHA after @. A version-shaped token in the trailing comment, when present, anchors the current version and its style. A pin with no comment at all is located with no current version, so run resolves it fresh and Render appends the comment. It errors for each way the line fails to be a SHA pin (no reference, not SHA-pinned, short SHA), and when a comment is present but carries no version - clover will not guess whether a human note like "# pinned" was meant to be a version.
type ActionTag ¶
type ActionTag struct{}
ActionTag rewrites a tag-pinned GitHub Actions reference, converting it to the secure pin format - clover is secure by default:
uses: owner/repo@v4 -> uses: owner/repo@<40-hex-sha> # v4.2.2
The tag anchors the current version and its constraint; Render replaces it with the resolved candidate's commit SHA and appends a comment naming the full resolved version, whatever precision the original tag carried. The converted line is a secure pin, so subsequent runs route to ActionPin.
func NewActionTag ¶
func NewActionTag() ActionTag
NewActionTag returns the action-tag rewriter (stateless value, like Smart).
func (ActionTag) Locate ¶
Locate finds the @<tag> version reference of a uses: action, requiring the tag to be wholly version-shaped so a branch ref like @main is never treated as a version to bump. Stray text after the tag (a trailing comment, extra words) is rejected rather than guessed at, since Render appends its own version comment.
type ActionTrack ¶
type ActionTrack struct{}
ActionTrack rewrites a GitHub Actions secure pin whose trailing comment names a floating branch rather than a version:
uses: owner/repo@<40-hex-sha> # main
Like ActionPin it drives two spans from one candidate - the commit SHA (from Candidate.Commit) and the comment (from Candidate.Version) - but it takes the comment literally instead of requiring a version-shaped token, so a branch name anchors the line and Semver stays nil.
func NewActionTrack ¶
func NewActionTrack() ActionTrack
NewActionTrack returns the action-track rewriter (stateless value, like Smart).
type Context ¶
Context is what the dispatch table routes on: the file, the target line, the marker's provider, and the follower value kind.
type DockerPin ¶
type DockerPin struct{}
DockerPin rewrites a digest-pinned image reference, where one resolved candidate drives two spans on the same line:
FROM repo:1.27@sha256:<64-hex>
the tag (restyled from Candidate.Version) and the digest (from Candidate.Digest). The tag is the current-version anchor, so a pin without one is an error; it acts only on already-pinned lines, never adding a digest.
func NewDockerPin ¶
func NewDockerPin() DockerPin
NewDockerPin returns the docker-pin rewriter (stateless value, like Smart).
type DockerTag ¶
type DockerTag struct{}
DockerTag rewrites a tag-only image reference, where the version is the tag of an image ref:
FROM localhost:5000/team/api:2.0.1 image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/team/api:2.0.1
Unlike the smart rewriter it does not scan the whole line - a registry :port, an ECR account id, or a region like us-east-1 are all version-shaped and would make the line ambiguous. Instead it anchors on the image reference, taking the tag as the last colon-segment after the last slash, so only the tag is read. The located tag re-styles exactly like a smart token, so Locate returns a smartLocated.
func NewDockerTag ¶
func NewDockerTag() DockerTag
NewDockerTag returns the docker tag-only rewriter (stateless value, like Smart).
type DockerTrack ¶
type DockerTrack struct{}
DockerTrack rewrites a digest-pinned image reference whose tag is a floating ref (latest, nonroot, edge) rather than a version:
FROM repo:latest@sha256:<64-hex>
Like DockerPin it drives two spans from one candidate - the tag (from Candidate.Version) and the digest (from Candidate.Digest) - but it takes the tag literally instead of requiring a version-shaped token, so a floating tag anchors the line and Semver stays nil. It acts only on already digest-pinned lines, never adding a digest.
func NewDockerTrack ¶
func NewDockerTrack() DockerTrack
NewDockerTrack returns the docker-track rewriter (stateless value, like Smart).
type FindReplace ¶
type FindReplace struct {
// contains filtered or unexported fields
}
FindReplace is the explicit find/replace rewriter. find locates the region to rewrite: a glob with <placeholders> (each a capturing group of its shape), or a /regex/ (strict, no placeholders; group 1 is the value). replace is optional: without it each captured value is substituted in place, preserving the rest; with it the whole matched region is re-rendered from the template. A token renders its resolved value when clover computes one, else the text find captured, so a match-only <hex> is preserved.
func NewFindReplace ¶
func NewFindReplace(find, replace string) (FindReplace, error)
NewFindReplace compiles a find/replace pair through the shared pattern grammar: a /regex/ find is strict (nil tokens), any other find is a glob with placeholders.
func (FindReplace) Locate ¶
func (fr FindReplace) Locate(line string) (Location, error)
Locate matches find against the line: the whole match is the span to rewrite, and the value anchoring selection is the first version-shaped capture (glob) or capture group 1 (regex), falling back to the whole match.
type Guarded ¶
type Guarded struct {
// contains filtered or unexported fields
}
Guarded is a rewriter wrapper that first requires a find/replace-style guard to match the line, then delegates the actual location and rendering to another rewriter. It is useful when a sidecar's jq locator selects the line, but a find pattern should still fail loud if the line has drifted to another source.
func NewGuarded ¶
NewGuarded returns a rewriter guarded by find. The guard is match-only; render behavior comes entirely from inner.
type Hash ¶
type Hash struct{}
Hash rewrites a follower's commit or sha256 line by swapping the existing hex token for the resolved one. It locates by shape (a 40- or 64-char hex run), so it needs no anchor; the resolved value the pipeline passes is spliced in as-is.
type Inference ¶
type Inference struct {
Host string
Package string
Product string
Provider string
Registry string
Repository string
Source string
TagPrefix string
Track string
}
Inference is what auto-detection resolved for a `provider=auto` marker from its target line: the real provider plus any provider parameters readable from the line. Empty parameter fields mean the line did not carry that detail.
func Infer ¶
Infer is the one-shot form of Table.Infer, for a caller inferring a single line. A loop over a file's lines builds one Table instead.
func (Inference) Missing ¶
Missing reports why the inference cannot resolve - a route matched but the line carries no usable reference - or "" when the inference is complete. The forge and image providers need a repository, hashicorp needs a product, and node needs nothing beyond the provider itself.
type Location ¶
type Location interface {
// Current is the version text currently on the line, recorded as the old value.
Current() string
// Semver is the parsed core of the current version, nil when unparseable. It
// anchors selection.
Semver() *version.Version
// NeedsDigest reports whether rendering will rewrite a content digest, so the
// pipeline knows to resolve one for the candidate.
NeedsDigest() bool
// Render rewrites the line for the resolved candidate, returning the new line
// and whether it changed. It errors rather than reporting a silent no-op when
// the candidate lacks a field it needs or the located span no longer fits.
Render(line string, candidate model.Candidate) (string, bool, error)
}
Location is what a Rewriter found on a target line: the common anchors the pipeline reads (Current, Semver, NeedsDigest) plus the ability to render itself for a resolved candidate. Each rewriter returns its own implementation, so the renderer-specific state (spans, captures) stays private to the rewriter that produced it rather than piling into a shared struct.
type PythonTag ¶
type PythonTag struct{}
PythonTag rewrites a compact Python target-version token - py314 for Python 3.14. The token is not version-shaped (no dots), so the smart rewriter cannot see it; this rewriter parses the major and minor out of the pyXY form, anchors selection on that line, and renders the resolved version back into the same compact form (dropping patch and prerelease, which the form does not carry).
func NewPythonTag ¶
func NewPythonTag() PythonTag
NewPythonTag returns the compact Python target-version rewriter (stateless value, like the other format rewriters).
type Renderer ¶
Renderer is the optional capability of a Location that can report the exact version text it will write for a candidate, which may differ from the candidate's raw version once restyled (a stripped variant, a re-precisioned or re-prefixed core). The pipeline resolves a digest for this text rather than the raw candidate, so a pinned image's digest always describes the tag written. It also marks the target as restyling, so selection drops any candidate that is not version-shaped (see Shaped) - restyling cannot write one faithfully.
type Requirement ¶ added in v0.3.5
type Requirement struct{}
Requirement rewrites the pinned version of a quoted PEP 508 dependency specifier in pyproject.toml, e.g. "uv_build>=0.8.24". It anchors on the specifier's own version - the token just past the comparator - so another version elsewhere on the line (an environment marker's, another entry's) is never the one bumped, and it demands the constraint end at that version, so a range or a .post suffix is rejected rather than half-rewritten.
func NewRequirement ¶ added in v0.3.5
func NewRequirement() Requirement
NewRequirement returns the dependency-specifier rewriter (stateless value, like the other format rewriters).
func (Requirement) Locate ¶ added in v0.3.5
func (Requirement) Locate(line string) (Location, error)
Locate finds the single dependency specifier on the line and the version it pins. It errors when the line carries no specifier or more than one (a single-line group like dev = ["a>=1", "b>=2"] is ambiguous), when the pinned version is not version-shaped (a four-component core), when it carries a local +tag the rewriter cannot re-render, or when the constraint continues past it (a range, a .post suffix, trailing prose).
type Rewriter ¶
type Rewriter interface {
// Locate extracts the version currently on the line, erroring when the
// rewriter cannot act on it (no target, ambiguous, or malformed).
Locate(line string) (Location, error)
}
Rewriter locates the version a target line carries. Implementations range from the shape-based Smart rewriter to format-specific ones. Locate is offline and pure, so lint runs it to validate a marker without resolving anything; the Location it returns renders the line once a candidate is resolved.
type SecurePin ¶
type SecurePin interface {
Pinned() string
}
SecurePin is the optional capability of a Location whose target pins a secure value beside the version - an action commit SHA or an image content digest. Pinned reports the value currently on the line, so a run can cross-check it against the value the resolved tag reports and catch a committed pin that no longer matches upstream.
type Smart ¶
type Smart struct{}
Smart is the default rewriter. It locates a version by shape - no provider anchor is needed for the v0.1.0 providers, which are weakly anchored - and renders a new version that preserves the original's style: its v-prefix, component precision, and variant suffix, carrying the resolved prerelease through whenever the chosen version has one.
func NewSmart ¶
func NewSmart() Smart
NewSmart returns the default smart rewriter. It takes no arguments today but is the seam for future options, and keeps construction uniform with the rest of the codebase. The value is returned directly: Smart is stateless, so a pointer would only add an allocation and indirection.
type Table ¶ added in v0.3.11
type Table struct {
// contains filtered or unexported fields
}
Table is the dispatch table scoped to one file: the routes whose path guard matches the file, computed once so per-line inference never re-evaluates a path glob. Inference is called for every line of every scanned file, and the glob matching dwarfs the line matching, so the scoping is what makes a large tree affordable.
func (Table) Infer ¶ added in v0.3.11
Infer resolves the provider for an `auto` marker from its target line (lines[target]), reusing the dispatch routes: the first route whose line matches (ignoring its provider guard, which is the answer) names the provider. It also reads the provider's parameters from the line - the repository from a GitHub Actions pin, the registry and repository from a container image reference - so a bare `provider=auto` needs no further keys. The surrounding lines matter only to the Terraform route, whose source address lives on a sibling line of its block. It returns ok=false when nothing matches, leaving the marker for the caller to reject.
type Token ¶
type Token struct {
Span Span
Prefix string // "v", or "" when bare
Core string // numeric core, 1-3 dotted components, e.g. "1.27"
Prerelease string // prerelease identifiers without the leading -, or ""
Dashless bool // prerelease glued to the core with no dash (3.15.0b3)
Suffix string // recognized variant suffix without the leading -, or ""
Build string // build metadata without the leading +, or ""
}
Token is a version reference located in a line: its byte span plus the parts it decomposes into. Keeping the numeric Core separate from the Prefix, Prerelease, variant Suffix, and Build means the rewriter can normalize on the core and re-apply each decoration exactly once when rendering a new version.