guppy/lib.rs
1// Copyright (c) The cargo-guppy Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Track and query Cargo dependency graphs.
5//!
6//! `guppy` provides a Rust interface to run queries over Cargo dependency graphs. `guppy` parses
7//! the output of [`cargo metadata`](https://doc.rust-lang.org/cargo/commands/cargo-metadata.html),
8//! then presents a graph interface over it.
9//!
10//! # Types and lifetimes
11//!
12//! The central structure exposed by `guppy` is [`PackageGraph`](crate::graph::PackageGraph). This
13//! represents a directed (though [not necessarily acyclic](crate::graph::Cycles)) graph where every
14//! node is a package and every edge represents a dependency.
15//!
16//! Other types borrow data from a `PackageGraph` and have a `'g` lifetime parameter indicating
17//! that. A lifetime parameter named `'g` always indicates that data is borrowed from a
18//! `PackageGraph`.
19//!
20//! [`PackageMetadata`](crate::graph::PackageMetadata) contains information about individual
21//! packages, such as the data in
22//! [the `[package]` section](https://doc.rust-lang.org/cargo/reference/manifest.html#the-package-section).
23//!
24//! For traversing the graph, `guppy` provides a few types:
25//! * [`PackageLink`](crate::graph::PackageLink) represents both ends of a dependency edge, along
26//! with details about the dependency (whether it is dev-only, platform-specific, and so on).
27//! * [`PackageQuery`](crate::graph::PackageQuery) represents the input parameters to a dependency
28//! traversal: a set of packages and a direction. A traversal is performed with
29//! [`PackageQuery::resolve`](crate::graph::PackageQuery::resolve), and fine-grained control over
30//! the traversal is achieved with
31//! [`PackageQuery::resolve_with_fn`](crate::graph::PackageQuery::resolve_with_fn).
32//! * [`PackageSet`](crate::graph::PackageSet) represents the result of a graph traversal. This
33//! struct provides several methods to iterate over packages.
34//!
35//! For some operations, `guppy` builds an auxiliary [`FeatureGraph`](crate::graph::feature::FeatureGraph)
36//! the first time it is required. Every node in a `FeatureGraph` is a combination of a package and
37//! a feature declared in it, and every edge is a feature dependency.
38//!
39//! For traversing the feature graph, `guppy` provides the analogous [`FeatureQuery`](crate::graph::feature::FeatureQuery) and
40//! [`FeatureSet`](crate::graph::feature::FeatureSet) types.
41//!
42//! `FeatureSet` also has an [`into_cargo_set`](crate::graph::feature::FeatureSet::into_cargo_set)
43//! method, to simulate Cargo builds. This method produces a [`CargoSet`](crate::graph::cargo::CargoSet),
44//! which is essentially two `FeatureSet`s along with some more useful information.
45//!
46//! `guppy`'s data structures are immutable, with some internal caches. All of `guppy`'s types are
47//! `Send + Sync`, and all lifetime parameters are [covariant](https://github.com/sunshowers/lifetime-variance-example/).
48//!
49//! # Optional features
50//!
51//! * `custom-cfg-platforms`: Support for custom platforms defined by
52//! `rustc --print=cfg` output, through `Platform::new_custom_cfg`.
53//! * `custom-platforms`: Support for custom platforms defined by a
54//! [target specification JSON](https://doc.rust-lang.org/rustc/targets/custom.html)
55//! file, through `Platform::new_custom`. Implies `custom-cfg-platforms`.
56//! * `proptest1`: Support for [property-based testing](https://jessitron.com/2013/04/25/property-based-testing-what-is-it/)
57//! using the [`proptest`](https://altsysrq.github.io/proptest-book/intro.html) framework.
58//! * `rayon1`: Support for parallel iterators through [Rayon](docs.rs/rayon/1) (preliminary work
59//! so far, more parallel iterators to be added in the future).
60//! * `summaries`: Support for writing out [build summaries](https://github.com/guppy-rs/guppy/tree/main/guppy-summaries).
61//!
62//! # Examples
63//!
64//! Print out all direct dependencies of a package:
65//!
66//! ```
67//! use guppy::{CargoMetadata, PackageId};
68//!
69//! // `guppy` accepts `cargo metadata` JSON output. Use a pre-existing fixture for these examples.
70//! let metadata = CargoMetadata::parse_json(include_str!("../../fixtures/small/metadata1.json")).unwrap();
71//! let package_graph = metadata.build_graph().unwrap();
72//!
73//! // `guppy` provides several ways to get hold of package IDs. Use a pre-defined one for this
74//! // example.
75//! let package_id = PackageId::new("testcrate 0.1.0 (path+file:///fakepath/testcrate)");
76//!
77//! // The `metadata` method returns information about the package, or `None` if the package ID
78//! // wasn't recognized.
79//! let package = package_graph.metadata(&package_id).unwrap();
80//!
81//! // `direct_links` returns all direct dependencies of a package.
82//! for link in package.direct_links() {
83//! // A dependency link contains `from()`, `to()` and information about the specifics of the
84//! // dependency.
85//! println!("direct dependency: {}", link.to().id());
86//! }
87//! ```
88//!
89//! For more examples, see
90//! [the `examples` directory](https://github.com/guppy-rs/guppy/tree/main/guppy/examples).
91
92#![warn(missing_docs)]
93#![cfg_attr(doc_cfg, feature(doc_cfg))]
94
95#[macro_use]
96mod macros;
97
98mod dependency_kind;
99pub mod errors;
100pub mod graph;
101mod metadata_command;
102mod package_id;
103pub(crate) mod petgraph_support;
104pub mod platform;
105pub(crate) mod sorted_set;
106#[cfg(test)]
107mod unit_tests;
108
109pub use dependency_kind::*;
110pub use errors::Error;
111pub use metadata_command::*;
112pub use package_id::PackageId;
113
114// Public re-exports for upstream crates used in APIs. The no_inline ensures that they show up as
115// re-exports in documentation.
116#[doc(no_inline)]
117pub use semver::{Version, VersionReq};
118#[doc(no_inline)]
119pub use serde_json::Value as JsonValue;