diff options
author | David Torosyan <davidtorosyan.git@gmail.com> | 2019-01-20 17:32:34 -0800 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2019-01-22 20:03:59 -0500 |
commit | 718a00f6f2f88238546f7d33c1ea52217002495e (patch) | |
tree | 6dc4db1c1d1af1f5d87957754341b4f74ff41984 /ignore | |
parent | 7cbc535d70a53c81dfa3e58552c01f21c2e38d28 (diff) |
ripgrep: add --ignore-file-case-insensitive
The --ignore-file-case-insensitive flag causes all
.gitignore/.rgignore/.ignore files to have their globs matched without
regard for case. Because this introduces a potentially significant
performance regression, this is always disabled by default. Users that
need case insensitive matching can enable it on a case by case basis.
Closes #1164, Closes #1170
Diffstat (limited to 'ignore')
-rw-r--r-- | ignore/src/dir.rs | 49 | ||||
-rw-r--r-- | ignore/src/gitignore.rs | 49 | ||||
-rw-r--r-- | ignore/src/overrides.rs | 7 | ||||
-rw-r--r-- | ignore/src/walk.rs | 8 |
4 files changed, 94 insertions, 19 deletions
diff --git a/ignore/src/dir.rs b/ignore/src/dir.rs index 66b18635..30f4cb87 100644 --- a/ignore/src/dir.rs +++ b/ignore/src/dir.rs @@ -73,6 +73,8 @@ struct IgnoreOptions { git_ignore: bool, /// Whether to read .git/info/exclude files. git_exclude: bool, + /// Whether to ignore files case insensitively + ignore_case_insensitive: bool, } /// Ignore is a matcher useful for recursively walking one or more directories. @@ -225,7 +227,11 @@ impl Ignore { Gitignore::empty() } else { let (m, err) = - create_gitignore(&dir, &self.0.custom_ignore_filenames); + create_gitignore( + &dir, + &self.0.custom_ignore_filenames, + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -233,7 +239,12 @@ impl Ignore { if !self.0.opts.ignore { Gitignore::empty() } else { - let (m, err) = create_gitignore(&dir, &[".ignore"]); + let (m, err) = + create_gitignore( + &dir, + &[".ignore"], + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -241,7 +252,12 @@ impl Ignore { if !self.0.opts.git_ignore { Gitignore::empty() } else { - let (m, err) = create_gitignore(&dir, &[".gitignore"]); + let (m, err) = + create_gitignore( + &dir, + &[".gitignore"], + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -249,7 +265,12 @@ impl Ignore { if !self.0.opts.git_exclude { Gitignore::empty() } else { - let (m, err) = create_gitignore(&dir, &[".git/info/exclude"]); + let (m, err) = + create_gitignore( + &dir, + &[".git/info/exclude"], + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -483,6 +504,7 @@ impl IgnoreBuilder { git_global: true, git_ignore: true, git_exclude: true, + ignore_case_insensitive: false, }, } } @@ -496,7 +518,11 @@ impl IgnoreBuilder { if !self.opts.git_global { Gitignore::empty() } else { - let (gi, err) = Gitignore::global(); + let mut builder = GitignoreBuilder::new(""); + builder + .case_insensitive(self.opts.ignore_case_insensitive) + .unwrap(); + let (gi, err) = builder.build_global(); if let Some(err) = err { debug!("{}", err); } @@ -627,6 +653,17 @@ impl IgnoreBuilder { self.opts.git_exclude = yes; self } + + /// Process ignore files case insensitively + /// + /// This is disabled by default. + pub fn ignore_case_insensitive( + &mut self, + yes: bool, + ) -> &mut IgnoreBuilder { + self.opts.ignore_case_insensitive = yes; + self + } } /// Creates a new gitignore matcher for the directory given. @@ -638,9 +675,11 @@ impl IgnoreBuilder { pub fn create_gitignore<T: AsRef<OsStr>>( dir: &Path, names: &[T], + case_insensitive: bool, ) -> (Gitignore, Option<Error>) { let mut builder = GitignoreBuilder::new(dir); let mut errs = PartialErrorBuilder::default(); + builder.case_insensitive(case_insensitive).unwrap(); for name in names { let gipath = dir.join(name.as_ref()); errs.maybe_push_ignore_io(builder.add(gipath)); diff --git a/ignore/src/gitignore.rs b/ignore/src/gitignore.rs index a151e2de..66f98dfe 100644 --- a/ignore/src/gitignore.rs +++ b/ignore/src/gitignore.rs @@ -127,16 +127,7 @@ impl Gitignore { /// `$XDG_CONFIG_HOME/git/ignore` is read. If `$XDG_CONFIG_HOME` is not /// set or is empty, then `$HOME/.config/git/ignore` is used instead. pub fn global() -> (Gitignore, Option<Error>) { - match gitconfig_excludes_path() { - None => (Gitignore::empty(), None), - Some(path) => { - if !path.is_file() { - (Gitignore::empty(), None) - } else { - Gitignore::new(path) - } - } - } + GitignoreBuilder::new("").build_global() } /// Creates a new empty gitignore matcher that never matches anything. @@ -359,6 +350,36 @@ impl GitignoreBuilder { }) } + /// Build a global gitignore matcher using the configuration in this + /// builder. + /// + /// This consumes ownership of the builder unlike `build` because it + /// must mutate the builder to add the global gitignore globs. + /// + /// Note that this ignores the path given to this builder's constructor + /// and instead derives the path automatically from git's global + /// configuration. + pub fn build_global(mut self) -> (Gitignore, Option<Error>) { + match gitconfig_excludes_path() { + None => (Gitignore::empty(), None), + Some(path) => { + if !path.is_file() { + (Gitignore::empty(), None) + } else { + let mut errs = PartialErrorBuilder::default(); + errs.maybe_push_ignore_io(self.add(path)); + match self.build() { + Ok(gi) => (gi, errs.into_error_option()), + Err(err) => { + errs.push(err); + (Gitignore::empty(), errs.into_error_option()) + } + } + } + } + } + } + /// Add each glob from the file path given. /// /// The file given should be formatted as a `gitignore` file. @@ -505,12 +526,16 @@ impl GitignoreBuilder { /// Toggle whether the globs should be matched case insensitively or not. /// - /// When this option is changed, only globs added after the change will be affected. + /// When this option is changed, only globs added after the change will be + /// affected. /// /// This is disabled by default. pub fn case_insensitive( - &mut self, yes: bool + &mut self, + yes: bool, ) -> Result<&mut GitignoreBuilder, Error> { + // TODO: This should not return a `Result`. Fix this in the next semver + // release. self.case_insensitive = yes; Ok(self) } diff --git a/ignore/src/overrides.rs b/ignore/src/overrides.rs index c63532af..08dbdac2 100644 --- a/ignore/src/overrides.rs +++ b/ignore/src/overrides.rs @@ -139,13 +139,16 @@ impl OverrideBuilder { } /// Toggle whether the globs should be matched case insensitively or not. - /// + /// /// When this option is changed, only globs added after the change will be affected. /// /// This is disabled by default. pub fn case_insensitive( - &mut self, yes: bool + &mut self, + yes: bool, ) -> Result<&mut OverrideBuilder, Error> { + // TODO: This should not return a `Result`. Fix this in the next semver + // release. self.builder.case_insensitive(yes)?; Ok(self) } diff --git a/ignore/src/walk.rs b/ignore/src/walk.rs index aee7a881..ae1f58ba 100644 --- a/ignore/src/walk.rs +++ b/ignore/src/walk.rs @@ -764,6 +764,14 @@ impl WalkBuilder { self } + /// Process ignore files case insensitively + /// + /// This is disabled by default. + pub fn ignore_case_insensitive(&mut self, yes: bool) -> &mut WalkBuilder { + self.ig_builder.ignore_case_insensitive(yes); + self + } + /// Set a function for sorting directory entries by their path. /// /// If a compare function is set, the resulting iterator will return all |