mod package_sources

module package_sources

Ordered local package source roots for robot-hole discovery.

When a package-closure hole has no compatible target-robot candidate and no explicit catalog override, these roots supply EasyBuild recipes at other generations (annual-bump path) and unambiguous conda-forge, Spack, or Cargo recipes (new-package path). Lookup uses package identity normalization and version requirements only — never package-name control flow.

Variables

const PACKAGE_SOURCE_ROOTS_SCHEMA_VERSION: u32

Schema version of a source-roots configuration.

Functions

fn discover_provider_candidates_for_hole(index: &PackageSourceIndex, hole: &UnsatisfiedDirectDependency, target_parent: &Toolchain, hierarchy: Option<&ToolchainHierarchy>) -> Result<Vec<PackageSourceProvider>, ProviderDiscoveryError>

Return every compatible provider version after variant and source-generation ambiguity has been removed. Closure planning gives multiple EasyBuild versions to Resolvo and emits only the selected annual bump.

fn discover_provider_for_hole(index: &PackageSourceIndex, hole: &UnsatisfiedDirectDependency, target_parent: &Toolchain, hierarchy: Option<&ToolchainHierarchy>) -> Result<PackageSourceProvider, ProviderDiscoveryError>

Resolve a hole to a single provider: EasyBuild cross-generation first, then foreign. Fail with typed evidence when zero or many compatible candidates remain.

target_parent is the root package toolchain. EasyBuild bumps remap the source recipe’s toolchain family through hierarchy (see map_source_toolchain_to_target).

fn map_source_toolchain_to_target(source: Option<&Toolchain>, target_parent: &Toolchain, hierarchy: Option<&ToolchainHierarchy>) -> Toolchain

Map a source EasyBuild recipe’s toolchain family onto the target generation.

Subtoolchains stay in-family: a GCCcore source becomes the GCCcore member of the requested target hierarchy (for example GCCcore-15.2.0 under foss-2026.1), never the composite parent. Composite sources of the parent family retarget to the parent. SYSTEM stays SYSTEM.

fn package_identity(name: &str) -> String

A name reduced to lowercase alphanumerics, for matching across ecosystems that punctuate differently.

some-crate and Some_Crate become the same identity.

Enums

enum PackageSourceError

Why source roots could not be configured or read.

UnsupportedSchema(u32)

The configuration declares a schema this build does not read.

Toml(toml::de::Error)

The configuration is not valid TOML.

Io(String, std::io::Error)

A configured path could not be read.

EmptyPath

A root has an empty path.

EmptyPackageConfigPath

A configuration layer path is empty.

EasyBuildPackageConfig

An easyconfig root was given configuration layers, which only apply when generating from a foreign recipe.

Discovery(String)

A root could not be walked.

PackageConfig(String, String)

A configuration layer for a discovered candidate was invalid.

enum ProviderDiscoveryError

Typed discovery failure with candidate evidence for operators and tests.

Missing

No candidate matched the requirement.

name: String

Package that was needed.

version_req: String

Requirement it had to meet.

candidates: Vec<DiscoveredCandidate>

Candidates considered and rejected.

Ambiguous

Several candidates matched and none is clearly right.

name: String

Package with several matches.

version_req: String

Requirement they all meet.

count: usize

How many matched.

candidates: Vec<DiscoveredCandidate>

The candidates in question.

Incompatible

A candidate exists but cannot satisfy the required version.

name: String

Package whose candidate is the wrong version.

provided: String

Version available.

required: String

Version needed.

candidates: Vec<DiscoveredCandidate>

Candidates considered.

SourceParseFailure

Every candidate that could have matched failed to parse.

name: String

Package whose candidates all failed to parse.

version_req: String

Requirement that had to be met.

failures: Vec<SourceParseFailure>

Why each candidate failed.

enum SourceRootKind

Kind of local recipe index under a source root.

EasyBuild

EasyBuild easyconfig tree (.eb files, any generation).

Public TOML spelling is easybuild (not easy-build).

CondaForge

conda-forge recipes or feedstocks (meta.yaml / recipe.yaml).

Spack

Spack package tree (package.py files).

Cargo

Cargo.toml or crates.io JSON documents for crate / PyO3 leftovers.

Implementations

impl SourceRootKind

Functions

fn as_str(self) -> &'static str

The stable kebab-case name used in configuration and output.

Structs and Unions

struct DiscoveredCandidate

One discovered recipe candidate with enough identity for selection evidence.

name: String

Package name as the recipe declares it.

version: String

Version the recipe declares.

path: PathBuf

Recipe file this was read from.

kind: SourceRootKind

Which root it came from.

format: Option<ForeignFormat>

Foreign format, when the recipe is not an easyconfig.

toolchain: Option<Toolchain>

Toolchain the recipe targets, for an easyconfig.

versionsuffix: Option<String>

Versionsuffix, when the recipe carries one.

package_config: Vec<PathBuf>

Configuration layers to apply when this candidate is generated from.

source_checksums: Vec<String>

Positional source checksums the root supplies for this candidate.

struct PackageSourceIndex

Indexed view of all configured source roots for hole resolution.

Implementations

impl PackageSourceIndex

Functions

fn build(roots: &PackageSourceRoots) -> Result<Self, PackageSourceError>

Walk every configured root and index parseable package identities.

fn easybuild_candidates(&self) -> &[DiscoveredCandidate]

Candidates parsed from easyconfig roots.

fn foreign_candidates(&self) -> &[DiscoveredCandidate]

Candidates parsed from foreign-recipe roots.

fn parse_failures(&self) -> &[SourceParseFailure]

Recipes that could not be parsed, so a gap can be explained.

struct PackageSourceRoots

Layered ordered source roots (package-neutral public configuration).

schema_version: u32

Must equal PACKAGE_SOURCE_ROOTS_SCHEMA_VERSION.

source_roots: Vec<SourceRoot>

Roots searched for package sources, in order.

Implementations

impl PackageSourceRoots

Functions

fn extend_from(&mut self, other: &PackageSourceRoots)

Append roots from another layer; later roots retain later-list order.

fn from_path(path: &Path) -> Result<Self, PackageSourceError>

Parse source roots from a file, resolving relative paths against it.

fn from_toml_str(input: &str) -> Result<Self, PackageSourceError>

Parse source roots from TOML text.

fn is_empty(&self) -> bool

Whether any root is configured.

fn push(&mut self, kind: SourceRootKind, path: PathBuf)

Add a root with no configuration layers.

struct SourceParseFailure

A recipe that was found under a configured source root but could not be parsed. name is retained when it can be inferred without interpreting the invalid recipe, allowing lookup to distinguish relevant failures from unrelated syntax that appears elsewhere in a broad source tree.

name: Option<String>

Package name, when enough was parsed to learn it.

path: PathBuf

Recipe that failed to parse.

kind: SourceRootKind

Root it came from.

format: ForeignFormat

Format it was read as.

error: String

Why it failed. Kept so a missing provider can be explained by a parse failure rather than looking like an absent recipe.

struct SourceRoot

One ordered local root in a package-sources configuration.

kind: SourceRootKind

What kind of recipes this root holds.

path: PathBuf

Directory to walk.

package_config: Vec<PathBuf>

Package-neutral authoring layers applied to foreign recipes discovered under this root. This is where shared provider aliases and exclusions live; package-specific policy remains an explicit catalog override.