4 releases (breaking)
0.4.0 | Jan 25, 2024 |
---|---|
0.3.0 | Jun 18, 2023 |
0.2.0 | May 29, 2023 |
0.1.0 | May 29, 2023 |
#169 in Build Utils
4,571 downloads per month
28KB
357 lines
git2version
The 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.
- Add this to your Cargo.toml:
[workspace]
[dependencies]
version_proxy = {path = "./version_proxy"}
- Add these files to make up the proxy crate:
version_proxy/Cargo.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:
fn main() {
git2version::init_proxy_build!();
}
version_proxy/src/lib.rs:
git2version::init_proxy_lib!();
Usage
The init_proxy_lib!
macro in your proxy crate will generate something similar to the following:
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:
fn main() {
println!("Version from git: {:?}", version_proxy::GITINFO);
}
Alternatives
The 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 crate to read git information. This means it works without requiring agit
executable in your path.git2version
outputs structured information about the git version, whilegit-version
only outputs a string as produced bygit describe
. Ingit-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 thecargo:rerun-if-changed
mechanism ofbuild.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 aninclude_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 forbuild.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.
License: MIT OR Apache-2.0
Dependencies
~1.4–3.5MB
~74K SLoC