Documentation
¶
Overview ¶
Package presetref parses and classifies a preset reference — the string in a `preset:` field that locates a preset fragment, optionally from a remote source at a git ref. Classification decides how the loader resolves it (local read, live fetch, or cache-authoritative), per the identity model's preset-resolution design. This is pure parsing and static classification — no I/O; the one genuinely source-dependent case (a bare ref name that could be a branch or a tag) is marked Named and left for the fetch layer to resolve against the source.
Index ¶
Constants ¶
const DefaultMaxFallbackAge = 7 * 24 * time.Hour
DefaultMaxFallbackAge is how long a retained copy may stand in for an unreachable source before resolution stops accepting it. Unbounded is not a safe default: it is how a source that quietly stops answering leaves everyone frozen on old content. A week absorbs a long outage while still surfacing one that is not going to end.
Variables ¶
This section is empty.
Functions ¶
func CacheKey ¶
CacheKey is the retention-store key for a ref: source + ref + path, sanitized to a safe relative path. A pinned ref's key includes its immutable ref; a tracked ref's key is stable across runs so a re-fetch overwrites the same entry.
func IsURL ¶ added in v0.11.0
IsURL reports whether raw is an http(s) URL. Only these two schemes: another scheme (ssh://, git://) addresses a repository, which reaches Parse through the separator form and keeps its repo/path split. Exported so the fetch layer routes on the same predicate the parser classified with, rather than a second copy that can drift.
Types ¶
type AgedCache ¶ added in v0.11.0
AgedCache is an optional Cache capability: how long ago an entry was retained. Without it a fallback cannot be bounded, because there is no way to tell a copy retained five minutes ago from one retained five months ago.
type Cache ¶
Cache is the retention store for fetched presets — the fallback for tracked refs and the authoritative store for pinned refs. Keyed by a ref's CacheKey.
type FSCache ¶
type FSCache struct {
Root string
}
FSCache is a filesystem-backed Cache rooted at a directory — typically a repo's .stagefreight/preset-cache. It stores each fetched preset under its (sanitized, slash-bearing but ..-free) CacheKey, so pinned refs and tracked-ref fallbacks persist across runs.
type FetchMode ¶
type FetchMode int
FetchMode controls network behavior.
const ( // FetchLive is the default: a tracked ref is fetched each run (cache as fallback); a // pinned ref is served from cache if present, else fetched once. FetchLive FetchMode = iota // FetchOffline never touches the network: everything resolves from cache, and a miss // is an error. For air-gapped CI running against a pre-seeded cache. FetchOffline )
type Fetcher ¶
type Fetcher interface {
// Fetch returns the file at path from source at ref (ref "" = the default branch).
Fetch(source, ref, path string) ([]byte, error)
// Classify resolves a BARE Named ref against the source: a tag → Pinned, a branch →
// Tracked. Called only for Named refs. Takes the path for the same reason Fetch does:
// it is what distinguishes a repository source from a bare document URL.
Classify(source, ref, path string) (Kind, error)
}
Fetcher does the actual remote I/O for a preset source; the Resolver stays pure policy over it, so the tracked/pinned/fallback logic is testable without a network.
type Kind ¶
type Kind int
Kind is how a preset reference resolves.
const ( // Local is an in-repo path (no source): read from the working tree / preset-cache. Local Kind = iota // Tracked is a source at a branch (or no ref): fetched live each run so a change at // the source propagates to every tracking repo, with the cache as offline fallback. Tracked // Pinned is a source at a provably-immutable ref (a sha or a refs/tags/ tag): // cache-authoritative — resolved from cache when present, fetched once otherwise. Pinned // Named is a source at a BARE ref name (e.g. "main", "v1.0") that can't be classified // statically — a branch and a tag look identical as strings. The fetch layer resolves // it against the source (a tag → pinned, a branch → tracked). Pinning explicitly // (a sha or refs/tags/…) avoids this deferral. Named )
type MismatchPolicy ¶ added in v0.11.0
type MismatchPolicy string
Resolver resolves a SOURCED preset Ref (Tracked/Pinned/Named) to its content, applying the source-tracking policy. Local refs are out of scope — the local loader handles them. MismatchPolicy decides what happens when a PINNED reference's source no longer serves what was retained. Only a pin can mismatch: it asserts a revision is immutable, and that assertion is what the source can contradict. A tracked reference asserts nothing, so a change there is simply the new value.
There is no universally right answer, which is why it is the operator's: one shop sees a moved pin as tampering and wants everything to stop; another trusts the source and wants the newer content; a third wants what it already had, plus a warning.
const ( // MismatchFail stops. The default, because it is the only option that does not // choose for an operator who has not said which side they trust. MismatchFail MismatchPolicy = "fail" // MismatchSource adopts what the source serves. MismatchSource MismatchPolicy = "source" // MismatchRetained keeps what was retained. MismatchRetained MismatchPolicy = "retained" )
func (MismatchPolicy) Valid ¶ added in v0.11.0
func (p MismatchPolicy) Valid() bool
Valid reports whether p is a policy the resolver understands.
type NoCache ¶ added in v0.11.0
type NoCache struct{}
NoCache retains nothing. For a caller that fetches in order to write the content somewhere else — governance materializing a preset into a satellite's cache — where a second copy in the control repo would serve no one.
type Outcome ¶ added in v0.11.0
type Outcome struct {
Ref Ref
Kind Kind
Fetched bool // reached the source on this run
Drifted bool // what the source served differs from what was retained
Fallback bool // source unreachable; the retained copy was served instead
Violated bool // pinned, and the source no longer serves what was retained
Unchanged bool // the source serves what was retained; nothing written
// Refreshed reports that THIS run wrote the retained copy — replacing one that
// differed, or creating one governance never seeded. It is what a satellite
// republishes: a retained copy the run produced but never committed leaves the
// working tree dirty, which is a failure, not a diagnostic. Distinct from Drifted,
// which answers whether the content changed: a first retention changes nothing and
// still has to be carried back, and an adopted pin mismatch is a write the operator
// asked for.
Refreshed bool
}
Outcome records how one reference resolved. A tracked source changing is the behaviour the operator selected by not pinning, so this exists to make the change visible and auditable — not to flag it as suspect.
type PinViolation ¶ added in v0.11.0
PinViolation reports a pinned reference whose source no longer serves what was retained. Returned as an error so the default is to stop; a caller that would rather warn can recognize it and continue with Retained.
func (*PinViolation) Error ¶ added in v0.11.0
func (e *PinViolation) Error() string
type Ref ¶
type Ref struct {
Raw string // the original string
Kind Kind
Source string // "<source>" (forge repo or URL); "" for Local
Path string // preset path within the source, or the local path for Local
Ref string // the git ref (branch / tag / sha, possibly refs/-qualified); "" = default branch
}
Ref is a parsed preset reference.
func Parse ¶
Parse classifies a preset reference. Forms:
preset/lint.yml → Local https://example.org/lint.yml → Tracked (the URL is the whole source) gitlab:Org/Repo//preset/lint.yml → Tracked (default branch) …//preset/lint.yml@main → Named (bare — resolved at fetch) …//preset/lint.yml@refs/heads/main → Tracked …//preset/lint.yml@refs/tags/v1.0 → Pinned …//preset/lint.yml@v1.0 → Named (bare — resolved at fetch) …//preset/lint.yml@1a2b3c4 → Pinned (sha)
type Resolver ¶
type Resolver struct {
Fetcher Fetcher
Cache Cache
Mode FetchMode
// Observe, if set, receives one Outcome per resolved reference.
Observe func(Outcome)
// MaxFallbackAge bounds how long a retained copy may stand in for an unreachable
// source. Zero is unbounded. Without a bound, a source that stays unreachable leaves
// every consumer silently frozen on old content — the failure this whole mechanism
// exists to remove, arriving by a different route.
MaxFallbackAge time.Duration
// OnMismatch decides what a pinned reference does when its source disagrees with
// what was retained. Empty means MismatchFail.
OnMismatch MismatchPolicy
// Warnf, if set, reports a non-fatal condition (e.g. a stale-cache fallback).
Warnf func(format string, args ...any)
}