Documentation
¶
Overview ¶
Package ebuilds reads the ebuild tree of an overlay: it locates a package directory, lists its ebuilds, selects the current ebuild for a slot or a version series, splits package atoms, labels and slots, and extracts EbuildMetadata from an ebuild file.
It walks directories and parses ebuild files; version parsing and comparison live in internal/common/ebuild. It sits at the bottom of the autoupdate package graph and imports no other autoupdate package.
Index ¶
- Variables
- func ApplyRevision(version string, revision int) string
- func DetectBinaryPackage(content []byte) bool
- func ExtractGitHubInfo(meta *EbuildMetadata) (owner, repo string, found bool)
- func ExtractVersionFromFilename(name string) string
- func FindEbuilds(pkgDir string) ([]string, error)
- func NewSeriesMatcher(log *slog.Logger, series string) seriesMatcher
- func ParsePkgAtom(key string) (category, pkgName string, err error)
- func PkgDirFor(overlayPath, pkg string) string
- func SelectCurrentEbuild(log *slog.Logger, overlayPath, pkg, series string) (ebuildCandidate, error)
- func SplitPackageKey(key string) (category, name string, ok bool)
- func SplitPkgAtom(key string) (category, pkgName string, ok bool)
- func SplitPkgLabel(key string) (rest, label string)
- func SplitPkgSlot(key string) (atom, slot string)
- type EbuildMetadata
- type PackageType
Constants ¶
This section is empty.
Variables ¶
var ( // PythonDepRegex matches Python-related dependencies PythonDepRegex = regexp.MustCompile(`dev-python/|python-`) // NodeDepRegex matches Node.js-related dependencies NodeDepRegex = regexp.MustCompile(`net-libs/nodejs|dev-nodejs/`) // RustDepRegex matches Rust-related dependencies RustDepRegex = regexp.MustCompile(`dev-lang/rust|virtual/rust|dev-rust/`) )
Regular expressions for parsing ebuild variables
var ( // ErrPackageNotFound is returned when a package is not found in the configuration ErrPackageNotFound = errors.New("package not found in configuration") // ErrNoEbuildFound is returned when no ebuild file is found for a package ErrNoEbuildFound = errors.New("no ebuild file found for package") // ErrEbuildNotFound is returned when the source ebuild file is not found ErrEbuildNotFound = errors.New("source ebuild file not found") )
Sentinel errors for locating packages and ebuilds in an overlay tree.
var ( // ErrEbuildParseFailed is returned when the ebuild file cannot be parsed ErrEbuildParseFailed = errors.New("failed to parse ebuild") )
Error variables for ebuild metadata extraction
var ErrSeriesNotFound = errors.New("no ebuild in the package directory matches the entry's series")
ErrSeriesNotFound is returned when a package's directory IS present in the overlay but no ebuild in it matches the entry's `series`. Like ErrSlotNotFound — and for the same reason — it is deliberately NOT an ErrNoEbuildFound: the package is there, the entry's filter is what selects nothing, and auto-disabling it would turn a config mistake into a package that quietly stops being updated.
var ErrSlotNotFound = errors.New("no ebuild in the package directory declares the requested slot")
ErrSlotNotFound is returned when a package's directory IS present in the overlay but no ebuild in it declares the slot the entry's key asks for.
It is deliberately NOT an ErrNoEbuildFound. That error means "this package is gone from the overlay", and the checker acts on it: the entry is auto-disabled in packages.toml so a removed package stops being processed. A slot that matches nothing is the opposite situation — the package is right there, the key is wrong (a typo, or a slot that has not been packaged yet) — and silently writing enabled = false for it would turn a config mistake into a package that quietly stops being updated.
This distinction is not hypothetical. A 0.14.0 checker, which predates slot keys entirely, reads "net-libs/webkit-gtk:4.1" as a directory name, fails to find it, concludes the ebuild was removed and disables both webkit-gtk slot entries — with no error and no exit code to notice. Config the checker cannot interpret must fail loudly, never silently downgrade itself.
var RevisionSuffixRegex = regexp.MustCompile(`-r\d+$`)
RevisionSuffixRegex matches the trailing -rN of a PV.
Functions ¶
func ApplyRevision ¶
ApplyRevision returns the PV to write for a freshly bumped ebuild, attaching the revision a multi-slot package pins via `revision = N` in packages.toml.
The revision is configured rather than carried over from the source ebuild because carrying it over is wrong twice. For an ordinary package the revision must RESET on a PV change — bumping foo-1.2.3-r1 produces foo-1.2.4, never foo-1.2.4-r1. And where a revision does discriminate slots, the value to write is the slot's base, not the source's: ::gentoo bumps webkit-gtk-2.52.3-r411 (SLOT 4.1) to webkit-gtk-2.52.5-r410, because r411 was a revbump within the old PV. Neither rule is derivable from the source filename, so it is declared.
revision <= 0 means "plain PV", which is both the default and correct for every single-slot package — and for a slot that happens to use a bare PV, as the bentoo overlay's SLOT 6 webkit-gtk ebuild does.
func DetectBinaryPackage ¶
DetectBinaryPackage checks if the ebuild is for a binary package
func ExtractGitHubInfo ¶
func ExtractGitHubInfo(meta *EbuildMetadata) (owner, repo string, found bool)
ExtractGitHubInfo extracts owner and repo from GitHub URLs in metadata
func ExtractVersionFromFilename ¶
ExtractVersionFromFilename extracts version from an ebuild filename. Format: package-version (without .ebuild suffix) Examples: "hello-1.0.0" -> "1.0.0", "firefox-bin-120.0" -> "120.0"
func FindEbuilds ¶
FindEbuilds finds all ebuild files in a package directory
func NewSeriesMatcher ¶
NewSeriesMatcher compiles series into a matcher. An empty series yields a pass-everything matcher. An uncompilable one is warned and also passes everything: ValidatePackageConfig rejects it up front, and a scan that got this far must not silently select the wrong ebuild — a filter that fails open is visible (the wrong line gets bumped and the warning says why), one that fails closed looks exactly like a removed package. The warning goes to log; nil discards it.
func ParsePkgAtom ¶
ParsePkgAtom is splitPkgAtom with the refusal explained: the error names the half that cannot be used as one directory name. Callers that report a bad key to a person (ValidatePackageConfig) use it; path builders use splitPkgAtom.
func PkgDirFor ¶
PkgDirFor returns the overlay directory holding pkg's ebuilds, or "" when the key is malformed.
func SelectCurrentEbuild ¶
func SelectCurrentEbuild(log *slog.Logger, overlayPath, pkg, series string) (ebuildCandidate, error)
SelectCurrentEbuild returns the highest-version, non-live ebuild for pkg in the overlay — the one scan behind the checker's getCurrentVersion and currentEbuildPath and the applier's resolveCurrentVersion. Two filters narrow it, and an entry uses whichever tells its package's parallel ebuilds apart:
- ":slot" in the key — only ebuilds whose SLOT= declares that slot.
- `series` — only ebuilds whose version matches that regex, for a package whose parallel ebuilds share one SLOT and differ by release line.
Without them the scan returns the highest PV whatever its line: with zed-bin-1.13.1 and zed-bin-1.14.1_pre both present, an entry tracking stable would see every stable release as older than the preview and stop updating.
Only the slot filter reads file contents; the unfiltered and series scans cost one readdir (series matches on the version in the filename).
A series that does not compile is warned about to log; nil discards it.
func SplitPackageKey ¶
SplitPackageKey splits a packages.toml key into its category and package-name components, dropping any ":slot" suffix. It is the exported form of splitPkgAtom, for callers outside this package that turn a key into a filesystem path (cmd/bentoo's revive flow) — a second, slot-blind copy of the split is exactly the bug the slot suffix invites.
func SplitPkgAtom ¶
SplitPkgAtom splits a package key into its category and package-name components, dropping any ":slot" and "@label" suffix. It reports false when the key is not a well-formed "category/package" atom, leaving the (varied) error wording to each caller. This is the single place that knows a package key is not necessarily a bare atom, so path building cannot silently inherit a suffix.
Both halves are joined under the overlay (and the staged tree) as directory names, and the key comes from packages.toml, so each half must name exactly one directory: "../x" or "cat/.." would otherwise be accepted as an atom and build a path outside the package directory. parsePkgAtom says which half was refused and why.
func SplitPkgLabel ¶
SplitPkgLabel splits a package key into everything before its "@label" and the label itself. A key with no "@" yields an empty label. The label carries no behavior of its own — it exists so two entries for the same atom and slot can coexist — so every consumer other than the config map simply drops it.
func SplitPkgSlot ¶
SplitPkgSlot splits a package key into its "category/package" atom and its optional slot restriction, dropping any "@label" first. A key with no ":" yields an empty slot, which every consumer reads as "no slot filtering" — the behaviour of every single-slot package, i.e. all of them before this existed.
Types ¶
type EbuildMetadata ¶
type EbuildMetadata struct {
// Package is the full package name in category/package format
Package string
// Version is the current ebuild version
Version string
// Homepage is the HOMEPAGE variable from the ebuild
Homepage string
// SrcURI is the SRC_URI variable from the ebuild
SrcURI string
// Dependencies contains DEPEND and RDEPEND entries
Dependencies []string
// IsLive indicates if this is a live/git ebuild (version 9999)
IsLive bool
// IsBinary indicates if this is a binary package (RESTRICT="bindist" or similar)
IsBinary bool
}
EbuildMetadata contains extracted ebuild information
func ExtractEbuildMetadata ¶
func ExtractEbuildMetadata(overlayPath, pkg string) (*EbuildMetadata, error)
ExtractEbuildMetadata extracts metadata from an ebuild file. It finds the highest version ebuild in the package directory and extracts HOMEPAGE, SRC_URI, DEPEND, RDEPEND, and detects live/binary packages.
type PackageType ¶
type PackageType string
PackageType represents the detected package type based on metadata
const ( // PackageTypeGitHub indicates a package hosted on GitHub PackageTypeGitHub PackageType = "github" // PackageTypePyPI indicates a Python package from PyPI PackageTypePyPI PackageType = "pypi" // PackageTypeNPM indicates a Node.js package from npm PackageTypeNPM PackageType = "npm" // PackageTypeCrates indicates a Rust crate from crates.io PackageTypeCrates PackageType = "crates" // PackageTypeGeneric indicates a package with no specific ecosystem detected PackageTypeGeneric PackageType = "generic" )
func DetectPackageType ¶
func DetectPackageType(meta *EbuildMetadata) PackageType
DetectPackageType determines the package type from metadata. It analyzes HOMEPAGE, SRC_URI, and dependencies to identify the ecosystem.