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