mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
install: Fix behaviour of the -d flag
The '-d' flag should create all ancestors (or components) of a directory regardless of the presence of the "-D" flag. From the man page: -d, --directory treat all arguments as directory names; create all components of the specified directories With GNU: $ install -v -d dir1/di2 install: creating directory 'dir1' install: creating directory 'dir1/di2' With this version: $ ./target/release/install -v -d dir3/di4 install: dir3/di4: No such file or directory (os error 2) install: dir3/di4: chmod failed with error No such file or directory (os error 2) install: created directory 'dir3/di4' Also, one of the unit tests misinterprets what a "component" is, and hence was fixed.
This commit is contained in:
parent
2a02f01fc2
commit
97da14fcb2
2 changed files with 78 additions and 13 deletions
|
@ -356,13 +356,17 @@ fn directory(paths: Vec<String>, b: Behavior) -> i32 {
|
|||
} else {
|
||||
let mut all_successful = true;
|
||||
|
||||
for directory in paths.iter() {
|
||||
let path = Path::new(directory);
|
||||
|
||||
for path in paths.iter().map(Path::new) {
|
||||
// if the path already exist, don't try to create it again
|
||||
if !path.exists() {
|
||||
if let Err(e) = fs::create_dir(directory) {
|
||||
show_info!("{}: {}", path.display(), e.to_string());
|
||||
// Differently than the primary functionality (MainFunction::Standard), the directory
|
||||
// functionality should create all ancestors (or components) of a directory regardless
|
||||
// of the presence of the "-D" flag.
|
||||
// NOTE: the GNU "install" sets the expected mode only for the target directory. All
|
||||
// created ancestor directories will have the default mode. Hence it is safe to use
|
||||
// fs::create_dir_all and then only modify the target's dir mode.
|
||||
if let Err(e) = fs::create_dir_all(path) {
|
||||
show_info!("{}: {}", path.display(), e);
|
||||
all_successful = false;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -87,20 +87,81 @@ fn test_install_unimplemented_arg() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_component_directories() {
|
||||
fn test_install_ancestors_directories() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let component1 = "component1";
|
||||
let component2 = "component2";
|
||||
let component3 = "component3";
|
||||
let ancestor1 = "ancestor1";
|
||||
let ancestor2 = "ancestor1/ancestor2";
|
||||
let target_dir = "ancestor1/ancestor2/target_dir";
|
||||
let directories_arg = "-d";
|
||||
|
||||
ucmd.args(&[directories_arg, component1, component2, component3])
|
||||
ucmd.args(&[directories_arg, target_dir])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(component1));
|
||||
assert!(at.dir_exists(component2));
|
||||
assert!(at.dir_exists(component3));
|
||||
assert!(at.dir_exists(ancestor1));
|
||||
assert!(at.dir_exists(ancestor2));
|
||||
assert!(at.dir_exists(target_dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_ancestors_mode_directories() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let ancestor1 = "ancestor1";
|
||||
let ancestor2 = "ancestor1/ancestor2";
|
||||
let target_dir = "ancestor1/ancestor2/target_dir";
|
||||
let directories_arg = "-d";
|
||||
let mode_arg = "--mode=700";
|
||||
|
||||
ucmd.args(&[mode_arg, directories_arg, target_dir])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(ancestor1));
|
||||
assert!(at.dir_exists(ancestor2));
|
||||
assert!(at.dir_exists(target_dir));
|
||||
|
||||
assert_ne!(0o40700 as u32, at.metadata(ancestor1).permissions().mode());
|
||||
assert_ne!(0o40700 as u32, at.metadata(ancestor2).permissions().mode());
|
||||
|
||||
// Expected mode only on the target_dir.
|
||||
assert_eq!(0o40700 as u32, at.metadata(target_dir).permissions().mode());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_parent_directories() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let ancestor1 = "ancestor1";
|
||||
let ancestor2 = "ancestor1/ancestor2";
|
||||
let target_dir = "ancestor1/ancestor2/target_dir";
|
||||
let directories_arg = "-d";
|
||||
|
||||
// Here one of the ancestors already exist and only the target_dir and
|
||||
// its parent must be created.
|
||||
at.mkdir(ancestor1);
|
||||
|
||||
ucmd.args(&[directories_arg, target_dir])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(ancestor2));
|
||||
assert!(at.dir_exists(target_dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_several_directories() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir1 = "dir1";
|
||||
let dir2 = "dir2";
|
||||
let dir3 = "dir3";
|
||||
let directories_arg = "-d";
|
||||
|
||||
ucmd.args(&[directories_arg, dir1, dir2, dir3])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(dir1));
|
||||
assert!(at.dir_exists(dir2));
|
||||
assert!(at.dir_exists(dir3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue