Add command_prelude module (#12291)

# Description
When implementing a `Command`, one must also import all the types
present in the function signatures for `Command`. This makes it so that
we often import the same set of types in each command implementation
file. E.g., something like this:
```rust
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
    record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
    ShellError, Signature, Span, Type, Value,
};
```

This PR adds the `nu_engine::command_prelude` module which contains the
necessary and commonly used types to implement a `Command`:
```rust
// command_prelude.rs
pub use crate::CallExt;
pub use nu_protocol::{
    ast::{Call, CellPath},
    engine::{Command, EngineState, Stack},
    record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, IntoSpanned,
    PipelineData, Record, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
};
```

This should reduce the boilerplate needed to implement a command and
also gives us a place to track the breadth of the `Command` API. I tried
to be conservative with what went into the prelude modules, since it
might be hard/annoying to remove items from the prelude in the future.
Let me know if something should be included or excluded.
This commit is contained in:
Ian Manske
2024-03-26 21:17:30 +00:00
committed by GitHub
parent f8c1e3ac61
commit c747ec75c9
660 changed files with 1634 additions and 4332 deletions

View File

@ -1,17 +1,15 @@
use std::{
borrow::Cow,
collections::HashMap,
sync::{atomic::AtomicBool, Arc},
};
use crate::util::MutableCow;
use nu_engine::{get_eval_block_with_early_return, get_full_help};
use nu_protocol::{
ast::Call,
engine::{Closure, EngineState, Redirection, Stack},
Config, IntoSpanned, IoStream, PipelineData, PluginIdentity, ShellError, Spanned, Value,
};
use crate::util::MutableCow;
use std::{
borrow::Cow,
collections::HashMap,
sync::{atomic::AtomicBool, Arc},
};
/// Object safe trait for abstracting operations required of the plugin context.
///

View File

@ -1,13 +1,9 @@
use super::{GetPlugin, PluginExecutionCommandContext, PluginSource};
use crate::protocol::{CallInfo, EvaluatedCall};
use nu_engine::{command_prelude::*, get_eval_expression};
use nu_protocol::{PluginIdentity, PluginSignature};
use std::sync::Arc;
use nu_engine::get_eval_expression;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{ast::Call, PluginSignature, Signature};
use nu_protocol::{Example, PipelineData, PluginIdentity, ShellError};
#[doc(hidden)] // Note: not for plugin authors / only used in nu-parser
#[derive(Clone)]
pub struct PluginDeclaration {

View File

@ -1,13 +1,11 @@
use crate::PersistentPlugin;
use nu_protocol::{PluginGcConfig, RegisteredPlugin};
use std::{
sync::{mpsc, Arc, Weak},
thread,
time::{Duration, Instant},
};
use nu_protocol::{PluginGcConfig, RegisteredPlugin};
use crate::PersistentPlugin;
/// Plugin garbage collector
///
/// Many users don't want all of their plugins to stay running indefinitely after using them, so

View File

@ -1,16 +1,5 @@
//! Implements the stream multiplexing interface for both the plugin side and the engine side.
use std::{
io::Write,
sync::{
atomic::{AtomicBool, Ordering::Relaxed},
Arc, Mutex,
},
thread,
};
use nu_protocol::{ListStream, PipelineData, RawStream, ShellError};
use crate::{
plugin::Encoder,
protocol::{
@ -18,6 +7,15 @@ use crate::{
},
sequence::Sequence,
};
use nu_protocol::{ListStream, PipelineData, RawStream, ShellError};
use std::{
io::Write,
sync::{
atomic::{AtomicBool, Ordering::Relaxed},
Arc, Mutex,
},
thread,
};
mod stream;

View File

@ -1,30 +1,23 @@
//! Interface used by the plugin to communicate with the engine.
use std::{
collections::{btree_map, BTreeMap, HashMap},
sync::{mpsc, Arc},
use super::{
stream::{StreamManager, StreamManagerHandle},
Interface, InterfaceManager, PipelineDataWriter, PluginRead, PluginWrite, Sequence,
};
use crate::protocol::{
CallInfo, CustomValueOp, EngineCall, EngineCallId, EngineCallResponse, Ordering, PluginCall,
PluginCallId, PluginCallResponse, PluginCustomValue, PluginInput, PluginOption, PluginOutput,
ProtocolInfo,
};
use nu_protocol::{
engine::Closure, Config, IntoInterruptiblePipelineData, LabeledError, ListStream, PipelineData,
PluginSignature, ShellError, Spanned, Value,
};
use crate::{
protocol::{
CallInfo, CustomValueOp, EngineCall, EngineCallId, EngineCallResponse, Ordering,
PluginCall, PluginCallId, PluginCallResponse, PluginCustomValue, PluginInput, PluginOption,
ProtocolInfo,
},
PluginOutput,
use std::{
collections::{btree_map, BTreeMap, HashMap},
sync::{mpsc, Arc},
};
use super::{
stream::{StreamManager, StreamManagerHandle},
Interface, InterfaceManager, PipelineDataWriter, PluginRead, PluginWrite,
};
use crate::sequence::Sequence;
/// Plugin calls that are received by the [`EngineInterfaceManager`] for handling.
///
/// With each call, an [`EngineInterface`] is included that can be provided to the plugin code

View File

@ -1,13 +1,4 @@
use std::{
collections::HashMap,
sync::mpsc::{self, TryRecvError},
};
use nu_protocol::{
engine::Closure, Config, CustomValue, IntoInterruptiblePipelineData, LabeledError,
PipelineData, PluginExample, PluginSignature, ShellError, Span, Spanned, Value,
};
use super::{EngineInterfaceManager, ReceivedPluginCall};
use crate::{
plugin::interface::{test_util::TestCase, Interface, InterfaceManager},
protocol::{
@ -18,8 +9,14 @@ use crate::{
},
EvaluatedCall, PluginCallResponse, PluginOutput,
};
use super::{EngineInterfaceManager, ReceivedPluginCall};
use nu_protocol::{
engine::Closure, Config, CustomValue, IntoInterruptiblePipelineData, LabeledError,
PipelineData, PluginExample, PluginSignature, ShellError, Span, Spanned, Value,
};
use std::{
collections::HashMap,
sync::mpsc::{self, TryRecvError},
};
#[test]
fn manager_consume_all_consumes_messages() -> Result<(), ShellError> {

View File

@ -1,15 +1,9 @@
//! Interface used by the engine to communicate with the plugin.
use std::{
collections::{btree_map, BTreeMap},
sync::{atomic::AtomicBool, mpsc, Arc, OnceLock},
use super::{
stream::{StreamManager, StreamManagerHandle},
Interface, InterfaceManager, PipelineDataWriter, PluginRead, PluginWrite,
};
use nu_protocol::{
ast::Operator, IntoInterruptiblePipelineData, IntoSpanned, ListStream, PipelineData,
PluginSignature, ShellError, Span, Spanned, Value,
};
use crate::{
plugin::{context::PluginExecutionContext, gc::PluginGc, PluginSource},
protocol::{
@ -19,10 +13,13 @@ use crate::{
},
sequence::Sequence,
};
use super::{
stream::{StreamManager, StreamManagerHandle},
Interface, InterfaceManager, PipelineDataWriter, PluginRead, PluginWrite,
use nu_protocol::{
ast::Operator, IntoInterruptiblePipelineData, IntoSpanned, ListStream, PipelineData,
PluginSignature, ShellError, Span, Spanned, Value,
};
use std::{
collections::{btree_map, BTreeMap},
sync::{atomic::AtomicBool, mpsc, Arc, OnceLock},
};
#[cfg(test)]

View File

@ -1,10 +1,6 @@
use std::{sync::mpsc, time::Duration};
use nu_protocol::{
engine::Closure, IntoInterruptiblePipelineData, PipelineData, PluginSignature, ShellError,
Span, Spanned, Value,
use super::{
Context, PluginCallState, PluginInterface, PluginInterfaceManager, ReceivedPluginCallMessage,
};
use crate::{
plugin::{
context::PluginExecutionBogusContext,
@ -19,10 +15,11 @@ use crate::{
},
EvaluatedCall, PluginCallResponse, PluginOutput,
};
use super::{
Context, PluginCallState, PluginInterface, PluginInterfaceManager, ReceivedPluginCallMessage,
use nu_protocol::{
engine::Closure, IntoInterruptiblePipelineData, PipelineData, PluginSignature, ShellError,
Span, Spanned, Value,
};
use std::{sync::mpsc, time::Duration};
#[test]
fn manager_consume_all_consumes_messages() -> Result<(), ShellError> {

View File

@ -1,3 +1,5 @@
use crate::protocol::{StreamData, StreamId, StreamMessage};
use nu_protocol::{ShellError, Span, Value};
use std::{
collections::{btree_map, BTreeMap},
iter::FusedIterator,
@ -5,10 +7,6 @@ use std::{
sync::{mpsc, Arc, Condvar, Mutex, MutexGuard, Weak},
};
use nu_protocol::{ShellError, Span, Value};
use crate::protocol::{StreamData, StreamId, StreamMessage};
#[cfg(test)]
mod tests;

View File

@ -6,11 +6,9 @@ use std::{
time::{Duration, Instant},
};
use nu_protocol::{ShellError, Value};
use crate::protocol::{StreamData, StreamMessage};
use super::{StreamManager, StreamReader, StreamWriter, StreamWriterSignal, WriteStreamMessage};
use crate::protocol::{StreamData, StreamMessage};
use nu_protocol::{ShellError, Value};
// Should be long enough to definitely complete any quick operation, but not so long that tests are
// slow to complete. 10 ms is a pretty long time

View File

@ -1,14 +1,11 @@
use super::{EngineInterfaceManager, PluginInterfaceManager, PluginRead, PluginWrite};
use crate::{plugin::PluginSource, protocol::PluginInput, PluginOutput};
use nu_protocol::ShellError;
use std::{
collections::VecDeque,
sync::{Arc, Mutex},
};
use nu_protocol::ShellError;
use crate::{plugin::PluginSource, protocol::PluginInput, PluginOutput};
use super::{EngineInterfaceManager, PluginInterfaceManager, PluginRead, PluginWrite};
/// Mock read/write helper for the engine and plugin interfaces.
#[derive(Debug, Clone)]
pub(crate) struct TestCase<I, O> {

View File

@ -1,9 +1,8 @@
use std::{path::Path, sync::Arc};
use nu_protocol::{
DataSource, ListStream, PipelineData, PipelineMetadata, RawStream, ShellError, Span, Value,
use super::{
stream::{StreamManager, StreamManagerHandle},
test_util::TestCase,
Interface, InterfaceManager, PluginRead, PluginWrite,
};
use crate::{
protocol::{
ExternalStreamInfo, ListStreamInfo, PipelineDataHeader, PluginInput, PluginOutput,
@ -11,12 +10,10 @@ use crate::{
},
sequence::Sequence,
};
use super::{
stream::{StreamManager, StreamManagerHandle},
test_util::TestCase,
Interface, InterfaceManager, PluginRead, PluginWrite,
use nu_protocol::{
DataSource, ListStream, PipelineData, PipelineMetadata, RawStream, ShellError, Span, Value,
};
use std::{path::Path, sync::Arc};
fn test_metadata() -> PipelineMetadata {
PipelineMetadata {

View File

@ -1,33 +1,31 @@
use crate::{
plugin::interface::ReceivedPluginCall,
protocol::{CallInfo, CustomValueOp, PluginCustomValue, PluginInput, PluginOutput},
EncodingType,
};
use nu_engine::documentation::get_flags_section;
use nu_protocol::LabeledError;
use thiserror::Error;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fmt::Write;
use std::io::{BufReader, Read, Write as WriteTrait};
use std::path::Path;
use std::process::{Child, ChildStdout, Command as CommandSys, Stdio};
use std::{env, thread};
use std::sync::mpsc::TrySendError;
use std::sync::{mpsc, Arc, Mutex};
use crate::plugin::interface::ReceivedPluginCall;
use crate::protocol::{CallInfo, CustomValueOp, PluginCustomValue, PluginInput, PluginOutput};
use crate::EncodingType;
use nu_protocol::{
ast::Operator, CustomValue, IntoSpanned, LabeledError, PipelineData, PluginSignature,
ShellError, Spanned, Value,
};
#[cfg(unix)]
use std::os::unix::process::CommandExt;
#[cfg(windows)]
use std::os::windows::process::CommandExt;
use nu_protocol::{
ast::Operator, CustomValue, IntoSpanned, PipelineData, PluginSignature, ShellError, Spanned,
Value,
use std::{
cmp::Ordering,
collections::HashMap,
env,
ffi::OsStr,
fmt::Write,
io::{BufReader, Read, Write as WriteTrait},
path::Path,
process::{Child, ChildStdout, Command as CommandSys, Stdio},
sync::mpsc::TrySendError,
sync::{mpsc, Arc, Mutex},
thread,
};
use thiserror::Error;
use self::gc::PluginGc;
pub use self::interface::{PluginRead, PluginWrite};

View File

@ -1,14 +1,12 @@
use std::{
ffi::OsStr,
sync::{Arc, Mutex},
};
use super::{create_command, gc::PluginGc, make_plugin_interface, PluginInterface, PluginSource};
use nu_protocol::{
engine::{EngineState, Stack},
PluginGcConfig, PluginIdentity, RegisteredPlugin, ShellError,
};
use super::{create_command, gc::PluginGc, make_plugin_interface, PluginInterface, PluginSource};
use std::{
ffi::OsStr,
sync::{Arc, Mutex},
};
/// A box that can keep a plugin that was spawned persistent for further uses. The plugin may or
/// may not be currently running. [`.get()`] gets the currently running plugin, or spawns it if it's

View File

@ -1,8 +1,6 @@
use std::sync::{Arc, Weak};
use nu_protocol::{PluginIdentity, ShellError, Span};
use super::GetPlugin;
use nu_protocol::{PluginIdentity, ShellError, Span};
use std::sync::{Arc, Weak};
/// The source of a custom value or plugin command. Includes a weak reference to the persistent
/// plugin so it can be retrieved.

View File

@ -1,7 +1,5 @@
use nu_protocol::ast::Expression;
use nu_protocol::{
ast::Call,
ast::{Call, Expression},
engine::{EngineState, Stack},
FromValue, ShellError, Span, Spanned, Value,
};

View File

@ -8,18 +8,18 @@ mod tests;
#[cfg(test)]
pub(crate) mod test_util;
use std::collections::HashMap;
pub use evaluated_call::EvaluatedCall;
use nu_protocol::{
ast::Operator, engine::Closure, Config, LabeledError, PipelineData, PluginSignature, RawStream,
ShellError, Span, Spanned, Value,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub use evaluated_call::EvaluatedCall;
pub use plugin_custom_value::PluginCustomValue;
#[cfg(test)]
pub use protocol_info::Protocol;
pub use protocol_info::ProtocolInfo;
use serde::{Deserialize, Serialize};
/// A sequential identifier for a stream
pub type StreamId = usize;

View File

@ -1,9 +1,7 @@
use std::{cmp::Ordering, convert::Infallible, sync::Arc};
use crate::plugin::{PluginInterface, PluginSource};
use nu_protocol::{ast::Operator, CustomValue, IntoSpanned, ShellError, Span, Value};
use serde::{Deserialize, Serialize};
use crate::plugin::{PluginInterface, PluginSource};
use std::{cmp::Ordering, convert::Infallible, sync::Arc};
#[cfg(test)]
mod tests;

View File

@ -1,9 +1,4 @@
use std::sync::Arc;
use nu_protocol::{
ast::RangeInclusion, engine::Closure, record, CustomValue, Range, ShellError, Span, Value,
};
use super::PluginCustomValue;
use crate::{
plugin::PluginSource,
protocol::test_util::{
@ -11,8 +6,10 @@ use crate::{
TestCustomValue,
},
};
use super::PluginCustomValue;
use nu_protocol::{
ast::RangeInclusion, engine::Closure, record, CustomValue, Range, ShellError, Span, Value,
};
use std::sync::Arc;
#[test]
fn serialize_deserialize() -> Result<(), ShellError> {

View File

@ -1,10 +1,8 @@
use super::PluginCustomValue;
use crate::plugin::PluginSource;
use nu_protocol::{CustomValue, ShellError, Span, Value};
use serde::{Deserialize, Serialize};
use crate::plugin::PluginSource;
use super::PluginCustomValue;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub(crate) struct TestCustomValue(pub i32);

View File

@ -1,6 +1,5 @@
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use nu_protocol::ShellError;
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
/// Implements an atomically incrementing sequential series of numbers
#[derive(Debug, Default)]