Skip to content

Commit

Permalink
export rich version information from cargo::version
Browse files Browse the repository at this point in the history
To support `cargo --version --verbose`, ala rustc, we need more
information to be injected into cargo when it's built from the Makefile,
and a more explicit data structure to be returned from cargo::version.
We implement fmt::Display for our newly-created structure so clients
don't have to bother with the details of interpreting the structure if
all they want is a string.
  • Loading branch information
froydnj committed Jan 27, 2017
1 parent 84ef722 commit 775c900
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 16 deletions.
28 changes: 22 additions & 6 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ endif
# allow build systems to use a constant date instead of the current one
CFG_BUILD_DATE = $(shell SOURCE_DATE_EPOCH="$${SOURCE_DATE_EPOCH:-$$(date +%s)}" ; date -u -d "@$$SOURCE_DATE_EPOCH" +%F 2>/dev/null || date -u -r "$$SOURCE_DATE_EPOCH" +%F 2>/dev/null || date -u +%F)

ifeq ($(wildcard $(CFG_SRC_DIR)/.git),)
CFG_VERSION = $(CFG_RELEASE) (built $(CFG_BUILD_DATE))
else
CFG_VER_DATE = $(shell git --git-dir='$(CFG_SRC_DIR).git' log -1 --date=short --pretty=format:'%cd')
CFG_VER_HASH = $(shell git --git-dir='$(CFG_SRC_DIR).git' rev-parse --short HEAD)
CFG_VERSION = $(CFG_RELEASE) ($(CFG_VER_HASH) $(CFG_VER_DATE))
ifneq ($(wildcard $(CFG_SRC_DIR)/.git),)
CFG_COMMIT_DATE = $(shell git --git-dir='$(CFG_SRC_DIR).git' log -1 --date=short --pretty=format:'%cd')
CFG_SHORT_COMMIT_HASH = $(shell git --git-dir='$(CFG_SRC_DIR).git' rev-parse --short HEAD)
CFG_COMMIT_HASH = $(shell git --git-dir='$(CFG_SRC_DIR).git' rev-parse HEAD)
endif
PKG_NAME = cargo-$(CFG_PACKAGE_VERS)

Expand Down Expand Up @@ -58,7 +56,25 @@ endif

S := $(CFG_SRC_DIR)/

CFG_RELEASE_PARTS := $(subst ., ,$(CFG_RELEASE_NUM))
CFG_VERSION_MAJOR := $(word 1,$(CFG_RELEASE_PARTS))
CFG_VERSION_MINOR := $(word 2,$(CFG_RELEASE_PARTS))
CFG_VERSION_PATCH := $(word 3,$(CFG_RELEASE_PARTS))

export CFG_VERSION
export CFG_VERSION_MAJOR
export CFG_VERSION_MINOR
export CFG_VERSION_PATCH
ifneq ($(CFG_PRERELEASE_VERSION),)
export CFG_PRERELEASE_VERSION
endif
ifneq ($(CFG_COMMIT_HASH),)
export CFG_COMMIT_HASH
export CFG_COMMIT_DATE
export CFG_SHORT_COMMIT_HASH
endif
export CFG_BUILD_DATE
export CFG_RELEASE_CHANNEL
export CFG_DISABLE_CROSS_TESTS

ifeq ($(OS),Windows_NT)
Expand Down
107 changes: 98 additions & 9 deletions src/cargo/lib.rs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extern crate toml;
extern crate url;

use std::env;
use std::fmt;
use std::io;
use rustc_serialize::{Decodable, Encodable};
use rustc_serialize::json;
Expand All @@ -49,6 +50,62 @@ 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 date that the build was performed.
pub build_date: String,
// The release channel we were built for.
pub release_channel: String,
}

pub struct VersionInfo {
pub major: String,
pub minor: String,
pub patch: String,
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, "cargo-{}.{}.{}",
self.major, self.minor, self.patch)?;
match self.cfg_info.as_ref().map(|ci| &ci.release_channel) {
Some(channel) => {
if channel != "stable" {
write!(f, "-{}", channel)?;
let empty = String::from("");
write!(f, "{}", self.pre_release.as_ref().unwrap_or(&empty))?;
}
},
None => (),
};

if let Some(ref cfg) = self.cfg_info {
match cfg.commit_info {
Some(ref ci) => {
write!(f, " ({} {})",
ci.short_commit_hash, ci.commit_date)?;
},
None => {
write!(f, " (built {})",
cfg.build_date)?;
}
}
};
Ok(())
}
}

pub fn execute_main_without_stdin<T, V>(
exec: fn(T, &Config) -> CliResult<Option<V>>,
options_first: bool,
Expand Down Expand Up @@ -201,15 +258,47 @@ fn handle_cause(mut cargo_err: &CargoError, shell: &mut MultiShell) -> bool {
}
}

pub fn version() -> String {
format!("cargo {}", match option_env!("CFG_VERSION") {
Some(s) => s.to_string(),
None => format!("{}.{}.{}{}",
env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR"),
env!("CARGO_PKG_VERSION_PATCH"),
option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
})
pub fn version() -> VersionInfo {
macro_rules! env_str {
($name:expr) => { env!($name).to_string() }
}
macro_rules! option_env_str {
($name:expr) => { option_env!($name).map(|s| s.to_string()) }
}
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: option_env_str!("CFG_VERSION_MAJOR").unwrap(),
minor: option_env_str!("CFG_VERSION_MINOR").unwrap(),
patch: option_env_str!("CFG_VERSION_PATCH").unwrap(),
pre_release: option_env_str!("CFG_PRERELEASE_VERSION"),
cfg_info: Some(CfgInfo {
build_date: option_env_str!("CFG_BUILD_DATE").unwrap(),
release_channel: option_env_str!("CFG_RELEASE_CHANNEL").unwrap(),
commit_info: commit_info,
}),
}
},
// We are being compiled by Cargo itself.
None => {
VersionInfo {
major: env_str!("CARGO_PKG_VERSION_MAJOR"),
minor: env_str!("CARGO_PKG_VERSION_MINOR"),
patch: env_str!("CARGO_PKG_VERSION_PATCH"),
pre_release: option_env_str!("CARGO_PKG_VERSION_PRE"),
cfg_info: None,
}
}
}
}

fn flags_from_args<T>(usage: &str, args: &[String], options_first: bool) -> CliResult<T>
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ pub fn http_handle(config: &Config) -> CargoResult<Easy> {
handle.connect_timeout(Duration::new(30, 0))?;
handle.low_speed_limit(10 /* bytes per second */)?;
handle.low_speed_time(Duration::new(30, 0))?;
handle.useragent(&version())?;
handle.useragent(&version().to_string())?;
if let Some(proxy) = http_proxy(config)? {
handle.proxy(&proxy)?;
}
Expand Down

0 comments on commit 775c900

Please sign in to comment.