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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// Copyright Open Logistics Foundation
//
// Licensed under the Open Logistics Foundation License 1.3.
// For details on the licensing terms, see the LICENSE file.
// SPDX-License-Identifier: OLFL-1.3
// When used in a build.rs, we use std features for convenience. When used in a (possibly no_std)
// firmware or application, this is a no_std lib which only defines the SemanticVersion and
// GitVersion types.
//! Tool to extract SemVer Version Information from annotated git tags
//! This package allows to extract SemVer version information from annotated git tags in the format
//! "vX.Y.Z". It is used from build.rs build scripts. For usage details, see the API documentation.
//!
//! This crate is made to call and parse the git describe command. It is assumed that the repo uses
//! _annotated_ git tags in the format "vX.Y.Z" or "vX.Y.Z-rc". So for example, the first commit of
//! the release candidate branch for 1.0.0 should be tagged with "v1.0.0-rc" and the actual 1.0.0
//! release should be tagged with "v1.0.0". This information has to be extracted at compile time so
//! it needs to be done in a `build.rs`. Since the `build.rs` is run in the directory of the crate
//! it belongs to, your project itself should contain that `build.rs`, i.e. it should not be done
//! in a git submodule or a dependency of your project. The following `build.rs` will write the
//! version information to `version.rs` in the current `OUT_DIR` directory which is
//! ["the folder in which all output and intermediate artifacts should be placed"](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts)
//! by build scripts:
//!
//! ```
//! use std::env;
//! use std::fs;
//! use std::path::Path;
//! use std::process::Command;
//! use git_tags_semver::{Rust, Lang};
//!
//! # // The test only works if the "build" feature is activated. To prevent the test from failing,
//! # // we add an empty main function below if it is not activated.
//! fn main() {
//! // Tell Cargo that if the given file changes, to rerun this build script (adjust the path
//! // to the .git directory accordingly if required, e.g. when the crate is in a workspace)
//! println!("cargo:rerun-if-changed=.git/index");
//! println!("cargo:rerun-if-changed=.git/HEAD");
//! println!("cargo:rerun-if-changed=.git/logs/HEAD");
//! println!("cargo:rerun-if-changed=build.rs");
//!
//! // Extract the version information and generate the corresponding code
//! let out = Rust.fmt_version_getter(&git_tags_semver::parse_git_describe().unwrap());
//! # // We are not in a true build.rs here, so set the required environment variables manually
//! # unsafe { env::set_var("OUT_DIR", env::temp_dir()); };
//!
//! // Write the generated version information code to version.rs in the OUT_DIR directory
//! let out_dir = env::var_os("OUT_DIR").unwrap();
//! let dest_path = Path::new(&out_dir).join("version.rs");
//! fs::write(&dest_path, &out).unwrap();
//!
//! // Touch build.rs to force recompilation on every workspace build. This may be desirable
//! // because it ensures that the information is guaranteed to be up-to-date. On the other
//! // hand, it may slow down your development process a tiny little bit because it enforces
//! // a rebuild all the time. For example, your crate will be rebuilt before each `cargo run`
//! // which does not happen normally (if the crate was built before, it can normally be run
//! // immediately).
//! Command::new("touch")
//! .args(&["build.rs"])
//! .output()
//! .expect("Could not touch build.rs!");
//! # // Currently, this crate does not have a build.rs so we have to clean up after ourselves
//! # Command::new("rm").args(&["build.rs"]).output()
//! # .expect("Could not clean up, i.e. remove build.rs");
//! }
//! ```
//!
//! Afterwards, `<OUT_DIR>/version.rs` contains a `pub fn get_version() ->` [`GitVersion`](GitVersion).
//! Specifically, that file looks like:
//!
//! ```ignore
//! pub fn get_version() -> git_tags_semver::GitVersion {
//! git_tags_semver::GitVersion {
//! semver: Some(git_tags_semver::SemanticVersion {
//! major: 1,
//! minor: 0,
//! patch: 0,
//! rc: false,
//! commits: 0
//! }),
//! hash: [
//! 0x12,
//! 0x34,
//! 0xab,
//! 0xcd,
//! ],
//! dirty: false,
//! git_string: "v1.0.0-00-g1234abcd"
//! }
//! }
//! ```
//!
//! To use it in your application, you can include the generated code like that:
//!
//! ```ignore
//! include!(concat!(env!("OUT_DIR"), "/version.rs"));
//!
//! fn main() {
//! println!("{:?}", get_version());
//! }
//! ```
//!
//! # Cargo.toml / Feature-Gates
//!
//! This tool is especially designed to be used in `no_std` contexts, e.g. bare-metal firmwares.
//! Therefore, it is generally `no_std` (the type definitions) but for extracting and writing the
//! version information to an intermediate file, it needs the standard library (and `build.rs` is
//! run with `std`, even for `no_std` packages). Thus, the standard library usage which enables the
//! part required in the `build.rs` has to be enabled with the "build" feature. So, for a `no_std`
//! package, you need to add it as a dependency twice, the corresponding part in your `Cargo.toml`
//! could look like this:
//!
//! ```toml
//! [dependencies]
//! git-tags-semver = { version = "1.0.0", default-features = false }
//!
//! [build-dependencies]
//! git-tags-semver = { version = "1.0.0" }
//! ```
//!
//! Note that this additionally requires to use
//! [feature resolver version 2](https://doc.rust-lang.org/cargo/reference/resolver.html#feature-resolver-version-2)
//! for your project which is
//! [the default since Rust's 2021 edition](https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions)
//! or can be specified with `resolver = "2"` in your `Cargo.toml` (if using a workspace, this must
//! be done in the top-level/workspace `Cargo.toml`).
//!
//! # License
//!
//! Open Logistics Foundation License
//! Version 1.3, January 2023\
//! See the LICENSE file in the top-level directory.
//!
//! # Contact
//!
//! Fraunhofer IML Embedded Rust Group - <embedded-rust@iml.fraunhofer.de>
pub use heapless;
pub use crate;
pub use crate;
/// Create the Rust getter function of the `GitVersion` struct
///
/// This function is deprecated. Instead you should use the following (this is exactly what is done
/// in this function):
/// ```rust
/// use git_tags_semver::{Rust, Lang};
/// let out = Rust.fmt_version_getter(&git_tags_semver::parse_git_describe().unwrap());
/// ```
/// Run and parse the `git describe` command to build a `GitVersion` struct
/// Create the full language code, including the prelude