mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 12:46:00 +02:00
Accept filenames in other plugin management commands (#12639)
# Description This allows the following commands to all accept a filename instead of a plugin name: - `plugin use` - `plugin rm` - `plugin stop` Slightly complicated because of the need to also check against `NU_PLUGIN_DIRS`, but I also fixed some issues with that at the same time Requested by @fdncred # User-Facing Changes The new commands are updated as described. # Tests + Formatting Tests for `NU_PLUGIN_DIRS` handling also made more robust. - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` # After Submitting - [ ] Double check new docs to make sure they describe this capability
This commit is contained in:
@ -4,7 +4,7 @@ use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_plugin::{GetPlugin, PersistentPlugin};
|
||||
use nu_protocol::{PluginCacheItem, PluginGcConfig, PluginIdentity, RegisteredPlugin};
|
||||
|
||||
use crate::util::modify_plugin_file;
|
||||
use crate::util::{get_plugin_dirs, modify_plugin_file};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PluginAdd;
|
||||
@ -85,24 +85,10 @@ apparent the next time `nu` is next launched with that plugin cache file.
|
||||
let cwd = current_dir(engine_state, stack)?;
|
||||
|
||||
// Check the current directory, or fall back to NU_PLUGIN_DIRS
|
||||
let filename_expanded = match nu_path::canonicalize_with(&filename.item, &cwd) {
|
||||
Ok(path) => path,
|
||||
Err(err) => {
|
||||
// Try to find it in NU_PLUGIN_DIRS first, before giving up
|
||||
let mut found = None;
|
||||
if let Some(nu_plugin_dirs) = stack.get_env_var(engine_state, "NU_PLUGIN_DIRS") {
|
||||
for dir in nu_plugin_dirs.into_list().unwrap_or(vec![]) {
|
||||
if let Ok(path) = nu_path::canonicalize_with(dir.as_str()?, &cwd)
|
||||
.and_then(|dir| nu_path::canonicalize_with(&filename.item, dir))
|
||||
{
|
||||
found = Some(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
found.ok_or(err.into_spanned(filename.span))?
|
||||
}
|
||||
};
|
||||
let filename_expanded = nu_path::locate_in_dirs(&filename.item, &cwd, || {
|
||||
get_plugin_dirs(engine_state, stack)
|
||||
})
|
||||
.err_span(filename.span)?;
|
||||
|
||||
let shell_expanded = shell
|
||||
.as_ref()
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_engine::command_prelude::*;
|
||||
|
||||
use crate::util::modify_plugin_file;
|
||||
use crate::util::{canonicalize_possible_filename_arg, modify_plugin_file};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PluginRm;
|
||||
@ -28,7 +28,7 @@ impl Command for PluginRm {
|
||||
.required(
|
||||
"name",
|
||||
SyntaxShape::String,
|
||||
"The name of the plugin to remove (not the filename)",
|
||||
"The name, or filename, of the plugin to remove",
|
||||
)
|
||||
.category(Category::Plugin)
|
||||
}
|
||||
@ -61,6 +61,11 @@ fixed with `plugin add`.
|
||||
description: "Remove the installed signatures for the `inc` plugin.",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
example: "plugin rm ~/.cargo/bin/nu_plugin_inc",
|
||||
description: "Remove the installed signatures for the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
example: "plugin rm --plugin-config polars.msgpackz polars",
|
||||
description: "Remove the installed signatures for the `polars` plugin from the \"polars.msgpackz\" plugin cache file.",
|
||||
@ -80,8 +85,19 @@ fixed with `plugin add`.
|
||||
let custom_path = call.get_flag(engine_state, stack, "plugin-config")?;
|
||||
let force = call.has_flag(engine_state, stack, "force")?;
|
||||
|
||||
let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
|
||||
|
||||
modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| {
|
||||
if !force && !contents.plugins.iter().any(|p| p.name == name.item) {
|
||||
if let Some(index) = contents
|
||||
.plugins
|
||||
.iter()
|
||||
.position(|p| p.name == name.item || p.filename == filename)
|
||||
{
|
||||
contents.plugins.remove(index);
|
||||
Ok(())
|
||||
} else if force {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ShellError::GenericError {
|
||||
error: format!("Failed to remove the `{}` plugin", name.item),
|
||||
msg: "couldn't find a plugin with this name in the cache file".into(),
|
||||
@ -89,9 +105,6 @@ fixed with `plugin add`.
|
||||
help: None,
|
||||
inner: vec![],
|
||||
})
|
||||
} else {
|
||||
contents.remove_plugin(&name.item);
|
||||
Ok(())
|
||||
}
|
||||
})?;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
use nu_engine::command_prelude::*;
|
||||
|
||||
use crate::util::canonicalize_possible_filename_arg;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PluginStop;
|
||||
|
||||
@ -14,7 +16,7 @@ impl Command for PluginStop {
|
||||
.required(
|
||||
"name",
|
||||
SyntaxShape::String,
|
||||
"The name of the plugin to stop.",
|
||||
"The name, or filename, of the plugin to stop",
|
||||
)
|
||||
.category(Category::Plugin)
|
||||
}
|
||||
@ -30,6 +32,11 @@ impl Command for PluginStop {
|
||||
description: "Stop the plugin named `inc`.",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
example: "plugin stop ~/.cargo/bin/nu_plugin_inc",
|
||||
description: "Stop the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
example: "plugin list | each { |p| plugin stop $p.name }",
|
||||
description: "Stop all plugins.",
|
||||
@ -47,9 +54,12 @@ impl Command for PluginStop {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
|
||||
let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
|
||||
|
||||
let mut found = false;
|
||||
for plugin in engine_state.plugins() {
|
||||
if plugin.identity().name() == name.item {
|
||||
let id = &plugin.identity();
|
||||
if id.name() == name.item || id.filename() == filename {
|
||||
plugin.stop()?;
|
||||
found = true;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ impl Command for PluginUse {
|
||||
.required(
|
||||
"name",
|
||||
SyntaxShape::String,
|
||||
"The name of the plugin to load (not the filename)",
|
||||
"The name, or filename, of the plugin to load",
|
||||
)
|
||||
.category(Category::Plugin)
|
||||
}
|
||||
@ -41,6 +41,9 @@ preparing a plugin cache file and passing `--plugin-config`, or using the
|
||||
|
||||
If the plugin was already loaded, this will reload the latest definition from
|
||||
the cache file into scope.
|
||||
|
||||
Note that even if the plugin filename is specified, it will only be loaded if
|
||||
it was already previously registered with `plugin add`.
|
||||
"#
|
||||
.trim()
|
||||
}
|
||||
@ -70,6 +73,11 @@ the cache file into scope.
|
||||
example: r#"plugin use query"#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Load the commands for the plugin with the filename `~/.cargo/bin/nu_plugin_query` from $nu.plugin-path",
|
||||
example: r#"plugin use ~/.cargo/bin/nu_plugin_query"#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description:
|
||||
"Load the commands for the `query` plugin from a custom plugin cache file",
|
||||
|
Reference in New Issue
Block a user