diff --git a/crates/nu-cli/src/config_files.rs b/crates/nu-cli/src/config_files.rs index ff6b4916f9..2fd7836604 100644 --- a/crates/nu-cli/src/config_files.rs +++ b/crates/nu-cli/src/config_files.rs @@ -1,7 +1,13 @@ use crate::util::{eval_source, report_error}; #[cfg(feature = "plugin")] use log::info; +#[cfg(feature = "plugin")] +use nu_parser::ParseError; +#[cfg(feature = "plugin")] +use nu_path::canonicalize_with; use nu_protocol::engine::{EngineState, Stack, StateWorkingSet}; +#[cfg(feature = "plugin")] +use nu_protocol::Spanned; use nu_protocol::{HistoryFileFormat, PipelineData, Span}; use std::path::PathBuf; @@ -15,12 +21,13 @@ const HISTORY_FILE_SQLITE: &str = "history.sqlite3"; pub fn read_plugin_file( engine_state: &mut EngineState, stack: &mut Stack, + plugin_file: Option>, storage_path: &str, is_perf_true: bool, ) { // Reading signatures from signature file // The plugin.nu file stores the parsed signature collected from each registered plugin - add_plugin_file(engine_state, storage_path); + add_plugin_file(engine_state, plugin_file, storage_path); let plugin_path = engine_state.plugin_signatures.clone(); if let Some(plugin_path) = plugin_path { @@ -43,8 +50,23 @@ pub fn read_plugin_file( } #[cfg(feature = "plugin")] -pub fn add_plugin_file(engine_state: &mut EngineState, storage_path: &str) { - if let Some(mut plugin_path) = nu_path::config_dir() { +pub fn add_plugin_file( + engine_state: &mut EngineState, + plugin_file: Option>, + storage_path: &str, +) { + if let Some(plugin_file) = plugin_file { + let working_set = StateWorkingSet::new(engine_state); + let cwd = working_set.get_cwd(); + + match canonicalize_with(&plugin_file.item, cwd) { + Ok(path) => engine_state.plugin_signatures = Some(path), + Err(_) => { + let e = ParseError::FileNotFound(plugin_file.item, plugin_file.span); + report_error(&working_set, &e); + } + } + } else if let Some(mut plugin_path) = nu_path::config_dir() { // Path to store plugins signatures plugin_path.push(storage_path); plugin_path.push(PLUGIN_FILE); diff --git a/src/main.rs b/src/main.rs index cec1130881..c5d9e0cb5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,6 +103,8 @@ fn main() -> Result<()> { args.next().map(|a| escape_quote_string(&a)) } "--config" | "--env-config" => args.next().map(|a| escape_quote_string(&a)), + #[cfg(feature = "plugin")] + "--plugin-config" => args.next().map(|a| escape_quote_string(&a)), "--log-level" | "--testbin" | "--threads" | "-t" => args.next(), _ => None, }; @@ -204,6 +206,7 @@ fn main() -> Result<()> { read_plugin_file( &mut engine_state, &mut stack, + binary_args.plugin_file, NUSHELL_FOLDER, is_perf_true(), ); @@ -256,6 +259,7 @@ fn main() -> Result<()> { read_plugin_file( &mut engine_state, &mut stack, + binary_args.plugin_file, NUSHELL_FOLDER, is_perf_true(), ); @@ -304,6 +308,8 @@ fn main() -> Result<()> { setup_config( &mut engine_state, &mut stack, + #[cfg(feature = "plugin")] + binary_args.plugin_file, binary_args.config_file, binary_args.env_file, binary_args.login_shell.is_some(), @@ -329,12 +335,19 @@ fn main() -> Result<()> { fn setup_config( engine_state: &mut EngineState, stack: &mut Stack, + #[cfg(feature = "plugin")] plugin_file: Option>, config_file: Option>, env_file: Option>, is_login_shell: bool, ) { #[cfg(feature = "plugin")] - read_plugin_file(engine_state, stack, NUSHELL_FOLDER, is_perf_true()); + read_plugin_file( + engine_state, + stack, + plugin_file, + NUSHELL_FOLDER, + is_perf_true(), + ); if is_perf_true() { info!("read_config_file {}:{}:{}", file!(), line!(), column!()); @@ -398,6 +411,8 @@ fn parse_commandline_args( let commands: Option = call.get_flag_expr("commands"); let testbin: Option = call.get_flag_expr("testbin"); let perf = call.has_flag("perf"); + #[cfg(feature = "plugin")] + let plugin_file: Option = call.get_flag_expr("plugin-config"); let config_file: Option = call.get_flag_expr("config"); let env_file: Option = call.get_flag_expr("env-config"); let log_level: Option = call.get_flag_expr("log-level"); @@ -425,6 +440,8 @@ fn parse_commandline_args( let commands = extract_contents(commands)?; let testbin = extract_contents(testbin)?; + #[cfg(feature = "plugin")] + let plugin_file = extract_contents(plugin_file)?; let config_file = extract_contents(config_file)?; let env_file = extract_contents(env_file)?; let log_level = extract_contents(log_level)?; @@ -455,6 +472,8 @@ fn parse_commandline_args( interactive_shell, commands, testbin, + #[cfg(feature = "plugin")] + plugin_file, config_file, env_file, log_level, @@ -478,6 +497,8 @@ struct NushellCliArgs { interactive_shell: Option>, commands: Option>, testbin: Option>, + #[cfg(feature = "plugin")] + plugin_file: Option>, config_file: Option>, env_file: Option>, log_level: Option>, @@ -495,7 +516,7 @@ impl Command for Nu { } fn signature(&self) -> Signature { - Signature::build("nu") + let signature = Signature::build("nu") .usage("The nushell language and shell.") .switch("stdin", "redirect the stdin", None) .switch("login", "start as a login shell", Some('l')) @@ -558,7 +579,22 @@ impl Command for Nu { SyntaxShape::String, "parameters to the script file", ) - .category(Category::System) + .category(Category::System); + + #[cfg(feature = "plugin")] + { + signature.named( + "plugin-config", + SyntaxShape::String, + "start with an alternate plugin signature file", + None, + ) + } + + #[cfg(not(feature = "plugin"))] + { + signature + } } fn usage(&self) -> &str {