From aaf5684f9c4f661a99885ee26d1ba27e57c4cfaf Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Mon, 8 Aug 2022 20:26:49 +0800 Subject: [PATCH] when spawned process during register plugin, pass env to child process (#6261) * when spawned process during register plugin, pass env to child process * tweak comment * tweak comment * remove trailing whitespace Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com> --- Cargo.lock | 1 + crates/nu-parser/Cargo.toml | 1 + crates/nu-parser/src/parse_keywords.rs | 10 ++++++++-- crates/nu-plugin/src/plugin/declaration.rs | 4 ++++ crates/nu-plugin/src/plugin/mod.rs | 3 +++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8492d6d284..b70ddd6c84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2721,6 +2721,7 @@ dependencies = [ "itertools", "log", "miette 5.1.1", + "nu-engine", "nu-path", "nu-plugin", "nu-protocol", diff --git a/crates/nu-parser/Cargo.toml b/crates/nu-parser/Cargo.toml index 9633ec8fce..7c97c0f1e2 100644 --- a/crates/nu-parser/Cargo.toml +++ b/crates/nu-parser/Cargo.toml @@ -15,6 +15,7 @@ serde_json = "1.0" nu-path = {path = "../nu-path", version = "0.66.3" } nu-protocol = { path = "../nu-protocol", version = "0.66.3" } nu-plugin = { path = "../nu-plugin", optional = true, version = "0.66.3" } +nu-engine = { path = "../nu-engine", version = "0.66.3" } log = "0.4" [features] diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index 2d940b5b85..11fccb83de 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -2623,7 +2623,8 @@ pub fn parse_register( expand_aliases_denylist: &[usize], ) -> (Pipeline, Option) { use nu_plugin::{get_signature, EncodingType, PluginDeclaration}; - use nu_protocol::Signature; + use nu_protocol::{engine::Stack, Signature}; + let cwd = working_set.get_cwd(); // Checking that the function is used with the correct name @@ -2784,6 +2785,11 @@ pub fn parse_register( }, }; + // We need the current environment variables for `python` based plugins + // Or we'll likely have a problem when a plugin is implemented in a virtual Python environment. + let stack = Stack::new(); + let current_envs = + nu_engine::env::env_to_strings(working_set.permanent_state, &stack).unwrap_or_default(); let error = match signature { Some(signature) => arguments.and_then(|(path, encoding)| { signature.map(|signature| { @@ -2793,7 +2799,7 @@ pub fn parse_register( }) }), None => arguments.and_then(|(path, encoding)| { - get_signature(path.as_path(), &encoding, &shell) + get_signature(path.as_path(), &encoding, &shell, ¤t_envs) .map_err(|err| { ParseError::LabeledError( "Error getting signatures".into(), diff --git a/crates/nu-plugin/src/plugin/declaration.rs b/crates/nu-plugin/src/plugin/declaration.rs index 31c52d6961..c47b9003f2 100644 --- a/crates/nu-plugin/src/plugin/declaration.rs +++ b/crates/nu-plugin/src/plugin/declaration.rs @@ -61,6 +61,10 @@ impl Command for PluginDeclaration { // Create PipelineData let source_file = Path::new(&self.filename); let mut plugin_cmd = create_command(source_file, &self.shell); + // We need the current environment variables for `python` based plugins + // Or we'll likely have a problem when a plugin is implemented in a virtual Python environment. + let current_envs = nu_engine::env::env_to_strings(engine_state, stack).unwrap_or_default(); + plugin_cmd.envs(current_envs); let mut child = plugin_cmd.spawn().map_err(|err| { let decl = engine_state.get_decl(call.decl_id); diff --git a/crates/nu-plugin/src/plugin/mod.rs b/crates/nu-plugin/src/plugin/mod.rs index 53532725e3..194617c291 100644 --- a/crates/nu-plugin/src/plugin/mod.rs +++ b/crates/nu-plugin/src/plugin/mod.rs @@ -1,6 +1,7 @@ mod declaration; pub use declaration::PluginDeclaration; use nu_engine::documentation::get_flags_section; +use std::collections::HashMap; use crate::protocol::{CallInput, LabeledError, PluginCall, PluginData, PluginResponse}; use crate::EncodingType; @@ -117,9 +118,11 @@ pub fn get_signature( path: &Path, encoding: &EncodingType, shell: &Option, + current_envs: &HashMap, ) -> Result, ShellError> { let mut plugin_cmd = create_command(path, shell); + plugin_cmd.envs(current_envs); let mut child = plugin_cmd.spawn().map_err(|err| { ShellError::PluginFailedToLoad(format!("Error spawning child process: {}", err)) })?;