summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2016-10-10 19:16:52 -0400
committerAndrew Gallant <jamslam@gmail.com>2016-10-10 19:24:18 -0400
commite96d93034a4829250f61b190901a8faf9a1eeb1f (patch)
treee402ad6c7a66b95cda7e3ac2dae058aac5bdc1fc /src
parentbc5accc035846a930bc75cb5d710e477e4527a39 (diff)
Finish overhaul of glob matching.
This commit completes the initial move of glob matching to an external crate, including fixing up cross platform support, polishing the external crate for others to use and fixing a number of bugs in the process. Fixes #87, #127, #131
Diffstat (limited to 'src')
-rw-r--r--src/gitignore.rs27
-rw-r--r--src/types.rs18
2 files changed, 28 insertions, 17 deletions
diff --git a/src/gitignore.rs b/src/gitignore.rs
index 5e07531d..4c7e8203 100644
--- a/src/gitignore.rs
+++ b/src/gitignore.rs
@@ -28,7 +28,7 @@ use std::fs::File;
use std::io::{self, BufRead};
use std::path::{Path, PathBuf};
-use globset::{self, PatternBuilder, Set, SetBuilder};
+use globset::{self, Candidate, GlobBuilder, GlobSet, GlobSetBuilder};
use regex;
use pathutil::{is_file_name, strip_prefix};
@@ -82,7 +82,7 @@ impl From<io::Error> for Error {
/// Gitignore is a matcher for the glob patterns in a single gitignore file.
#[derive(Clone, Debug)]
pub struct Gitignore {
- set: Set,
+ set: GlobSet,
root: PathBuf,
patterns: Vec<Pattern>,
num_ignores: u64,
@@ -140,7 +140,8 @@ impl Gitignore {
};
MATCHES.with(|matches| {
let mut matches = matches.borrow_mut();
- self.set.matches_into(path, &mut *matches);
+ let candidate = Candidate::new(path);
+ self.set.matches_candidate_into(&candidate, &mut *matches);
for &i in matches.iter().rev() {
let pat = &self.patterns[i];
if !pat.only_dir || is_dir {
@@ -207,7 +208,7 @@ impl<'a> Match<'a> {
/// GitignoreBuilder constructs a matcher for a single set of globs from a
/// .gitignore file.
pub struct GitignoreBuilder {
- builder: SetBuilder,
+ builder: GlobSetBuilder,
root: PathBuf,
patterns: Vec<Pattern>,
}
@@ -237,7 +238,7 @@ impl GitignoreBuilder {
pub fn new<P: AsRef<Path>>(root: P) -> GitignoreBuilder {
let root = strip_prefix("./", root.as_ref()).unwrap_or(root.as_ref());
GitignoreBuilder {
- builder: SetBuilder::new(),
+ builder: GlobSetBuilder::new(),
root: root.to_path_buf(),
patterns: vec![],
}
@@ -262,8 +263,18 @@ impl GitignoreBuilder {
pub fn add_path<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
let rdr = io::BufReader::new(try!(File::open(&path)));
debug!("gitignore: {}", path.as_ref().display());
- for line in rdr.lines() {
- try!(self.add(&path, &try!(line)));
+ for (i, line) in rdr.lines().enumerate() {
+ let line = match line {
+ Ok(line) => line,
+ Err(err) => {
+ debug!("error reading line {} in {}: {}",
+ i, path.as_ref().display(), err);
+ continue;
+ }
+ };
+ if let Err(err) = self.add(&path, &line) {
+ debug!("error adding gitignore pattern: '{}': {}", line, err);
+ }
}
Ok(())
}
@@ -349,7 +360,7 @@ impl GitignoreBuilder {
pat.pat = format!("{}/*", pat.pat);
}
let parsed = try!(
- PatternBuilder::new(&pat.pat)
+ GlobBuilder::new(&pat.pat)
.literal_separator(literal_separator)
.build());
self.builder.add(parsed);
diff --git a/src/types.rs b/src/types.rs
index c084500e..69517124 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -11,7 +11,7 @@ use std::path::Path;
use regex;
use gitignore::{Match, Pattern};
-use globset::{self, PatternBuilder, Set, SetBuilder};
+use globset::{self, GlobBuilder, GlobSet, GlobSetBuilder};
const TYPE_EXTENSIONS: &'static [(&'static str, &'static [&'static str])] = &[
("asm", &["*.asm", "*.s", "*.S"]),
@@ -164,8 +164,8 @@ impl FileTypeDef {
#[derive(Clone, Debug)]
pub struct Types {
defs: Vec<FileTypeDef>,
- selected: Option<Set>,
- negated: Option<Set>,
+ selected: Option<GlobSet>,
+ negated: Option<GlobSet>,
has_selected: bool,
unmatched_pat: Pattern,
}
@@ -178,8 +178,8 @@ impl Types {
/// If has_selected is true, then at least one file type was selected.
/// Therefore, any non-matches should be ignored.
fn new(
- selected: Option<Set>,
- negated: Option<Set>,
+ selected: Option<GlobSet>,
+ negated: Option<GlobSet>,
has_selected: bool,
defs: Vec<FileTypeDef>,
) -> Types {
@@ -272,7 +272,7 @@ impl TypesBuilder {
if self.selected.is_empty() {
None
} else {
- let mut bset = SetBuilder::new();
+ let mut bset = GlobSetBuilder::new();
for name in &self.selected {
let globs = match self.types.get(name) {
Some(globs) => globs,
@@ -283,7 +283,7 @@ impl TypesBuilder {
};
for glob in globs {
let pat = try!(
- PatternBuilder::new(glob)
+ GlobBuilder::new(glob)
.literal_separator(true).build());
bset.add(pat);
}
@@ -294,7 +294,7 @@ impl TypesBuilder {
if self.negated.is_empty() {
None
} else {
- let mut bset = SetBuilder::new();
+ let mut bset = GlobSetBuilder::new();
for name in &self.negated {
let globs = match self.types.get(name) {
Some(globs) => globs,
@@ -305,7 +305,7 @@ impl TypesBuilder {
};
for glob in globs {
let pat = try!(
- PatternBuilder::new(glob)
+ GlobBuilder::new(glob)
.literal_separator(true).build());
bset.add(pat);
}