Impl one configurable function to run scripts (#3242)

* Impl one func to run scripts

* Add exit_on_err

* Remove run_standalone

* Make the compiler happy :)
This commit is contained in:
Leonhard Kipp
2021-04-03 21:31:53 +02:00
committed by GitHub
parent 4bc9d9fd3b
commit 28e1a7915d
16 changed files with 305 additions and 216 deletions

View File

@ -1,6 +1,10 @@
use crate::line_editor::configure_ctrl_c;
use nu_command::commands::default_context::create_default_context;
use nu_engine::{maybe_print_errors, run_block, script::run_script_standalone, EvaluationContext};
use nu_engine::{
filesystem::filesystem_shell::FilesystemShellMode, maybe_print_errors, run_block, script,
EvaluationContext,
};
use std::error::Error;
#[allow(unused_imports)]
pub(crate) use nu_engine::script::{process_script, LineResult};
@ -15,7 +19,7 @@ use crate::line_editor::{
use nu_data::config;
use nu_source::{Tag, Text};
use nu_stream::InputStream;
use std::ffi::{OsStr, OsString};
use std::ffi::OsString;
#[allow(unused_imports)]
use std::sync::atomic::Ordering;
@ -24,10 +28,11 @@ use rustyline::{self, error::ReadlineError};
use nu_errors::ShellError;
use nu_parser::ParserScope;
use nu_protocol::{hir::ExternalRedirection, ConfigPath, UntaggedValue, Value};
use nu_protocol::{
hir::ExternalRedirection, ConfigPath, NuScript, RunScriptOptions, UntaggedValue, Value,
};
use log::trace;
use std::error::Error;
use std::iter::Iterator;
use std::path::PathBuf;
@ -55,45 +60,6 @@ impl Options {
}
}
pub struct NuScript {
pub filepath: Option<OsString>,
pub contents: String,
}
impl NuScript {
pub fn code<'a>(content: impl Iterator<Item = &'a str>) -> Result<Self, ShellError> {
let text = content
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join("\n");
Ok(Self {
filepath: None,
contents: text,
})
}
pub fn get_code(&self) -> &str {
&self.contents
}
pub fn source_file(path: &OsStr) -> Result<Self, ShellError> {
use std::fs::File;
use std::io::Read;
let path = path.to_os_string();
let mut file = File::open(&path)?;
let mut buffer = String::new();
file.read_to_string(&mut buffer)?;
Ok(Self {
filepath: Some(path),
contents: buffer,
})
}
}
pub fn search_paths() -> Vec<std::path::PathBuf> {
use std::env;
@ -123,8 +89,11 @@ pub fn search_paths() -> Vec<std::path::PathBuf> {
search_paths
}
pub async fn run_script_file(options: Options) -> Result<(), Box<dyn Error>> {
let context = create_default_context(false)?;
pub async fn run_script_file(
options: Options,
run_options: RunScriptOptions,
) -> Result<(), Box<dyn Error>> {
let context = create_default_context(FilesystemShellMode::Script, false)?;
if let Some(cfg) = options.config {
load_cfg_as_global_cfg(&context, PathBuf::from(cfg)).await;
@ -135,12 +104,9 @@ pub async fn run_script_file(options: Options) -> Result<(), Box<dyn Error>> {
let _ = register_plugins(&context);
let _ = configure_ctrl_c(&context);
let script = options
.scripts
.get(0)
.ok_or_else(|| ShellError::unexpected("Nu source code not available"))?;
run_script_standalone(script.get_code().to_string(), options.stdin, &context, true).await?;
for script in options.scripts {
script::run_script(script, &run_options, &context).await;
}
Ok(())
}
@ -218,6 +184,10 @@ pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box
let mut ctrlcbreak = false;
let mut run_options = RunScriptOptions::default()
.cli_mode(true)
.redirect_stdin(false);
loop {
if context.ctrl_c.load(Ordering::SeqCst) {
context.ctrl_c.store(false, Ordering::SeqCst);
@ -303,14 +273,8 @@ pub async fn cli(context: EvaluationContext, options: Options) -> Result<(), Box
let line = match convert_rustyline_result_to_string(readline) {
LineResult::Success(_) => {
process_script(
&session_text[line_start..],
&context,
false,
line_start,
true,
)
.await
run_options = run_options.span_offset(line_start);
process_script(&session_text[line_start..], &run_options, &context).await
}
x => x,
};
@ -501,14 +465,14 @@ fn current_branch() -> String {
#[cfg(test)]
mod tests {
use nu_engine::basic_evaluation_context;
use nu_engine::{basic_evaluation_context, filesystem::filesystem_shell::FilesystemShellMode};
#[quickcheck]
fn quickcheck_parse(data: String) -> bool {
let (tokens, err) = nu_parser::lex(&data, 0);
let (lite_block, err2) = nu_parser::parse_block(tokens);
if err.is_none() && err2.is_none() {
let context = basic_evaluation_context().unwrap();
let context = basic_evaluation_context(FilesystemShellMode::Cli).unwrap();
let _ = nu_parser::classify_block(&lite_block, &context.scope);
}
true

View File

@ -22,8 +22,8 @@ pub mod types;
#[cfg(feature = "rustyline-support")]
pub use crate::cli::cli;
pub use crate::cli::Options;
pub use crate::cli::{parse_and_eval, register_plugins, run_script_file};
pub use crate::cli::{NuScript, Options};
pub use nu_command::commands::default_context::create_default_context;
pub use nu_data::config;

View File

@ -150,6 +150,7 @@ impl rustyline::Helper for Helper {}
mod tests {
use super::*;
use nu_engine::basic_evaluation_context;
use nu_engine::filesystem::filesystem_shell::FilesystemShellMode;
use rustyline::completion::Completer;
use rustyline::line_buffer::LineBuffer;
@ -163,7 +164,10 @@ mod tests {
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 1);
let helper = Helper::new(basic_evaluation_context().unwrap(), None);
let helper = Helper::new(
basic_evaluation_context(FilesystemShellMode::Cli).unwrap(),
None,
);
helper.update(&mut buffer, "cd ".len(), &replacement);
@ -183,7 +187,10 @@ mod tests {
buffer.insert_str(0, text);
buffer.set_pos(text.len() - 30);
let helper = Helper::new(basic_evaluation_context().unwrap(), None);
let helper = Helper::new(
basic_evaluation_context(FilesystemShellMode::Cli).unwrap(),
None,
);
helper.update(&mut buffer, "cd ".len(), &replacement);