mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-11-23 21:54:45 +02:00
globset: add allow_unclosed_class toggle
When enabled, patterns like `[abc`, `[]`, `[!]` are treated as if the opening `[` is just a literal. This is in contrast the default behavior, which prioritizes better error messages, of returning a parse error. Fixes #3127, Closes #3145
This commit is contained in:
@@ -308,6 +308,7 @@ pub struct GitignoreBuilder {
|
||||
root: PathBuf,
|
||||
globs: Vec<Glob>,
|
||||
case_insensitive: bool,
|
||||
allow_unclosed_class: bool,
|
||||
}
|
||||
|
||||
impl GitignoreBuilder {
|
||||
@@ -324,6 +325,7 @@ impl GitignoreBuilder {
|
||||
root: strip_prefix("./", root).unwrap_or(root).to_path_buf(),
|
||||
globs: vec![],
|
||||
case_insensitive: false,
|
||||
allow_unclosed_class: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,6 +513,7 @@ impl GitignoreBuilder {
|
||||
.literal_separator(true)
|
||||
.case_insensitive(self.case_insensitive)
|
||||
.backslash_escape(true)
|
||||
.allow_unclosed_class(self.allow_unclosed_class)
|
||||
.build()
|
||||
.map_err(|err| Error::Glob {
|
||||
glob: Some(glob.original.clone()),
|
||||
@@ -536,6 +539,26 @@ impl GitignoreBuilder {
|
||||
self.case_insensitive = yes;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Toggle whether unclosed character classes are allowed. When allowed,
|
||||
/// a `[` without a matching `]` is treated literally instead of resulting
|
||||
/// in a parse error.
|
||||
///
|
||||
/// For example, if this is set then the glob `[abc` will be treated as the
|
||||
/// literal string `[abc` instead of returning an error.
|
||||
///
|
||||
/// By default, this is true in order to match established `gitignore`
|
||||
/// semantics. Generally speaking, enabling this leads to worse failure
|
||||
/// modes since the glob parser becomes more permissive. You might want to
|
||||
/// enable this when compatibility (e.g., with POSIX glob implementations)
|
||||
/// is more important than good error messages.
|
||||
pub fn allow_unclosed_class(
|
||||
&mut self,
|
||||
yes: bool,
|
||||
) -> &mut GitignoreBuilder {
|
||||
self.allow_unclosed_class = yes;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the file path of the current environment's global gitignore file.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*!
|
||||
The overrides module provides a way to specify a set of override globs.
|
||||
|
||||
This provides functionality similar to `--include` or `--exclude` in command
|
||||
line tools.
|
||||
*/
|
||||
@@ -120,7 +121,9 @@ impl OverrideBuilder {
|
||||
///
|
||||
/// Matching is done relative to the directory path provided.
|
||||
pub fn new<P: AsRef<Path>>(path: P) -> OverrideBuilder {
|
||||
OverrideBuilder { builder: GitignoreBuilder::new(path) }
|
||||
let mut builder = GitignoreBuilder::new(path);
|
||||
builder.allow_unclosed_class(false);
|
||||
OverrideBuilder { builder }
|
||||
}
|
||||
|
||||
/// Builds a new override matcher from the globs added so far.
|
||||
@@ -143,7 +146,8 @@ 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.
|
||||
/// When this option is changed, only globs added after the change will be
|
||||
/// affected.
|
||||
///
|
||||
/// This is disabled by default.
|
||||
pub fn case_insensitive(
|
||||
@@ -155,6 +159,28 @@ impl OverrideBuilder {
|
||||
self.builder.case_insensitive(yes)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Toggle whether unclosed character classes are allowed. When allowed,
|
||||
/// a `[` without a matching `]` is treated literally instead of resulting
|
||||
/// in a parse error.
|
||||
///
|
||||
/// For example, if this is set then the glob `[abc` will be treated as the
|
||||
/// literal string `[abc` instead of returning an error.
|
||||
///
|
||||
/// By default, this is false. Generally speaking, enabling this leads to
|
||||
/// worse failure modes since the glob parser becomes more permissive. You
|
||||
/// might want to enable this when compatibility (e.g., with POSIX glob
|
||||
/// implementations) is more important than good error messages.
|
||||
///
|
||||
/// This default is different from the default for [`Gitignore`]. Namely,
|
||||
/// [`Gitignore`] is intended to match git's behavior as-is. But this
|
||||
/// abstraction for "override" globs does not necessarily conform to any
|
||||
/// other known specification and instead prioritizes better error
|
||||
/// messages.
|
||||
pub fn allow_unclosed_class(&mut self, yes: bool) -> &mut OverrideBuilder {
|
||||
self.builder.allow_unclosed_class(yes);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user