diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 128049ed5b..7584a55756 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -4,10 +4,35 @@ use nu_parser::parse; use nu_plugin::{EncodingType, PluginResponse}; use nu_protocol::{engine::EngineState, PipelineData, Span, Value}; use nu_utils::{get_default_config, get_default_env}; +use std::path::{Path, PathBuf}; fn load_bench_commands() -> EngineState { nu_command::add_shell_command_context(nu_cmd_lang::create_default_context()) } + +fn canonicalize_path(engine_state: &EngineState, path: &Path) -> PathBuf { + let cwd = engine_state.current_work_dir(); + + if path.exists() { + match nu_path::canonicalize_with(path, cwd) { + Ok(canon_path) => canon_path, + Err(_) => path.to_owned(), + } + } else { + path.to_owned() + } +} + +fn get_home_path(engine_state: &EngineState) -> PathBuf { + let home_path = if let Some(path) = nu_path::home_dir() { + let canon_home_path = canonicalize_path(engine_state, &path); + canon_home_path + } else { + std::path::PathBuf::new() + }; + home_path +} + // FIXME: All benchmarks live in this 1 file to speed up build times when benchmarking. // When the *_benchmarks functions were in different files, `cargo bench` would build // an executable for every single one - incredibly slowly. Would be nice to figure out @@ -15,10 +40,12 @@ fn load_bench_commands() -> EngineState { fn parser_benchmarks(c: &mut Criterion) { let mut engine_state = load_bench_commands(); - // parsing config.nu breaks without PWD set + let home_path = get_home_path(&engine_state); + + // parsing config.nu breaks without PWD set, so set a valid path engine_state.add_env_var( "PWD".into(), - Value::string("/some/dir".to_string(), Span::test_data()), + Value::string(home_path.to_string_lossy(), Span::test_data()), ); let default_env = get_default_env().as_bytes(); @@ -41,7 +68,6 @@ fn parser_benchmarks(c: &mut Criterion) { c.bench_function("eval default_env.nu", |b| { b.iter(|| { - let mut engine_state = load_bench_commands(); let mut stack = nu_protocol::engine::Stack::new(); eval_source( &mut engine_state, @@ -56,12 +82,6 @@ fn parser_benchmarks(c: &mut Criterion) { c.bench_function("eval default_config.nu", |b| { b.iter(|| { - let mut engine_state = load_bench_commands(); - // parsing config.nu breaks without PWD set - engine_state.add_env_var( - "PWD".into(), - Value::string("/some/dir".to_string(), Span::test_data()), - ); let mut stack = nu_protocol::engine::Stack::new(); eval_source( &mut engine_state, @@ -76,9 +96,17 @@ fn parser_benchmarks(c: &mut Criterion) { } fn eval_benchmarks(c: &mut Criterion) { + let mut engine_state = load_bench_commands(); + let home_path = get_home_path(&engine_state); + + // parsing config.nu breaks without PWD set, so set a valid path + engine_state.add_env_var( + "PWD".into(), + Value::string(home_path.to_string_lossy(), Span::test_data()), + ); + c.bench_function("eval default_env.nu", |b| { b.iter(|| { - let mut engine_state = load_bench_commands(); let mut stack = nu_protocol::engine::Stack::new(); eval_source( &mut engine_state, @@ -93,12 +121,6 @@ fn eval_benchmarks(c: &mut Criterion) { c.bench_function("eval default_config.nu", |b| { b.iter(|| { - let mut engine_state = load_bench_commands(); - // parsing config.nu breaks without PWD set - engine_state.add_env_var( - "PWD".into(), - Value::string("/some/dir".to_string(), Span::test_data()), - ); let mut stack = nu_protocol::engine::Stack::new(); eval_source( &mut engine_state, diff --git a/crates/nu-utils/src/sample_config/default_env.nu b/crates/nu-utils/src/sample_config/default_env.nu index 79b3285781..5585fac326 100644 --- a/crates/nu-utils/src/sample_config/default_env.nu +++ b/crates/nu-utils/src/sample_config/default_env.nu @@ -8,7 +8,7 @@ def create_left_prompt [] { # Perform tilde substitution on dir # To determine if the prefix of the path matches the home dir, we split the current path into # segments, and compare those with the segments of the home dir. In cases where the current dir - # is a parent of the home dir (e.g. `/home`, homedir is `/home/user`), this comparison will + # is a parent of the home dir (e.g. `/home`, homedir is `/home/user`), this comparison will # also evaluate to true. Inside the condition, we attempt to str replace `$home` with `~`. # Inside the condition, either: # 1. The home prefix will be replaced @@ -86,14 +86,14 @@ $env.ENV_CONVERSIONS = { } # Directories to search for scripts when calling source or use +# The default for this is $nu.default-config-dir/scripts $env.NU_LIB_DIRS = [ - # FIXME: This default is not implemented in rust code as of 2023-09-06. ($nu.default-config-dir | path join 'scripts') # add /scripts ] # Directories to search for plugin binaries when calling register +# The default for this is $nu.default-config-dir/plugins $env.NU_PLUGIN_DIRS = [ - # FIXME: This default is not implemented in rust code as of 2023-09-06. ($nu.default-config-dir | path join 'plugins') # add /plugins ] diff --git a/src/main.rs b/src/main.rs index abdfdbefab..87c0b73483 100644 --- a/src/main.rs +++ b/src/main.rs @@ -80,6 +80,33 @@ fn main() -> Result<()> { ctrlc_protection(&mut engine_state, &ctrlc); sigquit_protection(&mut engine_state); + // Begin: Default NU_LIB_DIRS, NU_PLUGIN_DIRS + // Set default NU_LIB_DIRS and NU_PLUGIN_DIRS here before the env.nu is processed. If + // the env.nu file exists, these values will be overwritten, if it does not exist, or + // there is an error reading it, these values will be used. + let nushell_config_path = if let Some(mut path) = nu_path::config_dir() { + path.push("nushell"); + path + } else { + // Not really sure what to default this to if nu_path::config_dir() returns None + std::path::PathBuf::new() + }; + + let mut default_nu_lib_dirs_path = nushell_config_path.clone(); + default_nu_lib_dirs_path.push("scripts"); + engine_state.add_env_var( + "NU_LIB_DIRS".to_string(), + Value::test_string(default_nu_lib_dirs_path.to_string_lossy()), + ); + + let mut default_nu_plugin_dirs_path = nushell_config_path; + default_nu_plugin_dirs_path.push("plugins"); + engine_state.add_env_var( + "NU_PLUGIN_DIRS".to_string(), + Value::test_string(default_nu_plugin_dirs_path.to_string_lossy()), + ); + // End: Default NU_LIB_DIRS, NU_PLUGIN_DIRS + // This is the real secret sauce to having an in-memory sqlite db. You must // start a connection to the memory database in main so it will exist for the // lifetime of the program. If it's created with how MEMORY_DB is defined