diff --git a/src/main.rs b/src/main.rs index 9b293bc7fa..9fac8d1b56 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ use miette::Result; use nu_cli::gather_parent_env_vars; use nu_cmd_base::util::get_init_cwd; use nu_lsp::LanguageServer; +use nu_path::canonicalize_with; use nu_protocol::{ engine::EngineState, eval_const::create_nu_constant, report_error_new, util::BufferedReader, PipelineData, RawStream, ShellError, Span, Value, NU_VARIABLE_ID, @@ -35,7 +36,7 @@ use run::{run_commands, run_file, run_repl}; use signals::ctrlc_protection; use std::{ io::BufReader, - path::Path, + path::PathBuf, str::FromStr, sync::{atomic::AtomicBool, Arc}, }; @@ -94,7 +95,11 @@ fn main() -> Result<()> { if let Ok(xdg_config_home) = std::env::var("XDG_CONFIG_HOME") { if !xdg_config_home.is_empty() { - if nushell_config_path != Path::new(&xdg_config_home).join("nushell") { + if nushell_config_path + != canonicalize_with(&xdg_config_home, &init_cwd) + .unwrap_or(PathBuf::from(&xdg_config_home)) + .join("nushell") + { report_error_new( &engine_state, &ShellError::InvalidXdgConfig { diff --git a/src/tests/test_config_path.rs b/src/tests/test_config_path.rs index 19a6ff7b64..620ad6a48d 100644 --- a/src/tests/test_config_path.rs +++ b/src/tests/test_config_path.rs @@ -62,6 +62,23 @@ fn run(playground: &mut Playground, command: &str) -> String { .to_string() } +#[cfg(not(windows))] +fn run_interactive_stderr(xdg_config_home: impl AsRef) -> String { + let child_output = std::process::Command::new("sh") + .arg("-c") + .arg(format!( + "{:?} -i -c 'echo $nu.is-interactive'", + nu_test_support::fs::executable_path() + )) + .env("XDG_CONFIG_HOME", adjust_canonicalization(xdg_config_home)) + .output() + .expect("Should have outputted"); + + return String::from_utf8_lossy(&child_output.stderr) + .trim() + .to_string(); +} + fn test_config_path_helper(playground: &mut Playground, config_dir_nushell: PathBuf) { // Create the config dir folder structure if it does not already exist if !config_dir_nushell.exists() { @@ -217,10 +234,10 @@ fn test_xdg_config_empty() { Playground::setup("xdg_config_empty", |_, playground| { playground.with_env("XDG_CONFIG_HOME", ""); - let actual = nu!("$nu.default-config-dir"); + let actual = run(playground, "$nu.default-config-dir"); let expected = dirs_next::config_dir().unwrap().join("nushell"); assert_eq!( - actual.out, + actual, adjust_canonicalization(expected.canonicalize().unwrap_or(expected)) ); }); @@ -229,13 +246,38 @@ fn test_xdg_config_empty() { #[test] fn test_xdg_config_bad() { Playground::setup("xdg_config_bad", |_, playground| { - playground.with_env("XDG_CONFIG_HOME", r#"mn2''6t\/k*((*&^//k//: "#); + let xdg_config_home = r#"mn2''6t\/k*((*&^//k//: "#; + playground.with_env("XDG_CONFIG_HOME", xdg_config_home); - let actual = nu!("$nu.default-config-dir"); + let actual = run(playground, "$nu.default-config-dir"); let expected = dirs_next::config_dir().unwrap().join("nushell"); assert_eq!( - actual.out, + actual, adjust_canonicalization(expected.canonicalize().unwrap_or(expected)) ); + + #[cfg(not(windows))] + { + let stderr = run_interactive_stderr(xdg_config_home); + assert!( + stderr.contains("xdg_config_home_invalid"), + "stderr was {}", + stderr + ); + } + }); +} + +/// Shouldn't complain if XDG_CONFIG_HOME is a symlink +#[test] +#[cfg(not(windows))] +fn test_xdg_config_symlink() { + Playground::setup("xdg_config_symlink", |_, playground| { + let config_link = "config_link"; + + playground.symlink("real", config_link); + + let stderr = run_interactive_stderr(playground.cwd().join(config_link)); + assert!(stderr.is_empty(), "stderr was {}", stderr); }); }