Struct krates::Builder

source ·
pub struct Builder { /* private fields */ }
Expand description

A builder used to create a Krates graph, either by running a cargo metadata command, or using an already deserialized cargo_metadata::Metadata

Implementations§

source§

impl Builder

source

pub fn new() -> Self

source

pub fn ignore_kind(&mut self, kind: DepKind, scope: Scope) -> &mut Self

Ignores a specific dependency kind in the given scope.

Builder::new().ignore_kind(DepKind::Build, Scope::NonWorkspace);

In the above example, let’s say we depended on zstd. zstd depends on the cc crate (zstd -> zstd-safe -> zstd-sys -> cc) for building C code. By ignoring the build kind for non-workspace crates, the link from zstd-sys -> cc will be filtered out. If the same cc is not depended on by a crate in the workspace, cc will not end up in the final Krates graph.

Note that ignoring DepKind::Dev for Scope::NonWorkspace is meaningless as dev dependencies are not resolved by cargo for transitive dependencies.

source

pub fn workspace(&mut self, workspace: bool) -> &mut Self

By default, the response from cargo metadata determines what the root(s) of the crate graph will be. If the Cargo.toml path used is a virtual manifest, then each workspace member will be used as a root. If the manifest path is for a single crate, or a non-virtual manifest inside a workspace, then only that single crate will be used as the root, and in the workspace case, only other workspace members that are dependencies of that root crate, directly or indirectly, will be included in the final graph.

Setting workspace = true will change that default behavior, and instead include all workspace crates (unless they are filtered via other methods) even if the manifest path is not a virtual manifest inside a workspace

Builder::new().workspace(true);
source

pub fn exclude<I>(&mut self, exclude: I) -> &mut Self
where I: IntoIterator<Item = PkgSpec>,

Package specification(s) to exclude from the final graph. Unlike with cargo, each exclusion spec can apply to more than 1 instance of a package, eg if multiple crates are sourced from the same url, or multiple versions of the same crate

Builder::new().exclude(["a-crate:0.1.0"].iter().map(|spec| spec.parse().unwrap()));
source

pub fn include_workspace_crates<P, I>(&mut self, crates: I) -> &mut Self
where P: AsRef<Path>, I: IntoIterator<Item = P>,

By default, every workspace crate is treated as a root node and implicitly added to the graph if the graph is built from a workspace context and not a specific crate in the workspace.

By using this method, only the workspace crates whose Cargo.toml path matches one of the specified crates will be added as root nodes, meaning that any workspace crate not in the list that doesn’t have any dependendents on a workspace crate that does, will no longer appear in the graph.

If you specify only a single path, and that path is actually to a a workspace’s virtual manifest, the graph will be the same as if Builder::include_workspace_crates was not specified.

Builder::new().include_workspace_crates(&["path/to/some/crate"]);
source

pub fn include_targets<S: Into<Target>>( &mut self, targets: impl IntoIterator<Item = (S, Vec<String>)> ) -> &mut Self

By default, cargo resolves all target specific dependencies. Optionally, you can use the --filter-platform option on cargo metadata to resolve only dependencies that match the specified target, but it can only do this for one platlform.

By using this method, you can specify one or more targets by their triple, as well as any target_features that you promise are enabled for that target to filter dependencies by. If any of the specified targets matches a target specific dependency, it will be included in the graph.

When specifying a target triple, only builtin targets of rustc can be used to evaluate cfg() expressions. If the triple is not recognized, it will only be evaluated against [target.<triple-or-json>.<|build-|dev->dependencies].

let targets = [
    // the big 3
    "x86_64-unknown-linux-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-apple-darwin",
    // and musl!
    "x86_64-unknown-linux-musl",
    // and wasm (with the fancy atomics feature!)
    "wasm32-unknown-unknown",
];

Builder::new().include_targets(targets.iter().map(|triple| {
    if triple.starts_with("wasm32") {
        (*triple, vec!["atomics".to_owned()])
    } else {
        (*triple, vec![])
    }
}));
source

pub fn with_crates_io_index( &mut self, index_cache_build: BuildIndexCache ) -> &mut Self

Configures the index implementation

This method allows overriding the location of your CARGO_HOME, but note that no fetching from the remote index is performed by this library, so it is your responsibility to have called cargo fetch or similar to have an up to date index cache at the location provided

This method takes into account the local environment to open the correct crates.io registry, or replacement registry if the user has configured that

You can force the usage of the git registry (if not overridden in the local environment) by specifying Some("1.69.0") or lower semver as the sparse registry was not made the default until 1.70.0

source

pub fn build<N, E, F>( self, cmd: impl Into<MetadataCommand>, on_filter: F ) -> Result<Krates<N, E>, Error>
where N: From<Package>, E: From<Edge>, F: OnFilter,

Builds a Krates graph using metadata that be retrieved via the specified metadata command. If on_filter is specified, it will be called with each package that was filtered from the graph, if any.

This method will fail if the metadata command fails for some reason, or if the command specifies --no-deps which means there will be no resolution graph to build our graph from.

let mut mdc = krates::Cmd::new();
mdc.manifest_path("path/to/Cargo.toml");

if /*no_default_features*/ true {
    mdc.no_default_features();
}

if /*cfg.all_features*/ false {
    mdc.all_features();
}

mdc.features(
    ["cool-feature", "cooler-feature", "coolest-feature"]
        .iter()
        .map(|s| s.to_string()),
);

let mut builder = krates::Builder::new();

if /*cfg.ignore_build_dependencies*/ false {
    builder.ignore_kind(krates::DepKind::Build, krates::Scope::All);
}

if /*cfg.ignore_dev_dependencies*/ true {
    builder.ignore_kind(krates::DepKind::Dev, krates::Scope::All);
}

let graph: krates::Krates = builder.build(
    mdc,
    |filtered: Package| match filtered.source {
        Some(src) => {
            if src.is_crates_io() {
                println!("filtered {} {}", filtered.name, filtered.version);
            } else {
                println!("filtered {} {} {}", filtered.name, filtered.version, src);
            }
        }
        None => println!("filtered crate {} {}", filtered.name, filtered.version),
    },
).unwrap();
source

pub fn build_with_metadata<N, E, F>( self, md: Metadata, on_filter: F ) -> Result<Krates<N, E>, Error>
where N: From<Package>, E: From<Edge>, F: OnFilter,

Builds a Krates graph using the specified metadata. If on_filter is specified, it will be called with each package that was filtered from the graph, if any.

The metadata must have resolved dependencies for the graph to be built, so not having it is the only way this method will fail.

let contents = std::fs::read_to_string("metadata.json")
    .map_err(|e| format!("failed to load metadata file: {}", e)).unwrap();

let md: krates::cm::Metadata = serde_json::from_str(&contents)
    .map_err(|e| format!("failed to deserialize metadata: {}", e)).unwrap();

let krates: Krates = Builder::new().build_with_metadata(
    md,
    |pkg: Package| println!("filtered {}", pkg.id)
).unwrap();

println!("found {} unique crates", krates.len());

Trait Implementations§

source§

impl Default for Builder

source§

fn default() -> Builder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Builder

§

impl !RefUnwindSafe for Builder

§

impl !Send for Builder

§

impl !Sync for Builder

§

impl Unpin for Builder

§

impl !UnwindSafe for Builder

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> 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, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.