From 68211dea3ee7e919d9ec086cdbfac3235fcd61b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C5=BD=C3=A1dn=C3=ADk?= Date: Fri, 17 Nov 2023 01:30:57 +0200 Subject: [PATCH] Send only absolute paths to uu_cp (#11080) # Description Fixes https://github.com/nushell/nushell/issues/10832 Replaces: https://github.com/nushell/nushell/pull/10843 --- crates/nu-command/src/filesystem/ucp.rs | 8 +++++ crates/nu-command/src/filesystem/umkdir.rs | 4 +-- crates/nu-command/tests/commands/cp.rs | 34 ++++++++++++++++------ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/crates/nu-command/src/filesystem/ucp.rs b/crates/nu-command/src/filesystem/ucp.rs index 1cee2e0e8..a9df32d99 100644 --- a/crates/nu-command/src/filesystem/ucp.rs +++ b/crates/nu-command/src/filesystem/ucp.rs @@ -201,6 +201,14 @@ impl Command for UCp { sources.append(&mut app_vals); } + // Make sure to send absolute paths to avoid uu_cp looking for cwd in std::env which is not + // supported in Nushell + for src in sources.iter_mut() { + if !src.is_absolute() { + *src = nu_path::expand_path_with(&src, &cwd); + } + } + let options = uu_cp::Options { overwrite, reflink_mode, diff --git a/crates/nu-command/src/filesystem/umkdir.rs b/crates/nu-command/src/filesystem/umkdir.rs index cb89c230a..00ee64b59 100644 --- a/crates/nu-command/src/filesystem/umkdir.rs +++ b/crates/nu-command/src/filesystem/umkdir.rs @@ -50,11 +50,11 @@ impl Command for UMkdir { call: &Call, _input: PipelineData, ) -> Result { - let path = current_dir(engine_state, stack)?; + let cwd = current_dir(engine_state, stack)?; let mut directories = call .rest::(engine_state, stack, 0)? .into_iter() - .map(|dir| path.join(dir)) + .map(|dir| nu_path::expand_path_with(dir, &cwd)) .peekable(); let is_verbose = call.has_flag("verbose"); diff --git a/crates/nu-command/tests/commands/cp.rs b/crates/nu-command/tests/commands/cp.rs index 73c769044..91532dc3e 100644 --- a/crates/nu-command/tests/commands/cp.rs +++ b/crates/nu-command/tests/commands/cp.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use nu_test_support::fs::file_contents; use nu_test_support::fs::{ files_exist_at, AbsoluteFile, @@ -5,7 +7,6 @@ use nu_test_support::fs::{ }; use nu_test_support::nu; use nu_test_support::playground::Playground; -use std::path::Path; fn get_file_hash(file: T) -> String { nu!("open -r {} | to text | hash md5", file).out @@ -127,9 +128,9 @@ fn copies_the_directory_inside_directory_if_path_to_copy_is_directory_and_with_r vec![ Path::new("yehuda.txt"), Path::new("jttxt"), - Path::new("andres.txt") + Path::new("andres.txt"), ], - &expected_dir + &expected_dir, )); }) } @@ -175,15 +176,15 @@ fn deep_copies_with_recursive_flag_impl(progress: bool) { assert!(expected_dir.exists()); assert!(files_exist_at( vec![Path::new("errors.txt"), Path::new("multishells.txt")], - jts_expected_copied_dir + jts_expected_copied_dir, )); assert!(files_exist_at( vec![Path::new("coverage.txt"), Path::new("commands.txt")], - andres_expected_copied_dir + andres_expected_copied_dir, )); assert!(files_exist_at( vec![Path::new("defer-evaluation.txt")], - yehudas_expected_copied_dir + yehudas_expected_copied_dir, )); }) } @@ -221,7 +222,7 @@ fn copies_using_path_with_wildcard_impl(progress: bool) { Path::new("sgml_description.json"), Path::new("utf16.ini"), ], - dirs.test() + dirs.test(), )); // Check integrity after the copy is done @@ -266,7 +267,7 @@ fn copies_using_a_glob_impl(progress: bool) { Path::new("sgml_description.json"), Path::new("utf16.ini"), ], - dirs.test() + dirs.test(), )); // Check integrity after the copy is done @@ -340,7 +341,7 @@ fn copy_files_using_glob_two_parents_up_using_multiple_dots_imp(progress: bool) "kevin.txt", "many_more.ppl", ], - dirs.test() + dirs.test(), )); }) } @@ -615,3 +616,18 @@ fn copy_file_with_update_flag_impl(progress: bool) { assert_eq!(actual.out, "newest_body"); }); } + +#[test] +fn cp_with_cd() { + Playground::setup("cp_test_20", |_dirs, sandbox| { + sandbox + .mkdir("tmp_dir") + .with_files(vec![FileWithContent("tmp_dir/file.txt", "body")]); + + let actual = nu!( + cwd: sandbox.cwd(), + r#"do { cd tmp_dir; let f = 'file.txt'; cp $f .. }; open file.txt"#, + ); + assert!(actual.out.contains("body")); + }); +}