Support version option in Nu bin. (#3632)

Additionally we remove the little pieces that we relied on `clap` (for version number in this case).
This commit is contained in:
Andrés N. Robalino 2021-06-16 14:53:28 -05:00 committed by GitHub
parent 18be6768c9
commit 2a946af81e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 129 additions and 56 deletions

2
Cargo.lock generated
View file

@ -3292,7 +3292,6 @@ dependencies = [
"calamine",
"chrono",
"chrono-tz",
"clap",
"codespan-reporting",
"csv",
"ctrlc",
@ -3391,7 +3390,6 @@ dependencies = [
"calamine",
"chrono",
"chrono-tz",
"clap",
"codespan-reporting",
"crossterm 0.19.0",
"csv",

View file

@ -38,7 +38,6 @@ bytes = "1.0.1"
calamine = "0.17.0"
chrono = { version = "0.4.19", features = ["serde"] }
chrono-tz = "0.5.3"
clap = "2.33.3"
codespan-reporting = "0.11.0"
csv = "1.1.5"
ctrlc = { version = "3.1.7", optional = true }

View file

@ -6,11 +6,12 @@ pub use options::{CliOptions, NuScript, Options};
use options_parser::{NuParser, OptionsParser};
use nu_command::{commands::nu::Nu, utils::test_bins as binaries};
use nu_engine::get_full_help;
use nu_engine::{get_full_help, EvaluationContext};
use nu_errors::ShellError;
use nu_protocol::hir::{Call, Expression, SpannedExpression};
use nu_protocol::hir::{Call, Expression, SpannedExpression, Synthetic};
use nu_protocol::{Primitive, UntaggedValue};
use nu_source::{Span, Tag};
use nu_stream::InputStream;
pub struct App {
parser: Box<dyn OptionsParser>,
@ -43,29 +44,55 @@ impl App {
}
if self.help() {
let ctx = self.parser.context();
let autoview_cmd = ctx
.get_command("autoview")
.expect("could not find autoview command");
let context = self.parser.context();
let stream = nu_stream::OutputStream::one(
UntaggedValue::string(get_full_help(&Nu, &context.scope))
.into_value(nu_source::Tag::unknown()),
);
if let Ok(output_stream) = ctx.run_command(
autoview_cmd,
Tag::unknown(),
Call::new(
Box::new(SpannedExpression::new(
Expression::string("autoview".to_string()),
consume(context, stream)?;
std::process::exit(0);
}
if self.version() {
let context = self.parser.context();
let stream = nu_command::commands::version::version(nu_engine::CommandArgs {
context: context.clone(),
call_info: nu_engine::UnevaluatedCallInfo {
args: Call::new(
Box::new(SpannedExpression::new(
Expression::Synthetic(Synthetic::String("version".to_string())),
Span::unknown(),
)),
Span::unknown(),
)),
Span::unknown(),
),
nu_stream::OutputStream::one(
UntaggedValue::string(get_full_help(&Nu, &ctx.scope))
.into_value(nu_source::Tag::unknown()),
),
) {
for _ in output_stream {}
}
),
name_tag: Tag::unknown(),
},
input: InputStream::empty(),
})?;
let stream = {
let command = context
.get_command("pivot")
.expect("could not find version command");
context.run_command(
command,
Tag::unknown(),
Call::new(
Box::new(SpannedExpression::new(
Expression::Synthetic(Synthetic::String("pivot".to_string())),
Span::unknown(),
)),
Span::unknown(),
),
stream,
)?
};
consume(context, stream)?;
std::process::exit(0);
}
@ -169,6 +196,13 @@ impl App {
.unwrap_or(false)
}
pub fn version(&self) -> bool {
self.options
.get("version")
.map(|v| matches!(v.as_bool(), Ok(true)))
.unwrap_or(false)
}
pub fn scripts(&self) -> Option<Vec<Result<String, ShellError>>> {
self.options.get("args").map(|v| {
v.table_entries()
@ -284,6 +318,29 @@ fn quote_positionals(parameters: &[String]) -> Vec<String> {
.collect::<Vec<_>>()
}
fn consume(context: &EvaluationContext, stream: InputStream) -> Result<(), ShellError> {
let autoview_cmd = context
.get_command("autoview")
.expect("could not find autoview command");
let stream = context.run_command(
autoview_cmd,
Tag::unknown(),
Call::new(
Box::new(SpannedExpression::new(
Expression::Synthetic(Synthetic::String("autoview".to_string())),
Span::unknown(),
)),
Span::unknown(),
),
stream,
)?;
for _ in stream {}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
@ -300,6 +357,7 @@ mod tests {
let ui = cli_app();
ui.parse("nu")?;
assert_eq!(ui.version(), false);
assert_eq!(ui.help(), false);
assert_eq!(ui.takes_stdin(), false);
assert_eq!(ui.save_history(), true);
@ -397,6 +455,15 @@ mod tests {
Ok(())
}
#[test]
fn has_version() -> Result<(), ShellError> {
let ui = cli_app();
ui.parse("nu --version")?;
assert_eq!(ui.version(), true);
Ok(())
}
#[test]
fn has_help() -> Result<(), ShellError> {
let ui = cli_app();

View file

@ -1,7 +1,7 @@
use super::Options;
use nu_command::commands::nu::{self, Nu};
use nu_command::commands::Autoview;
use nu_command::commands::{Autoview, Pivot, Table, Version as NuVersion};
use nu_engine::{whole_stream_command, EvaluationContext};
use nu_errors::ShellError;
use nu_protocol::hir::{ClassifiedCommand, InternalCommand, NamedValue};
@ -22,7 +22,10 @@ impl NuParser {
let context = EvaluationContext::basic();
context.add_commands(vec![
whole_stream_command(Nu {}),
whole_stream_command(NuVersion {}),
whole_stream_command(Autoview {}),
whole_stream_command(Pivot {}),
whole_stream_command(Table {}),
]);
Self { context }

View file

@ -1,3 +1,5 @@
use super::Nu;
use crate::line_editor::configure_ctrl_c;
use nu_ansi_term::Color;
use nu_engine::{maybe_print_errors, run_block, script::run_script_standalone, EvaluationContext};
@ -148,7 +150,7 @@ pub fn cli(
if !skip_welcome_message {
println!(
"Welcome to Nushell {} (type 'help' for more info)",
clap::crate_version!()
Nu::version()
);
}

View file

@ -26,7 +26,10 @@ pub use crate::cli::cli;
pub use crate::app::App;
pub use crate::cli::{parse_and_eval, register_plugins, run_script_file};
pub use nu_command::commands::default_context::create_default_context;
pub use nu_command::{
commands::default_context::create_default_context, commands::nu as Nu,
commands::Version as NuVersion,
};
pub use nu_data::config;
pub use nu_data::dict::TaggedListBuilder;
pub use nu_data::primitive;

View file

@ -35,7 +35,6 @@ bytes = "1.0.1"
calamine = "0.17.0"
chrono = { version = "0.4.19", features = ["serde"] }
chrono-tz = "0.5.3"
clap = "2.33.3"
codespan-reporting = "0.11.0"
crossterm = { version = "0.19.0", optional = true }
csv = "1.1.3"

View file

@ -134,7 +134,7 @@ pub(crate) mod to_yaml;
pub(crate) mod uniq;
pub(crate) mod update;
pub(crate) mod url_;
pub(crate) mod version;
pub mod version;
pub(crate) mod where_;
pub(crate) mod which_;
pub(crate) mod with_env;
@ -254,7 +254,7 @@ pub(crate) use path::{
PathBasename, PathCommand, PathDirname, PathExists, PathExpand, PathJoin, PathParse,
PathRelativeTo, PathSplit, PathType,
};
pub(crate) use pivot::Pivot;
pub use pivot::Pivot;
pub(crate) use prepend::Prepend;
pub(crate) use prev::Previous;
pub(crate) use pwd::Pwd;
@ -291,7 +291,7 @@ pub(crate) use str_::{
StrReverse, StrScreamingSnakeCase, StrSnakeCase, StrStartsWith, StrSubstring, StrToDatetime,
StrToDecimal, StrToInteger, StrTrim, StrTrimLeft, StrTrimRight, StrUpcase,
};
pub(crate) use table::Table;
pub use table::Table;
pub(crate) use tags::Tags;
pub(crate) use termsize::TermSize;
pub(crate) use to::To;
@ -307,7 +307,7 @@ pub(crate) use to_yaml::ToYaml;
pub(crate) use touch::Touch;
pub(crate) use uniq::Uniq;
pub(crate) use url_::{UrlCommand, UrlHost, UrlPath, UrlQuery, UrlScheme};
pub(crate) use version::Version;
pub use version::Version;
pub(crate) use where_::Command as Where;
pub(crate) use which_::Which;
pub(crate) use with_env::WithEnv;

View file

@ -10,6 +10,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("nu")
.switch("version", "Display Nu version", Some('v'))
.switch("stdin", "redirect stdin", None)
.switch("skip-plugins", "do not load plugins", None)
.switch("no-history", "don't save history", None)
@ -46,19 +47,3 @@ impl WholeStreamCommand for Command {
"Nu - A new type of shell."
}
}
pub fn testbins() -> Vec<String> {
vec![
"echo_env", "cococo", "iecho", "fail", "nonu", "chop", "repeater", "meow",
]
.into_iter()
.map(String::from)
.collect()
}
pub fn loglevels() -> Vec<String> {
vec!["error", "warn", "info", "debug", "trace"]
.into_iter()
.map(String::from)
.collect()
}

View file

@ -2,5 +2,24 @@ pub mod command;
mod plugin;
pub use command::Command as Nu;
pub use command::{loglevels, testbins};
pub use plugin::SubCommand as NuPlugin;
pub fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
pub fn testbins() -> Vec<String> {
vec![
"echo_env", "cococo", "iecho", "fail", "nonu", "chop", "repeater", "meow",
]
.into_iter()
.map(String::from)
.collect()
}
pub fn loglevels() -> Vec<String> {
vec!["error", "warn", "info", "debug", "trace"]
.into_iter()
.map(String::from)
.collect()
}

View file

@ -23,7 +23,7 @@ impl WholeStreamCommand for Version {
"Display Nu version."
}
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
version(args)
}
@ -36,14 +36,14 @@ impl WholeStreamCommand for Version {
}
}
pub fn version(args: CommandArgs) -> Result<ActionStream, ShellError> {
pub fn version(args: CommandArgs) -> Result<OutputStream, ShellError> {
let tag = args.call_info.args.span;
let mut indexmap = IndexMap::with_capacity(4);
indexmap.insert(
"version".to_string(),
UntaggedValue::string(clap::crate_version!()).into_value(&tag),
UntaggedValue::string(super::nu::version()).into_value(&tag),
);
let branch: Option<&str> = Some(shadow::BRANCH).filter(|x| !x.is_empty());
@ -178,7 +178,7 @@ pub fn version(args: CommandArgs) -> Result<ActionStream, ShellError> {
);
let value = UntaggedValue::Row(Dictionary::from(indexmap)).into_value(&tag);
Ok(ActionStream::one(value))
Ok(OutputStream::one(value))
}
fn features_enabled() -> Vec<String> {

View file

@ -51,7 +51,6 @@ byte-unit = "2.1.0"
bytes = "0.4.12"
chrono-humanize = "0.0.11"
chrono-tz = "0.5.1"
clap = "2.33.0"
conch-parser = "0.1.1"
derive-new = "0.5.6"
dunce = "1.0.0"

View file

@ -46,7 +46,6 @@ language-reporting = "0.3.0"
directories = "2.0.2"
toml = "0.5.1"
toml-query = "0.9.0"
clap = "2.33.0"
[dependencies.pancurses]
version = "0.16"