mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Co-authored-by: Terts Diepraam <terts.diepraam@gmail.com>
This commit is contained in:
parent
e523a56dab
commit
493a2628d2
2 changed files with 76 additions and 2 deletions
|
@ -303,13 +303,36 @@ fn handle_dir(path: &Path, options: &Options) -> bool {
|
|||
}
|
||||
} else {
|
||||
let mut dirs: VecDeque<DirEntry> = VecDeque::new();
|
||||
// The Paths to not descend into. We need to this because WalkDir doesn't have a way, afaik, to not descend into a directory
|
||||
// So we have to just ignore paths as they come up if they start with a path we aren't descending into
|
||||
let mut not_descended: Vec<PathBuf> = Vec::new();
|
||||
|
||||
for entry in WalkDir::new(path) {
|
||||
'outer: for entry in WalkDir::new(path) {
|
||||
match entry {
|
||||
Ok(entry) => {
|
||||
if options.interactive == InteractiveMode::Always {
|
||||
for not_descend in ¬_descended {
|
||||
if entry.path().starts_with(not_descend) {
|
||||
// We don't need to continue the rest of code in this loop if we are in a directory we don't want to descend into
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
let file_type = entry.file_type();
|
||||
if file_type.is_dir() {
|
||||
dirs.push_back(entry);
|
||||
// If we are in Interactive Mode Always and the directory isn't empty we ask if we should descend else we push this directory onto dirs vector
|
||||
if options.interactive == InteractiveMode::Always
|
||||
&& fs::read_dir(entry.path()).unwrap().count() != 0
|
||||
{
|
||||
// If we don't descend we push this directory onto our not_descended vector else we push this directory onto dirs vector
|
||||
if prompt_descend(entry.path()) {
|
||||
dirs.push_back(entry);
|
||||
} else {
|
||||
not_descended.push(entry.path().to_path_buf());
|
||||
}
|
||||
} else {
|
||||
dirs.push_back(entry);
|
||||
}
|
||||
} else {
|
||||
had_err = remove_file(entry.path(), options).bitor(had_err);
|
||||
}
|
||||
|
@ -447,6 +470,10 @@ fn prompt_write_protected(path: &Path, is_dir: bool, options: &Options) -> bool
|
|||
}
|
||||
}
|
||||
|
||||
fn prompt_descend(path: &Path) -> bool {
|
||||
prompt(&(format!("rm: descend into directory {}? ", path.quote())))
|
||||
}
|
||||
|
||||
fn prompt_file(path: &Path, is_dir: bool) -> bool {
|
||||
if is_dir {
|
||||
prompt(&(format!("rm: remove directory {}? ", path.quote())))
|
||||
|
|
|
@ -353,6 +353,53 @@ fn test_rm_interactive_never() {
|
|||
assert!(!at.file_exists(file_2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_descend_directory() {
|
||||
// This test descends into each directory and deletes the files and folders inside of them
|
||||
// This test will have the rm process asks 6 question and us answering Y to them will delete all the files and folders
|
||||
use std::io::Write;
|
||||
use std::process::Child;
|
||||
|
||||
// Needed for talking with stdin on platforms where CRLF or LF matters
|
||||
const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" };
|
||||
|
||||
let yes = format!("y{}", END_OF_LINE);
|
||||
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
let file_1 = "a/at.txt";
|
||||
let file_2 = "a/b/bt.txt";
|
||||
|
||||
at.mkdir_all("a/b/");
|
||||
at.touch(file_1);
|
||||
at.touch(file_2);
|
||||
|
||||
let mut child: Child = scene.ucmd().arg("-ri").arg("a").run_no_wait();
|
||||
|
||||
// Needed so that we can talk to the rm program
|
||||
let mut child_stdin = child.stdin.take().unwrap();
|
||||
child_stdin.write_all(yes.as_bytes()).unwrap();
|
||||
child_stdin.flush().unwrap();
|
||||
child_stdin.write_all(yes.as_bytes()).unwrap();
|
||||
child_stdin.flush().unwrap();
|
||||
child_stdin.write_all(yes.as_bytes()).unwrap();
|
||||
child_stdin.flush().unwrap();
|
||||
child_stdin.write_all(yes.as_bytes()).unwrap();
|
||||
child_stdin.flush().unwrap();
|
||||
child_stdin.write_all(yes.as_bytes()).unwrap();
|
||||
child_stdin.flush().unwrap();
|
||||
child_stdin.write_all(yes.as_bytes()).unwrap();
|
||||
child_stdin.flush().unwrap();
|
||||
|
||||
child.wait_with_output().unwrap();
|
||||
|
||||
assert!(!at.dir_exists("a/b"));
|
||||
assert!(!at.dir_exists("a"));
|
||||
assert!(!at.file_exists(file_1));
|
||||
assert!(!at.file_exists(file_2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "issue #3722"]
|
||||
fn test_rm_directory_rights_rm1() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue