Skip to main content

guppy_summaries/
lib.rs

1// Copyright (c) The cargo-guppy Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Facilities to serialize, deserialize and compare build summaries.
5//!
6//! A *build summary* is a record of what packages and features are built on the target and host
7//! platforms. A summary file can be checked into a repository, kept up to date and compared in CI,
8//! and allow for tracking results of builds over time.
9//!
10//! `guppy-summaries` is designed to be small and independent of the main `guppy` crate.
11//!
12//! # Examples
13//!
14//! ```rust
15//! use guppy_summaries::{Summary, SummaryId, SummarySource, PackageStatus};
16//! use pretty_assertions::assert_eq;
17//! use semver::Version;
18//! use std::collections::BTreeSet;
19//!
20//! // A summary is a TOML file that has this format:
21//! static SUMMARY: &str = r#"
22//! [[target-package]]
23//! name = "foo"
24//! version = "1.2.3"
25//! workspace-path = "foo"
26//! status = 'initial'
27//! features = ["feature-a", "feature-c"]
28//!
29//! [[host-package]]
30//! name = "proc-macro"
31//! version = "0.1.2"
32//! workspace-path = "proc-macros/macro"
33//! status = 'workspace'
34//! features = ["macro-expand"]
35//!
36//! [[host-package]]
37//! name = "bar"
38//! version = "0.4.5"
39//! crates-io = true
40//! status = 'direct'
41//! features = []
42//! "#;
43//!
44//! // The summary can be deserialized:
45//! let summary = Summary::parse(SUMMARY).expect("from_str succeeded");
46//!
47//! // ... and a package and its features can be looked up.
48//! let summary_id = SummaryId::new("foo", Version::new(1, 2, 3), SummarySource::workspace("foo"));
49//! let info = &summary.target_packages[&summary_id];
50//! assert_eq!(info.status, PackageStatus::Initial, "correct status");
51//! assert_eq!(
52//!     info.features.iter().map(|feature| feature.as_str()).collect::<Vec<_>>(),
53//!     ["feature-a", "feature-c"],
54//!     "correct feature list"
55//! );
56//!
57//! // Another summary.
58//! static SUMMARY2: &str = r#"
59//! [[target-package]]
60//! name = "foo"
61//! version = "1.2.4"
62//! workspace-path = "new-location/foo"
63//! status = 'initial'
64//! features = ["feature-a", "feature-b"]
65//!
66//! [[target-package]]
67//! name = "once_cell"
68//! version = "1.4.0"
69//! source = "git+https://github.com/matklad/once_cell?tag=v1.4.0"
70//! status = 'transitive'
71//! features = ["std"]
72//!
73//! [[host-package]]
74//! name = "bar"
75//! version = "0.4.5"
76//! crates-io = true
77//! status = 'direct'
78//! features = []
79//! "#;
80//!
81//! let summary2 = Summary::parse(SUMMARY2).expect("from_str succeeded");
82//!
83//! // Diff summary and summary2.
84//! let diff = summary.diff(&summary2);
85//!
86//! // Pretty-print a report generated from the diff.
87//! let diff_str = format!("{}", diff.report());
88//! assert_eq!(
89//!     r#"target packages:
90//!   A once_cell 1.4.0 (transitive third-party, external 'git+https://github.com/matklad/once_cell?tag=v1.4.0')
91//!     * features: std
92//!   M foo 1.2.4 (initial, path 'new-location/foo')
93//!     * version upgraded from 1.2.3
94//!     * source changed from path 'foo'
95//!     * added features: feature-b
96//!     * removed features: feature-c
97//!     * (unchanged features: feature-a)
98//!     * (unchanged optional dependencies: [none])
99//!
100//! host packages:
101//!   R proc-macro 0.1.2 (workspace, path 'proc-macros/macro')
102//!     * (old features: macro-expand)
103//!
104//! "#,
105//!     diff_str,
106//! );
107//! ```
108
109#![forbid(unsafe_code)]
110#![warn(missing_docs)]
111
112pub mod diff;
113// report::SummaryReport is exported through the diff module.
114mod report;
115mod summary;
116pub mod toml_compat;
117#[cfg(test)]
118mod unit_tests;
119
120pub use summary::*;