diff --git a/Cargo.lock b/Cargo.lock index c42fe886..8834cc5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ [root] name = "exa" -version = "0.8.0" +version = "0.9.0-pre" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "datetime 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 3efefc1c..37c4780d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "exa" -version = "0.8.0" +version = "0.9.0-pre" authors = [ "ogham@bsago.me" ] +build = "build.rs" description = "A modern replacement for ls" homepage = "https://the.exa.website/" @@ -13,11 +14,13 @@ categories = ["command-line-utilities"] keywords = ["ls", "files", "command-line"] license = "MIT" + [[bin]] name = "exa" path = "src/bin/main.rs" doc = false + [lib] name = "exa" path = "src/exa.rs" @@ -41,6 +44,9 @@ unicode-width = "0.1.4" users = "0.5.2" zoneinfo_compiled = "0.4.5" +[build-dependencies] +datetime = "0.4.5" + [features] default = [ "git" ] git = [ "git2" ] diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..909633b9 --- /dev/null +++ b/build.rs @@ -0,0 +1,59 @@ +/// The version string isn’t the simplest: we want to show the version, +/// current Git hash, and compilation date when building *debug* versions, but +/// just the version for *release* versions so the builds are reproducible. +/// +/// This script generates the string from the environment variables that Cargo +/// adds (http://doc.crates.io/environment-variables.html) and runs `git` to +/// get the SHA1 hash. It then writes the string into a file, which exa then +/// includes at build-time. +/// +/// - https://stackoverflow.com/q/43753491/3484614 +/// - https://crates.io/crates/vergen + +extern crate datetime; +use std::io::Result as IOResult; +use std::env; + +fn git_hash() -> String { + use std::process::Command; + + String::from_utf8_lossy( + &Command::new("git") + .args(&["rev-parse", "--short", "HEAD"]) + .output().unwrap() + .stdout).trim().to_string() +} + +fn main() { + write_statics().unwrap(); +} + +fn is_development_version() -> bool { + env::var("PROFILE").unwrap() == "debug" +} + +fn cargo_version() -> String { + env::var("CARGO_PKG_VERSION").unwrap() +} + +fn build_date() -> String { + use datetime::{LocalDateTime, ISO}; + + let now = LocalDateTime::now(); + format!("{}", now.date().iso()) +} + +fn write_statics() -> IOResult<()> { + use std::fs::File; + use std::io::Write; + use std::path::PathBuf; + + let ver = match is_development_version() { + true => format!("exa v{} ({} built on {})", cargo_version(), git_hash(), build_date()), + false => format!("exa v{}", cargo_version()), + }; + + let out = PathBuf::from(env::var("OUT_DIR").unwrap()); + let mut f = File::create(&out.join("version_string.txt"))?; + write!(f, "{:?}", ver) +} diff --git a/src/options/version.rs b/src/options/version.rs index fc4fa96c..c5b60b9e 100644 --- a/src/options/version.rs +++ b/src/options/version.rs @@ -1,16 +1,16 @@ +//! Printing the version string. +//! +//! The code that works out which string to print is done in `build.rs`. + use std::fmt; use options::flags; use options::parser::MatchedFlags; -/// All the information needed to display the version information. #[derive(PartialEq, Debug)] -pub struct VersionString { - - /// The version number from cargo. - cargo: &'static str, -} +pub struct VersionString; +// There were options here once, but there aren’t anymore! impl VersionString { @@ -21,7 +21,7 @@ impl VersionString { /// Like --help, this doesn’t bother checking for errors. pub fn deduce(matches: &MatchedFlags) -> Result<(), VersionString> { if matches.count(&flags::VERSION) > 0 { - Err(VersionString { cargo: env!("CARGO_PKG_VERSION") }) + Err(VersionString) } else { Ok(()) // no version needs to be shown @@ -30,16 +30,12 @@ impl VersionString { } impl fmt::Display for VersionString { - - /// Format this help options into an actual string of help - /// text to be displayed to the user. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "exa v{}", self.cargo) + write!(f, "{}", include!(concat!(env!("OUT_DIR"), "/version_string.txt"))) } } - #[cfg(test)] mod test { use options::Options;