diff --git a/src/commands/cp.rs b/src/commands/cp.rs index f1acfc506a..00183647bc 100644 --- a/src/commands/cp.rs +++ b/src/commands/cp.rs @@ -35,7 +35,6 @@ pub fn cp(args: CommandArgs) -> Result { let mut source = PathBuf::from(args.shell_manager.path()); let mut destination = PathBuf::from(args.shell_manager.path()); - let mut dst = String::new(); match args .nth(0) @@ -55,26 +54,128 @@ pub fn cp(args: CommandArgs) -> Result { .as_str() { file => { - dst.push_str(file); destination.push(file); } } + let (sources, destinations) = ( + glob::glob(&source.to_string_lossy()), + glob::glob(&destination.to_string_lossy()), + ); + + if sources.is_err() || destinations.is_err() { + return Err(ShellError::string("Invalid pattern.")); + } + + let (sources, destinations): (Vec<_>, Vec<_>) = + (sources.unwrap().collect(), destinations.unwrap().collect()); + + if sources.len() == 1 { + if let Ok(entry) = &sources[0] { + if entry.is_file() { + if destinations.len() == 1 { + if let Ok(dst) = &destinations[0] { + if dst.is_file() { + std::fs::copy(entry, dst); + } + + if dst.is_dir() { + destination.push(entry.file_name().unwrap()); + std::fs::copy(entry, destination); + } + } + } else if destinations.is_empty() { + if destination.is_dir() { + destination.push(entry.file_name().unwrap()); + std::fs::copy(entry, destination); + } else { + std::fs::copy(entry, destination); + } + } + } + + if entry.is_dir() { + if destinations.len() == 1 { + if let Ok(dst) = &destinations[0] { + if dst.is_dir() && !args.has("recursive") { + return Err(ShellError::string(&format!( + "{:?} is a directory (not copied)", + entry.to_string_lossy() + ))); + } + + + if dst.is_dir() && args.has("recursive") { + let entries = std::fs::read_dir(&entry); + + let entries = match entries { + Err(e) => { + if let Some(s) = args.nth(0) { + return Err(ShellError::labeled_error( + e.to_string(), + e.to_string(), + s.span(), + )); + } else { + return Err(ShellError::labeled_error( + e.to_string(), + e.to_string(), + args.call_info.name_span, + )); + } + } + Ok(o) => o, + }; + + let mut x = dst.clone(); + + //x.pop(); + x.push(entry.file_name().unwrap()); + + + std::fs::create_dir(&x).expect("can not create directory"); + + for entry in entries { + let entry = entry?; + let file_path = entry.path(); + let file_name = file_path.file_name().unwrap(); + + let mut d = PathBuf::new(); + d.push(&x); + d.push(file_name); + + std::fs::copy(entry.path(), d); + } + } + } + } + } + } + } + /* if destination.is_dir() { if source.is_file() { let file_name = source.file_name().expect(""); let file_name = file_name.to_str().expect(""); destination.push(Path::new(file_name)); + + match std::fs::copy(source, destination) { + Err(_error) => return Err(ShellError::string("can not copy file")), + Ok(_) => return Ok(OutputStream::empty()), + } } else if source.is_dir() { - return Err(ShellError::string(&format!( - "{:?} is a directory (not copied)", - source.to_string_lossy() - ))); + + return Err(ShellError::string(&format!( + "{:?} is a directory (not copied)", + source.to_string_lossy() + ))); + } } match std::fs::copy(source, destination) { Err(_error) => Err(ShellError::string("can not copy file")), Ok(_) => Ok(OutputStream::empty()), - } + }*/ + Ok(OutputStream::empty()) } diff --git a/tests/command_cd_tests.rs b/tests/command_cd_tests.rs new file mode 100644 index 0000000000..626a59f795 --- /dev/null +++ b/tests/command_cd_tests.rs @@ -0,0 +1,16 @@ +mod helpers; + +use helpers::in_directory as cwd; +use helpers::Playground; + +#[test] +fn cd_directory_not_found() { + let sandbox = Playground::setup_for("cd_directory_not_found_test").test_dir_name(); + + let full_path = format!("{}/{}", Playground::root(), sandbox); + + nu_error!(output, cwd(&full_path), "cd dir_that_does_not_exist"); + + assert!(output.contains("dir_that_does_not_exist")); + assert!(output.contains("directory not found")); +} \ No newline at end of file diff --git a/tests/command_clip_tests.rs b/tests/command_clip_tests.rs new file mode 100644 index 0000000000..5d418c9a60 --- /dev/null +++ b/tests/command_clip_tests.rs @@ -0,0 +1,20 @@ +mod helpers; + +use helpers::in_directory as cwd; + +use clipboard::{ClipboardProvider, ClipboardContext}; + +#[test] +fn clip() { + + let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap(); + + nu!( + _output, + cwd("tests/fixtures/formats"), + "open caco3_plastics.csv --raw | lines | clip" + ); + + + assert!(ctx.get_contents().is_ok()); +} \ No newline at end of file diff --git a/tests/command_cp_tests.rs b/tests/command_cp_tests.rs new file mode 100644 index 0000000000..59d145b911 --- /dev/null +++ b/tests/command_cp_tests.rs @@ -0,0 +1,73 @@ +mod helpers; + +use h::{in_directory as cwd, Playground, Stub::*}; +use helpers as h; + +use std::path::{Path, PathBuf}; + +#[test] +fn cp_copies_a_file() { + let sandbox = Playground::setup_for("cp_test").test_dir_name(); + + let full_path = format!("{}/{}", Playground::root(), sandbox); + let expected_file = format!("{}/{}", full_path, "sample.ini"); + + nu!( + _output, + cwd(&Playground::root()), + "cp ../formats/sample.ini cp_test/sample.ini" + ); + + assert!(h::file_exists_at(PathBuf::from(expected_file))); +} + +#[test] +fn cp_copies_the_file_inside_directory_if_path_to_copy_is_directory() { + let sandbox = Playground::setup_for("cp_test_2").test_dir_name(); + + let full_path = format!("{}/{}", Playground::root(), sandbox); + let expected_file = format!("{}/{}", full_path, "sample.ini"); + + nu!( + _output, + cwd(&Playground::root()), + "cp ../formats/sample.ini cp_test_2" + ); + + assert!(h::file_exists_at(PathBuf::from(expected_file))); +} + +#[test] +fn cp_error_if_attempting_to_copy_a_directory_to_another_directory() { + Playground::setup_for("cp_test_3"); + + nu_error!(output, cwd(&Playground::root()), "cp ../formats cp_test_3"); + + assert!(output.contains("../formats")); + assert!(output.contains("is a directory (not copied)")); +} + +#[test] +fn cp_copies_the_directory_inside_directory_if_path_to_copy_is_directory_and_with_recursive_flag() { + let sandbox = Playground::setup_for("cp_test_4") + .within("originals") + .with_files(vec![ + EmptyFile("yehuda.txt"), + EmptyFile("jonathan.txt"), + EmptyFile("andres.txt"), + ]) + .within("copies_expected") + .test_dir_name(); + + let full_path = format!("{}/{}", Playground::root(), sandbox); + let expected_dir = format!("{}/{}", full_path, "copies_expected/originals"); + + nu!( + _output, + cwd(&full_path), + "cp originals copies_expected --recursive" + ); + + assert!(h::dir_exists_at(PathBuf::from(&expected_dir))); + assert!(h::files_exist_at(vec![Path::new("yehuda.txt"), Path::new("jonathan.txt"), Path::new("andres.txt")], PathBuf::from(&expected_dir))); +} \ No newline at end of file diff --git a/tests/commands_test.rs b/tests/commands_test.rs index a1699a8d85..1457934020 100644 --- a/tests/commands_test.rs +++ b/tests/commands_test.rs @@ -2,7 +2,7 @@ mod helpers; use h::{in_directory as cwd, Playground, Stub::*}; use helpers as h; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; #[test] fn lines() { @@ -129,48 +129,6 @@ fn save_can_write_out_csv() { assert!(actual.contains("[list list],A shell for the GitHub era,2018,ISC,nu,0.2.0")); } -#[test] -fn cp_can_copy_a_file() { - let sandbox = Playground::setup_for("cp_test").test_dir_name(); - - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_file = format!("{}/{}", full_path, "sample.ini"); - - nu!( - _output, - cwd(&Playground::root()), - "cp ../formats/sample.ini cp_test/sample.ini" - ); - - assert!(h::file_exists_at(&expected_file)); -} - -#[test] -fn cp_copies_the_file_inside_directory_if_path_to_copy_is_directory() { - let sandbox = Playground::setup_for("cp_test_2").test_dir_name(); - - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_file = format!("{}/{}", full_path, "sample.ini"); - - nu!( - _output, - cwd(&Playground::root()), - "cp ../formats/sample.ini cp_test_2" - ); - - assert!(h::file_exists_at(&expected_file)); -} - -#[test] -fn cp_error_if_attempting_to_copy_a_directory_to_another_directory() { - Playground::setup_for("cp_test_3"); - - nu_error!(output, cwd(&Playground::root()), "cp ../formats cp_test_3"); - - assert!(output.contains("../formats")); - assert!(output.contains("is a directory (not copied)")); -} - #[test] fn rm_removes_a_file() { let sandbox = Playground::setup_for("rm_test") @@ -183,12 +141,14 @@ fn rm_removes_a_file() { "rm rm_test/i_will_be_deleted.txt" ); - assert!(!h::file_exists_at(&format!( + let path = &format!( "{}/{}/{}", Playground::root(), sandbox, "i_will_be_deleted.txt" - ))); + ); + + assert!(!h::file_exists_at(PathBuf::from(path))); } #[test] @@ -243,21 +203,13 @@ fn rm_removes_files_with_wildcard() { "rm \"src/*/*/*.rs\"" ); - assert!(!h::file_exists_at(&format!( - "{}/src/parser/parse/token_tree.rs", - full_path - ))); - assert!(!h::file_exists_at(&format!( - "{}/src/parser/hir/baseline_parse.rs", - full_path - ))); - assert!(!h::file_exists_at(&format!( - "{}/src/parser/hir/baseline_parse_tokens.rs", - full_path - ))); + assert!(!h::files_exist_at(vec![ + Path::new("src/parser/parse/token_tree.rs"), + Path::new("src/parser/hir/baseline_parse.rs"), + Path::new("src/parser/hir/baseline_parse_tokens.rs")], PathBuf::from(&full_path))); assert_eq!( - Playground::glob_vec(&format!("{}/src/*/*/*.rs", full_path)), + Playground::glob_vec(&format!("{}/src/*/*/*.rs", &full_path)), Vec::::new() ); } @@ -278,11 +230,13 @@ fn rm_removes_directory_contents_with_recursive_flag() { "rm rm_test_recursive --recursive" ); - assert!(!h::file_exists_at(&format!( + let expected = format!( "{}/{}", Playground::root(), sandbox - ))); + ); + + assert!(!h::file_exists_at(PathBuf::from(expected))); } #[test] @@ -292,7 +246,7 @@ fn rm_errors_if_attempting_to_delete_a_directory_without_recursive_flag() { nu_error!(output, cwd(&Playground::root()), "rm rm_test_2"); - assert!(h::file_exists_at(&full_path)); + assert!(h::file_exists_at(PathBuf::from(full_path))); assert!(output.contains("is a directory")); } diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index c7a725ed83..f4823ad5de 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -181,12 +181,21 @@ pub fn copy_file_to(source: &str, destination: &str) { std::fs::copy(source, destination).expect("can not copy file"); } -pub fn file_exists_at(full_path: &str) -> bool { - PathBuf::from(full_path).exists() +pub fn files_exist_at(files: Vec<&Path>, path: PathBuf) -> bool { + files.iter() + .all(|f| { + let mut loc = path.clone(); + loc.push(f); + loc.exists() + }) } -pub fn dir_exists_at(full_path: &str) -> bool { - PathBuf::from(full_path).exists() +pub fn file_exists_at(path: PathBuf) -> bool { + path.exists() +} + +pub fn dir_exists_at(path: PathBuf) -> bool { + path.exists() } pub fn delete_directory_at(full_path: &str) {