Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync cargo-the-cli version with rustc. #10178

Merged
merged 3 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/bin/cargo/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,7 @@ pub fn get_version_string(is_verbose: bool) -> String {
let version = cargo::version();
let mut version_string = format!("cargo {}\n", version);
if is_verbose {
version_string.push_str(&format!(
"release: {}.{}.{}\n",
version.major, version.minor, version.patch
));
version_string.push_str(&format!("release: {}\n", version.version,));
if let Some(ref cfg) = version.cfg_info {
if let Some(ref ci) = cfg.commit_info {
version_string.push_str(&format!("commit-hash: {}\n", ci.commit_hash));
Expand Down
101 changes: 2 additions & 99 deletions src/cargo/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use crate::core::shell::Verbosity::Verbose;
use crate::core::Shell;
use anyhow::Error;
use log::debug;
use std::fmt;

pub use crate::util::errors::{InternalError, VerboseError};
pub use crate::util::{indented_lines, CargoResult, CliError, CliResult, Config};
pub use crate::version::version;

pub const CARGO_ENV: &str = "CARGO";

Expand All @@ -26,49 +26,7 @@ pub mod core;
pub mod ops;
pub mod sources;
pub mod util;

pub struct CommitInfo {
pub short_commit_hash: String,
pub commit_hash: String,
pub commit_date: String,
}

pub struct CfgInfo {
// Information about the Git repository we may have been built from.
pub commit_info: Option<CommitInfo>,
// The release channel we were built for.
pub release_channel: String,
}

pub struct VersionInfo {
pub major: u8,
pub minor: u8,
pub patch: u8,
pub pre_release: Option<String>,
// Information that's only available when we were built with
// configure/make, rather than Cargo itself.
pub cfg_info: Option<CfgInfo>,
}

impl fmt::Display for VersionInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)?;
if let Some(channel) = self.cfg_info.as_ref().map(|ci| &ci.release_channel) {
if channel != "stable" {
write!(f, "-{}", channel)?;
let empty = String::new();
write!(f, "{}", self.pre_release.as_ref().unwrap_or(&empty))?;
}
};

if let Some(ref cfg) = self.cfg_info {
if let Some(ref ci) = cfg.commit_info {
write!(f, " ({} {})", ci.short_commit_hash, ci.commit_date)?;
}
};
Ok(())
}
}
mod version;

pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! {
debug!("exit_with_error; err={:?}", err);
Expand Down Expand Up @@ -143,58 +101,3 @@ fn _display_error(err: &Error, shell: &mut Shell, as_err: bool) -> bool {
}
false
}

pub fn version() -> VersionInfo {
macro_rules! option_env_str {
($name:expr) => {
option_env!($name).map(|s| s.to_string())
};
}

// So this is pretty horrible...
// 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.
//
// We want to make the `binary` version the same as the corresponding Rust/rustc release.
// At the same time, we want to keep the library version at `0.x`, because Cargo as
// a library is (and probably will always be) unstable.
//
// Historically, Cargo used the same version number for both the binary and the library.
// Specifically, rustc 1.x.z was paired with cargo 0.x+1.w.
// We continue to use this scheme for the library, but transform it to 1.x.w for the purposes
// of `cargo --version`.
let major = 1;
let minor = env!("CARGO_PKG_VERSION_MINOR").parse::<u8>().unwrap() - 1;
let patch = env!("CARGO_PKG_VERSION_PATCH").parse::<u8>().unwrap();

match option_env!("CFG_RELEASE_CHANNEL") {
// We have environment variables set up from configure/make.
Some(_) => {
let commit_info = option_env!("CFG_COMMIT_HASH").map(|s| CommitInfo {
commit_hash: s.to_string(),
short_commit_hash: option_env_str!("CFG_SHORT_COMMIT_HASH").unwrap(),
commit_date: option_env_str!("CFG_COMMIT_DATE").unwrap(),
});
VersionInfo {
major,
minor,
patch,
pre_release: option_env_str!("CARGO_PKG_VERSION_PRE"),
cfg_info: Some(CfgInfo {
release_channel: option_env_str!("CFG_RELEASE_CHANNEL").unwrap(),
commit_info,
}),
}
}
// We are being compiled by Cargo itself.
None => VersionInfo {
major,
minor,
patch,
pre_release: option_env_str!("CARGO_PKG_VERSION_PRE"),
cfg_info: None,
},
}
}
95 changes: 95 additions & 0 deletions src/cargo/version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//! 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,
}

/// Information provided by the outer build system (rustbuild aka bootstrap).
pub struct CfgInfo {
/// Information about the Git repository we may have been built from.
pub commit_info: Option<CommitInfo>,
/// The release channel we were built for (stable/beta/nightly/dev).
pub release_channel: 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,
/// Information that's only available when we were built with
/// rustbuild, rather than Cargo itself.
pub cfg_info: Option<CfgInfo>,
}

impl fmt::Display for VersionInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.version)?;

if let Some(ref cfg) = self.cfg_info {
if let Some(ref ci) = cfg.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 rustbuild, which we use to match rustc.
let version = option_env_str!("CFG_RELEASE").unwrap_or_else(|| {
// If cargo is not being built by rustbuild, 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)
});

match option_env!("CFG_RELEASE_CHANNEL") {
// We have environment variables set up from configure/make.
Some(_) => {
let commit_info = option_env!("CFG_COMMIT_HASH").map(|s| CommitInfo {
commit_hash: s.to_string(),
short_commit_hash: option_env_str!("CFG_SHORT_COMMIT_HASH").unwrap(),
commit_date: option_env_str!("CFG_COMMIT_DATE").unwrap(),
});
VersionInfo {
version,
cfg_info: Some(CfgInfo {
release_channel: option_env_str!("CFG_RELEASE_CHANNEL").unwrap(),
commit_info,
}),
}
}
// We are being compiled by Cargo itself.
None => VersionInfo {
version,
cfg_info: None,
},
}
}