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
//! Retrieve Git tag, store as environment variable at build time
//!
//! The command `git describe --tags`
//!
//! > ... finds the most recent tag that is reachable from a commit. If
//! > the tag points to the commit, then only the tag is shown. Otherwise,
//! > it suffixes the tag name with the number of additional commits on
//! > top of the tagged object and the abbreviated object name of the most
//! > recent commit. The result is a "human-readable" object name which
//! > can also be used to identify the commit to other git commands ...
//! >
//! > -- Git Manual
//!
//! Example
//! -------
//!
//! To use, simply add as a build dependency to your `cargo.toml`
//!
//! ```text
//! [package]
//! build = "build.rs"
//!
//! [build-dependencies]
//! git_describe_build_tool = "~1.0.0"
//! ```
//!
//! Then, add `build.rs`
//!
//! ```no_run
//! # #[allow(clippy::needless_doctest_main)]
//! use git_describe_build_tool::prelude::*;
//!
//! fn main() {
//!     git_build_script();
//! }
//! ```
//!
//! Then, in your code, whenever you want to reference the current version
//! use the `env!` macro
//!
//! ```no_run
//! pub const GIT_COMMIT_DESCRIBE: &str = env!("GIT_COMMIT_DESCRIBE");
//!
//! assert_eq! {
//!     "0.11.0-51-g4446464",
//!     GIT_COMMIT_DESCRIBE
//! }
//! ```

/// Name of the environment variable
pub const ENV_VAR_NAME: &str = "GIT_COMMIT_DESCRIBE";

pub mod prelude {
    pub use super::git_build_script;
}

/// Retrieve the version from git, then store in environment variable
pub fn git_build_script() {
    let _ = retrieve_app_version_from_git_repository()
        .or_else(|| Some("UNKNOWN".to_owned()))
        .map(store_app_version_in_environment_variable);
}

/// Retrieve the version from git
pub fn retrieve_app_version_from_git_repository() -> Option<String> {
    { std::process::Command::new("git").args(&["describe", "--tags"]) }
        .output()
        .ok()
        .filter(|o| o.status.success())
        .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_owned())
}

/// Store the version in environment variable
pub fn store_app_version_in_environment_variable(app_version: String) {
    println!("cargo:rustc-env={ENV_VAR_NAME}={app_version}");
}