#
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,
        }
    }