mod package_closure¶
- module package_closure¶
Recursive package-closure planner and aggregate bundle writer.
Closes a root foreign package plan over robot candidates, optional catalog overrides, and ordered local source roots (EasyBuild / conda-forge / Spack / Cargo). Compatible robot candidates win. Holes resolve robot-first, then catalog overrides, then EasyBuild cross-generation bump, then an unambiguous foreign recipe. Package names never appear as control flow.
The aggregate writer places root artifacts at the bundle root, companion artifacts under packages/<name>-<version>-<toolchain>/, and every recipe and verified patch into one shared
easyconfigs/overlay.Variables
- const CLOSURE_BUNDLE_SCHEMA_VERSION: u32¶
Schema version for
build-order.jsonandclosure.plan.json.
Functions
-
fn merge_closure_sboms<'a, I>(sboms: I) -> Result<Value, PackageClosureError>¶
where
I: IntoIterator<Item = &'a Value>
¶ Merge root and companion CycloneDX documents into one aggregate BOM.
Components and dependency graph edges are deduplicated by
bom-refwhen present, otherwise by a stabletype|name|versionidentity. The result is a real CycloneDX JSON document, not a custom wrapper.
- fn package_layout_segment(bundle: &PackageBundle) -> Result<String, PackageClosureError>¶
Deterministic companion directory segment under
packages/.Format: <name>-<version>-<toolchain-name>-<toolchain-version>. Each field is validated as a single safe path component so no package-specific branches are required to keep the layout inside the bundle.
- fn plan_package_closure(request: &NewPackageRequest, catalog: &PackageSourceCatalog) -> Result<PackageClosure, PackageClosureError>¶
Plan a root package and recursively close robot holes (catalog only).
Prefer
plan_package_closure_with_sourceswhen ordered EasyBuild / conda-forge / Spack source roots are configured.
- fn plan_package_closure_with_sources(request: &NewPackageRequest, catalog: &PackageSourceCatalog, source_roots: &PackageSourceRoots) -> Result<PackageClosure, PackageClosureError>¶
Plan a root package and close robot holes via catalog overrides and source roots.
The EasyBuild robot is parsed once. Each requested root profile is solved against robot candidates plus generated companions. Holes are discovered by inspecting the admitted candidate universe, never by parsing solver text. Explicit catalog entries override discovery for the same identity.
- fn write_package_closure(closure: &PackageClosure, output_directory: &Path) -> Result<WrittenPackageClosure, PackageClosureError>¶
Write a planned package closure into a single campaign-ready bundle layout.
Root manifest/SBOM/locks stay at the bundle root. Each companion is written under packages/<name>-<version>-<toolchain-name>-<toolchain-version>/. Every recipe and verified patch lands in one shared
easyconfigs/overlay; colliding destinations are rejected. Profile order within each package is preserved; companions precede the root inbuild-order.json.
Enums
- enum PackageClosureError¶
Why a package closure could not be completed.
Most variants name an ambiguity rather than a hard failure: closing a dependency graph means choosing providers, and a choice the tool cannot make on evidence is surfaced instead of guessed at.
- Workflow(PackageWorkflowError)¶
A package in the closure could not be planned or written.
- Catalog(PackageCatalogError)¶
The provider catalog could not be built.
- SourceRoots(PackageSourceError)¶
A configured source root could not be read.
- Solve(ProfileSolveError)¶
A profile’s dependency solve failed.
- Cycle¶
The dependency graph has a cycle, so no build order exists.
- path: Vec<String>¶
The cycle, in the order it was walked.
- MissingProvider¶
Nothing in the catalog provides a required package.
- name: String¶
Package nothing provides.
- version: String¶
Version that was required.
- AmbiguousProvider¶
Several candidates provide it and none is clearly right.
- name: String¶
Package with several providers.
- version: String¶
Version that was required.
- count: usize¶
How many candidates matched.
- MissingSource¶
No source recipe was found to generate a needed companion from.
- name: String¶
Package no source recipe was found for.
- version_req: String¶
Version requirement that had to be met.
- candidates: Vec<DiscoveredCandidate>¶
Sources that were considered and rejected.
- AmbiguousSource¶
Several source recipes match, so which to generate from is unclear.
- name: String¶
Package with several matching sources.
- version_req: String¶
Version requirement that had to be met.
- count: usize¶
How many sources matched.
- candidates: Vec<DiscoveredCandidate>¶
The sources in question.
- SourceParseFailure¶
Every candidate source recipe failed to parse.
- name: String¶
Package whose sources all failed to parse.
- version_req: String¶
Version requirement that had to be met.
- failures: Vec<SourceParseFailure>¶
Why each candidate failed.
- IncompatibleProviderVersion¶
The available provider cannot satisfy the required version.
- name: String¶
Package whose provider is too old or too new.
- provided: String¶
Version the provider offers.
- required: String¶
Version that was needed.
- GeneratedCandidateNotAdmitted¶
A companion was generated but the solve still would not take it, which means generating it did not close the gap.
- name: String¶
Companion that was generated.
- required: String¶
Version the solve still demands.
- profile: String¶
Profile that would not take it.
- MissingProfile¶
A package has no profile by that name.
- package: String¶
Package that has no such profile.
- profile: String¶
Profile that was asked for.
- ProfileAmbiguity¶
Which profile to use could not be decided.
- package: String¶
Package whose profile could not be decided.
- reason: String¶
Why the choice is ambiguous.
- GeneratedCandidate(String)¶
A generated companion was itself invalid.
- Layout(String)¶
The closure could not be laid out on disk.
- AggregateSbom(String)¶
The combined SBOM could not be produced.
Structs and Unions
- struct ClosureBuildOrder¶
Declared EasyBuild build order for a closed package bundle.
- schema_version: u32¶
Must equal
CLOSURE_BUNDLE_SCHEMA_VERSION.
- recipes: Vec<String>¶
Bundle-relative recipe paths using
/separators.
- struct ClosurePackageRef¶
One package identity inside a written closure layout.
- name: String¶
Package name.
- version: String¶
Package version.
- directory: String¶
Bundle-relative directory (
.for the root package).
- manifest: String¶
Bundle-relative path to the package plan.
- sbom: String¶
Bundle-relative path to the package SBOM.
- recipes: Vec<String>¶
Bundle-relative paths of the emitted easyconfigs.
- struct ClosurePlanDocument¶
Aggregate description of a written package closure.
- schema_version: u32¶
Must equal
CLOSURE_BUNDLE_SCHEMA_VERSION.
- root: ClosurePackageRef¶
The requested package.
- companions: Vec<ClosurePackageRef>¶
Generated companions, dependencies before dependents.
- build_order: String¶
Bundle-relative path of the build-order document.
- struct PackageClosure¶
Root package bundle plus generated companions in topological build order.
- root: PackageBundle¶
The package that was asked for.
- companions: Vec<PackageBundle>¶
Generated companion bundles, dependencies before dependents.
- struct WrittenPackageClosure¶
Paths written for a closed multi-package bundle.
- root: WrittenPackageBundle¶
Where the requested package landed.
- companions: Vec<WrittenPackageBundle>¶
Where each generated companion landed, in build order.
- build_order: PathBuf¶
The build-order document.
- closure_plan: PathBuf¶
The aggregate plan describing the whole closure.
- closure_sbom: PathBuf¶
The aggregate SBOM covering every package in it.