From c09a8a5ec954974cf22ae2e4d7f2c99628272116 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Thu, 20 Jun 2024 06:30:43 -0500 Subject: [PATCH] add a system level folder for future autoloading (#13180) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This PR adds a directory to the `$nu` constant that shows where the system level autoload directory is located at. This folder is modifiable at compile time with environment variables. ```rust // Create a system level directory for nushell scripts, modules, completions, etc // that can be changed by setting the NU_VENDOR_AUTOLOAD_DIR env var on any platform // before nushell is compiled OR if NU_VENDOR_AUTOLOAD_DIR is not set for non-windows // systems, the PREFIX env var can be set before compile and used as PREFIX/nushell/vendor/autoload // 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 ``` ### Windows default ```nushell ❯ $nu.vendor-autoload-dir C:\ProgramData\nushell\vendor\autoload ``` ### Non-Windows default ```nushell ❯ $nu.vendor-autoload-dir /usr/local/share/nushell/vendor/autoload ``` ### Non-Windows with PREFIX set ```nushell ❯ PREFIX=/usr/bob cargo r ❯ $nu.vendor-autoload-dir /usr/bob/share/nushell/vendor/autoload ``` ### Non-Windows with NU_VENDOR_AUTOLOAD_DIR set ```nushell ❯ NU_VENDOR_AUTOLOAD_DIR=/some/other/path/nushell/stuff cargo r ❯ $nu.vendor-autoload-dir /some/other/path/nushell/stuff ``` > [!IMPORTANT] To be clear, this PR does not do the auto-loading, it just sets up the folder to support that functionality that can be added in a later PR. The PR also does not create the folder defined. It's just setting the $nu constant.   # User-Facing Changes # Tests + Formatting # After Submitting --- crates/nu-cli/tests/completions/mod.rs | 3 +- crates/nu-protocol/src/eval_const.rs | 40 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/crates/nu-cli/tests/completions/mod.rs b/crates/nu-cli/tests/completions/mod.rs index 107de98c80..35e9435b41 100644 --- a/crates/nu-cli/tests/completions/mod.rs +++ b/crates/nu-cli/tests/completions/mod.rs @@ -763,7 +763,7 @@ fn variables_completions() { // Test completions for $nu let suggestions = completer.complete("$nu.", 4); - assert_eq!(17, suggestions.len()); + assert_eq!(18, suggestions.len()); let expected: Vec = vec![ "cache-dir".into(), @@ -783,6 +783,7 @@ fn variables_completions() { "plugin-path".into(), "startup-time".into(), "temp-path".into(), + "vendor-autoload-dir".into(), ]; // Match results diff --git a/crates/nu-protocol/src/eval_const.rs b/crates/nu-protocol/src/eval_const.rs index 9f81a6f38b..8f6382ae44 100644 --- a/crates/nu-protocol/src/eval_const.rs +++ b/crates/nu-protocol/src/eval_const.rs @@ -181,6 +181,46 @@ pub(crate) fn create_nu_constant(engine_state: &EngineState, span: Span) -> Valu }, ); + // Create a system level directory for nushell scripts, modules, completions, etc + // that can be changed by setting the NU_VENDOR_AUTOLOAD_DIR env var on any platform + // before nushell is compiled OR if NU_VENDOR_AUTOLOAD_DIR is not set for non-windows + // systems, the PREFIX env var can be set before compile and used as PREFIX/nushell/vendor/autoload + record.push( + "vendor-autoload-dir", + // 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 + 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, + ), + ); + record.push("temp-path", { let canon_temp_path = canonicalize_path(engine_state, &std::env::temp_dir()); Value::string(canon_temp_path.to_string_lossy(), span)