From f19a8010228e1dd7b101fd567849b786a4ab3dc4 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Tue, 1 Dec 2020 13:57:49 -0600 Subject: [PATCH] enhanced version command with more info (#2773) --- Cargo.lock | 11 ++ crates/nu-cli/Cargo.toml | 20 +- crates/nu-cli/build.rs | 38 +--- crates/nu-cli/src/commands/version.rs | 270 ++++++++++++++++++++++++-- 4 files changed, 281 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c07015686..70ac84f06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3208,6 +3208,7 @@ dependencies = [ "serde_urlencoded 0.7.0", "serde_yaml", "sha2 0.9.2", + "shadow-rs", "shellexpand", "strip-ansi-escapes", "sxd-document", @@ -5180,6 +5181,16 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "shadow-rs" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa99d59fca26677e3582f69069226abb6b2ce7e02d1068bcfd57510fa16ab87" +dependencies = [ + "chrono", + "git2", +] + [[package]] name = "shell-words" version = "1.0.0" diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index ae066a3eb..8db023f25 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -5,6 +5,7 @@ edition = "2018" license = "MIT" name = "nu-cli" version = "0.23.0" +build = "build.rs" [lib] doctest = false @@ -31,6 +32,7 @@ bytes = "0.5.6" calamine = "0.16.1" chrono = {version = "0.4.15", features = ["serde"]} clap = "2.33.3" +clipboard = {version = "0.5.0", optional = true} codespan-reporting = "0.9.5" csv = "1.1.3" ctrlc = {version = "3.1.6", optional = true} @@ -40,11 +42,12 @@ dirs = {version = "3.0.1", optional = true} dtparse = "1.2.0" dunce = "1.0.1" eml-parser = "0.1.0" +encoding_rs = "0.8.24" filesize = "0.2.0" fs_extra = "1.2.0" futures = {version = "0.3.5", features = ["compat", "io-compat"]} -futures-util = "0.3.5" futures_codec = "0.4.1" +futures-util = "0.3.5" getset = "0.1.1" git2 = {version = "0.13.11", default_features = false, optional = true} glob = "0.3.0" @@ -53,7 +56,9 @@ htmlescape = "0.3.1" ical = "0.6.0" ichwh = {version = "0.3.4", optional = true} indexmap = {version = "1.6.0", features = ["serde-1"]} +Inflector = "0.11" itertools = "0.9.0" +lazy_static = "1.*" log = "0.4.11" meval = "0.2.0" num-bigint = {version = "0.3.0", features = ["serde"]} @@ -66,6 +71,7 @@ ptree = {version = "0.3.0", optional = true} query_interface = "0.3.5" quick-xml = "0.18.1" rand = "0.7.3" +rayon = "1.4.0" regex = "1.3.9" roxmltree = "0.13.0" rust-embed = "5.6.0" @@ -86,19 +92,13 @@ term = {version = "0.6.1", optional = true} term_size = "0.3.2" termcolor = "1.1.0" toml = "0.5.6" +trash = {version = "1.2.0", optional = true} unicode-segmentation = "1.6.0" uom = {version = "0.28.0", features = ["f64", "try-from"]} +url = "2.1.1" uuid_crate = {package = "uuid", version = "0.8.1", features = ["v4"], optional = true} which = {version = "4.0.2", optional = true} zip = {version = "0.5.7", optional = true} -lazy_static = "1.*" - -Inflector = "0.11" -clipboard = {version = "0.5.0", optional = true} -encoding_rs = "0.8.24" -rayon = "1.4.0" -trash = {version = "1.2.0", optional = true} -url = "2.1.1" [target.'cfg(unix)'.dependencies] umask = "1.0.0" @@ -116,7 +116,7 @@ optional = true version = "0.24.0" [build-dependencies] -git2 = {version = "0.13.11", optional = true} +shadow-rs = "0.3.20" [dev-dependencies] quickcheck = "0.9.2" diff --git a/crates/nu-cli/build.rs b/crates/nu-cli/build.rs index 54091cff2..fc8ddfcf9 100644 --- a/crates/nu-cli/build.rs +++ b/crates/nu-cli/build.rs @@ -1,36 +1,6 @@ -use std::path::Path; -use std::{env, fs, io}; - -fn main() -> Result<(), io::Error> { - let out_dir = env::var_os("OUT_DIR").expect( - "\ - OUT_DIR environment variable not found. \ - OUT_DIR is guaranteed to exist in a build script by cargo - see \ - https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts\ - "); - - let latest_commit_hash = latest_commit_hash(env::current_dir()?).unwrap_or_default(); - - let commit_hash_path = Path::new(&out_dir).join("git_commit_hash"); - fs::write(commit_hash_path, latest_commit_hash)?; - +fn main() -> shadow_rs::SdResult<()> { + let src_path = std::env::var("CARGO_MANIFEST_DIR")?; + let out_path = std::env::var("OUT_DIR")?; + shadow_rs::Shadow::build(src_path, out_path)?; Ok(()) } - -#[allow(unused_variables)] -fn latest_commit_hash>(dir: P) -> Result> { - #[cfg(feature = "git2")] - { - use git2::Repository; - let dir = dir.as_ref(); - Ok(Repository::discover(dir)? - .head()? - .peel_to_commit()? - .id() - .to_string()) - } - #[cfg(not(feature = "git2"))] - { - Ok(String::new()) - } -} diff --git a/crates/nu-cli/src/commands/version.rs b/crates/nu-cli/src/commands/version.rs index 39bbedbfb..d30103f81 100644 --- a/crates/nu-cli/src/commands/version.rs +++ b/crates/nu-cli/src/commands/version.rs @@ -1,12 +1,12 @@ use crate::commands::WholeStreamCommand; use crate::prelude::*; use indexmap::IndexMap; -use nu_data::TaggedListBuilder; use nu_errors::ShellError; -use nu_protocol::{Dictionary, Signature, UntaggedValue}; - -const GIT_COMMIT_HASH: &str = include_str!(concat!(env!("OUT_DIR"), "/git_commit_hash")); +use nu_protocol::{value::StrExt, value::StringExt, Dictionary, Signature, UntaggedValue}; +pub mod shadow { + include!(concat!(env!("OUT_DIR"), "/shadow.rs")); +} pub struct Version; #[async_trait] @@ -50,35 +50,277 @@ pub fn version(args: CommandArgs, _registry: &CommandRegistry) -> Result = Some(shadow::BRANCH).filter(|x| !x.is_empty()); + if let Some(branch) = branch { indexmap.insert( - "commit_hash".to_string(), - UntaggedValue::string(commit_hash).into_value(&tag), + "branch".to_string(), + branch.to_pattern_untagged_value().into_value(&tag), ); } - indexmap.insert("features".to_string(), features_enabled(&tag).into_value()); + let short_commit: Option<&str> = Some(shadow::SHORT_COMMIT).filter(|x| !x.is_empty()); + if let Some(short_commit) = short_commit { + indexmap.insert( + "short_commit".to_string(), + short_commit.to_pattern_untagged_value().into_value(&tag), + ); + } + let commit_hash: Option<&str> = Some(shadow::COMMIT_HASH).filter(|x| !x.is_empty()); + if let Some(commit_hash) = commit_hash { + indexmap.insert( + "commit_hash".to_string(), + commit_hash.to_pattern_untagged_value().into_value(&tag), + ); + } + let commit_date: Option<&str> = Some(shadow::COMMIT_DATE).filter(|x| !x.is_empty()); + if let Some(commit_date) = commit_date { + indexmap.insert( + "commit_date".to_string(), + commit_date.to_pattern_untagged_value().into_value(&tag), + ); + } + + // let commit_author: Option<&str> = Some(shadow::COMMIT_AUTHOR).filter(|x| !x.is_empty()); + // if let Some(commit_author) = commit_author { + // indexmap.insert( + // "commit_author".to_string(), + // commit_author.to_pattern_untagged_value().into_value(&tag), + // ); + // } + let _commit_autor = shadow::COMMIT_AUTHOR; + + // let commit_email: Option<&str> = Some(shadow::COMMIT_EMAIL).filter(|x| !x.is_empty()); + // if let Some(commit_email) = commit_email { + // indexmap.insert( + // "commit_email".to_string(), + // commit_email.to_pattern_untagged_value().into_value(&tag), + // ); + // } + let _commit_email = shadow::COMMIT_EMAIL; + + let build_os: Option<&str> = Some(shadow::BUILD_OS).filter(|x| !x.is_empty()); + if let Some(build_os) = build_os { + indexmap.insert( + "build_os".to_string(), + build_os.to_pattern_untagged_value().into_value(&tag), + ); + } + + let rust_version: Option<&str> = Some(shadow::RUST_VERSION).filter(|x| !x.is_empty()); + if let Some(rust_version) = rust_version { + indexmap.insert( + "rust_version".to_string(), + rust_version.to_pattern_untagged_value().into_value(&tag), + ); + } + + let rust_channel: Option<&str> = Some(shadow::RUST_CHANNEL).filter(|x| !x.is_empty()); + if let Some(rust_channel) = rust_channel { + indexmap.insert( + "rust_channel".to_string(), + rust_channel.to_pattern_untagged_value().into_value(&tag), + ); + } + + let cargo_version: Option<&str> = Some(shadow::CARGO_VERSION).filter(|x| !x.is_empty()); + if let Some(cargo_version) = cargo_version { + indexmap.insert( + "cargo_version".to_string(), + cargo_version.to_pattern_untagged_value().into_value(&tag), + ); + } + + let pkg_version: Option<&str> = Some(shadow::PKG_VERSION).filter(|x| !x.is_empty()); + if let Some(pkg_version) = pkg_version { + indexmap.insert( + "pkg_version".to_string(), + pkg_version.to_pattern_untagged_value().into_value(&tag), + ); + } + + // let cargo_tree: Option<&str> = Some(shadow::CARGO_TREE).filter(|x| !x.is_empty()); + // if let Some(cargo_tree) = cargo_tree { + // indexmap.insert( + // "cargo_tree".to_string(), + // cargo_tree.to_pattern_untagged_value().into_value(&tag), + // ); + // } + let _cargo_tree = shadow::CARGO_TREE; + + // let project_name: Option<&str> = Some(shadow::PROJECT_NAME).filter(|x| !x.is_empty()); + // if let Some(project_name) = project_name { + // indexmap.insert( + // "project_name".to_string(), + // project_name.to_pattern_untagged_value().into_value(&tag), + // ); + // } + let _project_name = shadow::PROJECT_NAME; + + let build_time: Option<&str> = Some(shadow::BUILD_TIME).filter(|x| !x.is_empty()); + if let Some(build_time) = build_time { + indexmap.insert( + "build_time".to_string(), + build_time.to_pattern_untagged_value().into_value(&tag), + ); + } + + let build_rust_channel: Option<&str> = + Some(shadow::BUILD_RUST_CHANNEL).filter(|x| !x.is_empty()); + if let Some(build_rust_channel) = build_rust_channel { + indexmap.insert( + "build_rust_channel".to_string(), + build_rust_channel + .to_pattern_untagged_value() + .into_value(&tag), + ); + } + + indexmap.insert( + "features".to_string(), + features_enabled().join(", ").to_string_value_create_tag(), + ); let value = UntaggedValue::Row(Dictionary::from(indexmap)).into_value(&tag); Ok(OutputStream::one(value)) } -fn features_enabled(tag: impl Into) -> TaggedListBuilder { - let mut names = TaggedListBuilder::new(tag); +fn features_enabled() -> Vec { + let mut names = vec![]; - names.push_untagged(UntaggedValue::string("default")); + names.push("default".to_string()); + + #[cfg(feature = "ctrlc")] + { + names.push("ctrlc".to_string()); + } + + #[cfg(feature = "dirs")] + { + names.push("dirs".to_string()); + } + + #[cfg(feature = "directories")] + { + names.push("directories".to_string()); + } + + #[cfg(feature = "git2")] + { + names.push("git".to_string()); + } + + #[cfg(feature = "ptree")] + { + names.push("ptree".to_string()); + } + + #[cfg(feature = "rich-benchmark")] + { + names.push("rich-benchmark".to_string()); + } + + #[cfg(feature = "rustyline-support")] + { + names.push("rustyline".to_string()); + } + + #[cfg(feature = "term")] + { + names.push("term".to_string()); + } + + #[cfg(feature = "uuid_crate")] + { + names.push("uuid".to_string()); + } + + #[cfg(feature = "which")] + { + names.push("which".to_string()); + } + + #[cfg(feature = "ichwh")] + { + names.push("ichwh".to_string()); + } + + #[cfg(feature = "zip")] + { + names.push("zip".to_string()); + } #[cfg(feature = "clipboard-cli")] { - names.push_untagged(UntaggedValue::string("clipboard")); + names.push("clipboard-cli".to_string()); } #[cfg(feature = "trash-support")] { - names.push_untagged(UntaggedValue::string("trash")); + names.push("trash".to_string()); } + // #[cfg(feature = "binaryview")] + // { + // names.push("binaryview".to_string()); + // } + + // #[cfg(feature = "start")] + // { + // names.push("start".to_string()); + // } + + // #[cfg(feature = "bson")] + // { + // names.push("bson".to_string()); + // } + + // #[cfg(feature = "sqlite")] + // { + // names.push("sqlite".to_string()); + // } + + // #[cfg(feature = "s3")] + // { + // names.push("s3".to_string()); + // } + + // #[cfg(feature = "chart")] + // { + // names.push("chart".to_string()); + // } + + // #[cfg(feature = "xpath")] + // { + // names.push("xpath".to_string()); + // } + + // #[cfg(feature = "selector")] + // { + // names.push("selector".to_string()); + // } + + // #[cfg(feature = "extra")] + // { + // names.push("extra".to_string()); + // } + + // #[cfg(feature = "preserve_order")] + // { + // names.push("preserve_order".to_string()); + // } + + // #[cfg(feature = "wee_alloc")] + // { + // names.push("wee_alloc".to_string()); + // } + + // #[cfg(feature = "console_error_panic_hook")] + // { + // names.push("console_error_panic_hook".to_string()); + // } + + names.sort(); + names }