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
//! The [git2version](https://crates.io/crates/git2version) crate provides a way to get the version of the package from git and incorporate it as a constant into your program.
//!
//!
//! ## Setup
//!
//! To use this, you need to setup a proxy-crate in your workspace.
//!
//! 1. Add this to your Cargo.toml:
//!
//! ```toml
//! [workspace]
//!
//! [dependencies]
//! version_proxy = {path = "./version_proxy"}
//! ```
//!
//! 2. Add these files to make up the proxy crate:
//!
//! #### version_proxy/Cargo.toml:
//! ```toml
//! [package]
//! name = "version_proxy"
//! # The version field here is ignored, no need to change it
//! version = "0.0.0"
//!
//! [dependencies]
//! git2version = "*"
//!
//! [build-dependencies]
//! git2version = "*"
//! ```
//! You can also lock the version of git2version to a specific version instead of using `*`.
//!
//! #### version_proxy/build.rs:
//! ```ignore
//! fn main() {
//! git2version::init_proxy_build!();
//! }
//! ```
//!
//! #### version_proxy/src/lib.rs:
//! ```ignore
//! git2version::init_proxy_lib!();
//! ```
//!
//!
//! ## Usage
//!
//! The `init_proxy_lib!` macro in your proxy crate will generate something similar to the following:
//! ```rust
//! # use git2version::{GitInfo, TagInfo};
//! pub const GITINFO: Option<GitInfo> =
//! Some(GitInfo {
//! tag_info: Some(TagInfo {
//! tag:"v1.2.3-alpha",
//! commits_since_tag: 5,
//! }),
//! commit_id: "a9ebd080a7",
//! modified: false,
//! });
//! ```
//! This object can be `None` if the crate is not in a git repository or if there was an error looking up the version information from git.
//!
//! You can use this const from your main crate, for example like this:
//! ```ignore
//! fn main() {
//! println!("Version from git: {:?}", version_proxy::GITINFO);
//! }
//! ```
//!
//!
//! ## Alternatives
//!
//! The [git-version](https://crates.io/crates/git-version) crate provides similar functionality.
//!
//! The main advantage of `git-version` over `git2version` is that it is much simpler to use. It uses a proc-macro based approach and doesn't require you to set up a proxy crate.
//!
//! The advantages of `git2version` over `git-version` are as follows:
//! * `git2version` uses the [git2](https://crates.io/crates/git2) crate to read git information. This means it works without requiring a `git` executable in your path.
//! * `git2version` outputs structured information about the git version, while `git-version` only outputs a string as produced by `git describe`.
//! In `git-version`, you have to parse that string yourself and it might not always contain all the information (e.g. `git describe --tags` doesn't output the commit id when you have the
//! tag itself checked out). `git2version` always gives you the commit id.
//!
//! Another point of note is that both crates use a different mechanism for change detection for incremental builds.
//! * `git2version` uses the `cargo:rerun-if-changed` mechanism of `build.rs` to re-generate the version number whenever the git repository changes (e.g. new tags being added, `git fetch` being called, ...)
//! and whenever files in the working copy change. The latter is important because it could cause a change to the `-modified` flag of the reported version.
//! * `git-version` uses an `include_bytes!` mechanism to include bytes from your git repository data into the generated source code, which will cause cargo to detect it as a dependency and rerun the proc macro
//! when the git repository data changes. This sounds hacky but might work. I have not tested how reliable or scalable that approach is.
//! `cargo:rerun-if-changed` is the officially supported way to do this kind of change detection, so I would expect it to be more reliable, but it only works for `build.rs` scripts, not for proc macros.
//!
//!
//! ## Why is the proxy crate required?
//!
//! The crate needs to know the directory of your git repository to read version information.
//! However, the `git2version` crate gets compiled independently from that and doesn't have access to your git repository.
//! This is why we need a proxy crate inside of your git repository that knows its location and can evaluate the version information.
//!
//! You may ask why we do it in a proxy crate instead of just having your main crate evaluate the version information, after all
//! your main crate is also in your repository. The reason is that the `build.rs` code used to evaluate the version information
//! needs to run **after every single file modification** because that could influence the `modified` tag of the git version information.
//! If we put this into your main crate, then incremental compilations become basically useless because it needs to re-compile everything
//! for every change. By putting it into a proxy crate, we only need to re-compile the code in the proxy crate and link your main crate
//! against it.
// TODO #![cfg_attr(not(feature = "std"), no_std)]
/// The length of the shortened git commit hash used in [`GitInfo::commit_id`].
///
/// This is set to 10 characters, which provides sufficient uniqueness for most
/// repositories while remaining human-readable. The git default of 7 characters
/// can have collisions in larger repositories, so this crate uses a slightly longer value.
///
/// # Example
///
/// A full commit hash like `a9ebd080a7b1c76a8b3f3080a7b1c7c76a8b3f30` would be
/// shortened to `a9ebd080a7` (10 characters).
pub const COMMIT_ID_SHORT_HASH_LENGTH: usize = 10;
pub use ;
pub use ;
// We need to re-export this because our macros use it
pub use git2;
pub use konst;