diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 9d1acdc7e..1ac9bc743 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -426,18 +426,25 @@ fn copy_files_into_dir(files: &[PathBuf], target_dir: &PathBuf, b: &Behavior) -> let mut all_successful = true; for sourcepath in files.iter() { - let targetpath = match sourcepath.as_os_str().to_str() { - Some(name) => target_dir.join(name), - None => { - show_error!( - "cannot stat '{}': No such file or directory", - sourcepath.display() - ); + if !sourcepath.exists() { + show_info!( + "cannot stat '{}': No such file or directory", + sourcepath.display() + ); - all_successful = false; - continue; - } - }; + all_successful = false; + continue; + } + + if sourcepath.is_dir() { + show_info!("omitting directory '{}'", sourcepath.display()); + all_successful = false; + continue; + } + + let mut targetpath = target_dir.clone().to_path_buf(); + let filename = sourcepath.components().last().unwrap(); + targetpath.push(filename); if copy(sourcepath, &targetpath, b).is_err() { all_successful = false; diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index 7b3706f9e..89dfb0e56 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -17,9 +17,9 @@ fn test_install_help() { #[test] fn test_install_basic() { let (at, mut ucmd) = at_and_ucmd!(); - let dir = "test_install_target_dir_dir_a"; - let file1 = "test_install_target_dir_file_a1"; - let file2 = "test_install_target_dir_file_a2"; + let dir = "target_dir"; + let file1 = "source_file1"; + let file2 = "source_file2"; at.touch(file1); at.touch(file2); @@ -34,7 +34,7 @@ fn test_install_basic() { #[test] fn test_install_twice_dir() { - let dir = "test_install_target_dir_dir_a"; + let dir = "dir"; let scene = TestScenario::new(util_name!()); scene.ucmd().arg("-d").arg(dir).succeeds(); @@ -47,9 +47,9 @@ fn test_install_twice_dir() { #[test] fn test_install_failing_not_dir() { let (at, mut ucmd) = at_and_ucmd!(); - let file1 = "test_install_target_dir_file_a1"; - let file2 = "test_install_target_dir_file_a2"; - let file3 = "test_install_target_dir_file_a3"; + let file1 = "file1"; + let file2 = "file2"; + let file3 = "file3"; at.touch(file1); at.touch(file2); @@ -66,8 +66,8 @@ fn test_install_failing_not_dir() { #[test] fn test_install_unimplemented_arg() { let (at, mut ucmd) = at_and_ucmd!(); - let dir = "test_install_target_dir_dir_b"; - let file = "test_install_target_dir_file_b"; + let dir = "target_dir"; + let file = "source_file"; let context_arg = "--context"; at.touch(file); @@ -86,9 +86,9 @@ fn test_install_unimplemented_arg() { #[test] fn test_install_component_directories() { let (at, mut ucmd) = at_and_ucmd!(); - let component1 = "test_install_target_dir_component_c1"; - let component2 = "test_install_target_dir_component_c2"; - let component3 = "test_install_target_dir_component_c3"; + let component1 = "component1"; + let component2 = "component2"; + let component3 = "component3"; let directories_arg = "-d"; ucmd.args(&[directories_arg, component1, component2, component3]) @@ -104,10 +104,10 @@ fn test_install_component_directories() { fn test_install_mode_numeric() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; - let dir = "test_install_target_dir_dir_e"; - let dir2 = "test_install_target_dir_dir_e2"; + let dir = "dir1"; + let dir2 = "dir2"; - let file = "test_install_target_dir_file_e"; + let file = "file"; let mode_arg = "--mode=333"; at.touch(file); @@ -145,8 +145,8 @@ fn test_install_mode_numeric() { #[test] fn test_install_mode_symbolic() { let (at, mut ucmd) = at_and_ucmd!(); - let dir = "test_install_target_dir_dir_f"; - let file = "test_install_target_dir_file_f"; + let dir = "target_dir"; + let file = "source_file"; let mode_arg = "--mode=o+wx"; at.touch(file); @@ -163,8 +163,8 @@ fn test_install_mode_symbolic() { #[test] fn test_install_mode_failing() { let (at, mut ucmd) = at_and_ucmd!(); - let dir = "test_install_target_dir_dir_g"; - let file = "test_install_target_dir_file_g"; + let dir = "target_dir"; + let file = "source_file"; let mode_arg = "--mode=999"; at.touch(file); @@ -185,7 +185,7 @@ fn test_install_mode_failing() { #[test] fn test_install_mode_directories() { let (at, mut ucmd) = at_and_ucmd!(); - let component = "test_install_target_dir_component_h"; + let component = "component"; let directories_arg = "-d"; let mode_arg = "--mode=333"; @@ -203,8 +203,8 @@ fn test_install_mode_directories() { #[test] fn test_install_target_file() { let (at, mut ucmd) = at_and_ucmd!(); - let file1 = "test_install_target_file_file_i1"; - let file2 = "test_install_target_file_file_i2"; + let file1 = "source_file"; + let file2 = "target_file"; at.touch(file1); at.touch(file2); @@ -217,8 +217,8 @@ fn test_install_target_file() { #[test] fn test_install_target_new_file() { let (at, mut ucmd) = at_and_ucmd!(); - let file = "test_install_target_new_filer_file_j"; - let dir = "test_install_target_new_file_dir_j"; + let file = "file"; + let dir = "target_dir"; at.touch(file); at.mkdir(dir); @@ -234,8 +234,8 @@ fn test_install_target_new_file() { #[test] fn test_install_target_new_file_with_group() { let (at, mut ucmd) = at_and_ucmd!(); - let file = "test_install_target_new_filer_file_j"; - let dir = "test_install_target_new_file_dir_j"; + let file = "file"; + let dir = "target_dir"; let gid = get_effective_gid(); at.touch(file); @@ -264,8 +264,8 @@ fn test_install_target_new_file_with_group() { #[test] fn test_install_target_new_file_with_owner() { let (at, mut ucmd) = at_and_ucmd!(); - let file = "test_install_target_new_filer_file_j"; - let dir = "test_install_target_new_file_dir_j"; + let file = "file"; + let dir = "target_dir"; let uid = get_effective_uid(); at.touch(file); @@ -294,9 +294,9 @@ fn test_install_target_new_file_with_owner() { #[test] fn test_install_target_new_file_failing_nonexistent_parent() { let (at, mut ucmd) = at_and_ucmd!(); - let file1 = "test_install_target_new_file_failing_file_k1"; - let file2 = "test_install_target_new_file_failing_file_k2"; - let dir = "test_install_target_new_file_failing_dir_k"; + let file1 = "source_file"; + let file2 = "target_file"; + let dir = "target_dir"; at.touch(file1); @@ -312,8 +312,8 @@ fn test_install_target_new_file_failing_nonexistent_parent() { #[test] fn test_install_preserve_timestamps() { let (at, mut ucmd) = at_and_ucmd!(); - let file1 = "test_install_target_dir_file_a1"; - let file2 = "test_install_target_dir_file_a2"; + let file1 = "source_file"; + let file2 = "target_file"; at.touch(file1); ucmd.arg(file1).arg(file2).arg("-p").succeeds().no_stderr(); @@ -338,8 +338,8 @@ fn test_install_preserve_timestamps() { #[test] fn test_install_copy_file() { let (at, mut ucmd) = at_and_ucmd!(); - let file1 = "test_install_target_dir_file_a1"; - let file2 = "test_install_target_dir_file_a2"; + let file1 = "source_file"; + let file2 = "target_file"; at.touch(file1); ucmd.arg(file1).arg(file2).succeeds().no_stderr(); @@ -353,8 +353,57 @@ fn test_install_copy_file() { fn test_install_target_file_dev_null() { let (at, mut ucmd) = at_and_ucmd!(); let file1 = "/dev/null"; - let file2 = "test_install_target_file_file_i2"; + let file2 = "target_file"; ucmd.arg(file1).arg(file2).succeeds().no_stderr(); assert!(at.file_exists(file2)); } + +#[test] +fn test_install_nested_paths_copy_file() { + let (at, mut ucmd) = at_and_ucmd!(); + let file1 = "source_file"; + let dir1 = "source_dir"; + let dir2 = "target_dir"; + + at.mkdir(dir1); + at.mkdir(dir2); + at.touch(&format!("{}/{}", dir1, file1)); + + ucmd.arg(format!("{}/{}", dir1, file1)) + .arg(dir2) + .succeeds() + .no_stderr(); + assert!(at.file_exists(&format!("{}/{}", dir2, file1))); +} + +#[test] +fn test_install_failing_omitting_directory() { + let (at, mut ucmd) = at_and_ucmd!(); + let file1 = "source_file"; + let dir1 = "source_dir"; + let dir2 = "target_dir"; + + at.mkdir(dir1); + at.mkdir(dir2); + at.touch(file1); + + let r = ucmd.arg(dir1).arg(file1).arg(dir2).run(); + assert!(r.code == Some(1)); + assert!(r.stderr.contains("omitting directory")); +} + +#[test] +fn test_install_failing_no_such_file() { + let (at, mut ucmd) = at_and_ucmd!(); + let file1 = "source_file"; + let file2 = "inexistent_file"; + let dir1 = "target_dir"; + + at.mkdir(dir1); + at.touch(file1); + + let r = ucmd.arg(file1).arg(file2).arg(dir1).run(); + assert!(r.code == Some(1)); + assert!(r.stderr.contains("No such file or directory")); +}