implement autoloading

This commit is contained in:
Darren Schroeder 2024-06-24 16:24:38 -05:00
parent 4509944988
commit 9a4e6b5163
2 changed files with 87 additions and 26 deletions

View File

@ -194,31 +194,11 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
// if not, use the default /usr/share/nushell/vendor/autoload
// check to see if NU_VENDOR_AUTOLOAD_DIR env var is set, if not, use the default
Value::string(
option_env!("NU_VENDOR_AUTOLOAD_DIR")
.map(String::from)
.unwrap_or_else(|| {
if cfg!(windows) {
let all_user_profile = match engine_state.get_env_var("ALLUSERPROFILE") {
Some(v) => format!(
"{}\\nushell\\vendor\\autoload",
v.coerce_string().unwrap_or("C:\\ProgramData".into())
),
None => "C:\\ProgramData\\nushell\\vendor\\autoload".into(),
};
all_user_profile
} else {
// In non-Windows environments, if NU_VENDOR_AUTOLOAD_DIR is not set
// check to see if PREFIX env var is set, and use it as PREFIX/nushell/vendor/autoload
// otherwise default to /usr/share/nushell/vendor/autoload
option_env!("PREFIX").map(String::from).map_or_else(
|| "/usr/local/share/nushell/vendor/autoload".into(),
|prefix| format!("{}/share/nushell/vendor/autoload", prefix),
)
}
}),
span,
),
if let Some(path) = get_vendor_autoload_dir(engine_state) {
Value::string(path.to_string_lossy(), span)
} else {
Value::error(ShellError::ConfigDirNotFound { span: Some(span) }, span)
},
);
record.push("temp-path", {
@ -275,6 +255,41 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu
Value::record(record, span)
}
pub fn get_vendor_autoload_dir(engine_state: &EngineState) -> Option<PathBuf> {
// pseudo code
// if env var NU_VENDOR_AUTOLOAD_DIR is set, in any platform, use it
// if not, if windows, use ALLUSERPROFILE\nushell\vendor\autoload
// if not, if non-windows, if env var PREFIX is set, use PREFIX/share/nushell/vendor/autoload
// if not, use the default /usr/share/nushell/vendor/autoload
// check to see if NU_VENDOR_AUTOLOAD_DIR env var is set, if not, use the default
Some(
option_env!("NU_VENDOR_AUTOLOAD_DIR")
.map(String::from)
.unwrap_or_else(|| {
if cfg!(windows) {
let all_user_profile = match engine_state.get_env_var("ALLUSERPROFILE") {
Some(v) => format!(
"{}\\nushell\\vendor\\autoload",
v.coerce_string().unwrap_or("C:\\ProgramData".into())
),
None => "C:\\ProgramData\\nushell\\vendor\\autoload".into(),
};
all_user_profile
} else {
// In non-Windows environments, if NU_VENDOR_AUTOLOAD_DIR is not set
// check to see if PREFIX env var is set, and use it as PREFIX/nushell/vendor/autoload
// otherwise default to /usr/share/nushell/vendor/autoload
option_env!("PREFIX").map(String::from).map_or_else(
|| "/usr/local/share/nushell/vendor/autoload".into(),
|prefix| format!("{}/share/nushell/vendor/autoload", prefix),
)
}
})
.into(),
)
}
fn eval_const_call(
working_set: &StateWorkingSet,
call: &Call,

View File

@ -9,8 +9,9 @@ use nu_protocol::{
};
use nu_utils::{get_default_config, get_default_env};
use std::{
fs,
fs::File,
io::Write,
io::{Result, Write},
panic::{catch_unwind, AssertUnwindSafe},
path::Path,
sync::Arc,
@ -176,6 +177,49 @@ pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut
}
}
fn read_and_sort_directory(path: &Path) -> Result<Vec<String>> {
let mut entries = Vec::new();
for entry in fs::read_dir(path)? {
let entry = entry?;
let file_name = entry.file_name();
let file_name_str = file_name.into_string().unwrap_or_default();
entries.push(file_name_str);
}
entries.sort();
Ok(entries)
}
pub(crate) fn read_vendor_autoload_files(engine_state: &mut EngineState, stack: &mut Stack) {
warn!(
"read_vendor_autoload_files() {}:{}:{}",
file!(),
line!(),
column!()
);
// read and source vendor_autoload_files file if exists
if let Some(autoload_dir) = nu_protocol::eval_const::get_vendor_autoload_dir(engine_state) {
warn!("read_vendor_autoload_files: {}", autoload_dir.display());
if autoload_dir.exists() {
let entries = read_and_sort_directory(&autoload_dir);
match entries {
Ok(entries) => {
for entry in entries {
let path = autoload_dir.join(entry);
warn!("AutoLoading: {:?}", path);
eval_config_contents(path, engine_state, stack);
}
}
Err(_) => {}
}
}
}
}
fn eval_default_config(
engine_state: &mut EngineState,
stack: &mut Stack,
@ -236,6 +280,8 @@ pub(crate) fn setup_config(
if is_login_shell {
read_loginshell_file(engine_state, stack);
}
// read and auto load vendor autoload files
read_vendor_autoload_files(engine_state, stack);
}));
if result.is_err() {
eprintln!(