git2version/
lib.rs

1//! 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.
2//!
3//!
4//! ## Setup
5//!
6//! To use this, you need to setup a proxy-crate in your workspace.
7//!
8//! 1. Add this to your Cargo.toml:
9//!
10//! ```toml
11//! [workspace]
12//!
13//! [dependencies]
14//! version_proxy = {path = "./version_proxy"}
15//! ```
16//!
17//! 2. Add these files to make up the proxy crate:
18//!
19//! #### version_proxy/Cargo.toml:
20//! ```toml
21//! [package]
22//! name = "version_proxy"
23//! # The version field here is ignored, no need to change it
24//! version = "0.0.0"
25//!
26//! [dependencies]
27//! git2version = "*"
28//!
29//! [build-dependencies]
30//! git2version = "*"
31//! ```
32//! You can also lock the version of git2version to a specific version instead of using `*`.
33//!
34//! #### version_proxy/build.rs:
35//! ```ignore
36//! fn main() {
37//!     git2version::init_proxy_build!();
38//! }
39//! ```
40//!
41//! #### version_proxy/src/lib.rs:
42//! ```ignore
43//! git2version::init_proxy_lib!();
44//! ```
45//!
46//!
47//! ## Usage
48//!
49//! The `init_proxy_lib!` macro in your proxy crate will generate something similar to the following:
50//! ```rust
51//! # use git2version::{GitInfo, TagInfo};
52//! pub const GITINFO: Option<GitInfo> =
53//!     Some(GitInfo {
54//!       tag_info: Some(TagInfo {
55//!         tag:"v1.2.3-alpha",
56//!         commits_since_tag: 5,
57//!       }),
58//!       commit_id: "a9ebd080a7",
59//!       modified: false,
60//!     });
61//! ```
62//! 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.
63//!
64//! You can use this const from your main crate, for example like this:
65//! ```ignore
66//! fn main() {
67//!     println!("Version from git: {:?}", version_proxy::GITINFO);
68//! }
69//! ```
70//!
71//!
72//! ## Alternatives
73//!
74//! The [git-version](https://crates.io/crates/git-version) crate provides similar functionality.
75//!
76//! 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.
77//!
78//! The advantages of `git2version` over `git-version` are as follows:
79//! * `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.
80//! * `git2version` outputs structured information about the git version, while `git-version` only outputs a string as produced by `git describe`.
81//!   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
82//!   tag itself checked out). `git2version` always gives you the commit id.
83//!
84//! Another point of note is that both crates use a different mechanism for change detection for incremental builds.
85//! * `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, ...)
86//!   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.
87//! * `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
88//!   when the git repository data changes. This sounds hacky but might work. I have not tested how reliable or scalable that approach is.
89//!   `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.
90//!
91//!
92//! ## Why is the proxy crate required?
93//!
94//! The crate needs to know the directory of your git repository to read version information.
95//! However, the `git2version` crate gets compiled independently from that and doesn't have access to your git repository.
96//! This is why we need a proxy crate inside of your git repository that knows its location and can evaluate the version information.
97//!
98//! You may ask why we do it in a proxy crate instead of just having your main crate evaluate the version information, after all
99//! your main crate is also in your repository. The reason is that the `build.rs` code used to evaluate the version information
100//! needs to run **after every single file modification** because that could influence the `modified` tag of the git version information.
101//! If we put this into your main crate, then incremental compilations become basically useless because it needs to re-compile everything
102//! 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
103//! against it.
104
105#![forbid(unsafe_code)]
106#![deny(missing_docs)]
107// TODO #![cfg_attr(not(feature = "std"), no_std)]
108
109/// The length of the shortened git commit hash used in [`GitInfo::commit_id`].
110///
111/// This is set to 10 characters, which provides sufficient uniqueness for most
112/// repositories while remaining human-readable. The git default of 7 characters
113/// can have collisions in larger repositories, so this crate uses a slightly longer value.
114///
115/// # Example
116///
117/// A full commit hash like `a9ebd080a7b1c76a8b3f3080a7b1c7c76a8b3f30` would be
118/// shortened to `a9ebd080a7` (10 characters).
119pub const COMMIT_ID_SHORT_HASH_LENGTH: usize = 10;
120
121#[cfg(feature = "build")]
122mod git_helpers;
123#[cfg(feature = "build")]
124mod gitinfo_owned;
125#[cfg(feature = "build")]
126pub use gitinfo_owned::{GitInfoOwned, get_git_info};
127
128mod gitinfo;
129pub use gitinfo::{GitInfo, TagInfo};
130
131mod proxy;
132
133// We need to re-export this because our macros use it
134#[cfg(feature = "build")]
135pub use git2;
136pub use konst;