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//! * `proptest1`: Support for [property-based testing](https://jessitron.com/2013/04/25/property-based-testing-what-is-it/)
52//! using the [`proptest`](https://altsysrq.github.io/proptest-book/intro.html) framework.
53//! * `rayon1`: Support for parallel iterators through [Rayon](docs.rs/rayon/1) (preliminary work
54//! so far, more parallel iterators to be added in the future).
55//! * `summaries`: Support for writing out [build summaries](https://github.com/guppy-rs/guppy/tree/main/guppy-summaries).
56//!
57//! # Examples
58//!
59//! Print out all direct dependencies of a package:
60//!
61//! ```
62//! use guppy::{CargoMetadata, PackageId};
63//!
64//! // `guppy` accepts `cargo metadata` JSON output. Use a pre-existing fixture for these examples.
65//! let metadata = CargoMetadata::parse_json(include_str!("../../fixtures/small/metadata1.json")).unwrap();
66//! let package_graph = metadata.build_graph().unwrap();
67//!
68//! // `guppy` provides several ways to get hold of package IDs. Use a pre-defined one for this
69//! // example.
70//! let package_id = PackageId::new("testcrate 0.1.0 (path+file:///fakepath/testcrate)");
71//!
72//! // The `metadata` method returns information about the package, or `None` if the package ID
73//! // wasn't recognized.
74//! let package = package_graph.metadata(&package_id).unwrap();
75//!
76//! // `direct_links` returns all direct dependencies of a package.
77//! for link in package.direct_links() {
78//! // A dependency link contains `from()`, `to()` and information about the specifics of the
79//! // dependency.
80//! println!("direct dependency: {}", link.to().id());
81//! }
82//! ```
83//!
84//! For more examples, see
85//! [the `examples` directory](https://github.com/guppy-rs/guppy/tree/main/guppy/examples).
86
87#![warn(missing_docs)]
88#![cfg_attr(doc_cfg, feature(doc_cfg, doc_auto_cfg))]
89
90#[macro_use]
91mod macros;
92
93// TODO: remove in the next major version of guppy
94#[doc(hidden)]
95pub use debug_ignore;
96mod dependency_kind;
97pub mod errors;
98pub mod graph;
99mod metadata_command;
100mod package_id;
101pub(crate) mod petgraph_support;
102pub mod platform;
103pub(crate) mod sorted_set;
104#[cfg(test)]
105mod unit_tests;
106
107pub use dependency_kind::*;
108pub use errors::Error;
109pub use metadata_command::*;
110pub use package_id::PackageId;
111
112// Public re-exports for upstream crates used in APIs. The no_inline ensures that they show up as
113// re-exports in documentation.
114#[doc(no_inline)]
115pub use semver::{Version, VersionReq};
116#[doc(no_inline)]
117pub use serde_json::Value as JsonValue;