Documentation
¶
Index ¶
- func Discover(ctx context.Context, opts map[string]any, files []lint.FileInfo) (*supplychain.Snapshot, error)
- func Resolve(ctx context.Context, opts map[string]any, files []lint.FileInfo) ([]supplychain.Dependency, error)
- func SplitImageNamespace(image string) (string, string)
- func SplitImageTag(ref string) (string, string)
- type FreshnessConfig
- func (c *FreshnessConfig) CacheTTL() time.Duration
- func (c *FreshnessConfig) EffectiveSeverity(dep supplychain.Dependency, updateType string) SeverityConfig
- func (c *FreshnessConfig) GroupForDep(dep supplychain.Dependency, updateType string) string
- func (c *FreshnessConfig) IsDisabledByRule(dep supplychain.Dependency) bool
- func (c *FreshnessConfig) IsIgnored(name string) bool
- func (c *FreshnessConfig) SourceEnabled(ecosystem string) bool
- func (c *FreshnessConfig) VulnSeverityOverride() bool
- type Group
- type PackageRule
- type RegistryConfig
- type RegistryEndpoint
- type Resolver
- func (m *Resolver) Config() *FreshnessConfig
- func (m *Resolver) Configure(opts map[string]any) error
- func (m *Resolver) FetchManifestDigest(ctx context.Context, image, tag string) (string, error)
- func (m *Resolver) ResolveFile(ctx context.Context, file lint.FileInfo) ([]supplychain.Dependency, error)
- func (m *Resolver) SetToolchainDesired(desired map[string]config.ToolConstraint)
- type SeverityConfig
- type SourceConfig
- type VulnConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Discover ¶
func Discover(ctx context.Context, opts map[string]any, files []lint.FileInfo) (*supplychain.Snapshot, error)
Discover runs the full dependency resolution pipeline once and returns an immutable supplychain.Snapshot. It is the single public Snapshot producer — callers that need ONE resolution pass shared across multiple consumers (e.g. the audition pipeline, which threads the Snapshot to both the freshness lint module and the dependency-update step) call Discover exactly once and pass the result down explicitly. Resolve remains the entry point for standalone callers (e.g. `stagefreight dependency update`) that don't need a shared Snapshot; Discover wraps it so both stay in sync.
func Resolve ¶
func Resolve(ctx context.Context, opts map[string]any, files []lint.FileInfo) ([]supplychain.Dependency, error)
Resolve runs the full dependency resolution pipeline across all files and returns raw Dependency structs with vulnerabilities correlated. opts is passed to Configure; nil uses FreshnessConfig defaults.
func SplitImageNamespace ¶
SplitImageNamespace splits an image name into (namespace, repo) for Docker Hub. "golang" → ("library", "golang") "prplanit/stagefreight" → ("prplanit", "stagefreight") "ghcr.io/owner/repo" → not Docker Hub, skip.
func SplitImageTag ¶
SplitImageTag splits "golang:1.25-alpine" into ("golang", "1.25-alpine").
Types ¶
type FreshnessConfig ¶
type FreshnessConfig struct {
Sources SourceConfig `json:"sources"`
Severity SeverityConfig `json:"severity"`
Vulnerability VulnConfig `json:"vulnerability"`
Registries RegistryConfig `json:"registries"`
Ignore []string `json:"ignore"`
PackageRules []PackageRule `json:"package_rules"`
Groups []Group `json:"groups"`
Timeout int `json:"timeout"` // HTTP timeout in seconds (default 10)
CacheTTLSecs int `json:"cache_ttl"` // cache TTL in seconds (default 300; 0 = cache forever; <0 = never cache)
// MinReleaseAge is a supply-chain cooldown: freshness will not recommend (and so
// stagefreight will not auto-adopt) a release published more recently than this window.
// Most malicious npm publishes — compromised maintainer tokens, typosquats — are caught
// and yanked within hours to days, so a cooldown sidesteps that exposure window. Accepts
// "7d", "2w", "72h", or any Go duration. Empty/0 = disabled. Implemented for npm (the
// registry exposes per-version publish times); other ecosystems ignore it until wired.
MinReleaseAge string `json:"min_release_age"`
// FetchVersionLists is a capability flag (NOT a policy): when set, resolvers that
// would otherwise fetch only the latest version also retrieve the full published
// version list into Dependency.AvailableVersions. The deps layer enables it solely
// under a patch-lock ceiling — the only case that re-targets to a lower in-range
// version and thus needs the list — so the default path pays no extra network. A
// resolver that already has the list for free (cargo) populates it regardless.
FetchVersionLists bool `json:"fetch_version_lists"`
}
FreshnessConfig holds per-source toggles, severity mapping, package rules, registry overrides, vulnerability correlation, and grouping configuration.
func DefaultConfig ¶
func DefaultConfig() FreshnessConfig
DefaultConfig returns production defaults.
func (*FreshnessConfig) CacheTTL ¶
func (c *FreshnessConfig) CacheTTL() time.Duration
CacheTTL returns the cache TTL as a time.Duration.
- >0 → cache with expiry (e.g. 300 → 5m)
- 0 → cache forever (content-hash only)
- <0 → never cache (always re-run)
func (*FreshnessConfig) EffectiveSeverity ¶
func (c *FreshnessConfig) EffectiveSeverity(dep supplychain.Dependency, updateType string) SeverityConfig
EffectiveSeverity returns the severity config for a dependency, checking packageRules first, then falling back to the global config.
func (*FreshnessConfig) GroupForDep ¶
func (c *FreshnessConfig) GroupForDep(dep supplychain.Dependency, updateType string) string
GroupForDep returns the group name assigned by a matching package rule.
func (*FreshnessConfig) IsDisabledByRule ¶
func (c *FreshnessConfig) IsDisabledByRule(dep supplychain.Dependency) bool
IsDisabledByRule checks if a package rule explicitly disables this dep.
func (*FreshnessConfig) IsIgnored ¶
func (c *FreshnessConfig) IsIgnored(name string) bool
IsIgnored returns true if name matches any ignore glob or a package rule disables it.
func (*FreshnessConfig) SourceEnabled ¶
func (c *FreshnessConfig) SourceEnabled(ecosystem string) bool
SourceEnabled checks whether a particular ecosystem is turned on.
func (*FreshnessConfig) VulnSeverityOverride ¶
func (c *FreshnessConfig) VulnSeverityOverride() bool
VulnSeverityOverride returns whether CVE-affected deps should be escalated to critical regardless of version delta.
type Group ¶
type Group struct {
Name string `json:"name"`
CommitMessagePrefix string `json:"commit_message_prefix"`
Automerge *bool `json:"automerge"` // group-level automerge default
SeparateMajor bool `json:"separate_major"` // split major bumps into own MR
}
Group configures how matched dependencies are batched together for future MR creation. Reserved in config shape now; the MR engine will consume these when update mode is implemented.
.stagefreight.yml example:
groups:
- name: "go-patch-updates"
commit_message_prefix: "deps(go): "
automerge: true
- name: "docker-base-images"
separate_major: true
type PackageRule ¶
type PackageRule struct {
// Pattern matching — all specified fields must match (AND logic).
MatchPackages []string `json:"match_packages"` // glob patterns on dependency name
MatchEcosystems []string `json:"match_ecosystems"` // ecosystem constants (docker-image, gomod, etc.)
MatchUpdateTypes []string `json:"match_update_types"` // "major", "minor", "patch"
MatchVulnerability *bool `json:"match_vulnerability"` // true = only match deps with known CVEs
// Overrides applied when matched.
Enabled *bool `json:"enabled"` // false = skip this dependency entirely
Severity *SeverityConfig `json:"severity"` // override severity/tolerance for matched deps
Group string `json:"group"` // assign to a named group (for future MR batching)
// Future update-mode fields (wired later, config-shape reserved now).
Automerge *bool `json:"automerge"` // auto-merge MR if CI passes
}
PackageRule overrides severity, tolerance, or behaviour for dependencies that match its patterns. Rules are evaluated in order; first match wins. Modeled after Renovate's packageRules.
.stagefreight.yml example:
package_rules:
- match_packages: ["golang", "alpine"]
severity: { major: 2, minor: 2, patch: 1 }
- match_packages: ["*.test", "mock-*"]
enabled: false
- match_ecosystems: ["gomod"]
match_update_types: ["patch"]
automerge: true
group: "go-patch-updates"
type RegistryConfig ¶
type RegistryConfig struct {
Docker *RegistryEndpoint `json:"docker"`
Go *RegistryEndpoint `json:"go"`
Npm *RegistryEndpoint `json:"npm"`
PyPI *RegistryEndpoint `json:"pypi"`
Crates *RegistryEndpoint `json:"crates"`
Alpine *RegistryEndpoint `json:"alpine"`
Debian *RegistryEndpoint `json:"debian"`
Ubuntu *RegistryEndpoint `json:"ubuntu"`
GitHub *RegistryEndpoint `json:"github"` // GitHub API for tool version checks
}
RegistryConfig overrides the default public registry URLs per ecosystem. Each field accepts a RegistryEndpoint; if URL is empty the public default is used. Auth is resolved from environment variables at runtime.
.stagefreight.yml example:
registries:
docker:
url: "https://jcr.pcfae.com/v2"
auth_env: "JCR_TOKEN"
go:
url: "https://goproxy.company.com"
npm:
url: "https://npm.company.com"
auth_env: "NPM_TOKEN"
type RegistryEndpoint ¶
type RegistryEndpoint struct {
URL string `json:"url"` // base URL (e.g. "https://jcr.pcfae.com/v2")
AuthEnv string `json:"auth_env"` // env var name holding auth token (Bearer)
}
RegistryEndpoint is a custom registry URL with optional auth.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver runs the dependency-resolution engine: per-ecosystem checkers, registry lookups, and vulnerability correlation. It holds no lint dependency beyond lint.FileInfo, the resolver input type.
func NewResolver ¶
func NewResolver() *Resolver
NewResolver constructs a Resolver with default configuration.
func (*Resolver) Config ¶
func (m *Resolver) Config() *FreshnessConfig
Config returns the resolver's active configuration.
func (*Resolver) FetchManifestDigest ¶
FetchManifestDigest queries the registry v2 manifest endpoint for the digest of image:tag. Used by the freshness renderer's digest-lock check for non-versioned tags (e.g. "latest", "noble").
func (*Resolver) ResolveFile ¶
func (m *Resolver) ResolveFile(ctx context.Context, file lint.FileInfo) ([]supplychain.Dependency, error)
ResolveFile resolves dependencies for a single file using the Resolver's current configuration, correlating vulnerabilities. Lazily initializes the HTTP client if Configure was not called (defaults). This is the entry point used by the freshness lint renderer's per-file Check.
func (*Resolver) SetToolchainDesired ¶
func (m *Resolver) SetToolchainDesired(desired map[string]config.ToolConstraint)
SetToolchainDesired records the toolchains.desired config used by checkToolchainDesired.
type SeverityConfig ¶
type SeverityConfig struct {
Major int `json:"major"` // 0=info, 1=warning, 2=critical (default: 2)
Minor int `json:"minor"` // default: 1
Patch int `json:"patch"` // default: 0
MajorTolerance int `json:"major_tolerance"` // default: 0
MinorTolerance int `json:"minor_tolerance"` // default: 0
PatchTolerance int `json:"patch_tolerance"` // default: 1
}
SeverityConfig maps version-delta levels to lint severities and controls how many versions behind are tolerated before reporting.
type SourceConfig ¶
type SourceConfig struct {
DockerImages *bool `json:"docker_images"`
GitHubReleases *bool `json:"github_releases"`
GoModules *bool `json:"go_modules"`
RustCrates *bool `json:"rust_crates"`
NpmPackages *bool `json:"npm_packages"`
AlpineAPK *bool `json:"alpine_apk"`
DebianAPT *bool `json:"debian_apt"`
PipPackages *bool `json:"pip_packages"`
}
SourceConfig toggles individual dependency ecosystems on or off. nil means "use default" (true for all).
type VulnConfig ¶
type VulnConfig struct {
Enabled *bool `json:"enabled"` // default true
MinSeverity string `json:"min_severity"` // "low", "moderate", "high", "critical" (default: "moderate")
SeverityOverride *bool `json:"severity_override"` // CVE-affected deps escalate to critical (default: true)
}
VulnConfig controls vulnerability correlation via the OSV database.
.stagefreight.yml example:
vulnerability: enabled: true min_severity: "moderate" severity_override: true