diff --git a/crates/nu-cli/src/eval_file.rs b/crates/nu-cli/src/eval_file.rs index a513ec56c..e28de2f08 100644 --- a/crates/nu-cli/src/eval_file.rs +++ b/crates/nu-cli/src/eval_file.rs @@ -2,6 +2,7 @@ use crate::util::eval_source; use log::info; use log::trace; use miette::{IntoDiagnostic, Result}; +use nu_engine::eval_block_with_early_return; use nu_engine::{convert_env_values, current_dir}; use nu_parser::parse; use nu_path::canonicalize_with; @@ -98,23 +99,59 @@ pub fn evaluate_file( Value::string(file_path.to_string_lossy(), Span::unknown()), ); + let source_filename = file_path + .file_name() + .expect("internal error: script missing filename"); + let mut working_set = StateWorkingSet::new(engine_state); trace!("parsing file: {}", file_path_str); - let _ = parse(&mut working_set, Some(file_path_str), &file, false); + let block = parse(&mut working_set, Some(file_path_str), &file, false); - if working_set.find_decl(b"main").is_some() { + for block in &mut working_set.delta.blocks { + if block.signature.name == "main" { + block.signature.name = source_filename.to_string_lossy().to_string(); + } else if block.signature.name.starts_with("main ") { + block.signature.name = source_filename.to_string_lossy().to_string() + + " " + + &String::from_utf8_lossy(&block.signature.name.as_bytes()[5..]); + } + } + + let _ = engine_state.merge_delta(working_set.delta); + + if engine_state.find_decl(b"main", &[]).is_some() { let args = format!("main {}", args.join(" ")); - if !eval_source( + let pipeline_data = eval_block_with_early_return( engine_state, stack, - &file, - file_path_str, + &block, PipelineData::empty(), - true, - ) { + false, + false, + ) + .unwrap_or_else(|e| { + let working_set = StateWorkingSet::new(engine_state); + report_error(&working_set, &e); std::process::exit(1); + }); + + let result = pipeline_data.print(engine_state, stack, true, false); + + match result { + Err(err) => { + let working_set = StateWorkingSet::new(engine_state); + + report_error(&working_set, &err); + std::process::exit(1); + } + Ok(exit_code) => { + if exit_code != 0 { + std::process::exit(exit_code as i32); + } + } } + if !eval_source( engine_state, stack, diff --git a/crates/nu-command/src/help/help_commands.rs b/crates/nu-command/src/help/help_commands.rs index ce360a244..621ba9e88 100644 --- a/crates/nu-command/src/help/help_commands.rs +++ b/crates/nu-command/src/help/help_commands.rs @@ -127,13 +127,12 @@ fn build_help_commands(engine_state: &EngineState, span: Span) -> Vec { let commands = engine_state.get_decls_sorted(false); let mut found_cmds_vec = Vec::new(); - for (name_bytes, decl_id) in commands { + for (_, decl_id) in commands { let mut cols = vec![]; let mut vals = vec![]; - let name = String::from_utf8_lossy(&name_bytes).to_string(); let decl = engine_state.get_decl(decl_id); - let sig = decl.signature().update_from_command(name, decl.borrow()); + let sig = decl.signature().update_from_command(decl.borrow()); let key = sig.name; let usage = sig.usage; diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 33bf06ed6..4bfd2bc9f 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -38,7 +38,7 @@ pub fn eval_call( let decl = engine_state.get_decl(call.decl_id); if !decl.is_known_external() && call.named_iter().any(|(flag, _, _)| flag.item == "help") { - let mut signature = decl.signature(); + let mut signature = engine_state.get_signature(decl); signature.usage = decl.usage().to_string(); signature.extra_usage = decl.extra_usage().to_string(); diff --git a/crates/nu-engine/src/scope.rs b/crates/nu-engine/src/scope.rs index 36610b003..1961ff7a7 100644 --- a/crates/nu-engine/src/scope.rs +++ b/crates/nu-engine/src/scope.rs @@ -534,12 +534,11 @@ impl<'e, 's> ScopeData<'e, 's> { pub fn collect_aliases(&self, span: Span) -> Vec { let mut aliases = vec![]; - for (name_bytes, decl_id) in self.engine_state.get_decls_sorted(false) { + for (_, decl_id) in self.engine_state.get_decls_sorted(false) { if self.visibility.is_decl_id_visible(&decl_id) { let decl = self.engine_state.get_decl(decl_id); if let Some(alias) = decl.as_alias() { - let name = String::from_utf8_lossy(&name_bytes).to_string(); - let sig = decl.signature().update_from_command(name, decl.borrow()); + let sig = decl.signature().update_from_command(decl.borrow()); let key = sig.name; aliases.push(Value::Record { diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index d6c56eb68..5e8dbb5e6 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -783,16 +783,22 @@ impl EngineState { decls.into_iter() } + #[allow(clippy::borrowed_box)] + pub fn get_signature(&self, decl: &Box) -> Signature { + if let Some(block_id) = decl.get_block_id() { + *self.blocks[block_id].signature.clone() + } else { + decl.signature() + } + } + /// Get signatures of all commands within scope. pub fn get_signatures(&self, include_hidden: bool) -> Vec { self.get_decls_sorted(include_hidden) - .map(|(name_bytes, id)| { + .map(|(_, id)| { let decl = self.get_decl(id); - // the reason to create the name this way is because the command could be renamed - // during module imports but the signature still contains the old name - let name = String::from_utf8_lossy(&name_bytes).to_string(); - (*decl).signature().update_from_command(name, decl.borrow()) + self.get_signature(decl).update_from_command(decl.borrow()) }) .collect() } @@ -807,13 +813,10 @@ impl EngineState { include_hidden: bool, ) -> Vec<(Signature, Vec, bool, bool, bool)> { self.get_decls_sorted(include_hidden) - .map(|(name_bytes, id)| { + .map(|(_, id)| { let decl = self.get_decl(id); - // the reason to create the name this way is because the command could be renamed - // during module imports but the signature still contains the old name - let name = String::from_utf8_lossy(&name_bytes).to_string(); - let signature = (*decl).signature().update_from_command(name, decl.borrow()); + let signature = self.get_signature(decl).update_from_command(decl.borrow()); ( signature, diff --git a/crates/nu-protocol/src/plugin_signature.rs b/crates/nu-protocol/src/plugin_signature.rs index 215a7e2ab..45a5072d8 100644 --- a/crates/nu-protocol/src/plugin_signature.rs +++ b/crates/nu-protocol/src/plugin_signature.rs @@ -48,8 +48,8 @@ impl PluginSignature { } /// Update signature's fields from a Command trait implementation - pub fn update_from_command(mut self, name: String, command: &dyn Command) -> PluginSignature { - self.sig = self.sig.update_from_command(name, command); + pub fn update_from_command(mut self, command: &dyn Command) -> PluginSignature { + self.sig = self.sig.update_from_command(command); self } diff --git a/crates/nu-protocol/src/signature.rs b/crates/nu-protocol/src/signature.rs index 81168b32b..5689692aa 100644 --- a/crates/nu-protocol/src/signature.rs +++ b/crates/nu-protocol/src/signature.rs @@ -237,8 +237,7 @@ impl Signature { } /// Update signature's fields from a Command trait implementation - pub fn update_from_command(mut self, name: String, command: &dyn Command) -> Signature { - self.name = name; + pub fn update_from_command(mut self, command: &dyn Command) -> Signature { self.search_terms = command .search_terms() .into_iter()