Skip to content

Commit

Permalink
Overhaul documentation
Browse files Browse the repository at this point in the history
This adds documentation to all important public items, reworks the main
crate documentation, and vastly improves the documentation generated for
build constants.
  • Loading branch information
kleinesfilmroellchen committed May 22, 2023
1 parent d1f4096 commit e2e3233
Show file tree
Hide file tree
Showing 9 changed files with 428 additions and 366 deletions.
172 changes: 70 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
@@ -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).
========================================
<p align="center">
<img
Expand All @@ -17,45 +17,35 @@
[![DepStatus](https://deps.rs/repo/github/baoyachi/shadow-rs/status.svg)](https://deps.rs/repo/github/baoyachi/shadow-rs)
[![Gitter](https://badges.gitter.im/shadow-rs/community.svg)](https://gitter.im/shadow-rs/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Coverage Status](https://coveralls.io/repos/github/baoyachi/shadow-rs/badge.svg)](https://coveralls.io/github/baoyachi/shadow-rs)
`shadow-rs` allows you to access properties of the build process and environment at runtime, including:

`shadow-rs` allows you to recall 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.

![build_module](./build_module.png)

# Notice ⚠️
# Note on Caching

> 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 <https://github.com/baoyachi/shadow-rs/issues/95>.

# 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"

Expand All @@ -65,80 +55,63 @@ shadow-rs = "{latest version}"
[build-dependencies]
shadow-rs = "{latest version}"
```
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]

### 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()
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;

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
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. '[email protected]'

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)'
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!("{}", 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);//[email protected]

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)
}
```

Expand All @@ -148,33 +121,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 |
Expand All @@ -190,14 +158,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
Expand Down
9 changes: 9 additions & 0 deletions src/build.rs
Original file line number Diff line number Diff line change
@@ -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<ShadowConst, ConstVal>;
}

/// 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,
}

Expand All @@ -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,
}

Expand Down
6 changes: 2 additions & 4 deletions src/ci.rs
Original file line number Diff line number Diff line change
@@ -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,
}

Expand All @@ -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(),
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/date_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pub fn now_date_time() -> DateTime {
.expect("Input SOURCE_DATE_EPOCH could not be parsed")
.parse::<i64>()
.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())
}
}
Expand All @@ -50,9 +49,9 @@ impl DateTime {

#[cfg(not(feature = "tzdb"))]
pub fn local_now() -> Result<Self, Box<dyn Error>> {
// 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())
Expand Down
Loading

0 comments on commit e2e3233

Please sign in to comment.