From 75782f0f50e81c8a73ce6e6ccf6b7fd73dc0f7a4 Mon Sep 17 00:00:00 2001 From: Yogi Date: Thu, 28 Oct 2021 17:35:07 +0530 Subject: [PATCH] Fix #4070: Inconsistent file matching rule for ls and rm (#4099) --- crates/nu-command/tests/commands/rm.rs | 18 ++++++++++++++++++ .../src/filesystem/filesystem_shell.rs | 16 +++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/crates/nu-command/tests/commands/rm.rs b/crates/nu-command/tests/commands/rm.rs index 4a20eb3821..ae7e35828d 100644 --- a/crates/nu-command/tests/commands/rm.rs +++ b/crates/nu-command/tests/commands/rm.rs @@ -306,3 +306,21 @@ fn rm_wildcard_leading_dot_deletes_dotfiles() { assert!(!files_exist_at(vec![".bar"], dirs.test())); }) } + +#[test] +fn removes_files_with_case_sensitive_glob_matches_by_default() { + Playground::setup("glob_test", |dirs, sandbox| { + sandbox.with_files(vec![EmptyFile("A0"), EmptyFile("a1")]); + + nu!( + cwd: dirs.root(), + "rm glob_test/A*" + ); + + let deleted_path = dirs.test().join("A0"); + let skipped_path = dirs.test().join("a1"); + + assert!(!deleted_path.exists()); + assert!(skipped_path.exists()); + }) +} diff --git a/crates/nu-engine/src/filesystem/filesystem_shell.rs b/crates/nu-engine/src/filesystem/filesystem_shell.rs index e483ac2cfa..1f74919c1b 100644 --- a/crates/nu-engine/src/filesystem/filesystem_shell.rs +++ b/crates/nu-engine/src/filesystem/filesystem_shell.rs @@ -28,6 +28,12 @@ use nu_errors::ShellError; use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue}; use nu_source::Tagged; +const GLOB_PARAMS: glob::MatchOptions = glob::MatchOptions { + case_sensitive: true, + require_literal_separator: false, + require_literal_leading_dot: false, +}; + #[derive(Eq, PartialEq, Clone, Copy)] pub enum FilesystemShellMode { Cli, @@ -159,7 +165,7 @@ impl Shell for FilesystemShell { let hidden_dir_specified = is_hidden_dir(&path); - let mut paths = glob::glob(&path.to_string_lossy()) + let mut paths = glob::glob_with(&path.to_string_lossy(), GLOB_PARAMS) .map_err(|e| ShellError::labeled_error(e.to_string(), "invalid pattern", &p_tag))? .peekable(); @@ -352,7 +358,7 @@ impl Shell for FilesystemShell { let source = path.join(&src.item); let destination = path.join(&dst.item); - let sources: Vec<_> = match glob::glob(&source.to_string_lossy()) { + let sources: Vec<_> = match glob::glob_with(&source.to_string_lossy(), GLOB_PARAMS) { Ok(files) => files.collect(), Err(e) => { return Err(ShellError::labeled_error( @@ -521,8 +527,8 @@ impl Shell for FilesystemShell { let source = path.join(&src.item); let destination = path.join(&dst.item); - let mut sources = - glob::glob(&source.to_string_lossy()).map_or_else(|_| Vec::new(), Iterator::collect); + let mut sources = glob::glob_with(&source.to_string_lossy(), GLOB_PARAMS) + .map_or_else(|_| Vec::new(), Iterator::collect); if sources.is_empty() { return Err(ShellError::labeled_error( @@ -650,7 +656,7 @@ impl Shell for FilesystemShell { &path.to_string_lossy(), glob::MatchOptions { require_literal_leading_dot: true, - ..Default::default() + ..GLOB_PARAMS }, ) { Ok(files) => {