Split the plugin crate (#12563)

# Description

This breaks `nu-plugin` up into four crates:

- `nu-plugin-protocol`: just the type definitions for the protocol, no
I/O. If someone wanted to wire up something more bare metal, maybe for
async I/O, they could use this.
- `nu-plugin-core`: the shared stuff between engine/plugin. Less stable
interface.
- `nu-plugin-engine`: everything required for the engine to talk to
plugins. Less stable interface.
- `nu-plugin`: everything required for the plugin to talk to the engine,
what plugin developers use. Should be the most stable interface.

No changes are made to the interface exposed by `nu-plugin` - it should
all still be there. Re-exports from `nu-plugin-protocol` or
`nu-plugin-core` are used as required. Plugins shouldn't ever have to
use those crates directly.

This should be somewhat faster to compile as `nu-plugin-engine` and
`nu-plugin` can compile in parallel, and the engine doesn't need
`nu-plugin` and plugins don't need `nu-plugin-engine` (except for test
support), so that should reduce what needs to be compiled too.

The only significant change here other than splitting stuff up was to
break the `source` out of `PluginCustomValue` and create a new
`PluginCustomValueWithSource` type that contains that instead. One bonus
of that is we get rid of the option and it's now more type-safe, but it
also means that the logic for that stuff (actually running the plugin
for custom value ops) can live entirely within the `nu-plugin-engine`
crate.

# User-Facing Changes
- New crates.
- Added `local-socket` feature for `nu` to try to make it possible to
compile without that support if needed.

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
This commit is contained in:
Devyn Cairns
2024-04-27 10:08:12 -07:00
committed by GitHub
parent 884d5312bb
commit 0c4d5330ee
74 changed files with 3514 additions and 3110 deletions

View File

@ -3555,7 +3555,7 @@ 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::{get_signature, PluginDeclaration};
use nu_plugin_engine::PluginDeclaration;
use nu_protocol::{
engine::Stack, ErrSpan, ParseWarning, PluginIdentity, PluginRegistryItem, PluginSignature,
RegisteredPlugin,
@ -3714,7 +3714,7 @@ pub fn parse_register(working_set: &mut StateWorkingSet, lite_command: &LiteComm
// 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::add_plugin_to_working_set(working_set, &identity)
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(
@ -3731,14 +3731,18 @@ pub fn parse_register(working_set: &mut StateWorkingSet, lite_command: &LiteComm
)
})?;
let signatures = get_signature(plugin.clone(), get_envs).map_err(|err| {
log::warn!("Error getting signatures: {err:?}");
ParseError::LabeledError(
"Error getting signatures".into(),
err.to_string(),
spans[0],
)
});
let signatures = plugin
.clone()
.get(get_envs)
.and_then(|p| p.get_signature())
.map_err(|err| {
log::warn!("Error getting signatures: {err:?}");
ParseError::LabeledError(
"Error getting signatures".into(),
err.to_string(),
spans[0],
)
});
if let Ok(ref signatures) = signatures {
// Add the loaded plugin to the delta
@ -3863,7 +3867,7 @@ pub fn parse_plugin_use(working_set: &mut StateWorkingSet, call: Box<Call>) -> P
})?;
// Now add the signatures to the working set
nu_plugin::load_plugin_registry_item(working_set, plugin_item, Some(call.head))
nu_plugin_engine::load_plugin_registry_item(working_set, plugin_item, Some(call.head))
.map_err(|err| err.wrap(working_set, call.head))?;
Ok(())