From 68dac7c4b0743a6a08f89f915957e23b8e3f3441 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Sat, 3 Feb 2018 10:41:36 -0500 Subject: [PATCH] build: add git hash This commit makes the git hash ripgrep was built with available for use in the version string. We also do a few minor touchups in build.rs and src/app.rs. --- build.rs | 23 ++++++++++++++++++++++- src/app.rs | 50 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/build.rs b/build.rs index 3c16b532..01b3d18e 100644 --- a/build.rs +++ b/build.rs @@ -5,6 +5,7 @@ extern crate lazy_static; use std::env; use std::fs; +use std::process; use clap::Shell; @@ -13,14 +14,34 @@ use clap::Shell; mod app; fn main() { + // OUT_DIR is set by Cargo and it's where any additional build artifacts + // are written. let outdir = match env::var_os("OUT_DIR") { - None => return, Some(outdir) => outdir, + None => { + eprintln!( + "OUT_DIR environment variable not defined. \ + Please file a bug: \ + https://github.com/BurntSushi/ripgrep/issues/new"); + process::exit(1); + } }; fs::create_dir_all(&outdir).unwrap(); + // Use clap to build completion files. let mut app = app::app(); app.gen_completions("rg", Shell::Bash, &outdir); app.gen_completions("rg", Shell::Fish, &outdir); app.gen_completions("rg", Shell::PowerShell, &outdir); + // Note that we do not use clap's support for zsh. Instead, zsh completions + // are manually maintained in `complete/_rg`. + + // Make the current git hash available to the build. + let result = process::Command::new("git") + .args(&["rev-parse", "--short=10", "HEAD"]) + .output(); + if let Ok(output) = result { + let hash = String::from_utf8_lossy(&output.stdout); + println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", hash); + } } diff --git a/src/app.rs b/src/app.rs index f2f084e3..2e374d78 100644 --- a/src/app.rs +++ b/src/app.rs @@ -44,6 +44,14 @@ OPTIONS: /// This is an intentionally stand-alone module so that it can be used easily /// in a `build.rs` script to build shell completion files. pub fn app() -> App<'static, 'static> { + // We need to specify our version in a static because we've painted clap + // into a corner. We've told it that every string we give it will be + // 'static, but we need to build the version string dynamically. We can + // fake the 'static lifetime with lazy_static. + lazy_static! { + static ref LONG_VERSION: String = long_version(); + } + let arg = |name| { Arg::with_name(name) .help(USAGES[name].short) @@ -194,6 +202,30 @@ pub fn app() -> App<'static, 'static> { .arg(flag("search-zip").short("z")) } +/// Return the "long" format of ripgrep's version string. +fn long_version() -> String { + // Let's say whether faster CPU instructions are enabled or not. + let mut features = vec![]; + if cfg!(feature = "simd-accel") { + features.push("+SIMD"); + } else { + features.push("-SIMD"); + } + if cfg!(feature = "avx-accel") { + features.push("+AVX"); + } else { + features.push("-AVX"); + } + // Do we have a git hash? + // (Yes, if ripgrep was built on a machine with `git` installed.) + let hash = match option_env!("RIPGREP_BUILD_GIT_HASH") { + None => String::new(), + Some(githash) => format!(" (rev {})", githash), + }; + // Put everything together. + format!("{}{}\n{}", crate_version!(), hash, features.join(" ")) +} + struct Usage { short: &'static str, long: &'static str, @@ -212,24 +244,6 @@ macro_rules! doc { } lazy_static! { - static ref LONG_VERSION: String = { - let mut features: Vec<&str> = vec![]; - - if cfg!(feature = "avx-accel") { - features.push("+AVX"); - } else { - features.push("-AVX"); - } - - if cfg!(feature = "simd-accel") { - features.push("+SIMD"); - } else { - features.push("-SIMD"); - } - - format!("{}\n{}", crate_version!(), features.join(" ")) - }; - static ref USAGES: HashMap<&'static str, Usage> = { let mut h = HashMap::new(); doc!(h, "help-short",