cargo/version.rs
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
//! Code for representing cargo's release version number.
use std::fmt;
/// Information about the git repository where cargo was built from.
pub struct CommitInfo {
pub short_commit_hash: String,
pub commit_hash: String,
pub commit_date: String,
}
/// Cargo's version.
pub struct VersionInfo {
/// Cargo's version, such as "1.57.0", "1.58.0-beta.1", "1.59.0-nightly", etc.
pub version: String,
/// The release channel we were built for (stable/beta/nightly/dev).
///
/// `None` if not built via bootstrap.
pub release_channel: Option<String>,
/// Information about the Git repository we may have been built from.
///
/// `None` if not built from a git repo.
pub commit_info: Option<CommitInfo>,
}
impl fmt::Display for VersionInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.version)?;
if let Some(ref ci) = self.commit_info {
write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
};
Ok(())
}
}
/// Returns information about cargo's version.
pub fn version() -> VersionInfo {
macro_rules! option_env_str {
($name:expr) => {
option_env!($name).map(|s| s.to_string())
};
}
// This is the version set in bootstrap, which we use to match rustc.
let version = option_env_str!("CFG_RELEASE").unwrap_or_else(|| {
// If cargo is not being built by bootstrap, then we just use the
// version from cargo's own `Cargo.toml`.
//
// There are two versions at play here:
// - version of cargo-the-binary, which you see when you type `cargo --version`
// - version of cargo-the-library, which you download from crates.io for use
// in your packages.
//
// The library is permanently unstable, so it always has a 0 major
// version. However, the CLI now reports a stable 1.x version
// (starting in 1.26) which stays in sync with rustc's version.
//
// Coincidentally, the minor version for cargo-the-library is always
// +1 of rustc's minor version (that is, `rustc 1.11.0` corresponds to
// `cargo `0.12.0`). The versions always get bumped in lockstep, so
// this should continue to hold.
let minor = env!("CARGO_PKG_VERSION_MINOR").parse::<u8>().unwrap() - 1;
let patch = env!("CARGO_PKG_VERSION_PATCH").parse::<u8>().unwrap();
format!("1.{}.{}", minor, patch)
});
let release_channel = option_env_str!("CFG_RELEASE_CHANNEL");
let commit_info = option_env_str!("CARGO_COMMIT_HASH").map(|commit_hash| CommitInfo {
short_commit_hash: option_env_str!("CARGO_COMMIT_SHORT_HASH").unwrap(),
commit_hash,
commit_date: option_env_str!("CARGO_COMMIT_DATE").unwrap(),
});
VersionInfo {
version,
release_channel,
commit_info,
}
}