diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index cab3dcc48a..5012754b3b 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -923,8 +923,8 @@ impl EngineState { } /// Returns the current working directory, which is guaranteed to be an - /// absolute path without trailing slashes, but might contain symlink - /// components. + /// absolute path without trailing slashes (unless it's the root path), but + /// might contain symlink components. /// /// If `stack` is supplied, also considers modifications to the working /// directory on the stack that have yet to be merged into the engine state. @@ -941,6 +941,11 @@ impl EngineState { }) } + // Helper function to check if a path is a root path. + fn is_root(path: &Path) -> bool { + path.parent().is_none() + } + // Helper function to check if a path has trailing slashes. fn has_trailing_slash(path: &Path) -> bool { nu_path::components(path).last() @@ -958,7 +963,9 @@ impl EngineState { if let Value::String { val, .. } = pwd { let path = PathBuf::from(val); - if has_trailing_slash(&path) { + // Technically, a root path counts as "having trailing slashes", but + // for the purpose of PWD, a root path is acceptable. + if !is_root(&path) && has_trailing_slash(&path) { error("$env.PWD contains trailing slashes") } else if !path.is_absolute() { error("$env.PWD is not an absolute path") @@ -1235,6 +1242,18 @@ mod test_cwd { engine_state.cwd(None).unwrap_err(); } + #[test] + fn pwd_points_to_root() { + #[cfg(windows)] + let root = Path::new(r"C:\"); + #[cfg(not(windows))] + let root = Path::new("/"); + + let engine_state = engine_state_with_pwd(root); + let cwd = engine_state.cwd(None).unwrap(); + assert_path_eq!(cwd, root); + } + #[test] fn pwd_points_to_normal_file() { let file = NamedTempFile::new().unwrap();