diff --git a/README.md b/README.md
index 707e6d1..5e4e771 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[shadow-rs][docsrs]: build-time information stored in your rust project. (binary, lib, cdylib and dylib)
+[`shadow-rs`][docsrs]: Build-time information stored in your Rust project (binary, lib, cdylib, dylib).
========================================
The build.rs **is not rebuilt** every-time if the repository has been history builld.
-> The recommended way is to run `cargo clean` first, then execute `cargo build`, or use a CI/CD pipeline tool to help
-> you
-> perform this operation.
-> For more details, see https://github.com/baoyachi/shadow-rs/issues/95.
+`shadow-rs` build information **is not always rebuilt** when you build a project. `shadow-rs` outputs several hints to Cargo in order to force rebuilds when required, but this does not always work. You can enforce up-to-date build information by running `cargo clean` before the build, or use a CI/CD pipeline tool. For more details, see .
-# Full Examples
+# Examples
-* 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.
-* Check out the [example_shadow_hook](https://github.com/baoyachi/shadow-rs/tree/master/example_shadow_hook) for a
- simple demonstration of how `shadow-rs` might be used to provide build-time information at run-time and add a custom
- hook.
-* Built-in function:[examples](https://github.com/baoyachi/shadow-rs/tree/master/examples).
+* 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.
+* 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.
+* 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.
-# Setup Guide
+# Setup
### 1) Modify `Cargo.toml` fields
-
Modify your `Cargo.toml` like so:
-```TOML
+```toml
[package]
build = "build.rs"
@@ -67,21 +57,18 @@ shadow-rs = "{latest version}"
```
### 2) Create `build.rs` file
-
Now in the root of your project (same directory as `Cargo.toml`) add a file `build.rs`:
-* with add custom `const` or `fn`
- see:[example_shadow_hook](https://github.com/baoyachi/shadow-rs/blob/master/example_shadow_hook/build.rs)
-
```rust
fn main() -> shadow_rs::SdResult<()> {
shadow_rs::new()
}
```
-### 3) Integrate shadow
+If you want to exclude some build constants, you can use [`new_deny`] instead of [`new`].
-In your rust file (e.g. `*.rs`):
+### 3) Integrate Shadow
+In your main Rust file (usually `main.rs` or `lib.rs`), add this:
```rust
use shadow_rs::shadow;
@@ -89,56 +76,41 @@ use shadow_rs::shadow;
shadow!(build);
```
-**Notice that the `shadow!` macro is provided the identifier `build`. You can now use this identifier to access
-build-time information.**
+The `shadow!` macro uses the given identifier to create a module with that name.
-### 4) Done. Use shadow.
+### 4) Use Shadow Constants
+You can now use the module defined with `shadow!` to access build-time information.
```rust
-fn main() {
-
- //shadow-rs built in function
+fn main(){
println!("debug:{}", shadow_rs::is_debug()); // check if this is a debug build. e.g 'true/false'
println!("branch:{}", shadow_rs::branch()); // get current project branch. e.g 'master/develop'
println!("tag:{}", shadow_rs::tag()); // get current project tag. e.g 'v1.3.5'
println!("git_clean:{}", shadow_rs::git_clean()); // get current project clean. e.g 'true/false'
println!("git_status_file:{}", shadow_rs::git_status_file()); // get current project statue file. e.g ' * examples/builtin_fn.rs (dirty)'
- //shadow-rs built in const
- println!("{}", build::VERSION); // the version (description binary detail information)
- println!("{}", build::CLAP_LONG_VERSION); // usually used by clap crates version() (description binary detail information)
- println!("{}", build::PKG_VERSION); // current package version. e.g. '1.3.15-beta2'
- println!("{}", build::PKG_VERSION_MAJOR); //current package major version. e.g. '1'
- println!("{}", build::PKG_VERSION_MINOR); //current package minor version. e.g. '3'
- println!("{}", build::PKG_VERSION_PATCH); //current package minor version. e.g. '15'
- println!("{}", build::PKG_VERSION_PRE); //current package minor version. e.g. 'beta2'
- println!("{}", build::BRANCH); // the branch, e.g. 'master'
- println!("{}", build::TAG); // the tag, e.g. 'v1.0.0'
- println!("{}", build::SHORT_COMMIT); // short commit hash, e.g. '8405e28e'
- println!("{}", build::COMMIT_HASH); // full commit hash, e.g. '8405e28e64080a09525a6cf1b07c22fcaf71a5c5'
- println!("{}", build::COMMIT_DATE); // commit date, e.g. '2021-08-04 12:34:03 +00:00'
- println!("{}", build::COMMIT_DATE_2822); // commit date, e.g. 'Thu, 24 Jun 2021 21:33:59 +0800'
- println!("{}", build::COMMIT_DATE_3339); // commit date, e.g. '2021-06-24T21:33:59.972494+08:00'
- println!("{}", build::COMMIT_AUTHOR); // commit author, e.g. 'baoyachi'
- println!("{}", build::COMMIT_EMAIL); // commit email, e.g. 'example@gmail.com'
-
- println!("{}", build::BUILD_OS); // the OS that built the binary, e.g. 'macos-x86_64'
- println!("{}", build::BUILD_TARGET); // the OS target that built the binary, e.g. 'x86_64-apple-darwin'
- println!("{}", build::BUILD_TARGET_ARCH); // the OS target arch that built the binary, e.g. 'x86_64'
- println!("{}", build::RUST_VERSION); // rustc version e.g. 'rustc 1.45.0 (5c1f21c3b 2020-07-13)'
- println!("{}", build::RUST_CHANNEL); // rust toolchain e.g. 'stable-x86_64-apple-darwin (default)'
- println!("{}", build::CARGO_VERSION); // cargo version e.g. 'cargo 1.45.0 (744bd1fbb 2020-06-15)'
- println!("{}", build::CARGO_TREE); // e.g. the output of '$ cargo tree'
- println!("{}", build::CARGO_MANIFEST_DIR); // e.g. /User/baoyachi/shadow-rs/
-
- println!("{}", build::PROJECT_NAME); // your project name, e.g. 'shadow-rs'
- // Time respects SOURCE_DATE_EPOCH environment variable - see below
- println!("{}", build::BUILD_TIME); // time when start build occurred, e.g. '2020-08-16 14:50:25'
- println!("{}", build::BUILD_TIME_2822); // time when start build occurred by rfc2822, e.g. 'Thu, 24 Jun 2021 21:33:59 +0800'
- println!("{}", build::BUILD_TIME_3339); // time when start build occurred by rfc3339, e.g. '2021-06-24T21:33:59.972494+08:00'
- println!("{}", build::BUILD_RUST_CHANNEL); // e.g. 'debug'
- println!("{}", build::GIT_CLEAN); // e.g. 'true'
- println!("{}", build::GIT_STATUS_FILE); // e.g. '* src/lib.rs (dirty)'
+ println!("{}", build::VERSION); //print version const
+ println!("{}", build::CLAP_LONG_VERSION); //print CLAP_LONG_VERSION const
+ println!("{}", build::BRANCH); //master
+ println!("{}", build::SHORT_COMMIT);//8405e28e
+ println!("{}", build::COMMIT_HASH);//8405e28e64080a09525a6cf1b07c22fcaf71a5c5
+ println!("{}", build::COMMIT_DATE);//2021-08-04 12:34:03 +00:00
+ println!("{}", build::COMMIT_AUTHOR);//baoyachi
+ println!("{}", build::COMMIT_EMAIL);//xxx@gmail.com
+
+ println!("{}", build::BUILD_OS);//macos-x86_64
+ println!("{}", build::RUST_VERSION);//rustc 1.45.0 (5c1f21c3b 2020-07-13)
+ println!("{}", build::RUST_CHANNEL);//stable-x86_64-apple-darwin (default)
+ println!("{}", build::CARGO_VERSION);//cargo 1.45.0 (744bd1fbb 2020-06-15)
+ println!("{}", build::PKG_VERSION);//0.3.13
+ println!("{}", build::CARGO_TREE); //like command:cargo tree
+ println!("{}", build::CARGO_MANIFEST_DIR); // /User/baoyachi/shadow-rs/ |
+
+ println!("{}", build::PROJECT_NAME);//shadow-rs
+ println!("{}", build::BUILD_TIME);//2020-08-16 14:50:25
+ println!("{}", build::BUILD_RUST_CHANNEL);//debug
+ println!("{}", build::GIT_CLEAN);//false
+ println!("{}", build::GIT_STATUS_FILE);//* src/lib.rs (dirty)
}
```
@@ -148,33 +120,28 @@ This tool includes the current time in the binary which would normally make it n
However, it respects the [`SOURCE_DATE_EPOCH` variable](https://reproducible-builds.org/docs/source-date-epoch/) - if
set to a Unix timestamp it will override the value of build time.
-## Clap Example
-
-You also can use shadow-rs with [`clap`](https://github.com/baoyachi/shadow-rs/blob/master/example_shadow/src/main.rs).
+## Clap
+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).
-## Constants and functions in table
+## List of Constants and Functions
-#### shadow-rs built in function.
+#### Functions
-* how to use 👉 : [examples](https://github.com/baoyachi/shadow-rs/tree/master/examples)
-
-| function | desc |
+| Function | Description |
| ------ | ------ |
-| is_debug() | check if this is a debug build.e.g.'true/false' |
-| branch() | get current project branch.e.g.'master/develop' |
-| tag() | get current project tag.e.g.'v1.3.5' |
-| git_clean() | get current project clean. e.g 'true/false' |
-| git_status_file() | get current project statue file. e.g ' * examples/builtin_fn.rs (dirty)' |
-
-#### shadow-rs support build const,function.
+| `is_debug()` | `true` if this is a build with debug assertions. |
+| `branch()` | Git branch at build time. |
+| `tag()` | Current Git tag at build time. |
+| `git_clean()` | Whether Git working tree was clean at build time. |
+| `git_status_file()` | `git status`-like output, e.g. ` * examples/builtin_fn.rs (dirty)` |
-* how to use 👉 : [shadow_example](https://github.com/baoyachi/shadow-rs/tree/master/example_shadow)
+#### Constants
-| const/fn | example |
+| Constant | Example |
| ------ | ------ |
-| VERSION | support mini version information.It's use easy. |
-| CLAP_LONG_VERSION | support mini version information for clap.It's use easy. |
-| BRANCH | master/develop |
+| VERSION | 3.4.5 |
+| CLAP_LONG_VERSION | (A multi-line string containing branch, commit hash, build time, Rust version and toolchain channel) |
+| BRANCH | master |
| TAG | v1.0.0 |
| SHORT_COMMIT | 8405e28e |
| COMMIT_HASH | 8405e28e64080a09525a6cf1b07c22fcaf71a5c5 |
@@ -190,14 +157,14 @@ You also can use shadow-rs with [`clap`](https://github.com/baoyachi/shadow-rs/b
| RUST_CHANNEL | stable-x86_64-apple-darwin (default) |
| CARGO_VERSION | cargo 1.45.0 (744bd1fbb 2020-06-15) |
| PKG_VERSION | 0.3.13 |
-| CARGO_TREE | cargo tree |
+| CARGO_TREE | (Output of `cargo tree`) |
| CARGO_MANIFEST_DIR | /User/baoyachi/shadow-rs/ |
| PROJECT_NAME | shadow-rs |
| BUILD_TIME | 2021-06-24 21:33:59 |
| BUILD_TIME_2822 | Thu, 24 Jun 2021 21:33:59 +0800 |
| BUILD_TIME_3339 | 2021-06-24T15:53:55+08:00 |
-| BUILD_RUST_CHANNEL | debug/release |
-| GIT_CLEAN | true/false |
+| BUILD_RUST_CHANNEL | release |
+| GIT_CLEAN | true |
| GIT_STATUS_FILE | * src/lib.rs (dirty) |
If you have any questions, please create an [issue](https://github.com/baoyachi/shadow-rs/issues/new) so we may improve
diff --git a/src/build.rs b/src/build.rs
index 8cb39e6..12365d8 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -1,15 +1,20 @@
use std::collections::BTreeMap;
+/// `shadow-rs` build constant identifiers.
pub type ShadowConst = &'static str;
pub trait ShadowGen {
fn gen_const(&self) -> BTreeMap;
}
+/// Serialized values for build constants.
#[derive(Debug, Clone)]
pub struct ConstVal {
+ /// User-facing documentation for the build constant.
pub desc: String,
+ /// Serialized value of the build constant.
pub v: String,
+ /// Type of the build constant.
pub t: ConstType,
}
@@ -31,10 +36,14 @@ impl ConstVal {
}
}
+/// Supported types of build constants.
#[derive(Debug, Clone)]
pub enum ConstType {
+ /// [`Option<&str>`](`Option`).
OptStr,
+ /// [`&str`](`str`).
Str,
+ /// [`bool`].
Bool,
}
diff --git a/src/ci.rs b/src/ci.rs
index e372267..518b864 100644
--- a/src/ci.rs
+++ b/src/ci.rs
@@ -1,9 +1,9 @@
+/// [`CiType`] holds the types of CI environment that `shadow-rs` can detect.
#[derive(Debug)]
pub enum CiType {
Github,
Gitlab,
- // Jenkins,
- // Travis,
+ // TODO: Recognize other CI types, especially Travis and Jenkins
None,
}
@@ -18,8 +18,6 @@ impl ToString for CiType {
match self {
CiType::Github => "github".into(),
CiType::Gitlab => "gitlab".into(),
- // CIType::Jenkins => "jenkins".into(),
- // CIType::Travis => "travis".into(),
_ => "none".into(),
}
}
diff --git a/src/date_time.rs b/src/date_time.rs
index 337f974..0d72857 100644
--- a/src/date_time.rs
+++ b/src/date_time.rs
@@ -24,7 +24,6 @@ pub fn now_date_time() -> DateTime {
.expect("Input SOURCE_DATE_EPOCH could not be parsed")
.parse::()
.expect("Input SOURCE_DATE_EPOCH could not be cast to a number");
- // BuildTime::Utc(Utc.timestamp(epoch, 0))
DateTime::Utc(OffsetDateTime::from_unix_timestamp(epoch).unwrap())
}
}
@@ -50,9 +49,9 @@ impl DateTime {
#[cfg(not(feature = "tzdb"))]
pub fn local_now() -> Result> {
- // Warning: Attempt to create a new OffsetDateTime with the current date and time in the local offset. If the offset cannot be determined, an error is returned.
- // At present, using it on MacOS return error. Use it with careful.
- // Suggestion use feature tzdb crate exposed function at below.
+ // Warning: This attempts to create a new OffsetDateTime with the current date and time in the local offset, which may fail.
+ // Currently, it always fails on MacOS.
+ // This issue does not exist with the "tzdb" feature (see below), which should be used instead.
OffsetDateTime::now_local()
.map(DateTime::Local)
.map_err(|e| e.into())
diff --git a/src/env.rs b/src/env.rs
index be27b89..6ef99c7 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -13,23 +13,70 @@ pub struct SystemEnv {
map: BTreeMap,
}
+const BUILD_OS_DOC: &str = r#"
+Operating system and architecture on which the project was build.
+The format of this variable is always `os-arch`,
+where `os` is the operating system name as returned by [`std::env::consts::OS`],
+and `arch` is the computer architecture as returned by [`std::env::consts::ARCH`]."#;
pub const BUILD_OS: ShadowConst = "BUILD_OS";
+
+const RUST_VERSION_DOC: &str = r#"
+Rust version with which the project was built.
+The version always uses the canonical Rust version format,
+and is therefore identical to the output of the build toolchain's `rustc --version`."#;
pub const RUST_VERSION: ShadowConst = "RUST_VERSION";
+
+const RUST_CHANNEL_DOC: &str = r#"
+The [Rustup toolchain](https://rust-lang.github.io/rustup/concepts/toolchains.html) with which the project was built.
+Note that as per Rustup toolchain format, this variable may or may not contain host and date information,
+but it will always contain [channel](https://rust-lang.github.io/rustup/concepts/channels.html) information (stable, beta or nightly)."#;
pub const RUST_CHANNEL: ShadowConst = "RUST_CHANNEL";
+
+const CARGO_VERSION_DOC: &str = r#"
+The cargo version which which the project was built, as output by `cargo --version`."#;
pub const CARGO_VERSION: ShadowConst = "CARGO_VERSION";
+
+const CARGO_TREE_DOC: &str = r#"
+The dependency tree of the project, as output by `cargo tree`.
+Note that this variable may contain local file system paths for path dependencies, and may therefore contain sensitive information and not be reproducible."#;
pub const CARGO_TREE: ShadowConst = "CARGO_TREE";
+const BUILD_TARGET_DOC: &str = r#"
+The [target](https://doc.rust-lang.org/rustc/targets/index.html) for this build.
+This is possibly distinct from the host target during build, in which case this project build was created via cross-compilation."#;
pub const BUILD_TARGET: ShadowConst = "BUILD_TARGET";
+
+const BUILD_TARGET_ARCH_DOC: &str = r#"
+The architecture of the target for this build. This is the "architecture" part of the [`BUILD_TARGET`] constant."#;
pub const BUILD_TARGET_ARCH: ShadowConst = "BUILD_TARGET_ARCH";
+const CARGO_MANIFEST_DIR_DOC: &str = r#"
+The directory of the Cargo.toml manifest file of the project during build.
+Note that this variable will contain a full local file system path, and will therefore contain sensitive information and not be reproducible."#;
pub const CARGO_MANIFEST_DIR: ShadowConst = "CARGO_MANIFEST_DIR";
-// const CARGO_METADATA: ShadowConst = "CARGO_METADATA";
+const PKG_VERSION_DOC: &str = r#"
+The project's full version string, as determined by the Cargo.toml manifest."#;
pub const PKG_VERSION: ShadowConst = "PKG_VERSION";
+
+const PKG_DESCRIPTION_DOC: &str = r#"
+The project's description, as determined by the Cargo.toml manifest."#;
pub const PKG_DESCRIPTION: ShadowConst = "PKG_DESCRIPTION";
+
+const PKG_VERSION_MAJOR_DOC: &str = r#"
+The project's semver major version, as determined by the Cargo.toml manifest."#;
pub const PKG_VERSION_MAJOR: ShadowConst = "PKG_VERSION_MAJOR";
+
+const PKG_VERSION_MINOR_DOC: &str = r#"
+The project's semver minor version, as determined by the Cargo.toml manifest."#;
pub const PKG_VERSION_MINOR: ShadowConst = "PKG_VERSION_MINOR";
+
+const PKG_VERSION_PATCH_DOC: &str = r#"
+The project's semver patch version, as determined by the Cargo.toml manifest."#;
pub const PKG_VERSION_PATCH: ShadowConst = "PKG_VERSION_PATCH";
+
+const PKG_VERSION_PRE_DOC: &str = r#"
+The project's semver pre-release version, as determined by the Cargo.toml manifest."#;
pub const PKG_VERSION_PRE: ShadowConst = "PKG_VERSION_PRE";
impl SystemEnv {
@@ -196,80 +243,54 @@ mod dep_source_replace {
}
}
+/// Create all `shadow-rs` constants which are determined by the build environment.
+/// The data for these constants is provided by the `std_env` argument.
pub fn new_system_env(std_env: &BTreeMap) -> BTreeMap {
let mut env = SystemEnv::default();
env.map.insert(
BUILD_OS,
ConstVal {
- desc: "display build system os".to_string(),
+ desc: BUILD_OS_DOC.to_string(),
v: format!("{}-{}", env::consts::OS, env::consts::ARCH),
t: ConstType::Str,
},
);
- env.map.insert(
- RUST_CHANNEL,
- ConstVal::new("display build system rust channel"),
- );
- env.map.insert(
- RUST_VERSION,
- ConstVal::new("display build system rust version"),
- );
- env.map.insert(
- CARGO_VERSION,
- ConstVal::new("display build system cargo version"),
- );
+ env.map
+ .insert(RUST_CHANNEL, ConstVal::new(RUST_CHANNEL_DOC));
+ env.map
+ .insert(RUST_VERSION, ConstVal::new(RUST_VERSION_DOC));
+ env.map
+ .insert(CARGO_VERSION, ConstVal::new(CARGO_VERSION_DOC));
- env.map.insert(
- CARGO_TREE,
- ConstVal::new("display build cargo dependencies.It's used by rust version 1.44.0"),
- );
+ env.map.insert(CARGO_TREE, ConstVal::new(CARGO_TREE_DOC));
// env.map.insert(
// CARGO_METADATA,
// ConstVal::new("display build cargo dependencies by metadata.It's use by exec command `cargo metadata`"),
// );
- env.map.insert(
- BUILD_TARGET,
- ConstVal::new("display build current project target"),
- );
+ env.map
+ .insert(BUILD_TARGET, ConstVal::new(BUILD_TARGET_DOC));
- env.map.insert(
- BUILD_TARGET_ARCH,
- ConstVal::new("display build current project version arch"),
- );
+ env.map
+ .insert(BUILD_TARGET_ARCH, ConstVal::new(BUILD_TARGET_ARCH_DOC));
- env.map.insert(
- PKG_VERSION,
- ConstVal::new("display build current project version"),
- );
+ env.map.insert(PKG_VERSION, ConstVal::new(PKG_VERSION_DOC));
- env.map.insert(
- PKG_DESCRIPTION,
- ConstVal::new("display build current project description"),
- );
+ env.map
+ .insert(PKG_DESCRIPTION, ConstVal::new(PKG_DESCRIPTION_DOC));
- env.map.insert(
- PKG_VERSION_MAJOR,
- ConstVal::new("display build current project major version"),
- );
- env.map.insert(
- PKG_VERSION_MINOR,
- ConstVal::new("display build current project minor version"),
- );
- env.map.insert(
- PKG_VERSION_PATCH,
- ConstVal::new("display build current project patch version"),
- );
- env.map.insert(
- PKG_VERSION_PRE,
- ConstVal::new("display build current project preview version"),
- );
- env.map.insert(
- CARGO_MANIFEST_DIR,
- ConstVal::new("display build current build cargo manifest dir"),
- );
+ env.map
+ .insert(PKG_VERSION_MAJOR, ConstVal::new(PKG_VERSION_MAJOR_DOC));
+ env.map
+ .insert(PKG_VERSION_MINOR, ConstVal::new(PKG_VERSION_MINOR_DOC));
+ env.map
+ .insert(PKG_VERSION_PATCH, ConstVal::new(PKG_VERSION_PATCH_DOC));
+ env.map
+ .insert(PKG_VERSION_PRE, ConstVal::new(PKG_VERSION_PRE_DOC));
+ env.map
+ .insert(CARGO_MANIFEST_DIR, ConstVal::new(CARGO_MANIFEST_DIR_DOC));
if let Err(e) = env.init(std_env) {
println!("{e}");
@@ -282,10 +303,25 @@ pub struct Project {
map: BTreeMap,
}
+const PROJECT_NAME_DOC: &str = r#"
+The project name, as determined by the Cargo.toml manifest."#;
const PROJECT_NAME: ShadowConst = "PROJECT_NAME";
+
+const BUILD_TIME_DOC: &str = r#"
+The project build time, formatted in modified ISO 8601 format (`YYYY-MM-DD HH-MM ±hh-mm` where hh-mm is the offset from UTC)."#;
const BUILD_TIME: ShadowConst = "BUILD_TIME";
+
+const BUILD_TIME_2822_DOC: &str = r#"
+The project build time, formatted according to [RFC 2822](https://datatracker.ietf.org/doc/html/rfc2822#section-3.3) (e.g. HTTP Headers)."#;
const BUILD_TIME_2822: ShadowConst = "BUILD_TIME_2822";
+
+const BUILD_TIME_3339_DOC: &str = r#"
+The project build time, formatted according to [RFC 3339 and ISO 8601](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6)."#;
const BUILD_TIME_3339: ShadowConst = "BUILD_TIME_3339";
+
+const BUILD_RUST_CHANNEL_DOC: &str = r#"
+The debug configuration with which the project was built.
+Note that this is not the Rust channel, but either `debug` or `release`, depending on whether debug assertions were enabled in the build or not. "#;
const BUILD_RUST_CHANNEL: ShadowConst = "BUILD_RUST_CHANNEL";
pub fn build_time(project: &mut Project) {
@@ -294,7 +330,7 @@ pub fn build_time(project: &mut Project) {
project.map.insert(
BUILD_TIME,
ConstVal {
- desc: "display project build time".to_string(),
+ desc: BUILD_TIME_DOC.to_string(),
v: time.human_format(),
t: ConstType::Str,
},
@@ -302,7 +338,7 @@ pub fn build_time(project: &mut Project) {
project.map.insert(
BUILD_TIME_2822,
ConstVal {
- desc: "display project build time by rfc2822".to_string(),
+ desc: BUILD_TIME_2822_DOC.to_string(),
v: time.to_rfc2822(),
t: ConstType::Str,
},
@@ -311,7 +347,7 @@ pub fn build_time(project: &mut Project) {
project.map.insert(
BUILD_TIME_3339,
ConstVal {
- desc: "display project build time by rfc3399".to_string(),
+ desc: BUILD_TIME_3339_DOC.to_string(),
v: time.to_rfc3339(),
t: ConstType::Str,
},
@@ -324,14 +360,14 @@ pub fn new_project(std_env: &BTreeMap) -> BTreeMap = Result;
+/// `shadow-rs` build process errors.
+/// This type wraps multiple kinds of underlying errors that can occur downstream of `shadow-rs`, such as [`std::io::Error`].
#[derive(Debug)]
pub enum ShadowError {
String(String),
diff --git a/src/gen_const.rs b/src/gen_const.rs
index b18b24f..4491bac 100644
--- a/src/gen_const.rs
+++ b/src/gen_const.rs
@@ -1,12 +1,16 @@
macro_rules! gen_const {
- ($fn_name:ident,$fn_desc:expr,$fn_body:expr) => {
+ ($fn_name:ident, $fn_body:expr) => {
pub fn $fn_name() -> String {
- format!("{}\n{}", $fn_desc, $fn_body)
+ $fn_body.to_string()
}
};
}
-const VERSION_BRANCH_CONST: &str = r##"#[allow(dead_code)]
+const VERSION_BRANCH_CONST: &str = r##"
+/// A long version string describing the project.
+/// The version string contains the package version, branch, commit hash, build time, and build environment on separate lines.
+/// This constant is suitable for printing to the user.
+#[allow(dead_code)]
pub const VERSION:&str = shadow_rs::formatcp!(r#"
pkg_version:{}
branch:{}
@@ -15,7 +19,11 @@ build_time:{}
build_env:{},{}"#,PKG_VERSION, BRANCH, SHORT_COMMIT, BUILD_TIME, RUST_VERSION, RUST_CHANNEL
);"##;
-const VERSION_TAG_CONST: &str = r##"#[allow(dead_code)]
+const VERSION_TAG_CONST: &str = r##"
+/// A long version string describing the project.
+/// The version string contains the package version, current Git tag, commit hash, build time, and build environment on separate lines.
+/// This constant is suitable for printing to the user.
+#[allow(dead_code)]
pub const VERSION:&str = shadow_rs::formatcp!(r#"
pkg_version:{}
tag:{}
@@ -42,7 +50,11 @@ build_time:{}
build_env:{},{}"#,PKG_VERSION, TAG, SHORT_COMMIT, BUILD_TIME, RUST_VERSION, RUST_CHANNEL
);"##;
-const CLAP_LONG_VERSION_BRANCH_CONST: &str = r##"#[allow(dead_code)]
+const CLAP_LONG_VERSION_BRANCH_CONST: &str = r##"
+/// A long version string describing the project.
+/// The version string contains the package version, branch, commit hash, build time, and build environment on separate lines.
+/// This constant is intended to be used by clap or other CLI tools as a long version string.
+#[allow(dead_code)]
pub const CLAP_LONG_VERSION:&str = shadow_rs::formatcp!(r#"{}
branch:{}
commit_hash:{}
@@ -50,7 +62,11 @@ build_time:{}
build_env:{},{}"#,PKG_VERSION, BRANCH, SHORT_COMMIT, BUILD_TIME, RUST_VERSION, RUST_CHANNEL
);"##;
-const CLAP_LONG_VERSION_TAG_CONST: &str = r##"#[allow(dead_code)]
+const CLAP_LONG_VERSION_TAG_CONST: &str = r##"
+/// A long version string describing the project.
+/// The version string contains the package version, current Git tag, commit hash, build time, and build environment on separate lines.
+/// This constant is intended to be used by clap or other CLI tools as a long version string.
+#[allow(dead_code)]
pub const CLAP_LONG_VERSION:&str = shadow_rs::formatcp!(r#"{}
tag:{}
commit_hash:{}
@@ -58,43 +74,15 @@ build_time:{}
build_env:{},{}"#,PKG_VERSION, TAG, SHORT_COMMIT, BUILD_TIME, RUST_VERSION, RUST_CHANNEL
);"##;
-const VERSION_CONST_DESC: &str = r#"/// The common version const. It's so easy to use this const."#;
-
-const CLAP_VERSION_CONST_DESC: &str =
- r#"/// The common version const. It's so easy to use this const with `CLAP_VERSION`."#;
-
-const CLAP_LONG_VERSION_CONST_DESC: &str =
- r#"/// The common version const. It's so easy to use this const with `CLAP_VERSION`."#;
-
-gen_const!(
- version_branch_const,
- VERSION_CONST_DESC,
- VERSION_BRANCH_CONST
-);
-
-gen_const!(version_tag_const, VERSION_CONST_DESC, VERSION_TAG_CONST);
-
-gen_const!(
- clap_version_branch_const,
- CLAP_VERSION_CONST_DESC,
- CLAP_VERSION_BRANCH_CONST
-);
-gen_const!(
- clap_version_tag_const,
- CLAP_VERSION_CONST_DESC,
- CLAP_VERSION_TAG_CONST
-);
-
+gen_const!(version_branch_const, VERSION_BRANCH_CONST);
+gen_const!(version_tag_const, VERSION_TAG_CONST);
+gen_const!(clap_version_branch_const, CLAP_VERSION_BRANCH_CONST);
+gen_const!(clap_version_tag_const, CLAP_VERSION_TAG_CONST);
gen_const!(
clap_long_version_branch_const,
- CLAP_LONG_VERSION_CONST_DESC,
CLAP_LONG_VERSION_BRANCH_CONST
);
-gen_const!(
- clap_long_version_tag_const,
- CLAP_LONG_VERSION_CONST_DESC,
- CLAP_LONG_VERSION_TAG_CONST
-);
+gen_const!(clap_long_version_tag_const, CLAP_LONG_VERSION_TAG_CONST);
pub(crate) const BUILD_CONST_VERSION: &str = "VERSION";
pub(crate) const BUILD_CONST_CLAP_LONG_VERSION: &str = "CLAP_LONG_VERSION";
@@ -105,11 +93,8 @@ mod tests {
#[test]
fn test_version_fn() {
- assert!(version_branch_const().contains(VERSION_CONST_DESC));
assert!(version_tag_const().contains(VERSION_TAG_CONST));
assert!(clap_version_branch_const().contains(CLAP_VERSION_BRANCH_CONST));
- assert!(clap_version_tag_const().contains(CLAP_VERSION_CONST_DESC));
assert!(clap_long_version_branch_const().contains(CLAP_LONG_VERSION_BRANCH_CONST));
- assert!(clap_long_version_tag_const().contains(CLAP_LONG_VERSION_CONST_DESC));
}
}
diff --git a/src/git.rs b/src/git.rs
index e86d031..b76e866 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -8,17 +8,74 @@ use std::io::{BufReader, Read};
use std::path::Path;
use std::process::{Command, Stdio};
+const BRANCH_DOC: &str = r#"
+The name of the Git branch that this project was built from.
+
+This constant will be empty if the branch cannot be determined."#;
pub const BRANCH: ShadowConst = "BRANCH";
+const TAG_DOC: &str = r#"
+The name of the Git tag that this project was built from.
+Note that this will be empty if there is no tag for the HEAD at the time of build."#;
pub const TAG: ShadowConst = "TAG";
+const LAST_TAG_DOC: &str = r#"
+The name of the last Git tag on the branch that this project was built from.
+As opposed to [`TAG`], this does not require the current commit to be tagged, just one of its parents.
+
+This constant will be empty if the last tag cannot be determined."#;
pub const LAST_TAG: ShadowConst = "LAST_TAG";
+const SHORT_COMMIT_DOC: &str = r#"
+The short hash of the Git commit that this project was built from.
+Note that this will always truncate [`COMMIT_HASH`] to 8 characters if necessary.
+Depending on the amount of commits in your project, this may not yield a unique Git identifier
+([see here for more details on hash abbreviation](https://git-scm.com/docs/git-describe#_examples)).
+
+This constant will be empty if the last commit cannot be determined."#;
pub const SHORT_COMMIT: ShadowConst = "SHORT_COMMIT";
+const COMMIT_HASH_DOC: &str = r#"
+The full commit hash of the Git commit that this project was built from.
+An abbreviated, but not necessarily unique, version of this is [`SHORT_COMMIT`].
+
+This constant will be empty if the last commit cannot be determined."#;
pub const COMMIT_HASH: ShadowConst = "COMMIT_HASH";
+const COMMIT_DATE_DOC: &str = r#"The time of the Git commit that this project was built from.
+The time is formatted in modified ISO 8601 format (`YYYY-MM-DD HH-MM ±hh-mm` where hh-mm is the offset from UTC).
+
+This constant will be empty if the last commit cannot be determined."#;
pub const COMMIT_DATE: ShadowConst = "COMMIT_DATE";
+const COMMIT_DATE_2822_DOC: &str = r#"
+The name of the Git branch that this project was built from.
+The time is formatted according to [RFC 2822](https://datatracker.ietf.org/doc/html/rfc2822#section-3.3) (e.g. HTTP Headers).
+
+This constant will be empty if the last commit cannot be determined."#;
pub const COMMIT_DATE_2822: ShadowConst = "COMMIT_DATE_2822";
+const COMMIT_DATE_3339_DOC: &str = r#"
+The name of the Git branch that this project was built from.
+The time is formatted according to [RFC 3339 and ISO 8601](https://datatracker.ietf.org/doc/html/rfc3339#section-5.6).
+
+This constant will be empty if the last commit cannot be determined."#;
pub const COMMIT_DATE_3339: ShadowConst = "COMMIT_DATE_3339";
+const COMMIT_AUTHOR_DOC: &str = r#"
+The author of the Git commit that this project was built from.
+
+This constant will be empty if the last commit cannot be determined."#;
pub const COMMIT_AUTHOR: ShadowConst = "COMMIT_AUTHOR";
+const COMMIT_EMAIL_DOC: &str = r#"
+The e-mail address of the author of the Git commit that this project was built from.
+
+This constant will be empty if the last commit cannot be determined."#;
pub const COMMIT_EMAIL: ShadowConst = "COMMIT_EMAIL";
+const GIT_CLEAN_DOC: &str = r#"
+Whether the Git working tree was clean at the time of project build (`true`), or not (`false`).
+
+This constant will be `false` if the last commit cannot be determined."#;
pub const GIT_CLEAN: ShadowConst = "GIT_CLEAN";
+const GIT_STATUS_FILE_DOC: &str = r#"
+The Git working tree status as a list of files with their status, similar to `git status`.
+Each line of the list is preceded with ` * `, followed by the file name.
+Files marked `(dirty)` have unstaged changes.
+Files marked `(staged)` have staged changes.
+
+This constant will be empty if the working tree status cannot be determined."#;
pub const GIT_STATUS_FILE: ShadowConst = "GIT_STATUS_FILE";
#[derive(Default, Debug)]
@@ -222,49 +279,33 @@ pub fn new_git(
map: Default::default(),
ci_type: ci,
};
- git.map
- .insert(BRANCH, ConstVal::new("display current branch"));
+ git.map.insert(BRANCH, ConstVal::new(BRANCH_DOC));
+
+ git.map.insert(TAG, ConstVal::new(TAG_DOC));
- git.map.insert(TAG, ConstVal::new("display current tag"));
+ git.map.insert(LAST_TAG, ConstVal::new(LAST_TAG_DOC));
- git.map.insert(LAST_TAG, ConstVal::new("display last tag"));
+ git.map.insert(COMMIT_HASH, ConstVal::new(COMMIT_HASH_DOC));
git.map
- .insert(COMMIT_HASH, ConstVal::new("display current commit_id"));
+ .insert(SHORT_COMMIT, ConstVal::new(SHORT_COMMIT_DOC));
- git.map.insert(
- SHORT_COMMIT,
- ConstVal::new("display current short commit_id"),
- );
+ git.map
+ .insert(COMMIT_AUTHOR, ConstVal::new(COMMIT_AUTHOR_DOC));
+ git.map
+ .insert(COMMIT_EMAIL, ConstVal::new(COMMIT_EMAIL_DOC));
+ git.map.insert(COMMIT_DATE, ConstVal::new(COMMIT_DATE_DOC));
- git.map.insert(
- COMMIT_AUTHOR,
- ConstVal::new("display current commit author"),
- );
git.map
- .insert(COMMIT_EMAIL, ConstVal::new("display current commit email"));
+ .insert(COMMIT_DATE_2822, ConstVal::new(COMMIT_DATE_2822_DOC));
+
+ git.map
+ .insert(COMMIT_DATE_3339, ConstVal::new(COMMIT_DATE_3339_DOC));
+
+ git.map.insert(GIT_CLEAN, ConstVal::new_bool(GIT_CLEAN_DOC));
+
git.map
- .insert(COMMIT_DATE, ConstVal::new("display current commit date"));
-
- git.map.insert(
- COMMIT_DATE_2822,
- ConstVal::new("display current commit date by rfc2822"),
- );
-
- git.map.insert(
- COMMIT_DATE_3339,
- ConstVal::new("display current commit date by rfc3339"),
- );
-
- git.map.insert(
- GIT_CLEAN,
- ConstVal::new_bool("display current git repository status clean:'true or false'"),
- );
-
- git.map.insert(
- GIT_STATUS_FILE,
- ConstVal::new("display current git repository status files:'dirty or stage'"),
- );
+ .insert(GIT_STATUS_FILE, ConstVal::new(GIT_STATUS_FILE_DOC));
if let Err(e) = git.init(path, std_env) {
println!("{e}");
diff --git a/src/lib.rs b/src/lib.rs
index 17ee351..09e796b 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,69 +1,23 @@
#![doc(html_logo_url = "https://raw.githubusercontent.com/baoyachi/shadow-rs/master/shadow-rs.png")]
-//! `shadow-rs` :build-time information stored in your rust project.(binary,lib,cdylib,dylib)
+//! `shadow-rs`: Build-time information stored in your Rust project (binary, lib, cdylib, dylib).
//!
-//! It's allows you to recall properties of the build process and environment at runtime, including:
+//! `shadow-rs` allows you to access properties of the build process and environment at runtime, including:
//!
-//! `Cargo.toml` project version
+//! * `Cargo.toml` information, such as the project version
//! * Dependency information
-//! * The Git commit that produced the build artifact (binary)
-//! * What version of the rust toolchain was used in compilation
+//! * Git information, such as the commit that produced the build artifact
+//! * What version of the Rust toolchain was used in compilation
//! * The build variant, e.g. `debug` or `release`
-//! * (And more)
+//! * ... And more!
//!
-//! You can use this tool to check in production exactly where a binary came from and how it was built.
+//! You can use this crate to programmatically check where a binary came from and how it was built.
//!
-//! # Full Examples
+//! # Examples
//! * 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.
-//! * Check out the [example_shadow_hook](https://github.com/baoyachi/shadow-rs/tree/master/example_shadow_hook) for a simple demonstration of how `shadow-rs` might be used to provide build-time information at run-time,and add custom hook.
+//! * 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.
+//! * 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.
//!
-//! ## Built in function
-//! * Check out the [examples](https://github.com/baoyachi/shadow-rs/tree/master/examples) for a simple demonstration of how `shadow-rs` might be used to provide build in function.
-//!
-//! # Example
-//!
-//! ```
-//! pub const PKG_VERSION :&str = "1.3.8-beta3";
-//! pub const PKG_VERSION_MAJOR :&str = "1";
-//! pub const PKG_VERSION_MINOR :&str = "3";
-//! pub const PKG_VERSION_PATCH :&str = "8";
-//! pub const PKG_VERSION_PRE :&str = "beta3";
-//! pub const RUST_VERSION :&str = "rustc 1.45.0 (5c1f21c3b 2020-07-13)";
-//! pub const BUILD_RUST_CHANNEL :&str = "debug";
-//! pub const COMMIT_AUTHOR :&str = "baoyachi";
-//! pub const BUILD_TIME :&str = "2020-08-16 13:48:52";
-//! pub const BUILD_TIME_2822 :&str = "Thu, 24 Jun 2021 21:44:14 +0800";
-//! pub const BUILD_TIME_3339 :&str = "2021-06-24T15:53:55+08:00";
-//! pub const COMMIT_DATE :&str = "2021-08-04 12:34:03 +00:00";
-//! pub const COMMIT_DATE_2822 :&str = "Thu, 24 Jun 2021 21:44:14 +0800";
-//! pub const COMMIT_DATE_3339 :&str = "2021-06-24T21:44:14.473058+08:00";
-//! pub const COMMIT_EMAIL :&str = "xxx@gmail.com";
-//! pub const PROJECT_NAME :&str = "shadow-rs";
-//! pub const RUST_CHANNEL :&str = "stable-x86_64-apple-darwin (default)";
-//! pub const BRANCH :&str = "master";
-//! pub const CARGO_LOCK :&str = r#"
-//! ├── chrono v0.4.19
-//! │ ├── libc v0.2.80
-//! │ ├── num-integer v0.1.44
-//! │ │ └── num-traits v0.2.14
-//! │ │ [build-dependencies]
-//! │ │ └── autocfg v1.0.1
-//! │ ├── num-traits v0.2.14 (*)
-//! │ └── time v0.1.44
-//! │ └── libc v0.2.80
-//! └── git2 v0.13.12
-//! ├── log v0.4.11
-//! │ └── cfg-if v0.1.10
-//! └── url v2.2.0
-//! ├── form_urlencoded v1.0.0
-//! │ └── percent-encoding v2.1.0
-//! └── percent-encoding v2.1.0"#;
-//! pub const CARGO_VERSION :&str = "cargo 1.45.0 (744bd1fbb 2020-06-15)";
-//! pub const BUILD_OS :&str = "macos-x86_64";
-//! pub const COMMIT_HASH :&str = "386741540d73c194a3028b96b92fdeb53ca2788a";
-//! pub const GIT_CLEAN :bool = true;
-//! pub const GIT_STATUS_FILE :&str = "* src/lib.rs (dirty)";
-//! ```
-//! # Setup Guide
+//! # Setup
//!
//! ### 1) Modify `Cargo.toml` fields
//! Modify your `Cargo.toml` like so:
@@ -85,63 +39,110 @@
//!
//! ```ignore
//! fn main() -> shadow_rs::SdResult<()> {
-//! shadow_rs::new()
+//! shadow_rs::new()
//! }
//! ```
//!
+//! If you want to exclude some build constants, you can use [`new_deny`] instead of [`new`].
+//!
//! ### 3) Integrate Shadow
-//! In your rust file (e.g. `*.rs`):
+//! In your main Rust file (usually `main.rs` or `lib.rs`), add this:
//!
//! ```ignore
//! use shadow_rs::shadow;
//!
//! shadow!(build);
//! ```
-//! **Notice that the `shadow!` macro is provided the identifier `build`. You can now use this identifier to access build-time information.**
//!
-//! ### 4) Done. Use Shadow.
-//! Then you can use const that's shadow build it(main.rs).
+//! The `shadow!` macro uses the given identifier to create a module with that name.
//!
-//! The `build` mod just we use `shadow!(build)` generated.
+//! ### 4) Use Shadow Constants
+//! You can now use the module defined with `shadow!` to access build-time information.
//!
//! ```ignore
//! fn main(){
-//! println!("debug:{}", shadow_rs::is_debug()); // check if this is a debug build. e.g 'true/false'
-//! println!("branch:{}", shadow_rs::branch()); // get current project branch. e.g 'master/develop'
-//! println!("tag:{}", shadow_rs::tag()); // get current project tag. e.g 'v1.3.5'
-//! println!("git_clean:{}", shadow_rs::git_clean()); // get current project clean. e.g 'true/false'
-//! println!("git_status_file:{}", shadow_rs::git_status_file()); // get current project statue file. e.g ' * examples/builtin_fn.rs (dirty)'
+//! println!("debug:{}", shadow_rs::is_debug()); // check if this is a debug build. e.g 'true/false'
+//! println!("branch:{}", shadow_rs::branch()); // get current project branch. e.g 'master/develop'
+//! println!("tag:{}", shadow_rs::tag()); // get current project tag. e.g 'v1.3.5'
+//! println!("git_clean:{}", shadow_rs::git_clean()); // get current project clean. e.g 'true/false'
+//! println!("git_status_file:{}", shadow_rs::git_status_file()); // get current project statue file. e.g ' * examples/builtin_fn.rs (dirty)'
//!
-//! println!("{}",build::VERSION); //print version const
-//! println!("{}",build::CLAP_LONG_VERSION); //print CLAP_LONG_VERSION const
-//! println!("{}",build::BRANCH); //master
-//! println!("{}",build::SHORT_COMMIT);//8405e28e
-//! println!("{}",build::COMMIT_HASH);//8405e28e64080a09525a6cf1b07c22fcaf71a5c5
-//! println!("{}",build::COMMIT_DATE);//2021-08-04 12:34:03 +00:00
-//! println!("{}",build::COMMIT_AUTHOR);//baoyachi
-//! println!("{}",build::COMMIT_EMAIL);//xxx@gmail.com
+//! println!("{}", build::VERSION); //print version const
+//! println!("{}", build::CLAP_LONG_VERSION); //print CLAP_LONG_VERSION const
+//! println!("{}", build::BRANCH); //master
+//! println!("{}", build::SHORT_COMMIT);//8405e28e
+//! println!("{}", build::COMMIT_HASH);//8405e28e64080a09525a6cf1b07c22fcaf71a5c5
+//! println!("{}", build::COMMIT_DATE);//2021-08-04 12:34:03 +00:00
+//! println!("{}", build::COMMIT_AUTHOR);//baoyachi
+//! println!("{}", build::COMMIT_EMAIL);//xxx@gmail.com
//!
-//! println!("{}",build::BUILD_OS);//macos-x86_64
-//! println!("{}",build::RUST_VERSION);//rustc 1.45.0 (5c1f21c3b 2020-07-13)
-//! println!("{}",build::RUST_CHANNEL);//stable-x86_64-apple-darwin (default)
-//! println!("{}",build::CARGO_VERSION);//cargo 1.45.0 (744bd1fbb 2020-06-15)
-//! println!("{}",build::PKG_VERSION);//0.3.13
-//! println!("{}",build::CARGO_TREE); //like command:cargo tree
-//! println!("{}",build::CARGO_MANIFEST_DIR); // /User/baoyachi/shadow-rs/ |
+//! println!("{}", build::BUILD_OS);//macos-x86_64
+//! println!("{}", build::RUST_VERSION);//rustc 1.45.0 (5c1f21c3b 2020-07-13)
+//! println!("{}", build::RUST_CHANNEL);//stable-x86_64-apple-darwin (default)
+//! println!("{}", build::CARGO_VERSION);//cargo 1.45.0 (744bd1fbb 2020-06-15)
+//! println!("{}", build::PKG_VERSION);//0.3.13
+//! println!("{}", build::CARGO_TREE); //like command:cargo tree
+//! println!("{}", build::CARGO_MANIFEST_DIR); // /User/baoyachi/shadow-rs/ |
//!
-//! println!("{}",build::PROJECT_NAME);//shadow-rs
-//! println!("{}",build::BUILD_TIME);//2020-08-16 14:50:25
-//! println!("{}",build::BUILD_RUST_CHANNEL);//debug
-//! println!("{}",build::GIT_CLEAN);//false
-//! println!("{}",build::GIT_STATUS_FILE);//* src/lib.rs (dirty)
+//! println!("{}", build::PROJECT_NAME);//shadow-rs
+//! println!("{}", build::BUILD_TIME);//2020-08-16 14:50:25
+//! println!("{}", build::BUILD_RUST_CHANNEL);//debug
+//! println!("{}", build::GIT_CLEAN);//false
+//! println!("{}", build::GIT_STATUS_FILE);//* src/lib.rs (dirty)
//! }
-//!```
+//! ```
+//!
+//! ## Clap
+//! 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).
//!
-//! ## Clap example
-//! And you can also use `shadow-rs` with [`clap`](https://github.com/baoyachi/shadow-rs/blob/master/example_shadow/src/main.rs).
+//! For the user guide and further documentation, see the [README of `shadow-rs`](https://github.com/baoyachi/shadow-rs).
//!
-//! For the user guide and further documentation, please read
-//! [The shadow-rs document](https://github.com/baoyachi/shadow-rs).
+//! # List of Generated Output Constants
+//!
+//! All constants produced by `shadow-rs` are documented in the module created with [`shadow!`], so `rustdoc` and your IDE will pick it up.
+//!
+//! ```
+//! pub const PKG_VERSION: &str = "1.3.8-beta3";
+//! pub const PKG_VERSION_MAJOR: &str = "1";
+//! pub const PKG_VERSION_MINOR: &str = "3";
+//! pub const PKG_VERSION_PATCH: &str = "8";
+//! pub const PKG_VERSION_PRE: &str = "beta3";
+//! pub const RUST_VERSION: &str = "rustc 1.45.0 (5c1f21c3b 2020-07-13)";
+//! pub const BUILD_RUST_CHANNEL: &str = "debug";
+//! pub const COMMIT_AUTHOR: &str = "baoyachi";
+//! pub const BUILD_TIME: &str = "2020-08-16 13:48:52";
+//! pub const BUILD_TIME_2822: &str = "Thu, 24 Jun 2021 21:44:14 +0800";
+//! pub const BUILD_TIME_3339: &str = "2021-06-24T15:53:55+08:00";
+//! pub const COMMIT_DATE: &str = "2021-08-04 12:34:03 +00:00";
+//! pub const COMMIT_DATE_2822: &str = "Thu, 24 Jun 2021 21:44:14 +0800";
+//! pub const COMMIT_DATE_3339: &str = "2021-06-24T21:44:14.473058+08:00";
+//! pub const COMMIT_EMAIL: &str = "xxx@gmail.com";
+//! pub const PROJECT_NAME: &str = "shadow-rs";
+//! pub const RUST_CHANNEL: &str = "stable-x86_64-apple-darwin (default)";
+//! pub const BRANCH: &str = "master";
+//! pub const CARGO_LOCK: &str = r#"
+//! ├── chrono v0.4.19
+//! │ ├── libc v0.2.80
+//! │ ├── num-integer v0.1.44
+//! │ │ └── num-traits v0.2.14
+//! │ │ [build-dependencies]
+//! │ │ └── autocfg v1.0.1
+//! │ ├── num-traits v0.2.14 (*)
+//! │ └── time v0.1.44
+//! │ └── libc v0.2.80
+//! └── git2 v0.13.12
+//! ├── log v0.4.11
+//! │ └── cfg-if v0.1.10
+//! └── url v2.2.0
+//! ├── form_urlencoded v1.0.0
+//! │ └── percent-encoding v2.1.0
+//! └── percent-encoding v2.1.0"#;
+//! pub const CARGO_VERSION: &str = "cargo 1.45.0 (744bd1fbb 2020-06-15)";
+//! pub const BUILD_OS: &str = "macos-x86_64";
+//! pub const COMMIT_HASH: &str = "386741540d73c194a3028b96b92fdeb53ca2788a";
+//! pub const GIT_CLEAN: bool = true;
+//! pub const GIT_STATUS_FILE: &str = "* src/lib.rs (dirty)";
+//! ```
//!
mod build;
@@ -152,14 +153,7 @@ mod err;
mod gen_const;
mod git;
-/// Get current project build mode.
-///
-/// It's very useful. Debug mode is usually used for debugging information.
-/// For example, log printing, environment variable switch.
-///
-/// The default value is `true`.
-///
-/// If we compile with `cargo build --release`. It's return value is `false`.
+/// Re-exported from the is_debug crate
pub use is_debug::*;
use build::*;
@@ -188,12 +182,21 @@ pub trait Format {
const SHADOW_RS: &str = "shadow.rs";
-/// Add a mod in project with `$build_mod`.
+/// Add a module with the provided name which contains the build information generated by `shadow-rs`.
+///
+/// # Example
+///
+/// ```ignore
+/// use shadow_rs::shadow;
///
-/// You can use `shadow!(build_shadow)`. Then shadow-rs can help you add a mod with name `build_shadow`.
-/// Next, use mod with name `build_shadow`,and also use const like:`build_shadow::BRANCH`.
+/// shadow!(my_build_information);
+///
+/// fn main() {
+/// println!("I'm version {}!", my_build_information::VERSION);
+/// }
+/// ```
///
-/// Normally, you just config `shadow!(build)`.It looks more concise.
+/// The convention, however, is to use `shadow!(build);`.
#[macro_export]
macro_rules! shadow {
($build_mod:ident) => {
@@ -204,13 +207,14 @@ macro_rules! shadow {
};
}
-/// It's shadow-rs Initialization entry.
+/// Generates build information for the current project.
+/// This function must be called from `build.rs`.
///
-/// In build.rs `main()` function call for this function.
-///
-/// # Examples
+/// # Example
///
/// ```ignore
+/// // build.rs
+///
/// fn main() -> shadow_rs::SdResult<()> {
/// shadow_rs::new()
/// }
@@ -220,14 +224,16 @@ pub fn new() -> SdResult<()> {
Ok(())
}
-/// It's shadow-rs Initialization entry, If deny const is configured, constants will not be generated.
+/// Identical to [`new`], but additionally accepts a build output denylist.
+/// This list determines constants to be excluded in the build output.
///
-/// In build.rs `main()` function call for this function.
-///
-/// # Examples
+/// Note that not all constants can be excluded independently, since some constants depend on others.
+/// See [`ShadowConst`] for a list of constants that can be excluded.
///
+/// # Example
///
/// ```ignore
+/// // build.rs
///
/// use std::collections::BTreeSet;
///
@@ -242,13 +248,15 @@ pub fn new_deny(deny_const: BTreeSet) -> SdResult<()> {
Ok(())
}
-/// It's shadow-rs Initialization entry with add custom hook.
-///
-/// In build.rs `main()` function call for this function.
+/// Identical to [`new`], but additionally accepts an output hook.
+/// The hook receives the output file of `shadow-rs`, and it can add additional entries to the output of `shadow-rs` by writing to this file.
+/// Note that since the output will be compiled as a Rust module, inserting invalid Rust code will lead to a compile error later on.
///
-/// # Examples
+/// # Example
///
/// ```ignore
+/// // build.rs
+///
/// fn main() -> shadow_rs::SdResult<()> {
/// shadow_rs::new_hook(append_write_const)
/// }
@@ -268,7 +276,7 @@ where
shadow.hook(f)
}
-/// get std::env:vars
+/// Returns the contents of [`std::env::vars`] as an ordered map.
pub fn get_std_env() -> BTreeMap {
let mut env_map = BTreeMap::new();
for (k, v) in std_env::vars() {
@@ -277,15 +285,25 @@ pub fn get_std_env() -> BTreeMap {
env_map
}
+/// `shadow-rs` configuration.
+///
+/// If you use the recommended utility functions [`new`], [`new_deny`], or [`new_hook`], you do not have to handle [`Shadow`] configurations themselves.
+/// However, this struct provides more fine-grained access to `shadow-rs` configuration, such as using a denylist and a hook function at the same time.
#[derive(Debug)]
pub struct Shadow {
+ /// The file that `shadow-rs` writes build information to.
pub f: File,
+ /// The values of build constants to be written.
pub map: BTreeMap,
+ /// Build environment variables, obtained through [`get_std_env`].
pub std_env: BTreeMap,
+ /// Constants in the denylist, passed through [`new_deny`] or [`Shadow::build`].
pub deny_const: BTreeSet,
}
impl Shadow {
+ /// Write the build configuration specified by this [`Shadow`] instance.
+ /// The hook function is run as well, allowing it to append to `shadow-rs`'s output.
pub fn hook(&self, f: F) -> SdResult<()>
where
F: FnOnce(&File) -> SdResult<()>,
@@ -296,7 +314,9 @@ impl Shadow {
Ok(())
}
- /// try get current ci env
+ /// Try to infer the CI system that we're currently running under.
+ ///
+ /// TODO: Recognize other CI types, especially Travis and Jenkins.
fn try_ci(&self) -> CiType {
if let Some(c) = self.std_env.get("GITLAB_CI") {
if c == "true" {
@@ -310,11 +330,11 @@ impl Shadow {
}
}
- //TODO completed [travis,jenkins] env
-
CiType::None
}
+ /// Create a new [`Shadow`] configuration with a provided denylist.
+ /// The project source path and output file are automatically derived from Cargo build environment variables.
pub fn build(deny_const: BTreeSet) -> SdResult {
let src_path = std::env::var("CARGO_MANIFEST_DIR")?;
let out_path = std::env::var("OUT_DIR")?;
@@ -382,12 +402,15 @@ impl Shadow {
Ok(())
}
+ /// Request Cargo to re-run the build script if any environment variable observed by this [`Shadow`] configuration changes.
pub fn cargo_rerun_if_env_changed(&self) {
for k in self.std_env.keys() {
println!("cargo:rerun-if-env-changed={k}");
}
}
+ /// Request Cargo to re-run the build script if any of the specified environment variables change.
+ /// This function is not influenced by this [`Shadow`] configuration.
pub fn cargo_rerun_env_inject(&self, env: &[&str]) {
for k in env {
println!("cargo:rerun-if-env-changed={}", *k);
@@ -404,10 +427,9 @@ impl Shadow {
fn gen_header(&self) -> SdResult<()> {
let desc = format!(
- r#"// Code generated by shadow-rs generator. DO NOT EDIT.
-// Author by:https://www.github.com/baoyachi
-// The build script repository:https://github.com/baoyachi/shadow-rs
-// Create time by:{}"#,
+ r#"// Code automatically generated by `shadow-rs` (https://github.com/baoyachi/shadow-rs), do not edit.
+// Author: https://www.github.com/baoyachi
+// Generation time: {}"#,
DateTime::now().human_format()
);
writeln!(&self.f, "{desc}\n\n")?;
@@ -492,7 +514,7 @@ impl Shadow {
}
let everything_define = format!(
- "/// print build in method\n\
+ "/// Prints all built-in `shadow-rs` build constants to standard output.\n\
#[allow(dead_code)]\n\
pub fn print_build_in() {\
{{print_val}}\