Skip to main content

battery_pack/
lib.rs

1//! battery-pack: Framework for building and using battery packs.
2//!
3//! Battery packs are curated collections of crates that work well together.
4//! The CLI (`cargo bp`) syncs real dependencies into your Cargo.toml,
5//! and this library provides build-time documentation generation and
6//! drift validation.
7//!
8//! # For Battery Pack Authors
9//!
10//! Your `build.rs` generates documentation:
11//!
12//! ```rust,ignore
13//! fn main() {
14//!     battery_pack::build::generate_docs().unwrap();
15//! }
16//! ```
17//!
18//! Your `lib.rs` includes the generated docs:
19//!
20//! ```rust,ignore
21//! #![doc = include_str!(concat!(env!("OUT_DIR"), "/docs.md"))]
22//! ```
23
24pub use bphelper_manifest::{BatteryPackSpec, CrateSpec, DepKind};
25
26/// Build-time documentation generation.
27///
28/// Use from your battery pack's `build.rs`:
29///
30/// ```rust,ignore
31/// fn main() {
32///     battery_pack::build::generate_docs().unwrap();
33/// }
34/// ```
35///
36/// See the [docgen spec](https://battery-pack-rs.github.io/battery-pack/spec/docgen.html)
37/// for details on templates and helpers.
38#[cfg(feature = "build")]
39pub mod build {
40    pub use bphelper_build::{
41        CrateEntry, DocsContext, Error, FeatureEntry, PackageInfo, build_context, generate_docs,
42        render_docs,
43    };
44}
45
46/// Validate that the calling crate's dependencies match a battery pack's specs.
47///
48/// Call this from your battery pack's `validate()` function, passing
49/// the embedded manifest string. This reads the user's Cargo.toml via
50/// the runtime `CARGO_MANIFEST_DIR` env var (which, in build.rs, points
51/// to the user's crate) and compares against the battery pack specs.
52///
53/// Emits `cargo:warning` messages for any drift. Never fails the build.
54pub fn validate(self_manifest: &str) {
55    let _bp_spec = match bphelper_manifest::parse_battery_pack(self_manifest) {
56        Ok(spec) => spec,
57        Err(e) => {
58            println!("cargo:warning=battery-pack: failed to parse battery pack manifest: {e}");
59            return;
60        }
61    };
62
63    let user_toml_path = match std::env::var("CARGO_MANIFEST_DIR") {
64        Ok(dir) => format!("{dir}/Cargo.toml"),
65        Err(_) => {
66            println!("cargo:warning=battery-pack: CARGO_MANIFEST_DIR not set, skipping validation");
67            return;
68        }
69    };
70
71    // TODO: implement drift detection against user's Cargo.toml
72    // For now, just ensure we rerun when the user's manifest changes.
73    println!("cargo:rerun-if-changed={user_toml_path}");
74}
75
76/// Test utilities for battery pack authors.
77///
78/// In your `src/lib.rs`:
79///
80/// ```rust,ignore
81/// #[cfg(test)]
82/// mod tests {
83///     #[test]
84///     fn validate_templates() {
85///         battery_pack::testing::validate_templates(env!("CARGO_MANIFEST_DIR")).unwrap();
86///     }
87/// }
88/// ```
89#[cfg(feature = "cli")]
90pub mod testing {
91    pub use bphelper_cli::validate_templates;
92}
93
94#[cfg(test)]
95mod tests {
96    #[test]
97    #[cfg(feature = "cli")]
98    fn validate_templates() {
99        battery_pack::testing::validate_templates(env!("CARGO_MANIFEST_DIR")).unwrap();
100    }
101}