forked from extern/nushell
Changes to allow plugins to be loaded in a multi-threaded manner (#1694)
* Changes to allow plugins to be loaded in a multi-threaded manner in order to decrease startup time. * Ran rust fmt and clippy to find and fix first pass errors. Updated launch.jason to make debugging easier in vscode. Also added tasks.json so tasks like clippy can be ran easily. * ran fmt again * Delete launch.json Remove IDE settings file * Remove IDE settings file * Ignore vscode IDE settings * Cloned the context instead of Arc/Mutexing it. Co-authored-by: Darren Schroeder <fdncred@hotmail.com> Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
This commit is contained in:
parent
a9968046ed
commit
d2ac506de3
3
.gitignore
vendored
3
.gitignore
vendored
@ -17,3 +17,6 @@ debian/nu/
|
||||
|
||||
# JetBrains' IDE items
|
||||
.idea/*
|
||||
|
||||
# VSCode's IDE items
|
||||
.vscode/*
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2175,6 +2175,7 @@ dependencies = [
|
||||
"quickcheck",
|
||||
"quickcheck_macros",
|
||||
"rand",
|
||||
"rayon",
|
||||
"regex",
|
||||
"roxmltree",
|
||||
"rusqlite",
|
||||
@ -2210,6 +2211,7 @@ dependencies = [
|
||||
"bigdecimal",
|
||||
"derive-new",
|
||||
"getset",
|
||||
"glob",
|
||||
"language-reporting",
|
||||
"nu-build",
|
||||
"nu-source",
|
||||
|
@ -89,6 +89,7 @@ which = "3"
|
||||
trash = { version = "1.0.0", optional = true }
|
||||
clipboard = { version = "0.5", optional = true }
|
||||
starship = { version = "0.39.0", optional = true }
|
||||
rayon = "1.3.0"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
users = "0.10.0"
|
||||
|
@ -26,6 +26,8 @@ use std::iter::Iterator;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> {
|
||||
let mut child = std::process::Command::new(path)
|
||||
.stdin(std::process::Stdio::piped())
|
||||
@ -132,58 +134,60 @@ pub fn load_plugins(context: &mut Context) -> Result<(), ShellError> {
|
||||
|
||||
pattern.push(std::path::Path::new("nu_plugin_[a-z0-9][a-z0-9]*"));
|
||||
|
||||
match glob::glob_with(&pattern.to_string_lossy(), opts) {
|
||||
Err(_) => {}
|
||||
Ok(binaries) => {
|
||||
for bin in binaries.filter_map(Result::ok) {
|
||||
let bin_name = {
|
||||
if let Some(name) = bin.file_name() {
|
||||
match name.to_str() {
|
||||
Some(raw) => raw,
|
||||
None => continue,
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
let plugs: Vec<_> = glob::glob_with(&pattern.to_string_lossy(), opts)?
|
||||
.filter_map(|x| x.ok())
|
||||
.collect();
|
||||
|
||||
let _failures: Vec<_> = plugs
|
||||
.par_iter()
|
||||
.map(|path| {
|
||||
let bin_name = {
|
||||
if let Some(name) = path.file_name() {
|
||||
match name.to_str() {
|
||||
Some(raw) => raw,
|
||||
None => "",
|
||||
}
|
||||
};
|
||||
|
||||
let is_valid_name = {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
bin_name
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.')
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
bin_name
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || c == '_')
|
||||
}
|
||||
};
|
||||
|
||||
let is_executable = {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
bin_name.ends_with(".exe") || bin_name.ends_with(".bat")
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
if is_valid_name && is_executable {
|
||||
trace!("Trying {:?}", bin.display());
|
||||
|
||||
// we are ok if this plugin load fails
|
||||
let _ = load_plugin(&bin, context);
|
||||
} else {
|
||||
""
|
||||
}
|
||||
};
|
||||
|
||||
let is_valid_name = {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
bin_name
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.')
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
bin_name
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || c == '_')
|
||||
}
|
||||
};
|
||||
|
||||
let is_executable = {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
bin_name.ends_with(".exe") || bin_name.ends_with(".bat")
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
if is_valid_name && is_executable {
|
||||
trace!("Trying {:?}", path.display());
|
||||
|
||||
// we are ok if this plugin load fails
|
||||
let _ = load_plugin(&path, &mut context.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -25,6 +25,7 @@ getset = "0.1.0"
|
||||
serde_yaml = "0.8"
|
||||
toml = "0.5.6"
|
||||
serde_json = "1.0.51"
|
||||
glob = "0.3.0"
|
||||
|
||||
[build-dependencies]
|
||||
nu-build = { version = "0.13.0", path = "../nu-build" }
|
||||
|
@ -864,6 +864,12 @@ impl std::convert::From<Box<dyn std::error::Error + Send + Sync>> for ShellError
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<glob::PatternError> for ShellError {
|
||||
fn from(input: glob::PatternError) -> ShellError {
|
||||
ShellError::untagged_runtime_error(format!("{:?}", input))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CoerceInto<U> {
|
||||
fn coerce_into(self, operation: impl Into<String>) -> Result<U, ShellError>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user