From 8ae8ebd1076ea1f37db92349ef8d84dfaabd0ada Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 13 Feb 2020 21:24:18 -0800 Subject: [PATCH] Add support for multiline script files (#1386) * Add support for multiline script files * clippy --- src/cli.rs | 25 ++++------------ src/context.rs | 2 +- src/env/environment.rs | 2 +- src/env/environment_syncer.rs | 6 ++++ src/lib.rs | 3 +- src/main.rs | 33 ++++++++++++++++++++++ src/utils.rs | 4 +++ tests/fixtures/formats/script_multiline.nu | 2 ++ tests/shell/pipeline/commands/external.rs | 9 ++++++ 9 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 tests/fixtures/formats/script_multiline.nu diff --git a/src/cli.rs b/src/cli.rs index 4c98d1318e..2ffe1f4e57 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -134,7 +134,7 @@ fn search_paths() -> Vec { search_paths } -fn load_plugins(context: &mut Context) -> Result<(), ShellError> { +pub fn load_plugins(context: &mut Context) -> Result<(), ShellError> { let opts = glob::MatchOptions { case_sensitive: false, require_literal_separator: false, @@ -376,24 +376,9 @@ pub fn create_default_context( pub async fn run_pipeline_standalone( pipeline: String, redirect_stdin: bool, + context: &mut Context, ) -> Result<(), Box> { - let mut syncer = crate::env::environment_syncer::EnvironmentSyncer::new(); - let mut context = create_default_context(&mut syncer)?; - - let _ = load_plugins(&mut context); - - let cc = context.ctrl_c.clone(); - - ctrlc::set_handler(move || { - cc.store(true, Ordering::SeqCst); - }) - .expect("Error setting Ctrl-C handler"); - - if context.ctrl_c.load(Ordering::SeqCst) { - context.ctrl_c.store(false, Ordering::SeqCst); - } - - let line = process_line(Ok(pipeline), &mut context, redirect_stdin).await; + let line = process_line(Ok(pipeline), context, redirect_stdin).await; match line { LineResult::Success(line) => { @@ -409,7 +394,9 @@ pub async fn run_pipeline_standalone( }; context.maybe_print_errors(Text::from(line)); - std::process::exit(error_code); + if error_code != 0 { + std::process::exit(error_code); + } } LineResult::Error(line, err) => { diff --git a/src/context.rs b/src/context.rs index d2d9bbfdbf..b2ff0c7188 100644 --- a/src/context.rs +++ b/src/context.rs @@ -12,7 +12,7 @@ use std::error::Error; use std::sync::atomic::AtomicBool; use std::sync::Arc; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct CommandRegistry { registry: Arc>>>, } diff --git a/src/env/environment.rs b/src/env/environment.rs index 5ea785b530..74d4843f04 100644 --- a/src/env/environment.rs +++ b/src/env/environment.rs @@ -30,7 +30,7 @@ impl Env for Box { } } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct Environment { environment_vars: Option, path_vars: Option, diff --git a/src/env/environment_syncer.rs b/src/env/environment_syncer.rs index 6dd2bd26a9..3fb0dcf54f 100644 --- a/src/env/environment_syncer.rs +++ b/src/env/environment_syncer.rs @@ -9,6 +9,12 @@ pub struct EnvironmentSyncer { pub config: Arc>, } +impl Default for EnvironmentSyncer { + fn default() -> Self { + Self::new() + } +} + impl EnvironmentSyncer { pub fn new() -> EnvironmentSyncer { EnvironmentSyncer { diff --git a/src/lib.rs b/src/lib.rs index e40e6f9faa..1d376bc3d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,10 +20,11 @@ mod shell; mod stream; mod utils; -pub use crate::cli::{cli, run_pipeline_standalone}; +pub use crate::cli::{cli, create_default_context, load_plugins, run_pipeline_standalone}; pub use crate::data::dict::TaggedListBuilder; pub use crate::data::primitive; pub use crate::data::value; +pub use crate::env::environment_syncer::EnvironmentSyncer; pub use crate::env::host::BasicHost; pub use nu_parser::TokenTreeBuilder; pub use nu_value_ext::ValueExt; diff --git a/src/main.rs b/src/main.rs index 464ca689bc..6c48ffccb9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use log::LevelFilter; use std::error::Error; use std::fs::File; use std::io::{prelude::*, BufReader}; +use std::sync::atomic::Ordering; fn main() -> Result<(), Box> { let matches = App::new("nushell") @@ -88,10 +89,26 @@ fn main() -> Result<(), Box> { match matches.values_of("commands") { None => {} Some(values) => { + let mut syncer = nu::EnvironmentSyncer::new(); + let mut context = nu::create_default_context(&mut syncer)?; + + let _ = nu::load_plugins(&mut context); + + let cc = context.ctrl_c.clone(); + + ctrlc::set_handler(move || { + cc.store(true, Ordering::SeqCst); + }) + .expect("Error setting Ctrl-C handler"); + + if context.ctrl_c.load(Ordering::SeqCst) { + context.ctrl_c.store(false, Ordering::SeqCst); + } for item in values { futures::executor::block_on(nu::run_pipeline_standalone( item.into(), matches.is_present("stdin"), + &mut context, ))?; } return Ok(()); @@ -102,12 +119,28 @@ fn main() -> Result<(), Box> { Some(script) => { let file = File::open(script)?; let reader = BufReader::new(file); + let mut syncer = nu::EnvironmentSyncer::new(); + let mut context = nu::create_default_context(&mut syncer)?; + + let _ = nu::load_plugins(&mut context); + + let cc = context.ctrl_c.clone(); + + ctrlc::set_handler(move || { + cc.store(true, Ordering::SeqCst); + }) + .expect("Error setting Ctrl-C handler"); + + if context.ctrl_c.load(Ordering::SeqCst) { + context.ctrl_c.store(false, Ordering::SeqCst); + } for line in reader.lines() { let line = line?; if !line.starts_with('#') { futures::executor::block_on(nu::run_pipeline_standalone( line, matches.is_present("stdin"), + &mut context, ))?; } } diff --git a/src/utils.rs b/src/utils.rs index 0e6a3f13ba..8a68a6ce32 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -324,6 +324,10 @@ mod tests { loc: fixtures().join("script.nu"), at: 0 }, + Res { + loc: fixtures().join("script_multiline.nu"), + at: 0 + }, Res { loc: fixtures().join("sgml_description.json"), at: 0 diff --git a/tests/fixtures/formats/script_multiline.nu b/tests/fixtures/formats/script_multiline.nu new file mode 100644 index 0000000000..5f3d864bfb --- /dev/null +++ b/tests/fixtures/formats/script_multiline.nu @@ -0,0 +1,2 @@ +echo [1 4] | count +echo [2 3 5] | count \ No newline at end of file diff --git a/tests/shell/pipeline/commands/external.rs b/tests/shell/pipeline/commands/external.rs index ebfa324b54..bb0230645e 100644 --- a/tests/shell/pipeline/commands/external.rs +++ b/tests/shell/pipeline/commands/external.rs @@ -156,6 +156,15 @@ mod nu_script { assert_eq!(actual, "done"); } + + #[test] + fn run_nu_script_multiline() { + let actual = nu!(cwd: "tests/fixtures/formats", r#" + nu script_multiline.nu + "#); + + assert_eq!(actual, "23"); + } } mod tilde_expansion {