Deprecate register and add plugin use (#12607)

# Description

Adds a new keyword, `plugin use`. Unlike `register`, this merely loads
the signatures from the plugin cache file. The file is configurable with
the `--plugin-config` option either to `nu` or to `plugin use` itself,
just like the other `plugin` family of commands. At the REPL, one might
do this to replace `register`:

```nushell
> plugin add ~/.cargo/bin/nu_plugin_foo
> plugin use foo
```

This will not work in a script, because `plugin use` is a keyword and
`plugin add` does not evaluate at parse time (intentionally). This means
we no longer run random binaries during parse.

The `--plugins` option has been added to allow running `nu` with certain
plugins in one step. This is used especially for the `nu_with_plugins!`
test macro, but I'd imagine is generally useful. The only weird quirk is
that it has to be a list, and we don't really do this for any of our
other CLI args at the moment.

`register` now prints a deprecation parse warning.

This should fix #11923, as we now have a complete alternative to
`register`.

# User-Facing Changes

- Add `plugin use` command
- Deprecate `register`
- Add `--plugins` option to `nu` to replace a common use of `register`

# Tests + Formatting

I think I've tested it thoroughly enough and every existing test passes.
Testing nu CLI options and alternate config files is a little hairy and
I wish there were some more generic helpers for this, so this will go on
my TODO list for refactoring.

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting

- [ ] Update plugins sections of book
- [ ] Release notes
This commit is contained in:
Devyn Cairns
2024-04-23 04:37:50 -07:00
committed by GitHub
parent 5c7f7883c8
commit 1f4131532d
27 changed files with 759 additions and 172 deletions

View File

@ -54,7 +54,7 @@ apparent the next time `nu` is next launched with that plugin cache file.
}
fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "add", "register", "load", "signature"]
vec!["load", "register", "signature"]
}
fn examples(&self) -> Vec<Example> {

View File

@ -29,6 +29,10 @@ impl Command for PluginList {
"List installed plugins."
}
fn search_terms(&self) -> Vec<&str> {
vec!["scope"]
}
fn examples(&self) -> Vec<nu_protocol::Example> {
vec![
Example {

View File

@ -4,11 +4,13 @@ mod add;
mod list;
mod rm;
mod stop;
mod use_;
pub use add::PluginAdd;
pub use list::PluginList;
pub use rm::PluginRm;
pub use stop::PluginStop;
pub use use_::PluginUse;
#[derive(Clone)]
pub struct PluginCommand;
@ -28,10 +30,6 @@ impl Command for PluginCommand {
"Commands for managing plugins."
}
fn extra_usage(&self) -> &str {
"To load a plugin, see `register`."
}
fn run(
&self,
engine_state: &EngineState,
@ -54,6 +52,20 @@ impl Command for PluginCommand {
fn examples(&self) -> Vec<Example> {
vec![
Example {
example: "plugin add nu_plugin_inc",
description: "Run the `nu_plugin_inc` plugin from the current directory and install its signatures.",
result: None,
},
Example {
example: "plugin use inc",
description: "
Load (or reload) the `inc` plugin from the plugin cache file and put its commands in scope.
The plugin must already be in the cache file at parse time.
"
.trim(),
result: None,
},
Example {
example: "plugin list",
description: "List installed plugins",
@ -64,11 +76,6 @@ impl Command for PluginCommand {
description: "Stop the plugin named `inc`.",
result: None,
},
Example {
example: "plugin add nu_plugin_inc",
description: "Run the `nu_plugin_inc` plugin from the current directory and install its signatures.",
result: None,
},
Example {
example: "plugin rm inc",
description: "Remove the installed signatures for the `inc` plugin.",

View File

@ -51,7 +51,7 @@ fixed with `plugin add`.
}
fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "rm", "remove", "delete", "signature"]
vec!["remove", "delete", "signature"]
}
fn examples(&self) -> Vec<Example> {

View File

@ -0,0 +1,81 @@
use nu_engine::command_prelude::*;
#[derive(Clone)]
pub struct PluginUse;
impl Command for PluginUse {
fn name(&self) -> &str {
"plugin use"
}
fn usage(&self) -> &str {
"Load a plugin from the plugin cache file into scope."
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build(self.name())
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.named(
"plugin-config",
SyntaxShape::Filepath,
"Use a plugin cache file other than the one set in `$nu.plugin-path`",
None,
)
.required(
"name",
SyntaxShape::String,
"The name of the plugin to load (not the filename)",
)
.category(Category::Plugin)
}
fn extra_usage(&self) -> &str {
r#"
This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html
The plugin definition must be available in the plugin cache file at parse time.
Run `plugin add` first in the REPL to do this, or from a script consider
preparing a plugin cache file and passing `--plugin-config`, or using the
`--plugin` option to `nu` instead.
If the plugin was already loaded, this will reload the latest definition from
the cache file into scope.
"#
.trim()
}
fn search_terms(&self) -> Vec<&str> {
vec!["add", "register", "scope"]
}
fn is_parser_keyword(&self) -> bool {
true
}
fn run(
&self,
_engine_state: &EngineState,
_stack: &mut Stack,
_call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(PipelineData::empty())
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Load the commands for the `query` plugin from $nu.plugin-path",
example: r#"plugin use query"#,
result: None,
},
Example {
description:
"Load the commands for the `query` plugin from a custom plugin cache file",
example: r#"plugin use --plugin-config local-plugins.msgpackz query"#,
result: None,
},
]
}
}