Don't make unquoted file/dir paths absolute (#15878)

# Description

Closes #15848. Currently, we expand unquoted strings to absolute paths
if they are of type `path` or `directory`. This PR makes this no longer
happen. `~`, `.`, and `..+` are still expanded, but a path like
`.../foo/bar/..` will only be turned into `../../foo`, rather than a
full absolute path.

This is mostly so that paths don't get modified before being sent to
known external commands (as in the linked issue). But also, it seems
unnecessary to make all unquoted paths absolute.

After feedback from @132ikl, this PR also makes it so that unquoted
paths are expanded at parse time, so that it matches the runtime
behavior. Previously, `path` expressions were turned into strings
verbatim, while `directory` expressions were treated as not being const.

API change: `nu_path::expansions::expand_path` is now exposed as
`nu_path::expand_path`.

# User-Facing Changes

This has the potential to silently break a lot of scripts. For example,
if someone has a command that expects an already-expanded absolute path,
changes the current working directory, and then passes the path
somewhere, they will now need to use `path expand` to expand the path
themselves before changing the current working directory.

# Tests + Formatting

Just added one test to make sure unquoted `path` arguments aren't made
absolute.

# After Submitting

This is a breaking change, so will need to be mentioned in the release
notes.
This commit is contained in:
Yash Thakur
2025-06-12 19:26:01 -04:00
committed by GitHub
parent 12465193a4
commit f8b0af70ff
7 changed files with 41 additions and 92 deletions

View File

@ -60,7 +60,10 @@ where
canonicalize(path)
}
fn expand_path(path: impl AsRef<Path>, need_expand_tilde: bool) -> PathBuf {
/// Resolve only path components (tilde, ., .., ...+), if possible.
///
/// Doesn't convert to absolute form or use syscalls. Output may begin with "../"
pub fn expand_path(path: impl AsRef<Path>, need_expand_tilde: bool) -> PathBuf {
let path = if need_expand_tilde {
expand_tilde(path)
} else {
@ -77,7 +80,7 @@ fn expand_path(path: impl AsRef<Path>, need_expand_tilde: bool) -> PathBuf {
///
/// Furthermore, unlike canonicalize(), it does not use sys calls (such as readlink).
///
/// Does not convert to absolute form nor does it resolve symlinks.
/// Converts to absolute form but does not resolve symlinks.
/// The input path is specified relative to another path
pub fn expand_path_with<P, Q>(path: P, relative_to: Q, expand_tilde: bool) -> PathBuf
where

View File

@ -10,7 +10,9 @@ mod tilde;
mod trailing_slash;
pub use components::components;
pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs};
pub use expansions::{
canonicalize_with, expand_path, expand_path_with, expand_to_real_path, locate_in_dirs,
};
pub use helpers::{cache_dir, data_dir, home_dir, nu_config_dir};
pub use path::*;
pub use tilde::expand_tilde;