Skip to main content

PackageGraph

Struct PackageGraph 

Source
pub struct PackageGraph {
    pub root_manifest_path: PathBuf,
    pub root_dir: PathBuf,
    pub is_workspace_root: bool,
    pub root_package: Option<usize>,
    pub root_settings: RootSettings,
    pub primary_packages: Vec<usize>,
    pub default_members: Vec<usize>,
    pub excluded_members: Vec<PathBuf>,
    pub packages: Vec<WorkspacePackage>,
}
Expand description

A loaded set of local Cabin packages with their dependency edges resolved against the local filesystem.

Packages appear in topological order: a package’s local dependencies always appear before the package itself in PackageGraph::packages.

Fields§

§root_manifest_path: PathBuf

Path to the manifest the user passed (canonicalized to absolute).

§root_dir: PathBuf

Directory containing the root manifest.

§is_workspace_root: bool

Whether the root manifest declares a [workspace] table.

§root_package: Option<usize>

If the root manifest itself is a package (i.e. has a [package] table), the index of that package in PackageGraph::packages.

§root_settings: RootSettings

Root-manifest policy settings. For package roots this mirrors the root package’s root-owned fields; for pure workspace roots this is the only place those settings are exposed.

§primary_packages: Vec<usize>

Indices of packages that count as “primary” - i.e. would be built when no narrower package selection is given.

For a single package this is the root. For a workspace root it is every member declared by [workspace.members]. Path dependencies pulled in transitively are not primary.

§default_members: Vec<usize>

Indices of packages listed under [workspace.default-members], validated to be members. Empty when the workspace declares no defaults - callers fall back to the documented “all members” behavior. Always a subset of primary_packages.

§excluded_members: Vec<PathBuf>

Relative paths under root_dir for any directories dropped by [workspace.exclude]. Carried through purely for metadata reporting; the loader has already removed them from primary_packages.

§packages: Vec<WorkspacePackage>

All loaded packages, in topological order.

Implementations§

Source§

impl PackageGraph

Source

pub fn package_by_name(&self, name: &str) -> Option<&WorkspacePackage>

Find a package by name. Linear scan; package counts are small.

Source

pub fn index_of(&self, name: &str) -> Option<usize>

Index of a package by name. Returned together with the reference for callers that need to record edges by index.

Source

pub fn consumer_standards( &self, members: &BTreeSet<usize>, primary: &[usize], enabled_features: &HashMap<usize, BTreeSet<String>>, dev_for: &BTreeSet<String>, ) -> ConsumerStandards

The consumer standards for standard-aware version preference (docs/design/standard-compatibility/preference-mode.md section 1): per language, the minimum effective implementation standard (spec D6 impl_L) across the targets of members that implement it. None for a language none of them compiles - it then imposes nothing on candidate ordering.

members must be the package set the resolve is actually for - the selected closure (ResolvedSelection::closure), not the whole graph - so an unselected member never lowers the consumer standard for a scoped resolve. Within each member the targets this invocation can build count: default-buildable kinds always, plus dev-only (test / example) targets for packages named in dev_for (the set whose [dev-dependencies] this invocation activates, e.g. cabin test), and in both cases only when their required-features are satisfied by enabled_features (keyed by package index). A target gated behind an unenabled feature, or a test / example under a plain cabin build, does not lower the consumer standard. Dev-only targets are counted whenever dev_for activates them, without a per-target reachability walk - the same conservative over-approximation applied to a path dependency’s libraries (below): it can only prefer an older, more broadly compatible version, never lock one a built target (such as an example a selected target references in deps) cannot consume.

The set is deliberately every default-buildable (plus dev_for) target of the selected packages, not the single target a --bin / --example / test-name narrows a later build to. cabin.lock is shared per project, so its versions must suit every target cabin build compiles; scoping resolution to one run/test target would under-constrain the shared lock for its siblings. Which target is finally compiled is a build-time decision, downstream of resolution.

This is the Cargo-style workspace-level approximation used during a partial solve: exactness is not required because the post-resolution validation remains the correctness authority.

primary is the originally selected package set (ResolvedSelection::packages), a subset of members: members also holds the transitive path-dependency packages the closure pulls in. A path dependency is built only for the library targets its consumers link, never for its own executables/tests, so a non-primary member counts only its archive-producing (library) targets. Whether each such library is in turn reachable (linked by a consumer target) is deliberately not computed here: that per-target build-graph walk is the planner’s post-resolution job, and counting a path dependency’s archive targets is a conservative over-approximation in the safe direction - it can only prefer an older, more broadly compatible version, never cause a wrong build.

This extends to a path dependency reached only through a feature-disabled optional edge: the loader records optional path edges unconditionally (only disabled optional registry deps are pruned), and this walk does no package-level feature-reachability pruning of members. That is deliberate and equally safe - each added member contributes only to the per-language min, which extra targets can lower but never raise, so an unbuilt optional dependency can at most prefer an older, more broadly compatible version. Pruning it would only ever raise the preferred version and never changes solvability, so it is left to the planner.

Trait Implementations§

Source§

impl Clone for PackageGraph

Source§

fn clone(&self) -> PackageGraph

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PackageGraph

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for PackageGraph

Source§

impl PartialEq for PackageGraph

Source§

fn eq(&self, other: &PackageGraph) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for PackageGraph

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V