Skip to content

Commit 45536a1

Browse files
authored
Add way to get build version information. (#748)
1 parent d118337 commit 45536a1

File tree

4 files changed

+116
-0
lines changed

4 files changed

+116
-0
lines changed

libgit2-sys/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ fn main() {
2222
}
2323
}
2424

25+
println!("cargo:rustc-cfg=libgit2_vendored");
26+
2527
if !Path::new("libgit2/.git").exists() {
2628
let _ = Command::new("git")
2729
.args(&["submodule", "update", "--init", "libgit2"])

libgit2-sys/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,15 @@ git_enum! {
19431943

19441944
pub type git_trace_cb = Option<extern "C" fn(level: git_trace_level_t, msg: *const c_char)>;
19451945

1946+
git_enum! {
1947+
pub enum git_feature_t {
1948+
GIT_FEATURE_THREADS = 1 << 0,
1949+
GIT_FEATURE_HTTPS = 1 << 1,
1950+
GIT_FEATURE_SSH = 1 << 2,
1951+
GIT_FEATURE_NSEC = 1 << 3,
1952+
}
1953+
}
1954+
19461955
extern "C" {
19471956
// threads
19481957
pub fn git_libgit2_init() -> c_int;
@@ -3948,6 +3957,9 @@ extern "C" {
39483957
given_opts: *const git_revert_options,
39493958
) -> c_int;
39503959

3960+
// Common
3961+
pub fn git_libgit2_version(major: *mut c_int, minor: *mut c_int, rev: *mut c_int) -> c_int;
3962+
pub fn git_libgit2_features() -> c_int;
39513963
pub fn git_libgit2_opts(option: c_int, ...) -> c_int;
39523964

39533965
// Worktrees
@@ -4092,3 +4104,8 @@ fn ssh_init() {
40924104

40934105
#[cfg(not(feature = "ssh"))]
40944106
fn ssh_init() {}
4107+
4108+
#[doc(hidden)]
4109+
pub fn vendored() -> bool {
4110+
cfg!(libgit2_vendored)
4111+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ pub use crate::transaction::Transaction;
135135
pub use crate::tree::{Tree, TreeEntry, TreeIter, TreeWalkMode, TreeWalkResult};
136136
pub use crate::treebuilder::TreeBuilder;
137137
pub use crate::util::IntoCString;
138+
pub use crate::version::Version;
138139
pub use crate::worktree::{Worktree, WorktreeAddOptions, WorktreeLockStatus, WorktreePruneOptions};
139140

140141
// Create a convinience method on bitflag struct which checks the given flag
@@ -695,6 +696,7 @@ mod tracing;
695696
mod transaction;
696697
mod tree;
697698
mod treebuilder;
699+
mod version;
698700
mod worktree;
699701

700702
fn init() {

src/version.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use crate::raw;
2+
use libc::c_int;
3+
use std::fmt;
4+
5+
/// Version information about libgit2 and the capabilities it supports.
6+
pub struct Version {
7+
major: c_int,
8+
minor: c_int,
9+
rev: c_int,
10+
features: c_int,
11+
}
12+
13+
macro_rules! flag_test {
14+
($features:expr, $flag:expr) => {
15+
($features as u32 & $flag as u32) != 0
16+
};
17+
}
18+
19+
impl Version {
20+
/// Returns a [`Version`] which provides information about libgit2.
21+
pub fn get() -> Version {
22+
let mut v = Version {
23+
major: 0,
24+
minor: 0,
25+
rev: 0,
26+
features: 0,
27+
};
28+
unsafe {
29+
raw::git_libgit2_version(&mut v.major, &mut v.minor, &mut v.rev);
30+
v.features = raw::git_libgit2_features();
31+
}
32+
v
33+
}
34+
35+
/// Returns the version of libgit2.
36+
///
37+
/// The return value is a tuple of `(major, minor, rev)`
38+
pub fn libgit2_version(&self) -> (u32, u32, u32) {
39+
(self.major as u32, self.minor as u32, self.rev as u32)
40+
}
41+
42+
/// Returns the version of the libgit2-sys crate.
43+
pub fn crate_version(&self) -> &'static str {
44+
env!("CARGO_PKG_VERSION")
45+
}
46+
47+
/// Returns true if this was built with the vendored version of libgit2.
48+
pub fn vendored(&self) -> bool {
49+
raw::vendored()
50+
}
51+
52+
/// Returns true if libgit2 was built thread-aware and can be safely used
53+
/// from multiple threads.
54+
pub fn threads(&self) -> bool {
55+
flag_test!(self.features, raw::GIT_FEATURE_THREADS)
56+
}
57+
58+
/// Returns true if libgit2 was built with and linked against a TLS implementation.
59+
///
60+
/// Custom TLS streams may still be added by the user to support HTTPS
61+
/// regardless of this.
62+
pub fn https(&self) -> bool {
63+
flag_test!(self.features, raw::GIT_FEATURE_HTTPS)
64+
}
65+
66+
/// Returns true if libgit2 was built with and linked against libssh2.
67+
///
68+
/// A custom transport may still be added by the user to support libssh2
69+
/// regardless of this.
70+
pub fn ssh(&self) -> bool {
71+
flag_test!(self.features, raw::GIT_FEATURE_SSH)
72+
}
73+
74+
/// Returns true if libgit2 was built with support for sub-second
75+
/// resolution in file modification times.
76+
pub fn nsec(&self) -> bool {
77+
flag_test!(self.features, raw::GIT_FEATURE_NSEC)
78+
}
79+
}
80+
81+
impl fmt::Debug for Version {
82+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
83+
let mut f = f.debug_struct("Version");
84+
f.field("major", &self.major)
85+
.field("minor", &self.minor)
86+
.field("rev", &self.rev)
87+
.field("crate_version", &self.crate_version())
88+
.field("vendored", &self.vendored())
89+
.field("threads", &self.threads())
90+
.field("https", &self.https())
91+
.field("ssh", &self.ssh())
92+
.field("nsec", &self.nsec());
93+
f.finish()
94+
}
95+
}

0 commit comments

Comments
 (0)