mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +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 {
|
} else {
|
||||||
let mut all_successful = true;
|
let mut all_successful = true;
|
||||||
|
|
||||||
for directory in paths.iter() {
|
for path in paths.iter().map(Path::new) {
|
||||||
let path = Path::new(directory);
|
|
||||||
|
|
||||||
// if the path already exist, don't try to create it again
|
// if the path already exist, don't try to create it again
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
if let Err(e) = fs::create_dir(directory) {
|
// Differently than the primary functionality (MainFunction::Standard), the directory
|
||||||
show_info!("{}: {}", path.display(), e.to_string());
|
// 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;
|
all_successful = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,20 +87,81 @@ fn test_install_unimplemented_arg() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_install_component_directories() {
|
fn test_install_ancestors_directories() {
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
let component1 = "component1";
|
let ancestor1 = "ancestor1";
|
||||||
let component2 = "component2";
|
let ancestor2 = "ancestor1/ancestor2";
|
||||||
let component3 = "component3";
|
let target_dir = "ancestor1/ancestor2/target_dir";
|
||||||
let directories_arg = "-d";
|
let directories_arg = "-d";
|
||||||
|
|
||||||
ucmd.args(&[directories_arg, component1, component2, component3])
|
ucmd.args(&[directories_arg, target_dir])
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.no_stderr();
|
.no_stderr();
|
||||||
|
|
||||||
assert!(at.dir_exists(component1));
|
assert!(at.dir_exists(ancestor1));
|
||||||
assert!(at.dir_exists(component2));
|
assert!(at.dir_exists(ancestor2));
|
||||||
assert!(at.dir_exists(component3));
|
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]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue