ignore: polish

Like previous commits, we do a bit of polishing and bring the style up
to my current practice.
This commit is contained in:
Andrew Gallant 2023-09-28 14:17:30 -04:00
parent be9e308999
commit f16ea0812d
12 changed files with 215 additions and 220 deletions

1
Cargo.lock generated
View File

@ -239,6 +239,7 @@ dependencies = [
name = "ignore" name = "ignore"
version = "0.4.20" version = "0.4.20"
dependencies = [ dependencies = [
"bstr",
"crossbeam-channel", "crossbeam-channel",
"crossbeam-deque", "crossbeam-deque",
"globset", "globset",

View File

@ -42,5 +42,7 @@ serde_json = "1.0.107"
[features] [features]
default = ["log"] default = ["log"]
# DEPRECATED. It is a no-op. SIMD is done automatically through runtime
# dispatch.
simd-accel = [] simd-accel = []
serde1 = ["serde"] serde1 = ["serde"]

View File

@ -12,7 +12,7 @@ repository = "https://github.com/BurntSushi/ripgrep/tree/master/crates/ignore"
readme = "README.md" readme = "README.md"
keywords = ["glob", "ignore", "gitignore", "pattern", "file"] keywords = ["glob", "ignore", "gitignore", "pattern", "file"]
license = "Unlicense OR MIT" license = "Unlicense OR MIT"
edition = "2018" edition = "2021"
[lib] [lib]
name = "ignore" name = "ignore"
@ -22,18 +22,21 @@ bench = false
crossbeam-deque = "0.8.3" crossbeam-deque = "0.8.3"
globset = { version = "0.4.10", path = "../globset" } globset = { version = "0.4.10", path = "../globset" }
lazy_static = "1.1" lazy_static = "1.1"
log = "0.4.5" log = "0.4.20"
memchr = "2.5" memchr = "2.6.3"
regex = { version = "1.9.0", default-features = false, features = ["perf", "std", "unicode-gencat"] } regex = { version = "1.9.5", default-features = false, features = ["perf", "std", "unicode-gencat"] }
same-file = "1.0.4" same-file = "1.0.6"
thread_local = "1" thread_local = "1"
walkdir = "2.2.7" walkdir = "2.4.0"
[target.'cfg(windows)'.dependencies.winapi-util] [target.'cfg(windows)'.dependencies.winapi-util]
version = "0.1.2" version = "0.1.2"
[dev-dependencies] [dev-dependencies]
crossbeam-channel = "0.5.0" bstr = { version = "1.6.2", default-features = false, features = ["std"] }
crossbeam-channel = "0.5.8"
[features] [features]
simd-accel = ["globset/simd-accel"] # DEPRECATED. It is a no-op. SIMD is done automatically through runtime
# dispatch.
simd-accel = []

View File

@ -1,10 +1,6 @@
use std::env; use std::{env, io::Write, path::Path};
use std::io::{self, Write};
use std::path::Path;
use std::thread;
use ignore::WalkBuilder; use {bstr::ByteVec, ignore::WalkBuilder, walkdir::WalkDir};
use walkdir::WalkDir;
fn main() { fn main() {
let mut path = env::args().nth(1).unwrap(); let mut path = env::args().nth(1).unwrap();
@ -19,10 +15,11 @@ fn main() {
simple = true; simple = true;
} }
let stdout_thread = thread::spawn(move || { let stdout_thread = std::thread::spawn(move || {
let mut stdout = io::BufWriter::new(io::stdout()); let mut stdout = std::io::BufWriter::new(std::io::stdout());
for dent in rx { for dent in rx {
write_path(&mut stdout, dent.path()); stdout.write(&*Vec::from_path_lossy(dent.path())).unwrap();
stdout.write(b"\n").unwrap();
} }
}); });
@ -65,16 +62,3 @@ impl DirEntry {
} }
} }
} }
#[cfg(unix)]
fn write_path<W: Write>(mut wtr: W, path: &Path) {
use std::os::unix::ffi::OsStrExt;
wtr.write(path.as_os_str().as_bytes()).unwrap();
wtr.write(b"\n").unwrap();
}
#[cfg(not(unix))]
fn write_path<W: Write>(mut wtr: W, path: &Path) {
wtr.write(path.to_string_lossy().as_bytes()).unwrap();
wtr.write(b"\n").unwrap();
}

View File

@ -9,7 +9,7 @@
/// Please try to keep this list sorted lexicographically and wrapped to 79 /// Please try to keep this list sorted lexicographically and wrapped to 79
/// columns (inclusive). /// columns (inclusive).
#[rustfmt::skip] #[rustfmt::skip]
pub const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[ pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
(&["ada"], &["*.adb", "*.ads"]), (&["ada"], &["*.adb", "*.ads"]),
(&["agda"], &["*.agda", "*.lagda"]), (&["agda"], &["*.agda", "*.lagda"]),
(&["aidl"], &["*.aidl"]), (&["aidl"], &["*.aidl"]),

View File

@ -13,24 +13,28 @@
// with non-obvious failure modes. Alas, such things haven't been documented // with non-obvious failure modes. Alas, such things haven't been documented
// well. // well.
use std::collections::HashMap; use std::{
use std::ffi::{OsStr, OsString}; collections::HashMap,
use std::fs::{File, FileType}; ffi::{OsStr, OsString},
use std::io::{self, BufRead}; fs::{File, FileType},
use std::path::{Path, PathBuf}; io::{self, BufRead},
use std::sync::{Arc, RwLock}; path::{Path, PathBuf},
sync::{Arc, RwLock},
};
use crate::gitignore::{self, Gitignore, GitignoreBuilder}; use crate::{
use crate::overrides::{self, Override}; gitignore::{self, Gitignore, GitignoreBuilder},
use crate::pathutil::{is_hidden, strip_prefix}; overrides::{self, Override},
use crate::types::{self, Types}; pathutil::{is_hidden, strip_prefix},
use crate::walk::DirEntry; types::{self, Types},
use crate::{Error, Match, PartialErrorBuilder}; walk::DirEntry,
{Error, Match, PartialErrorBuilder},
};
/// IgnoreMatch represents information about where a match came from when using /// IgnoreMatch represents information about where a match came from when using
/// the `Ignore` matcher. /// the `Ignore` matcher.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct IgnoreMatch<'a>(IgnoreMatchInner<'a>); pub(crate) struct IgnoreMatch<'a>(IgnoreMatchInner<'a>);
/// IgnoreMatchInner describes precisely where the match information came from. /// IgnoreMatchInner describes precisely where the match information came from.
/// This is private to allow expansion to more matchers in the future. /// This is private to allow expansion to more matchers in the future.
@ -85,7 +89,7 @@ struct IgnoreOptions {
/// Ignore is a matcher useful for recursively walking one or more directories. /// Ignore is a matcher useful for recursively walking one or more directories.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Ignore(Arc<IgnoreInner>); pub(crate) struct Ignore(Arc<IgnoreInner>);
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct IgnoreInner { struct IgnoreInner {
@ -134,22 +138,22 @@ struct IgnoreInner {
impl Ignore { impl Ignore {
/// Return the directory path of this matcher. /// Return the directory path of this matcher.
pub fn path(&self) -> &Path { pub(crate) fn path(&self) -> &Path {
&self.0.dir &self.0.dir
} }
/// Return true if this matcher has no parent. /// Return true if this matcher has no parent.
pub fn is_root(&self) -> bool { pub(crate) fn is_root(&self) -> bool {
self.0.parent.is_none() self.0.parent.is_none()
} }
/// Returns true if this matcher was added via the `add_parents` method. /// Returns true if this matcher was added via the `add_parents` method.
pub fn is_absolute_parent(&self) -> bool { pub(crate) fn is_absolute_parent(&self) -> bool {
self.0.is_absolute_parent self.0.is_absolute_parent
} }
/// Return this matcher's parent, if one exists. /// Return this matcher's parent, if one exists.
pub fn parent(&self) -> Option<Ignore> { pub(crate) fn parent(&self) -> Option<Ignore> {
self.0.parent.clone() self.0.parent.clone()
} }
@ -157,7 +161,7 @@ impl Ignore {
/// ///
/// Note that this can only be called on an `Ignore` matcher with no /// Note that this can only be called on an `Ignore` matcher with no
/// parents (i.e., `is_root` returns `true`). This will panic otherwise. /// parents (i.e., `is_root` returns `true`). This will panic otherwise.
pub fn add_parents<P: AsRef<Path>>( pub(crate) fn add_parents<P: AsRef<Path>>(
&self, &self,
path: P, path: P,
) -> (Ignore, Option<Error>) { ) -> (Ignore, Option<Error>) {
@ -222,7 +226,7 @@ impl Ignore {
/// returned if it exists. /// returned if it exists.
/// ///
/// Note that all I/O errors are completely ignored. /// Note that all I/O errors are completely ignored.
pub fn add_child<P: AsRef<Path>>( pub(crate) fn add_child<P: AsRef<Path>>(
&self, &self,
dir: P, dir: P,
) -> (Ignore, Option<Error>) { ) -> (Ignore, Option<Error>) {
@ -335,7 +339,7 @@ impl Ignore {
} }
/// Like `matched`, but works with a directory entry instead. /// Like `matched`, but works with a directory entry instead.
pub fn matched_dir_entry<'a>( pub(crate) fn matched_dir_entry<'a>(
&'a self, &'a self,
dent: &DirEntry, dent: &DirEntry,
) -> Match<IgnoreMatch<'a>> { ) -> Match<IgnoreMatch<'a>> {
@ -520,7 +524,7 @@ impl Ignore {
} }
/// Returns an iterator over parent ignore matchers, including this one. /// Returns an iterator over parent ignore matchers, including this one.
pub fn parents(&self) -> Parents<'_> { pub(crate) fn parents(&self) -> Parents<'_> {
Parents(Some(self)) Parents(Some(self))
} }
@ -534,7 +538,7 @@ impl Ignore {
/// An iterator over all parents of an ignore matcher, including itself. /// An iterator over all parents of an ignore matcher, including itself.
/// ///
/// The lifetime `'a` refers to the lifetime of the initial `Ignore` matcher. /// The lifetime `'a` refers to the lifetime of the initial `Ignore` matcher.
pub struct Parents<'a>(Option<&'a Ignore>); pub(crate) struct Parents<'a>(Option<&'a Ignore>);
impl<'a> Iterator for Parents<'a> { impl<'a> Iterator for Parents<'a> {
type Item = &'a Ignore; type Item = &'a Ignore;
@ -552,7 +556,7 @@ impl<'a> Iterator for Parents<'a> {
/// A builder for creating an Ignore matcher. /// A builder for creating an Ignore matcher.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct IgnoreBuilder { pub(crate) struct IgnoreBuilder {
/// The root directory path for this ignore matcher. /// The root directory path for this ignore matcher.
dir: PathBuf, dir: PathBuf,
/// An override matcher (default is empty). /// An override matcher (default is empty).
@ -572,7 +576,7 @@ impl IgnoreBuilder {
/// ///
/// All relative file paths are resolved with respect to the current /// All relative file paths are resolved with respect to the current
/// working directory. /// working directory.
pub fn new() -> IgnoreBuilder { pub(crate) fn new() -> IgnoreBuilder {
IgnoreBuilder { IgnoreBuilder {
dir: Path::new("").to_path_buf(), dir: Path::new("").to_path_buf(),
overrides: Arc::new(Override::empty()), overrides: Arc::new(Override::empty()),
@ -596,7 +600,7 @@ impl IgnoreBuilder {
/// ///
/// The matcher returned won't match anything until ignore rules from /// The matcher returned won't match anything until ignore rules from
/// directories are added to it. /// directories are added to it.
pub fn build(&self) -> Ignore { pub(crate) fn build(&self) -> Ignore {
let git_global_matcher = if !self.opts.git_global { let git_global_matcher = if !self.opts.git_global {
Gitignore::empty() Gitignore::empty()
} else { } else {
@ -638,7 +642,10 @@ impl IgnoreBuilder {
/// By default, no override matcher is used. /// By default, no override matcher is used.
/// ///
/// This overrides any previous setting. /// This overrides any previous setting.
pub fn overrides(&mut self, overrides: Override) -> &mut IgnoreBuilder { pub(crate) fn overrides(
&mut self,
overrides: Override,
) -> &mut IgnoreBuilder {
self.overrides = Arc::new(overrides); self.overrides = Arc::new(overrides);
self self
} }
@ -648,13 +655,13 @@ impl IgnoreBuilder {
/// By default, no file type matcher is used. /// By default, no file type matcher is used.
/// ///
/// This overrides any previous setting. /// This overrides any previous setting.
pub fn types(&mut self, types: Types) -> &mut IgnoreBuilder { pub(crate) fn types(&mut self, types: Types) -> &mut IgnoreBuilder {
self.types = Arc::new(types); self.types = Arc::new(types);
self self
} }
/// Adds a new global ignore matcher from the ignore file path given. /// Adds a new global ignore matcher from the ignore file path given.
pub fn add_ignore(&mut self, ig: Gitignore) -> &mut IgnoreBuilder { pub(crate) fn add_ignore(&mut self, ig: Gitignore) -> &mut IgnoreBuilder {
self.explicit_ignores.push(ig); self.explicit_ignores.push(ig);
self self
} }
@ -665,7 +672,7 @@ impl IgnoreBuilder {
/// ///
/// When specifying multiple names, earlier names have lower precedence than /// When specifying multiple names, earlier names have lower precedence than
/// later names. /// later names.
pub fn add_custom_ignore_filename<S: AsRef<OsStr>>( pub(crate) fn add_custom_ignore_filename<S: AsRef<OsStr>>(
&mut self, &mut self,
file_name: S, file_name: S,
) -> &mut IgnoreBuilder { ) -> &mut IgnoreBuilder {
@ -676,7 +683,7 @@ impl IgnoreBuilder {
/// Enables ignoring hidden files. /// Enables ignoring hidden files.
/// ///
/// This is enabled by default. /// This is enabled by default.
pub fn hidden(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn hidden(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.hidden = yes; self.opts.hidden = yes;
self self
} }
@ -687,7 +694,7 @@ impl IgnoreBuilder {
/// supported by search tools such as ripgrep and The Silver Searcher. /// supported by search tools such as ripgrep and The Silver Searcher.
/// ///
/// This is enabled by default. /// This is enabled by default.
pub fn ignore(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.ignore = yes; self.opts.ignore = yes;
self self
} }
@ -698,7 +705,7 @@ impl IgnoreBuilder {
/// file path given are respected. Otherwise, they are ignored. /// file path given are respected. Otherwise, they are ignored.
/// ///
/// This is enabled by default. /// This is enabled by default.
pub fn parents(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn parents(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.parents = yes; self.opts.parents = yes;
self self
} }
@ -711,7 +718,7 @@ impl IgnoreBuilder {
/// This overwrites any previous global gitignore setting. /// This overwrites any previous global gitignore setting.
/// ///
/// This is enabled by default. /// This is enabled by default.
pub fn git_global(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn git_global(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.git_global = yes; self.opts.git_global = yes;
self self
} }
@ -722,7 +729,7 @@ impl IgnoreBuilder {
/// man page. /// man page.
/// ///
/// This is enabled by default. /// This is enabled by default.
pub fn git_ignore(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn git_ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.git_ignore = yes; self.opts.git_ignore = yes;
self self
} }
@ -733,7 +740,7 @@ impl IgnoreBuilder {
/// `gitignore` man page. /// `gitignore` man page.
/// ///
/// This is enabled by default. /// This is enabled by default.
pub fn git_exclude(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn git_exclude(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.git_exclude = yes; self.opts.git_exclude = yes;
self self
} }
@ -743,7 +750,7 @@ impl IgnoreBuilder {
/// ///
/// When disabled, git-related ignore rules are applied even when searching /// When disabled, git-related ignore rules are applied even when searching
/// outside a git repository. /// outside a git repository.
pub fn require_git(&mut self, yes: bool) -> &mut IgnoreBuilder { pub(crate) fn require_git(&mut self, yes: bool) -> &mut IgnoreBuilder {
self.opts.require_git = yes; self.opts.require_git = yes;
self self
} }
@ -751,7 +758,7 @@ impl IgnoreBuilder {
/// Process ignore files case insensitively /// Process ignore files case insensitively
/// ///
/// This is disabled by default. /// This is disabled by default.
pub fn ignore_case_insensitive( pub(crate) fn ignore_case_insensitive(
&mut self, &mut self,
yes: bool, yes: bool,
) -> &mut IgnoreBuilder { ) -> &mut IgnoreBuilder {
@ -768,7 +775,7 @@ impl IgnoreBuilder {
/// precedence than later names). /// precedence than later names).
/// ///
/// I/O errors are ignored. /// I/O errors are ignored.
pub fn create_gitignore<T: AsRef<OsStr>>( pub(crate) fn create_gitignore<T: AsRef<OsStr>>(
dir: &Path, dir: &Path,
dir_for_ignorefile: &Path, dir_for_ignorefile: &Path,
names: &[T], names: &[T],
@ -861,22 +868,19 @@ fn resolve_git_commondir(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::fs::{self, File}; use std::{io::Write, path::Path};
use std::io::Write;
use std::path::Path;
use crate::dir::IgnoreBuilder; use crate::{
use crate::gitignore::Gitignore; dir::IgnoreBuilder, gitignore::Gitignore, tests::TempDir, Error,
use crate::tests::TempDir; };
use crate::Error;
fn wfile<P: AsRef<Path>>(path: P, contents: &str) { fn wfile<P: AsRef<Path>>(path: P, contents: &str) {
let mut file = File::create(path).unwrap(); let mut file = std::fs::File::create(path).unwrap();
file.write_all(contents.as_bytes()).unwrap(); file.write_all(contents.as_bytes()).unwrap();
} }
fn mkdirp<P: AsRef<Path>>(path: P) { fn mkdirp<P: AsRef<Path>>(path: P) {
fs::create_dir_all(path).unwrap(); std::fs::create_dir_all(path).unwrap();
} }
fn partial(err: Error) -> Vec<Error> { fn partial(err: Error) -> Vec<Error> {
@ -1193,7 +1197,7 @@ mod tests {
assert!(ignore.matched("ignore_me", false).is_ignore()); assert!(ignore.matched("ignore_me", false).is_ignore());
// missing commondir file // missing commondir file
assert!(fs::remove_file(commondir_path()).is_ok()); assert!(std::fs::remove_file(commondir_path()).is_ok());
let (_, err) = ib.add_child(td.path().join("linked-worktree")); let (_, err) = ib.add_child(td.path().join("linked-worktree"));
// We squash the error in this case, because it occurs in repositories // We squash the error in this case, because it occurs in repositories
// that are not linked worktrees but have submodules. // that are not linked worktrees but have submodules.

View File

@ -7,20 +7,24 @@ Note that this module implements the specification as described in the
the `git` command line tool. the `git` command line tool.
*/ */
use std::cell::RefCell; use std::{
use std::env; cell::RefCell,
use std::fs::File; fs::File,
use std::io::{self, BufRead, Read}; io::{BufRead, BufReader, Read},
use std::path::{Path, PathBuf}; path::{Path, PathBuf},
use std::str; sync::Arc,
use std::sync::Arc; };
use globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder}; use {
use regex::bytes::Regex; globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder},
use thread_local::ThreadLocal; regex::bytes::Regex,
thread_local::ThreadLocal,
};
use crate::pathutil::{is_file_name, strip_prefix}; use crate::{
use crate::{Error, Match, PartialErrorBuilder}; pathutil::{is_file_name, strip_prefix},
Error, Match, PartialErrorBuilder,
};
/// Glob represents a single glob in a gitignore file. /// Glob represents a single glob in a gitignore file.
/// ///
@ -337,7 +341,7 @@ impl GitignoreBuilder {
.build() .build()
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?; .map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
Ok(Gitignore { Ok(Gitignore {
set: set, set,
root: self.root.clone(), root: self.root.clone(),
globs: self.globs.clone(), globs: self.globs.clone(),
num_ignores: nignore as u64, num_ignores: nignore as u64,
@ -389,7 +393,7 @@ impl GitignoreBuilder {
Err(err) => return Some(Error::Io(err).with_path(path)), Err(err) => return Some(Error::Io(err).with_path(path)),
Ok(file) => file, Ok(file) => file,
}; };
let rdr = io::BufReader::new(file); let rdr = BufReader::new(file);
let mut errs = PartialErrorBuilder::default(); let mut errs = PartialErrorBuilder::default();
for (i, line) in rdr.lines().enumerate() { for (i, line) in rdr.lines().enumerate() {
let lineno = (i + 1) as u64; let lineno = (i + 1) as u64;
@ -448,7 +452,7 @@ impl GitignoreBuilder {
return Ok(self); return Ok(self);
} }
let mut glob = Glob { let mut glob = Glob {
from: from, from,
original: line.to_string(), original: line.to_string(),
actual: String::new(), actual: String::new(),
is_whitelist: false, is_whitelist: false,
@ -558,7 +562,7 @@ fn gitconfig_home_contents() -> Option<Vec<u8>> {
}; };
let mut file = match File::open(home.join(".gitconfig")) { let mut file = match File::open(home.join(".gitconfig")) {
Err(_) => return None, Err(_) => return None,
Ok(file) => io::BufReader::new(file), Ok(file) => BufReader::new(file),
}; };
let mut contents = vec![]; let mut contents = vec![];
file.read_to_end(&mut contents).ok().map(|_| contents) file.read_to_end(&mut contents).ok().map(|_| contents)
@ -567,13 +571,13 @@ fn gitconfig_home_contents() -> Option<Vec<u8>> {
/// Returns the file contents of git's global config file, if one exists, in /// Returns the file contents of git's global config file, if one exists, in
/// the user's XDG_CONFIG_HOME directory. /// the user's XDG_CONFIG_HOME directory.
fn gitconfig_xdg_contents() -> Option<Vec<u8>> { fn gitconfig_xdg_contents() -> Option<Vec<u8>> {
let path = env::var_os("XDG_CONFIG_HOME") let path = std::env::var_os("XDG_CONFIG_HOME")
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) }) .and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
.or_else(|| home_dir().map(|p| p.join(".config"))) .or_else(|| home_dir().map(|p| p.join(".config")))
.map(|x| x.join("git/config")); .map(|x| x.join("git/config"));
let mut file = match path.and_then(|p| File::open(p).ok()) { let mut file = match path.and_then(|p| File::open(p).ok()) {
None => return None, None => return None,
Some(file) => io::BufReader::new(file), Some(file) => BufReader::new(file),
}; };
let mut contents = vec![]; let mut contents = vec![];
file.read_to_end(&mut contents).ok().map(|_| contents) file.read_to_end(&mut contents).ok().map(|_| contents)
@ -583,7 +587,7 @@ fn gitconfig_xdg_contents() -> Option<Vec<u8>> {
/// ///
/// Specifically, this respects XDG_CONFIG_HOME. /// Specifically, this respects XDG_CONFIG_HOME.
fn excludes_file_default() -> Option<PathBuf> { fn excludes_file_default() -> Option<PathBuf> {
env::var_os("XDG_CONFIG_HOME") std::env::var_os("XDG_CONFIG_HOME")
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) }) .and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
.or_else(|| home_dir().map(|p| p.join(".config"))) .or_else(|| home_dir().map(|p| p.join(".config")))
.map(|x| x.join("git/ignore")) .map(|x| x.join("git/ignore"))
@ -608,7 +612,7 @@ fn parse_excludes_file(data: &[u8]) -> Option<PathBuf> {
None => return None, None => return None,
Some(caps) => caps, Some(caps) => caps,
}; };
str::from_utf8(&caps[1]).ok().map(|s| PathBuf::from(expand_tilde(s))) std::str::from_utf8(&caps[1]).ok().map(|s| PathBuf::from(expand_tilde(s)))
} }
/// Expands ~ in file paths to the value of $HOME. /// Expands ~ in file paths to the value of $HOME.
@ -622,18 +626,18 @@ fn expand_tilde(path: &str) -> String {
/// Returns the location of the user's home directory. /// Returns the location of the user's home directory.
fn home_dir() -> Option<PathBuf> { fn home_dir() -> Option<PathBuf> {
// We're fine with using env::home_dir for now. Its bugs are, IMO, pretty // We're fine with using std::env::home_dir for now. Its bugs are, IMO,
// minor corner cases. We should still probably eventually migrate to // pretty minor corner cases.
// the `dirs` crate to get a proper implementation.
#![allow(deprecated)] #![allow(deprecated)]
env::home_dir() std::env::home_dir()
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Gitignore, GitignoreBuilder};
use std::path::Path; use std::path::Path;
use super::{Gitignore, GitignoreBuilder};
fn gi_from_str<P: AsRef<Path>>(root: P, s: &str) -> Gitignore { fn gi_from_str<P: AsRef<Path>>(root: P, s: &str) -> Gitignore {
let mut builder = GitignoreBuilder::new(root); let mut builder = GitignoreBuilder::new(root);
builder.add_str(None, s).unwrap(); builder.add_str(None, s).unwrap();

View File

@ -46,9 +46,6 @@ See the documentation for `WalkBuilder` for many other options.
#![deny(missing_docs)] #![deny(missing_docs)]
use std::error;
use std::fmt;
use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub use crate::walk::{ pub use crate::walk::{
@ -101,7 +98,7 @@ pub enum Error {
child: PathBuf, child: PathBuf,
}, },
/// An error that occurs when doing I/O, such as reading an ignore file. /// An error that occurs when doing I/O, such as reading an ignore file.
Io(io::Error), Io(std::io::Error),
/// An error that occurs when trying to parse a glob. /// An error that occurs when trying to parse a glob.
Glob { Glob {
/// The original glob that caused this error. This glob, when /// The original glob that caused this error. This glob, when
@ -125,21 +122,23 @@ impl Clone for Error {
match *self { match *self {
Error::Partial(ref errs) => Error::Partial(errs.clone()), Error::Partial(ref errs) => Error::Partial(errs.clone()),
Error::WithLineNumber { line, ref err } => { Error::WithLineNumber { line, ref err } => {
Error::WithLineNumber { line: line, err: err.clone() } Error::WithLineNumber { line, err: err.clone() }
} }
Error::WithPath { ref path, ref err } => { Error::WithPath { ref path, ref err } => {
Error::WithPath { path: path.clone(), err: err.clone() } Error::WithPath { path: path.clone(), err: err.clone() }
} }
Error::WithDepth { depth, ref err } => { Error::WithDepth { depth, ref err } => {
Error::WithDepth { depth: depth, err: err.clone() } Error::WithDepth { depth, err: err.clone() }
} }
Error::Loop { ref ancestor, ref child } => Error::Loop { Error::Loop { ref ancestor, ref child } => Error::Loop {
ancestor: ancestor.clone(), ancestor: ancestor.clone(),
child: child.clone(), child: child.clone(),
}, },
Error::Io(ref err) => match err.raw_os_error() { Error::Io(ref err) => match err.raw_os_error() {
Some(e) => Error::Io(io::Error::from_raw_os_error(e)), Some(e) => Error::Io(std::io::Error::from_raw_os_error(e)),
None => Error::Io(io::Error::new(err.kind(), err.to_string())), None => {
Error::Io(std::io::Error::new(err.kind(), err.to_string()))
}
}, },
Error::Glob { ref glob, ref err } => { Error::Glob { ref glob, ref err } => {
Error::Glob { glob: glob.clone(), err: err.clone() } Error::Glob { glob: glob.clone(), err: err.clone() }
@ -183,22 +182,22 @@ impl Error {
} }
} }
/// Inspect the original [`io::Error`] if there is one. /// Inspect the original [`std::io::Error`] if there is one.
/// ///
/// [`None`] is returned if the [`Error`] doesn't correspond to an /// [`None`] is returned if the [`Error`] doesn't correspond to an
/// [`io::Error`]. This might happen, for example, when the error was /// [`std::io::Error`]. This might happen, for example, when the error was
/// produced because a cycle was found in the directory tree while /// produced because a cycle was found in the directory tree while
/// following symbolic links. /// following symbolic links.
/// ///
/// This method returns a borrowed value that is bound to the lifetime of the [`Error`]. To /// This method returns a borrowed value that is bound to the lifetime of the [`Error`]. To
/// obtain an owned value, the [`into_io_error`] can be used instead. /// obtain an owned value, the [`into_io_error`] can be used instead.
/// ///
/// > This is the original [`io::Error`] and is _not_ the same as /// > This is the original [`std::io::Error`] and is _not_ the same as
/// > [`impl From<Error> for std::io::Error`][impl] which contains additional context about the /// > [`impl From<Error> for std::io::Error`][impl] which contains
/// error. /// > additional context about the error.
/// ///
/// [`None`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#variant.None /// [`None`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#variant.None
/// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html /// [`std::io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
/// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html /// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
/// [`Error`]: struct.Error.html /// [`Error`]: struct.Error.html
/// [`into_io_error`]: struct.Error.html#method.into_io_error /// [`into_io_error`]: struct.Error.html#method.into_io_error
@ -224,10 +223,10 @@ impl Error {
} }
/// Similar to [`io_error`] except consumes self to convert to the original /// Similar to [`io_error`] except consumes self to convert to the original
/// [`io::Error`] if one exists. /// [`std::io::Error`] if one exists.
/// ///
/// [`io_error`]: struct.Error.html#method.io_error /// [`io_error`]: struct.Error.html#method.io_error
/// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html /// [`std::io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
pub fn into_io_error(self) -> Option<std::io::Error> { pub fn into_io_error(self) -> Option<std::io::Error> {
match self { match self {
Error::Partial(mut errs) => { Error::Partial(mut errs) => {
@ -268,7 +267,7 @@ impl Error {
/// Turn an error into a tagged error with the given depth. /// Turn an error into a tagged error with the given depth.
fn with_depth(self, depth: usize) -> Error { fn with_depth(self, depth: usize) -> Error {
Error::WithDepth { depth: depth, err: Box::new(self) } Error::WithDepth { depth, err: Box::new(self) }
} }
/// Turn an error into a tagged error with the given file path and line /// Turn an error into a tagged error with the given file path and line
@ -287,7 +286,7 @@ impl Error {
let depth = err.depth(); let depth = err.depth();
if let (Some(anc), Some(child)) = (err.loop_ancestor(), err.path()) { if let (Some(anc), Some(child)) = (err.loop_ancestor(), err.path()) {
return Error::WithDepth { return Error::WithDepth {
depth: depth, depth,
err: Box::new(Error::Loop { err: Box::new(Error::Loop {
ancestor: anc.to_path_buf(), ancestor: anc.to_path_buf(),
child: child.to_path_buf(), child: child.to_path_buf(),
@ -295,15 +294,15 @@ impl Error {
}; };
} }
let path = err.path().map(|p| p.to_path_buf()); let path = err.path().map(|p| p.to_path_buf());
let mut ig_err = Error::Io(io::Error::from(err)); let mut ig_err = Error::Io(std::io::Error::from(err));
if let Some(path) = path { if let Some(path) = path {
ig_err = Error::WithPath { path: path, err: Box::new(ig_err) }; ig_err = Error::WithPath { path, err: Box::new(ig_err) };
} }
ig_err ig_err
} }
} }
impl error::Error for Error { impl std::error::Error for Error {
#[allow(deprecated)] #[allow(deprecated)]
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { match *self {
@ -320,8 +319,8 @@ impl error::Error for Error {
} }
} }
impl fmt::Display for Error { impl std::fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self { match *self {
Error::Partial(ref errs) => { Error::Partial(ref errs) => {
let msgs: Vec<String> = let msgs: Vec<String> =
@ -359,8 +358,8 @@ impl fmt::Display for Error {
} }
} }
impl From<io::Error> for Error { impl From<std::io::Error> for Error {
fn from(err: io::Error) -> Error { fn from(err: std::io::Error) -> Error {
Error::Io(err) Error::Io(err)
} }
} }
@ -488,19 +487,18 @@ impl<T> Match<T> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::env; use std::{
use std::error; env, fs,
use std::fs; path::{Path, PathBuf},
use std::path::{Path, PathBuf}; };
use std::result;
/// A convenient result type alias. /// A convenient result type alias.
pub type Result<T> = pub(crate) type Result<T> =
result::Result<T, Box<dyn error::Error + Send + Sync>>; std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
macro_rules! err { macro_rules! err {
($($tt:tt)*) => { ($($tt:tt)*) => {
Box::<dyn error::Error + Send + Sync>::from(format!($($tt)*)) Box::<dyn std::error::Error + Send + Sync>::from(format!($($tt)*))
} }
} }

View File

@ -6,8 +6,10 @@ line tools.
use std::path::Path; use std::path::Path;
use crate::gitignore::{self, Gitignore, GitignoreBuilder}; use crate::{
use crate::{Error, Match}; gitignore::{self, Gitignore, GitignoreBuilder},
Error, Match,
};
/// Glob represents a single glob in an override matcher. /// Glob represents a single glob in an override matcher.
/// ///

View File

@ -1,5 +1,4 @@
use std::ffi::OsStr; use std::{ffi::OsStr, path::Path};
use std::path::Path;
use crate::walk::DirEntry; use crate::walk::DirEntry;
@ -9,7 +8,7 @@ use crate::walk::DirEntry;
/// ///
/// On Unix, this implements a more optimized check. /// On Unix, this implements a more optimized check.
#[cfg(unix)] #[cfg(unix)]
pub fn is_hidden(dent: &DirEntry) -> bool { pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
if let Some(name) = file_name(dent.path()) { if let Some(name) = file_name(dent.path()) {
@ -26,7 +25,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
/// * The base name of the path starts with a `.`. /// * The base name of the path starts with a `.`.
/// * The file attributes have the `HIDDEN` property set. /// * The file attributes have the `HIDDEN` property set.
#[cfg(windows)] #[cfg(windows)]
pub fn is_hidden(dent: &DirEntry) -> bool { pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
use std::os::windows::fs::MetadataExt; use std::os::windows::fs::MetadataExt;
use winapi_util::file; use winapi_util::file;
@ -49,7 +48,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
/// ///
/// This only returns true if the base name of the path starts with a `.`. /// This only returns true if the base name of the path starts with a `.`.
#[cfg(not(any(unix, windows)))] #[cfg(not(any(unix, windows)))]
pub fn is_hidden(dent: &DirEntry) -> bool { pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
if let Some(name) = file_name(dent.path()) { if let Some(name) = file_name(dent.path()) {
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false) name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
} else { } else {
@ -61,7 +60,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
/// ///
/// If `path` doesn't have a prefix `prefix`, then return `None`. /// If `path` doesn't have a prefix `prefix`, then return `None`.
#[cfg(unix)] #[cfg(unix)]
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>( pub(crate) fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
prefix: &'a P, prefix: &'a P,
path: &'a Path, path: &'a Path,
) -> Option<&'a Path> { ) -> Option<&'a Path> {
@ -80,7 +79,7 @@ pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
/// ///
/// If `path` doesn't have a prefix `prefix`, then return `None`. /// If `path` doesn't have a prefix `prefix`, then return `None`.
#[cfg(not(unix))] #[cfg(not(unix))]
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>( pub(crate) fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
prefix: &'a P, prefix: &'a P,
path: &'a Path, path: &'a Path,
) -> Option<&'a Path> { ) -> Option<&'a Path> {
@ -90,10 +89,11 @@ pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
/// Returns true if this file path is just a file name. i.e., Its parent is /// Returns true if this file path is just a file name. i.e., Its parent is
/// the empty string. /// the empty string.
#[cfg(unix)] #[cfg(unix)]
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool { pub(crate) fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
use memchr::memchr;
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
use memchr::memchr;
let path = path.as_ref().as_os_str().as_bytes(); let path = path.as_ref().as_os_str().as_bytes();
memchr(b'/', path).is_none() memchr(b'/', path).is_none()
} }
@ -101,7 +101,7 @@ pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
/// Returns true if this file path is just a file name. i.e., Its parent is /// Returns true if this file path is just a file name. i.e., Its parent is
/// the empty string. /// the empty string.
#[cfg(not(unix))] #[cfg(not(unix))]
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool { pub(crate) fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
path.as_ref().parent().map(|p| p.as_os_str().is_empty()).unwrap_or(false) path.as_ref().parent().map(|p| p.as_os_str().is_empty()).unwrap_or(false)
} }
@ -110,7 +110,7 @@ pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
/// If the path terminates in ., .., or consists solely of a root of prefix, /// If the path terminates in ., .., or consists solely of a root of prefix,
/// file_name will return None. /// file_name will return None.
#[cfg(unix)] #[cfg(unix)]
pub fn file_name<'a, P: AsRef<Path> + ?Sized>( pub(crate) fn file_name<'a, P: AsRef<Path> + ?Sized>(
path: &'a P, path: &'a P,
) -> Option<&'a OsStr> { ) -> Option<&'a OsStr> {
use memchr::memrchr; use memchr::memrchr;
@ -135,7 +135,7 @@ pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
/// If the path terminates in ., .., or consists solely of a root of prefix, /// If the path terminates in ., .., or consists solely of a root of prefix,
/// file_name will return None. /// file_name will return None.
#[cfg(not(unix))] #[cfg(not(unix))]
pub fn file_name<'a, P: AsRef<Path> + ?Sized>( pub(crate) fn file_name<'a, P: AsRef<Path> + ?Sized>(
path: &'a P, path: &'a P,
) -> Option<&'a OsStr> { ) -> Option<&'a OsStr> {
path.as_ref().file_name() path.as_ref().file_name()

View File

@ -84,18 +84,15 @@ assert!(matcher.matched("y.cpp", false).is_whitelist());
``` ```
*/ */
use std::cell::RefCell; use std::{cell::RefCell, collections::HashMap, path::Path, sync::Arc};
use std::collections::HashMap;
use std::path::Path;
use std::sync::Arc;
use globset::{GlobBuilder, GlobSet, GlobSetBuilder}; use {
use regex::Regex; globset::{GlobBuilder, GlobSet, GlobSetBuilder},
use thread_local::ThreadLocal; regex::Regex,
thread_local::ThreadLocal,
};
use crate::default_types::DEFAULT_TYPES; use crate::{default_types::DEFAULT_TYPES, pathutil::file_name, Error, Match};
use crate::pathutil::file_name;
use crate::{Error, Match};
/// Glob represents a single glob in a set of file type definitions. /// Glob represents a single glob in a set of file type definitions.
/// ///
@ -356,11 +353,11 @@ impl TypesBuilder {
.build() .build()
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?; .map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
Ok(Types { Ok(Types {
defs: defs, defs,
selections: selections, selections,
has_selected: has_selected, has_selected,
glob_to_selection: glob_to_selection, glob_to_selection,
set: set, set,
matches: Arc::new(ThreadLocal::default()), matches: Arc::new(ThreadLocal::default()),
}) })
} }

View File

@ -1,25 +1,26 @@
use std::cmp; use std::{
use std::ffi::OsStr; cmp::Ordering,
use std::fmt; ffi::OsStr,
use std::fs::{self, FileType, Metadata}; fs::{self, FileType, Metadata},
use std::io; io,
use std::iter::{self, FusedIterator}; path::{Path, PathBuf},
use std::path::{Path, PathBuf}; sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering},
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; sync::Arc,
use std::sync::Arc; };
use std::thread;
use std::time::Duration;
use std::vec;
use crossbeam_deque::{Stealer, Worker as Deque}; use {
use same_file::Handle; crossbeam_deque::{Stealer, Worker as Deque},
use walkdir::{self, WalkDir}; same_file::Handle,
walkdir::{self, WalkDir},
};
use crate::dir::{Ignore, IgnoreBuilder}; use crate::{
use crate::gitignore::GitignoreBuilder; dir::{Ignore, IgnoreBuilder},
use crate::overrides::Override; gitignore::GitignoreBuilder,
use crate::types::Types; overrides::Override,
use crate::{Error, PartialErrorBuilder}; types::Types,
Error, PartialErrorBuilder,
};
/// A directory entry with a possible error attached. /// A directory entry with a possible error attached.
/// ///
@ -107,11 +108,11 @@ impl DirEntry {
} }
fn new_walkdir(dent: walkdir::DirEntry, err: Option<Error>) -> DirEntry { fn new_walkdir(dent: walkdir::DirEntry, err: Option<Error>) -> DirEntry {
DirEntry { dent: DirEntryInner::Walkdir(dent), err: err } DirEntry { dent: DirEntryInner::Walkdir(dent), err }
} }
fn new_raw(dent: DirEntryRaw, err: Option<Error>) -> DirEntry { fn new_raw(dent: DirEntryRaw, err: Option<Error>) -> DirEntry {
DirEntry { dent: DirEntryInner::Raw(dent), err: err } DirEntry { dent: DirEntryInner::Raw(dent), err }
} }
} }
@ -251,8 +252,8 @@ struct DirEntryRaw {
metadata: fs::Metadata, metadata: fs::Metadata,
} }
impl fmt::Debug for DirEntryRaw { impl std::fmt::Debug for DirEntryRaw {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Leaving out FileType because it doesn't have a debug impl // Leaving out FileType because it doesn't have a debug impl
// in Rust 1.9. We could add it if we really wanted to by manually // in Rust 1.9. We could add it if we really wanted to by manually
// querying each possibly file type. Meh. ---AG // querying each possibly file type. Meh. ---AG
@ -324,7 +325,7 @@ impl DirEntryRaw {
) -> Result<DirEntryRaw, Error> { ) -> Result<DirEntryRaw, Error> {
let ty = ent.file_type().map_err(|err| { let ty = ent.file_type().map_err(|err| {
let err = Error::Io(io::Error::from(err)).with_path(ent.path()); let err = Error::Io(io::Error::from(err)).with_path(ent.path());
Error::WithDepth { depth: depth, err: Box::new(err) } Error::WithDepth { depth, err: Box::new(err) }
})?; })?;
DirEntryRaw::from_entry_os(depth, ent, ty) DirEntryRaw::from_entry_os(depth, ent, ty)
} }
@ -337,13 +338,13 @@ impl DirEntryRaw {
) -> Result<DirEntryRaw, Error> { ) -> Result<DirEntryRaw, Error> {
let md = ent.metadata().map_err(|err| { let md = ent.metadata().map_err(|err| {
let err = Error::Io(io::Error::from(err)).with_path(ent.path()); let err = Error::Io(io::Error::from(err)).with_path(ent.path());
Error::WithDepth { depth: depth, err: Box::new(err) } Error::WithDepth { depth, err: Box::new(err) }
})?; })?;
Ok(DirEntryRaw { Ok(DirEntryRaw {
path: ent.path(), path: ent.path(),
ty: ty, ty,
follow_link: false, follow_link: false,
depth: depth, depth,
metadata: md, metadata: md,
}) })
} }
@ -358,9 +359,9 @@ impl DirEntryRaw {
Ok(DirEntryRaw { Ok(DirEntryRaw {
path: ent.path(), path: ent.path(),
ty: ty, ty,
follow_link: false, follow_link: false,
depth: depth, depth,
ino: ent.ino(), ino: ent.ino(),
}) })
} }
@ -391,7 +392,7 @@ impl DirEntryRaw {
path: pb, path: pb,
ty: md.file_type(), ty: md.file_type(),
follow_link: link, follow_link: link,
depth: depth, depth,
metadata: md, metadata: md,
}) })
} }
@ -410,7 +411,7 @@ impl DirEntryRaw {
path: pb, path: pb,
ty: md.file_type(), ty: md.file_type(),
follow_link: link, follow_link: link,
depth: depth, depth,
ino: md.ino(), ino: md.ino(),
}) })
} }
@ -494,17 +495,15 @@ pub struct WalkBuilder {
#[derive(Clone)] #[derive(Clone)]
enum Sorter { enum Sorter {
ByName( ByName(Arc<dyn Fn(&OsStr, &OsStr) -> Ordering + Send + Sync + 'static>),
Arc<dyn Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static>, ByPath(Arc<dyn Fn(&Path, &Path) -> Ordering + Send + Sync + 'static>),
),
ByPath(Arc<dyn Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static>),
} }
#[derive(Clone)] #[derive(Clone)]
struct Filter(Arc<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>); struct Filter(Arc<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>);
impl fmt::Debug for WalkBuilder { impl std::fmt::Debug for WalkBuilder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WalkBuilder") f.debug_struct("WalkBuilder")
.field("paths", &self.paths) .field("paths", &self.paths)
.field("ig_builder", &self.ig_builder) .field("ig_builder", &self.ig_builder)
@ -578,7 +577,7 @@ impl WalkBuilder {
.into_iter(); .into_iter();
let ig_root = self.ig_builder.build(); let ig_root = self.ig_builder.build();
Walk { Walk {
its: its, its,
it: None, it: None,
ig_root: ig_root.clone(), ig_root: ig_root.clone(),
ig: ig_root.clone(), ig: ig_root.clone(),
@ -828,7 +827,7 @@ impl WalkBuilder {
/// Note that this is not used in the parallel iterator. /// Note that this is not used in the parallel iterator.
pub fn sort_by_file_path<F>(&mut self, cmp: F) -> &mut WalkBuilder pub fn sort_by_file_path<F>(&mut self, cmp: F) -> &mut WalkBuilder
where where
F: Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static, F: Fn(&Path, &Path) -> Ordering + Send + Sync + 'static,
{ {
self.sorter = Some(Sorter::ByPath(Arc::new(cmp))); self.sorter = Some(Sorter::ByPath(Arc::new(cmp)));
self self
@ -847,7 +846,7 @@ impl WalkBuilder {
/// Note that this is not used in the parallel iterator. /// Note that this is not used in the parallel iterator.
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
where where
F: Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static, F: Fn(&OsStr, &OsStr) -> Ordering + Send + Sync + 'static,
{ {
self.sorter = Some(Sorter::ByName(Arc::new(cmp))); self.sorter = Some(Sorter::ByName(Arc::new(cmp)));
self self
@ -911,7 +910,7 @@ impl WalkBuilder {
/// ignore files like `.gitignore` are respected. The precise matching rules /// ignore files like `.gitignore` are respected. The precise matching rules
/// and precedence is explained in the documentation for `WalkBuilder`. /// and precedence is explained in the documentation for `WalkBuilder`.
pub struct Walk { pub struct Walk {
its: vec::IntoIter<(PathBuf, Option<WalkEventIter>)>, its: std::vec::IntoIter<(PathBuf, Option<WalkEventIter>)>,
it: Option<WalkEventIter>, it: Option<WalkEventIter>,
ig_root: Ignore, ig_root: Ignore,
ig: Ignore, ig: Ignore,
@ -1040,7 +1039,7 @@ impl Iterator for Walk {
} }
} }
impl FusedIterator for Walk {} impl std::iter::FusedIterator for Walk {}
/// WalkEventIter transforms a WalkDir iterator into an iterator that more /// WalkEventIter transforms a WalkDir iterator into an iterator that more
/// accurately describes the directory tree. Namely, it emits events that are /// accurately describes the directory tree. Namely, it emits events that are
@ -1188,7 +1187,7 @@ impl<'s> ParallelVisitor for FnVisitorImp<'s> {
/// ///
/// Unlike `Walk`, this uses multiple threads for traversing a directory. /// Unlike `Walk`, this uses multiple threads for traversing a directory.
pub struct WalkParallel { pub struct WalkParallel {
paths: vec::IntoIter<PathBuf>, paths: std::vec::IntoIter<PathBuf>,
ig_root: Ignore, ig_root: Ignore,
max_filesize: Option<u64>, max_filesize: Option<u64>,
max_depth: Option<usize>, max_depth: Option<usize>,
@ -1268,9 +1267,9 @@ impl WalkParallel {
} }
}; };
stack.push(Message::Work(Work { stack.push(Message::Work(Work {
dent: dent, dent,
ignore: self.ig_root.clone(), ignore: self.ig_root.clone(),
root_device: root_device, root_device,
})); }));
} }
// ... but there's no need to start workers if we don't need them. // ... but there's no need to start workers if we don't need them.
@ -1408,7 +1407,7 @@ impl Stack {
// on wide directories with a lot of gitignores is disastrous (for // on wide directories with a lot of gitignores is disastrous (for
// example, searching a directory tree containing all of crates.io). // example, searching a directory tree containing all of crates.io).
let deques: Vec<Deque<Message>> = let deques: Vec<Deque<Message>> =
iter::repeat_with(Deque::new_lifo).take(threads).collect(); std::iter::repeat_with(Deque::new_lifo).take(threads).collect();
let stealers = Arc::<[Stealer<Message>]>::from( let stealers = Arc::<[Stealer<Message>]>::from(
deques.iter().map(Deque::stealer).collect::<Vec<_>>(), deques.iter().map(Deque::stealer).collect::<Vec<_>>(),
); );
@ -1707,7 +1706,8 @@ impl<'s> Worker<'s> {
// CPU waiting, we let the thread sleep for a bit. In // CPU waiting, we let the thread sleep for a bit. In
// general, this tends to only occur once the search is // general, this tends to only occur once the search is
// approaching termination. // approaching termination.
thread::sleep(Duration::from_millis(1)); let dur = std::time::Duration::from_millis(1);
std::thread::sleep(dur);
} }
} }
} }
@ -1716,22 +1716,22 @@ impl<'s> Worker<'s> {
/// Indicates that all workers should quit immediately. /// Indicates that all workers should quit immediately.
fn quit_now(&self) { fn quit_now(&self) {
self.quit_now.store(true, Ordering::SeqCst); self.quit_now.store(true, AtomicOrdering::SeqCst);
} }
/// Returns true if this worker should quit immediately. /// Returns true if this worker should quit immediately.
fn is_quit_now(&self) -> bool { fn is_quit_now(&self) -> bool {
self.quit_now.load(Ordering::SeqCst) self.quit_now.load(AtomicOrdering::SeqCst)
} }
/// Returns the number of pending jobs. /// Returns the number of pending jobs.
fn num_pending(&self) -> usize { fn num_pending(&self) -> usize {
self.num_pending.load(Ordering::SeqCst) self.num_pending.load(AtomicOrdering::SeqCst)
} }
/// Send work. /// Send work.
fn send(&self, work: Work) { fn send(&self, work: Work) {
self.num_pending.fetch_add(1, Ordering::SeqCst); self.num_pending.fetch_add(1, AtomicOrdering::SeqCst);
self.stack.push(Message::Work(work)); self.stack.push(Message::Work(work));
} }
@ -1747,7 +1747,7 @@ impl<'s> Worker<'s> {
/// Signal that work has been finished. /// Signal that work has been finished.
fn work_done(&self) { fn work_done(&self) {
self.num_pending.fetch_sub(1, Ordering::SeqCst); self.num_pending.fetch_sub(1, AtomicOrdering::SeqCst);
} }
} }