From 0da531a3194f0121777ace83ff8a1c3ee2a4799a Mon Sep 17 00:00:00 2001 From: Andy Gayton Date: Thu, 4 Jul 2024 17:33:31 -0400 Subject: [PATCH] wip --- crates/nu-parser/src/lib.rs | 3 - crates/nu-parser/src/parse_keywords.rs | 239 ------------------------- crates/nu-parser/src/parser.rs | 2 - 3 files changed, 244 deletions(-) diff --git a/crates/nu-parser/src/lib.rs b/crates/nu-parser/src/lib.rs index 89cba8d243..3c97012e8a 100644 --- a/crates/nu-parser/src/lib.rs +++ b/crates/nu-parser/src/lib.rs @@ -24,6 +24,3 @@ pub use parser::{ is_math_expression_like, parse, parse_block, parse_expression, parse_external_call, parse_unit_value, trim_quotes, trim_quotes_str, unescape_unquote_string, DURATION_UNIT_GROUPS, }; - -#[cfg(feature = "plugin")] -pub use parse_keywords::parse_register; diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index 70d217c564..4ac1d20699 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -82,7 +82,6 @@ pub const UNALIASABLE_PARSER_KEYWORDS: &[&[u8]] = &[ b"source-env", b"source", b"where", - b"register", b"plugin use", ]; @@ -3627,244 +3626,6 @@ pub fn parse_where(working_set: &mut StateWorkingSet, lite_command: &LiteCommand } } -/// `register` is deprecated and will be removed in 0.94. Use `plugin add` and `plugin use` instead. -#[cfg(feature = "plugin")] -pub fn parse_register(working_set: &mut StateWorkingSet, lite_command: &LiteCommand) -> Pipeline { - use nu_plugin_engine::PluginDeclaration; - use nu_protocol::{ - engine::Stack, ErrSpan, ParseWarning, PluginIdentity, PluginRegistryItem, PluginSignature, - RegisteredPlugin, - }; - - let spans = &lite_command.parts; - - #[allow(deprecated)] - let cwd = working_set.get_cwd(); - - // Checking that the function is used with the correct name - // Maybe this is not necessary but it is a sanity check - if working_set.get_span_contents(spans[0]) != b"register" { - working_set.error(ParseError::UnknownState( - "internal error: Wrong call name for 'register' function".into(), - Span::concat(spans), - )); - return garbage_pipeline(working_set, spans); - } - if let Some(redirection) = lite_command.redirection.as_ref() { - working_set.error(redirecting_builtin_error("register", redirection)); - return garbage_pipeline(working_set, spans); - } - - // Parsing the spans and checking that they match the register signature - // Using a parsed call makes more sense than checking for how many spans are in the call - // Also, by creating a call, it can be checked if it matches the declaration signature - let (call, call_span) = match working_set.find_decl(b"register") { - None => { - working_set.error(ParseError::UnknownState( - "internal error: Register declaration not found".into(), - Span::concat(spans), - )); - return garbage_pipeline(working_set, spans); - } - Some(decl_id) => { - let ParsedInternalCall { call, output } = - parse_internal_call(working_set, spans[0], &spans[1..], decl_id); - let decl = working_set.get_decl(decl_id); - - let call_span = Span::concat(spans); - - let starting_error_count = working_set.parse_errors.len(); - check_call(working_set, call_span, &decl.signature(), &call); - - let Ok(is_help) = has_flag_const(working_set, &call, "help") else { - return garbage_pipeline(working_set, spans); - }; - - if starting_error_count != working_set.parse_errors.len() || is_help { - return Pipeline::from_vec(vec![Expression::new( - working_set, - Expr::Call(call), - call_span, - output, - )]); - } - - (call, call_span) - } - }; - - // Now that the call is parsed, add the deprecation warning - working_set - .parse_warnings - .push(ParseWarning::DeprecatedWarning { - old_command: "register".into(), - new_suggestion: "use `plugin add` and `plugin use`".into(), - span: call.head, - url: "https://www.nushell.sh/book/plugins.html".into(), - }); - - // Extracting the required arguments from the call and keeping them together in a tuple - let arguments = call - .positional_nth(0) - .map(|expr| { - let val = - eval_constant(working_set, expr).map_err(|err| err.wrap(working_set, call.head))?; - let filename = val - .coerce_into_string() - .map_err(|err| err.wrap(working_set, call.head))?; - - let Some(path) = find_in_dirs(&filename, working_set, &cwd, Some(PLUGIN_DIRS_VAR)) - else { - return Err(ParseError::RegisteredFileNotFound(filename, expr.span)); - }; - - if path.exists() && path.is_file() { - Ok((path, expr.span)) - } else { - Err(ParseError::RegisteredFileNotFound(filename, expr.span)) - } - }) - .expect("required positional has being checked"); - - // Signature is an optional value from the call and will be used to decide if - // the plugin is called to get the signatures or to use the given signature - let signature = call.positional_nth(1).map(|expr| { - let signature = working_set.get_span_contents(expr.span); - serde_json::from_slice::(signature).map_err(|e| { - ParseError::LabeledError( - "Signature deserialization error".into(), - format!("unable to deserialize signature: {e}"), - spans[0], - ) - }) - }); - - // Shell is another optional value used as base to call shell to plugins - let shell = call.get_flag_expr("shell").map(|expr| { - let shell_expr = working_set.get_span_contents(expr.span); - - String::from_utf8(shell_expr.to_vec()) - .map_err(|_| ParseError::NonUtf8(expr.span)) - .and_then(|name| { - canonicalize_with(&name, cwd) - .map_err(|_| ParseError::RegisteredFileNotFound(name, expr.span)) - }) - .and_then(|path| { - if path.exists() & path.is_file() { - Ok(path) - } else { - Err(ParseError::RegisteredFileNotFound( - format!("{path:?}"), - expr.span, - )) - } - }) - }); - - let shell = match shell { - None => None, - Some(path) => match path { - Ok(path) => Some(path), - Err(err) => { - working_set.error(err); - return Pipeline::from_vec(vec![Expression::new( - working_set, - Expr::Call(call), - call_span, - Type::Any, - )]); - } - }, - }; - - // 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 get_envs = || { - let stack = Stack::new().capture(); - nu_engine::env::env_to_strings(working_set.permanent_state, &stack) - }; - - let error = arguments.and_then(|(path, path_span)| { - let path = path.path_buf(); - - // Create the plugin identity. This validates that the plugin name starts with `nu_plugin_` - let identity = PluginIdentity::new(path, shell).err_span(path_span)?; - - let plugin = nu_plugin_engine::add_plugin_to_working_set(working_set, &identity) - .map_err(|err| err.wrap(working_set, call.head))?; - - let signatures = signature.map_or_else( - || { - // It's important that the plugin is restarted if we're going to get signatures - // - // The user would expect that `register` would always run the binary to get new - // signatures, in case it was replaced with an updated binary - plugin.reset().map_err(|err| { - ParseError::LabeledError( - "Failed to restart plugin to get new signatures".into(), - err.to_string(), - spans[0], - ) - })?; - - let metadata_and_signatures = plugin - .clone() - .get(get_envs) - .and_then(|p| { - let meta = p.get_metadata()?; - let sigs = p.get_signature()?; - Ok((meta, sigs)) - }) - .map_err(|err| { - log::warn!("Error getting metadata and signatures: {err:?}"); - ParseError::LabeledError( - "Error getting metadata and signatures".into(), - err.to_string(), - spans[0], - ) - }); - - match metadata_and_signatures { - Ok((meta, sigs)) => { - // Set the metadata on the plugin - plugin.set_metadata(Some(meta.clone())); - // Add the loaded plugin to the delta - working_set.update_plugin_registry(PluginRegistryItem::new( - &identity, - meta, - sigs.clone(), - )); - Ok(sigs) - } - Err(err) => Err(err), - } - }, - |sig| sig.map(|sig| vec![sig]), - )?; - - for signature in signatures { - // create plugin command declaration (need struct impl Command) - // store declaration in working set - let plugin_decl = PluginDeclaration::new(plugin.clone(), signature); - - working_set.add_decl(Box::new(plugin_decl)); - } - - Ok(()) - }); - - if let Err(err) = error { - working_set.error(err); - } - - Pipeline::from_vec(vec![Expression::new( - working_set, - Expr::Call(call), - call_span, - Type::Nothing, - )]) -} - #[cfg(feature = "plugin")] pub fn parse_plugin_use(working_set: &mut StateWorkingSet, call: Box) -> Pipeline { use nu_protocol::{FromValue, PluginRegistryFile}; diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index c3d18b55ac..3ff7396e79 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -5419,8 +5419,6 @@ pub fn parse_builtin_commands( b"export" => parse_export_in_block(working_set, lite_command), b"hide" => parse_hide(working_set, lite_command), b"where" => parse_where(working_set, lite_command), - #[cfg(feature = "plugin")] - b"register" => parse_register(working_set, lite_command), // Only "plugin use" is a keyword #[cfg(feature = "plugin")] b"plugin"