| //! 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>, | |
| /// A descriptive string to be appended to version output. | |
| /// | |
| /// This is usually set by the bootstrap in rust-lang/rust | |
| /// via the `CFG_VER_DESCRIPTION` environment variable. | |
| /// Useful for showing vendor build information. | |
| /// For example, | |
| /// | |
| /// ```text | |
| /// cargo 1.85.0 (d73d2caf9 2024-12-31) (MyCustomBuild 1.85.0-3) | |
| /// ``` | |
| pub description: Option<String>, | |
| } | |
| 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)?; | |
| }; | |
| if let Some(description) = self.description.as_ref().filter(|d| !d.is_empty()) { | |
| write!(f, " ({description})")?; | |
| }; | |
| 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(), | |
| }); | |
| let description = option_env_str!("CFG_VER_DESCRIPTION"); | |
| VersionInfo { | |
| version, | |
| release_channel, | |
| commit_info, | |
| description, | |
| } | |
| } |