From 6e85b04923e86273e92ef0243ec960731a5df943 Mon Sep 17 00:00:00 2001 From: nicole mazzuca Date: Sat, 16 Apr 2022 13:05:42 -0700 Subject: [PATCH] [ls, path relative-to] Fix use of `ls ~ | path relative-to ~` (#5212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ls] implement 1b. > `ls ~` does not return paths relative to the current directory. We now return `/Users/blah` instead of `../../blah` * expand lhs and rhs on `path relative-to` /Users/nimazzuc/projects/nushell〉'~' | path relative-to '~' /Users/nimazzuc/projects/nushell〉'~/foo' | path relative-to '~' foo /Users/nimazzuc/projects/nushell〉'/Users/nimazzuc/foo' | path relative-to '~' foo /Users/nimazzuc/projects/nushell〉'~/foo' | path relative-to '/Users/nimazzuc' foo * format --- crates/nu-command/src/filesystem/ls.rs | 12 +++++++++--- crates/nu-command/src/path/relative_to.rs | 5 ++++- crates/nu-command/src/system/run_external.rs | 4 ++-- crates/nu-path/src/expansions.rs | 10 +++++----- crates/nu-path/src/lib.rs | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index c8f1f5254b..de59ea7d8a 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -3,6 +3,7 @@ use crate::DirInfo; use chrono::{DateTime, Local}; use nu_engine::env::current_dir; use nu_engine::CallExt; +use nu_path::expand_to_real_path; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ @@ -76,7 +77,7 @@ impl Command for Ls { let (path, p_tag, absolute_path) = match pattern_arg { Some(p) => { let p_tag = p.span; - let mut p = PathBuf::from(p.item); + let mut p = expand_to_real_path(p.item); let expanded = nu_path::expand_path_with(&p, &cwd); if expanded.is_dir() { @@ -223,6 +224,11 @@ impl Command for Ls { example: "ls subdir", result: None, }, + Example { + description: "List all files with full path in the parent directory", + example: "ls -f ..", + result: None, + }, Example { description: "List all rust files", example: "ls *.rs", @@ -234,8 +240,8 @@ impl Command for Ls { result: None, }, Example { - description: "List all dirs with full path name in your home directory", - example: "ls -f ~ | where type == dir", + description: "List all dirs in your home directory", + example: "ls ~ | where type == dir", result: None, }, Example { diff --git a/crates/nu-command/src/path/relative_to.rs b/crates/nu-command/src/path/relative_to.rs index 6f19132214..2c42edc559 100644 --- a/crates/nu-command/src/path/relative_to.rs +++ b/crates/nu-command/src/path/relative_to.rs @@ -1,6 +1,7 @@ use std::path::Path; use nu_engine::CallExt; +use nu_path::expand_to_real_path; use nu_protocol::{ engine::Command, Example, ShellError, Signature, Span, Spanned, SyntaxShape, Value, }; @@ -114,7 +115,9 @@ path."# } fn relative_to(path: &Path, span: Span, args: &Arguments) -> Value { - match path.strip_prefix(Path::new(&args.path.item)) { + let lhs = expand_to_real_path(path); + let rhs = expand_to_real_path(&args.path.item); + match lhs.strip_prefix(&rhs) { Ok(p) => Value::string(p.to_string_lossy(), span), Err(e) => Value::Error { error: ShellError::CantConvert(e.to_string(), "string".into(), span), diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index a979721b61..18ac3fb8cb 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -398,7 +398,7 @@ impl ExternalCommand { /// Spawn a command without shelling out to an external shell pub fn spawn_simple_command(&self, cwd: &str) -> Result { let head = trim_enclosing_quotes(&self.name.item); - let head = nu_path::expand_path_for_external_programs(head) + let head = nu_path::expand_to_real_path(head) .to_string_lossy() .to_string(); @@ -409,7 +409,7 @@ impl ExternalCommand { item: trim_enclosing_quotes(&arg.item), span: arg.span, }; - arg.item = nu_path::expand_path_for_external_programs(arg.item) + arg.item = nu_path::expand_to_real_path(arg.item) .to_string_lossy() .to_string(); diff --git a/crates/nu-path/src/expansions.rs b/crates/nu-path/src/expansions.rs index 96eb700365..af931cf5c3 100644 --- a/crates/nu-path/src/expansions.rs +++ b/crates/nu-path/src/expansions.rs @@ -50,8 +50,7 @@ where } fn expand_path(path: impl AsRef) -> PathBuf { - let path = expand_tilde(path); - let path = expand_ndots(path); + let path = expand_to_real_path(path); expand_dots(path) } @@ -74,12 +73,13 @@ where expand_path(path) } -/// Resolve similarly to other shells - tilde is expanded, and ndot path components are expanded. +/// Resolve to a path that is accepted by the system and no further - tilde is expanded, and ndot path components are expanded. /// /// This function will take a leading tilde path component, and expand it to the user's home directory; /// it will also expand any path elements consisting of only dots into the correct number of `..` path elements. -/// It does not touch the system at all, except for getting the home directory of the current user. -pub fn expand_path_for_external_programs

(path: P) -> PathBuf +/// It does not do any normalization except to what will be accepted by Path::open, +/// and it does not touch the system at all, except for getting the home directory of the current user. +pub fn expand_to_real_path

(path: P) -> PathBuf where P: AsRef, { diff --git a/crates/nu-path/src/lib.rs b/crates/nu-path/src/lib.rs index b389b2e128..c54b4207d4 100644 --- a/crates/nu-path/src/lib.rs +++ b/crates/nu-path/src/lib.rs @@ -4,7 +4,7 @@ mod helpers; mod tilde; mod util; -pub use expansions::{canonicalize_with, expand_path_for_external_programs, expand_path_with}; +pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path}; pub use helpers::{config_dir, home_dir}; pub use tilde::expand_tilde; pub use util::trim_trailing_slash;