mirror of
https://github.com/nushell/nushell.git
synced 2025-04-22 04:08:20 +02:00
Resolve issues with rm *
globbing (#3516)
Using the `*` wildcard should not attempt to delete files with a leading dot unless the more explicit `.*` is used. `rm *` should also not attempt to delete the current directory or its parent directory (`.` and `..`). I have resolved this bug as well in a less satisfactory way. I think it may be the case that we can only disambiguate the `.` and `..` path segments by using `Path::display`. Here is a short list of alternatives that I tried: - `Path::ends_with()` can detect `/..` but not `/.`. - `Path::iter()` and `Path::components()` leave out `/.`. - `Path::file_name()` normalizes `/.` to the parent component's file name. Fixes #3508
This commit is contained in:
parent
6fdfc84904
commit
4b11b283ac
@ -276,3 +276,33 @@ fn no_errors_if_attempting_to_delete_non_existent_file_with_f_flag() {
|
|||||||
assert!(!actual.err.contains("no valid path"));
|
assert!(!actual.err.contains("no valid path"));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rm_wildcard_keeps_dotfiles() {
|
||||||
|
Playground::setup("rm_test_15", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![EmptyFile("foo"), EmptyFile(".bar")]);
|
||||||
|
|
||||||
|
nu!(
|
||||||
|
cwd: dirs.test(),
|
||||||
|
r#"rm *"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(!files_exist_at(vec!["foo"], dirs.test()));
|
||||||
|
assert!(files_exist_at(vec![".bar"], dirs.test()));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rm_wildcard_leading_dot_deletes_dotfiles() {
|
||||||
|
Playground::setup("rm_test_16", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![EmptyFile("foo"), EmptyFile(".bar")]);
|
||||||
|
|
||||||
|
nu!(
|
||||||
|
cwd: dirs.test(),
|
||||||
|
r#"rm .*"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(files_exist_at(vec!["foo"], dirs.test()));
|
||||||
|
assert!(!files_exist_at(vec![".bar"], dirs.test()));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -643,11 +643,25 @@ impl Shell for FilesystemShell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let path = path.join(&target.item);
|
let path = path.join(&target.item);
|
||||||
match glob::glob(&path.to_string_lossy()) {
|
match glob::glob_with(
|
||||||
|
&path.to_string_lossy(),
|
||||||
|
glob::MatchOptions {
|
||||||
|
require_literal_leading_dot: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
) {
|
||||||
Ok(files) => {
|
Ok(files) => {
|
||||||
for file in files {
|
for file in files {
|
||||||
match file {
|
match file {
|
||||||
Ok(ref f) => {
|
Ok(ref f) => {
|
||||||
|
// It is not appropriate to try and remove the
|
||||||
|
// current directory or its parent when using
|
||||||
|
// glob patterns.
|
||||||
|
let name = format!("{}", f.display());
|
||||||
|
if name.ends_with("/.") || name.ends_with("/..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
all_targets
|
all_targets
|
||||||
.entry(f.clone())
|
.entry(f.clone())
|
||||||
.or_insert_with(|| target.tag.clone());
|
.or_insert_with(|| target.tag.clone());
|
||||||
|
Loading…
Reference in New Issue
Block a user