#
cargo/
version.rs

    1//! Code for representing cargo's release version number.
    2
    3use std::fmt;
    4
    5/// Information about the git repository where cargo was built from.
    6pub struct CommitInfo {
    7    pub short_commit_hash: String,
    8    pub commit_hash: String,
    9    pub commit_date: String,
    10}
    11
    12/// Cargo's version.
    13pub struct VersionInfo {
    14    /// Cargo's version, such as "1.57.0", "1.58.0-beta.1", "1.59.0-nightly", etc.
    15    pub version: String,
    16    /// The release channel we were built for (stable/beta/nightly/dev).
    17    ///
    18    /// `None` if not built via bootstrap.
    19    pub release_channel: Option<String>,
    20    /// Information about the Git repository we may have been built from.
    21    ///
    22    /// `None` if not built from a git repo.
    23    pub commit_info: Option<CommitInfo>,
    24
    25    /// A descriptive string to be appended to version output.
    26    ///
    27    /// This is usually set by the bootstrap in rust-lang/rust
    28    /// via the `CFG_VER_DESCRIPTION` environment variable.
    29    /// Useful for showing vendor build information.
    30    /// For example,
    31    ///
    32    /// ```text
    33    /// cargo 1.85.0 (d73d2caf9 2024-12-31) (MyCustomBuild 1.85.0-3)
    34    /// ```
    35    pub description: Option<String>,
    36}
    37
    38impl fmt::Display for VersionInfo {
    39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    40        write!(f, "{}", self.version)?;
    41
    42        if let Some(ref ci) = self.commit_info {
    43            write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
    44        };
    45
    46        if let Some(description) = self.description.as_ref().filter(|d| !d.is_empty()) {
    47            write!(f, " ({description})")?;
    48        };
    49        Ok(())
    50    }
    51}
    52
    53/// Returns information about cargo's version.
    54pub fn version() -> VersionInfo {
    55    macro_rules! option_env_str {
    56        ($name:expr) => {
    57            option_env!($name).map(|s| s.to_string())
    58        };
    59    }
    60
    61    // This is the version set in bootstrap, which we use to match rustc.
    62    let version = option_env_str!("CFG_RELEASE").unwrap_or_else(|| {
    63        // If cargo is not being built by bootstrap, then we just use the
    64        // version from cargo's own `Cargo.toml`.
    65        //
    66        // There are two versions at play here:
    67        //   - version of cargo-the-binary, which you see when you type `cargo --version`
    68        //   - version of cargo-the-library, which you download from crates.io for use
    69        //     in your packages.
    70        //
    71        // The library is permanently unstable, so it always has a 0 major
    72        // version. However, the CLI now reports a stable 1.x version
    73        // (starting in 1.26) which stays in sync with rustc's version.
    74        //
    75        // Coincidentally, the minor version for cargo-the-library is always
    76        // +1 of rustc's minor version (that is, `rustc 1.11.0` corresponds to
    77        // `cargo `0.12.0`). The versions always get bumped in lockstep, so
    78        // this should continue to hold.
    79        let minor = env!("CARGO_PKG_VERSION_MINOR").parse::<u8>().unwrap() - 1;
    80        let patch = env!("CARGO_PKG_VERSION_PATCH").parse::<u8>().unwrap();
    81        format!("1.{}.{}", minor, patch)
    82    });
    83
    84    let release_channel = option_env_str!("CFG_RELEASE_CHANNEL");
    85    let commit_info = option_env_str!("CARGO_COMMIT_HASH").map(|commit_hash| CommitInfo {
    86        short_commit_hash: option_env_str!("CARGO_COMMIT_SHORT_HASH").unwrap(),
    87        commit_hash,
    88        commit_date: option_env_str!("CARGO_COMMIT_DATE").unwrap(),
    89    });
    90    let description = option_env_str!("CFG_VER_DESCRIPTION");
    91
    92    VersionInfo {
    93        version,
    94        release_channel,
    95        commit_info,
    96        description,
    97    }
    98}