shadow_rs/lib.rs
1#![doc(html_logo_url = "https://raw.githubusercontent.com/baoyachi/shadow-rs/master/shadow-rs.png")]
2//! `shadow-rs`: Build-time information stored in your Rust project (binary, lib, cdylib, dylib).
3//!
4//! `shadow-rs` allows you to access properties of the build process and environment at runtime, including:
5//!
6//! * `Cargo.toml` information, such as the project version
7//! * Dependency information
8//! * Git information, such as the commit that produced the build artifact
9//! * What version of the Rust toolchain was used in compilation
10//! * The build variant, e.g. `debug` or `release`
11//! * ... And more!
12//!
13//! You can use this crate to programmatically check where a binary came from and how it was built.
14//!
15//! # Examples
16//! * Check out the [example_shadow](https://github.com/baoyachi/shadow-rs/tree/master/example_shadow) for a simple demonstration of how `shadow-rs` might be used to provide build-time information at run-time.
17//! * Check out the [example_shadow_hook](https://github.com/baoyachi/shadow-rs/tree/master/example_shadow_hook) for a demonstration of how custom hooks can be used to add extra information to `shadow-rs`'s output.
18//! * Check out the [`builtin_fn` example](https://github.com/baoyachi/shadow-rs/tree/master/examples/builtin_fn.rs) for a simple demonstration of the built-in functions that `shadow-rs` provides.
19//!
20//! # Setup
21//!
22//! ### 1) Modify `Cargo.toml` fields
23//! Modify your `Cargo.toml` like so:
24//!
25//! ```toml
26//! [package]
27//! build = "build.rs"
28//!
29//! [dependencies]
30//! shadow-rs = { version = "{latest version}", default-features = false }
31//!
32//! [build-dependencies]
33//! shadow-rs = "{latest version}"
34//! ```
35#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
36//!
37//! ### 2) Create `build.rs` file
38//! Now in the root of your project (same directory as `Cargo.toml`) add a file `build.rs`:
39//!
40//! ```ignore
41//! fn main() {
42//! ShadowBuilder::builder()
43//! .build_pattern(BuildPattern::RealTime)
44//! .build().unwrap();
45//! }
46//! ```
47//!
48//!
49//! ### 3) Integrate Shadow
50//! In your main Rust file (usually `main.rs` or `lib.rs`), add this:
51//!
52//! ```ignore
53//! use shadow_rs::shadow;
54//!
55//! shadow!(build);
56//! ```
57//!
58//! The `shadow!` macro uses the given identifier to create a module with that name.
59//!
60//! ### 4) Use Shadow Constants
61//! You can now use the module defined with `shadow!` to access build-time information.
62//!
63//! ```ignore
64//! fn main(){
65//! println!("debug:{}", shadow_rs::is_debug()); // check if this is a debug build. e.g 'true/false'
66//! println!("branch:{}", shadow_rs::branch()); // get current project branch. e.g 'master/develop'
67//! println!("tag:{}", shadow_rs::tag()); // get current project tag. e.g 'v1.3.5'
68//! println!("git_clean:{}", shadow_rs::git_clean()); // get current project clean. e.g 'true/false'
69//! println!("git_status_file:{}", shadow_rs::git_status_file()); // get current project statue file. e.g ' * examples/builtin_fn.rs (dirty)'
70//!
71//! println!("{}", build::VERSION); //print version const
72//! println!("{}", build::CLAP_LONG_VERSION); //print CLAP_LONG_VERSION const
73//! println!("{}", build::BRANCH); //master
74//! println!("{}", build::SHORT_COMMIT);//8405e28e
75//! println!("{}", build::COMMIT_HASH);//8405e28e64080a09525a6cf1b07c22fcaf71a5c5
76//! println!("{}", build::COMMIT_DATE);//2021-08-04 12:34:03 +00:00
77//! println!("{}", build::COMMIT_AUTHOR);//baoyachi
78//! println!("{}", build::COMMIT_EMAIL);//xxx@gmail.com
79//!
80//! println!("{}", build::BUILD_OS);//macos-x86_64
81//! println!("{}", build::RUST_VERSION);//rustc 1.45.0 (5c1f21c3b 2020-07-13)
82//! println!("{}", build::RUST_CHANNEL);//stable-x86_64-apple-darwin (default)
83//! println!("{}", build::CARGO_VERSION);//cargo 1.45.0 (744bd1fbb 2020-06-15)
84//! println!("{}", build::PKG_VERSION);//0.3.13
85//! println!("{}", build::CARGO_TREE); //like command:cargo tree
86//! println!("{}", build::CARGO_MANIFEST_DIR); // /User/baoyachi/shadow-rs/ |
87//!
88//! println!("{}", build::PROJECT_NAME);//shadow-rs
89//! println!("{}", build::BUILD_TIME);//2020-08-16 14:50:25
90//! println!("{}", build::BUILD_RUST_CHANNEL);//debug
91//! println!("{}", build::GIT_CLEAN);//false
92//! println!("{}", build::GIT_STATUS_FILE);//* src/lib.rs (dirty)
93//! }
94//! ```
95//!
96//! ## Clap
97//! You can also use `shadow-rs` to provide information to command-line interface crates such as [`clap`](https://docs.rs/clap/latest/clap/). An example of this can be found in [`example_shadow`](https://github.com/baoyachi/shadow-rs/blob/master/example_shadow/src/main.rs).
98//!
99//! For the user guide and further documentation, see the [README of `shadow-rs`](https://github.com/baoyachi/shadow-rs).
100//!
101//! # List of Generated Output Constants
102//!
103//! All constants produced by `shadow-rs` are documented in the module created with [`shadow!`], so `rustdoc` and your IDE will pick it up.
104//!
105//! ```
106//! pub const PKG_VERSION: &str = "1.3.8-beta3";
107//! pub const PKG_VERSION_MAJOR: &str = "1";
108//! pub const PKG_VERSION_MINOR: &str = "3";
109//! pub const PKG_VERSION_PATCH: &str = "8";
110//! pub const PKG_VERSION_PRE: &str = "beta3";
111//! pub const RUST_VERSION: &str = "rustc 1.45.0 (5c1f21c3b 2020-07-13)";
112//! pub const BUILD_RUST_CHANNEL: &str = "debug";
113//! pub const COMMIT_AUTHOR: &str = "baoyachi";
114//! pub const BUILD_TIME: &str = "2020-08-16 13:48:52";
115//! pub const BUILD_TIME_2822: &str = "Thu, 24 Jun 2021 21:44:14 +0800";
116//! pub const BUILD_TIME_3339: &str = "2021-06-24T15:53:55+08:00";
117//! pub const BUILD_TIMESTAMP: i64 = 1624548839;
118//! pub const COMMIT_DATE: &str = "2021-08-04 12:34:03 +00:00";
119//! pub const COMMIT_DATE_2822: &str = "Thu, 24 Jun 2021 21:44:14 +0800";
120//! pub const COMMIT_DATE_3339: &str = "2021-06-24T21:44:14.473058+08:00";
121//! pub const COMMIT_TIMESTAMP: i64 = 1624548854;
122//! pub const COMMIT_EMAIL: &str = "xxx@gmail.com";
123//! pub const PROJECT_NAME: &str = "shadow-rs";
124//! pub const RUST_CHANNEL: &str = "stable-x86_64-apple-darwin (default)";
125//! pub const BRANCH: &str = "master";
126//! pub const CARGO_LOCK: &str = r#"
127//! ├── chrono v0.4.19
128//! │ ├── libc v0.2.80
129//! │ ├── num-integer v0.1.44
130//! │ │ └── num-traits v0.2.14
131//! │ │ [build-dependencies]
132//! │ │ └── autocfg v1.0.1
133//! │ ├── num-traits v0.2.14 (*)
134//! │ └── time v0.1.44
135//! │ └── libc v0.2.80
136//! └── git2 v0.13.12
137//! ├── log v0.4.11
138//! │ └── cfg-if v0.1.10
139//! └── url v2.2.0
140//! ├── form_urlencoded v1.0.0
141//! │ └── percent-encoding v2.1.0
142//! └── percent-encoding v2.1.0"#;
143//! pub const CARGO_VERSION: &str = "cargo 1.45.0 (744bd1fbb 2020-06-15)";
144//! pub const BUILD_OS: &str = "macos-x86_64";
145//! pub const COMMIT_HASH: &str = "386741540d73c194a3028b96b92fdeb53ca2788a";
146//! pub const GIT_CLEAN: bool = true;
147//! pub const GIT_STATUS_FILE: &str = "* src/lib.rs (dirty)";
148//! ```
149//!
150
151#![cfg_attr(not(feature = "std"), no_std)]
152
153#[cfg(feature = "metadata")]
154pub extern crate cargo_metadata;
155#[cfg(feature = "metadata")]
156pub extern crate serde_json;
157
158#[cfg(feature = "build")]
159mod build;
160#[cfg(feature = "build")]
161mod ci;
162#[cfg(feature = "build")]
163mod date_time;
164#[cfg(feature = "build")]
165mod env;
166#[cfg(feature = "build")]
167mod err;
168#[cfg(feature = "build")]
169mod gen_const;
170#[cfg(feature = "build")]
171mod git;
172#[cfg(feature = "build")]
173mod hook;
174#[cfg(feature = "build")]
175mod shadow;
176
177/// Re-exported from the const_format crate
178pub use const_format::*;
179/// Re-exported from the is_debug crate
180pub use is_debug::*;
181
182#[cfg(feature = "build")]
183mod pub_export {
184 pub use crate::build::{BuildPattern, ShadowBuilder};
185 pub use crate::date_time::DateTime;
186 pub use crate::err::{SdResult, ShadowError};
187 pub use crate::shadow::Shadow;
188 pub use {crate::build::default_deny, crate::build::ShadowConst, crate::env::*, crate::git::*};
189
190 pub trait Format {
191 fn human_format(&self) -> String;
192 }
193}
194
195#[cfg(feature = "build")]
196pub use pub_export::*;
197
198pub const CARGO_CLIPPY_ALLOW_ALL: &str =
199 "#[allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]";
200
201/// Add a module with the provided name which contains the build information generated by `shadow-rs`.
202///
203/// # Example
204///
205/// ```ignore
206/// use shadow_rs::shadow;
207///
208/// shadow!(my_build_information);
209///
210/// fn main() {
211/// println!("I'm version {}!", my_build_information::VERSION);
212/// }
213/// ```
214///
215/// The convention, however, is to use `shadow!(build);`.
216#[macro_export]
217macro_rules! shadow {
218 ($build_mod:ident) => {
219 #[doc = r#"shadow-rs mod"#]
220 pub mod $build_mod {
221 include!(concat!(env!("OUT_DIR"), "/shadow.rs"));
222 }
223 };
224}