From f3d3e819fbde47d831c0db8d411d3d2b90ec0417 Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Mon, 14 Feb 2022 10:53:48 -0500 Subject: [PATCH] Fix main in scripts with captures (#4468) * Fix main in scripts with captures * Remove old comments --- src/config_files.rs | 21 +++++++-- src/eval_file.rs | 111 +++++++++++--------------------------------- src/main.rs | 9 +--- src/repl.rs | 4 +- src/utils.rs | 12 ++--- 5 files changed, 53 insertions(+), 104 deletions(-) diff --git a/src/config_files.rs b/src/config_files.rs index c211f36762..25984efbd3 100644 --- a/src/config_files.rs +++ b/src/config_files.rs @@ -2,6 +2,7 @@ use crate::is_perf_true; use crate::utils::{eval_source, report_error}; use log::info; use nu_protocol::engine::{EngineState, Stack, StateDelta, StateWorkingSet}; +use nu_protocol::{PipelineData, Span}; use std::path::PathBuf; const NUSHELL_FOLDER: &str = "nushell"; @@ -22,8 +23,14 @@ pub(crate) fn read_plugin_file(engine_state: &mut EngineState, stack: &mut Stack let plugin_filename = plugin_path.to_string_lossy().to_owned(); - if let Ok(contents) = std::fs::read_to_string(&plugin_path) { - eval_source(engine_state, stack, &contents, &plugin_filename); + if let Ok(contents) = std::fs::read(&plugin_path) { + eval_source( + engine_state, + stack, + &contents, + &plugin_filename, + PipelineData::new(Span::new(0, 0)), + ); } } if is_perf_true() { @@ -49,8 +56,14 @@ pub(crate) fn read_config_file(engine_state: &mut EngineState, stack: &mut Stack //println!("Loading config from: {:?}", config_path); let config_filename = config_path.to_string_lossy().to_owned(); - if let Ok(contents) = std::fs::read_to_string(&config_path) { - eval_source(engine_state, stack, &contents, &config_filename); + if let Ok(contents) = std::fs::read(&config_path) { + eval_source( + engine_state, + stack, + &contents, + &config_filename, + PipelineData::new(Span::new(0, 0)), + ); // Merge the delta in case env vars changed in the config match nu_engine::env::current_dir(engine_state, stack) { Ok(cwd) => { diff --git a/src/eval_file.rs b/src/eval_file.rs index 7a8e1653fc..9ed28b66e0 100644 --- a/src/eval_file.rs +++ b/src/eval_file.rs @@ -1,48 +1,27 @@ use crate::is_perf_true; -use crate::utils::{gather_parent_env_vars, report_error}; +use crate::utils::{eval_source, gather_parent_env_vars, report_error}; use log::info; use log::trace; use miette::{IntoDiagnostic, Result}; -use nu_engine::{convert_env_values, eval_block}; +use nu_engine::convert_env_values; use nu_parser::parse; use nu_protocol::{ ast::Call, - engine::{EngineState, Stack, StateDelta, StateWorkingSet}, + engine::{EngineState, Stack, StateWorkingSet}, Config, PipelineData, Span, Value, CONFIG_VARIABLE_ID, }; -use std::{io::Write, path::PathBuf}; +use std::io::Write; /// Main function used when a file path is found as argument for nu pub(crate) fn evaluate( path: String, args: &[String], - init_cwd: PathBuf, engine_state: &mut EngineState, input: PipelineData, ) -> Result<()> { // First, set up env vars as strings only gather_parent_env_vars(engine_state); - let file = std::fs::read(&path).into_diagnostic()?; - - let (block, delta) = { - let mut working_set = StateWorkingSet::new(engine_state); - trace!("parsing file: {}", path); - - let (output, err) = parse(&mut working_set, Some(&path), &file, false); - if let Some(err) = err { - report_error(&working_set, &err); - - std::process::exit(1); - } - (output, working_set.render()) - }; - - if let Err(err) = engine_state.merge_delta(delta, None, &init_cwd) { - let working_set = StateWorkingSet::new(engine_state); - report_error(&working_set, &err); - } - let mut stack = nu_protocol::engine::Stack::new(); // Set up our initial config to start from @@ -65,20 +44,6 @@ pub(crate) fn evaluate( } }; - // Merge the delta in case env vars changed in the config - match nu_engine::env::current_dir(engine_state, &stack) { - Ok(cwd) => { - if let Err(e) = engine_state.merge_delta(StateDelta::new(), Some(&mut stack), cwd) { - let working_set = StateWorkingSet::new(engine_state); - report_error(&working_set, &e); - } - } - Err(e) => { - let working_set = StateWorkingSet::new(engine_state); - report_error(&working_set, &e); - } - } - // Translate environment variables from Strings to Values if let Some(e) = convert_env_values(engine_state, &stack, &config) { let working_set = StateWorkingSet::new(engine_state); @@ -86,54 +51,32 @@ pub(crate) fn evaluate( std::process::exit(1); } - // Next, let's check if there are any flags we want to pass to the main function - if args.is_empty() && engine_state.find_decl(b"main").is_none() { - // We don't have a main, so evaluate the whole file - match eval_block(engine_state, &mut stack, &block, input) { - Ok(pipeline_data) => { - print_table_or_error(engine_state, &mut stack, pipeline_data, &config) - } - Err(err) => { - let working_set = StateWorkingSet::new(engine_state); + let file = std::fs::read(&path).into_diagnostic()?; - report_error(&working_set, &err); + let mut working_set = StateWorkingSet::new(engine_state); + trace!("parsing file: {}", path); - std::process::exit(1); - } - } + let _ = parse(&mut working_set, Some(&path), &file, false); + + if working_set.find_decl(b"main").is_some() { + let args = format!("main {}", args.join(" ")); + + eval_source( + engine_state, + &mut stack, + &file, + &path, + PipelineData::new(Span::new(0, 0)), + ); + eval_source( + engine_state, + &mut stack, + args.as_bytes(), + "", + input, + ); } else { - let args = format!("main {}", args.join(" ")).as_bytes().to_vec(); - - let (block, delta) = { - let mut working_set = StateWorkingSet::new(engine_state); - let (output, err) = parse(&mut working_set, Some(""), &args, false); - if let Some(err) = err { - report_error(&working_set, &err); - - std::process::exit(1); - } - (output, working_set.render()) - }; - - let cwd = nu_engine::env::current_dir_str(engine_state, &stack)?; - - if let Err(err) = engine_state.merge_delta(delta, Some(&mut stack), &cwd) { - let working_set = StateWorkingSet::new(engine_state); - report_error(&working_set, &err); - } - - match eval_block(engine_state, &mut stack, &block, input) { - Ok(pipeline_data) => { - print_table_or_error(engine_state, &mut stack, pipeline_data, &config) - } - Err(err) => { - let working_set = StateWorkingSet::new(engine_state); - - report_error(&working_set, &err); - - std::process::exit(1); - } - } + eval_source(engine_state, &mut stack, &file, &path, input); } if is_perf_true() { diff --git a/src/main.rs b/src/main.rs index 840b708d69..e45e8adf11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -188,13 +188,8 @@ fn main() -> Result<()> { ret_val } else if !script_name.is_empty() && binary_args.interactive_shell.is_none() { - let ret_val = eval_file::evaluate( - script_name, - &args_to_script, - init_cwd, - &mut engine_state, - input, - ); + let ret_val = + eval_file::evaluate(script_name, &args_to_script, &mut engine_state, input); if is_perf_true() { info!("eval_file execution {}:{}:{}", file!(), line!(), column!()); } diff --git a/src/repl.rs b/src/repl.rs index 071a6ce497..fe0103d076 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -12,6 +12,7 @@ use nu_cli::{NuCompleter, NuHighlighter, NuValidator, NushellPrompt}; use nu_color_config::get_color_config; use nu_engine::convert_env_values; use nu_parser::lex; +use nu_protocol::PipelineData; use nu_protocol::{ engine::{EngineState, StateWorkingSet}, Config, ShellError, Span, Value, CONFIG_VARIABLE_ID, @@ -300,8 +301,9 @@ pub(crate) fn evaluate(engine_state: &mut EngineState) -> Result<()> { eval_source( engine_state, &mut stack, - &s, + s.as_bytes(), &format!("entry #{}", entry_num), + PipelineData::new(Span::new(0, 0)), ); stack.add_env_var( diff --git a/src/utils.rs b/src/utils.rs index 82b2ef2bd2..21ecf7b258 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -257,8 +257,9 @@ fn print_pipeline_data( pub(crate) fn eval_source( engine_state: &mut EngineState, stack: &mut Stack, - source: &str, + source: &[u8], fname: &str, + input: PipelineData, ) -> bool { trace!("eval_source"); @@ -267,7 +268,7 @@ pub(crate) fn eval_source( let (output, err) = parse( &mut working_set, Some(fname), // format!("entry #{}", entry_num) - source.as_bytes(), + source, false, ); if let Some(err) = err { @@ -292,12 +293,7 @@ pub(crate) fn eval_source( report_error(&working_set, &err); } - match eval_block( - engine_state, - stack, - &block, - PipelineData::new(Span::new(0, 0)), - ) { + match eval_block(engine_state, stack, &block, input) { Ok(pipeline_data) => { if let Err(err) = print_pipeline_data(pipeline_data, engine_state, stack) { let working_set = StateWorkingSet::new(engine_state);