1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-03-17 20:28:03 +02:00

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"
version = "0.4.20"
dependencies = [
"bstr",
"crossbeam-channel",
"crossbeam-deque",
"globset",

View File

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

View File

@ -12,7 +12,7 @@ repository = "https://github.com/BurntSushi/ripgrep/tree/master/crates/ignore"
readme = "README.md"
keywords = ["glob", "ignore", "gitignore", "pattern", "file"]
license = "Unlicense OR MIT"
edition = "2018"
edition = "2021"
[lib]
name = "ignore"
@ -22,18 +22,21 @@ bench = false
crossbeam-deque = "0.8.3"
globset = { version = "0.4.10", path = "../globset" }
lazy_static = "1.1"
log = "0.4.5"
memchr = "2.5"
regex = { version = "1.9.0", default-features = false, features = ["perf", "std", "unicode-gencat"] }
same-file = "1.0.4"
log = "0.4.20"
memchr = "2.6.3"
regex = { version = "1.9.5", default-features = false, features = ["perf", "std", "unicode-gencat"] }
same-file = "1.0.6"
thread_local = "1"
walkdir = "2.2.7"
walkdir = "2.4.0"
[target.'cfg(windows)'.dependencies.winapi-util]
version = "0.1.2"
[dev-dependencies]
crossbeam-channel = "0.5.0"
bstr = { version = "1.6.2", default-features = false, features = ["std"] }
crossbeam-channel = "0.5.8"
[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::io::{self, Write};
use std::path::Path;
use std::thread;
use std::{env, io::Write, path::Path};
use ignore::WalkBuilder;
use walkdir::WalkDir;
use {bstr::ByteVec, ignore::WalkBuilder, walkdir::WalkDir};
fn main() {
let mut path = env::args().nth(1).unwrap();
@ -19,10 +15,11 @@ fn main() {
simple = true;
}
let stdout_thread = thread::spawn(move || {
let mut stdout = io::BufWriter::new(io::stdout());
let stdout_thread = std::thread::spawn(move || {
let mut stdout = std::io::BufWriter::new(std::io::stdout());
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
/// columns (inclusive).
#[rustfmt::skip]
pub const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
pub(crate) const DEFAULT_TYPES: &[(&[&str], &[&str])] = &[
(&["ada"], &["*.adb", "*.ads"]),
(&["agda"], &["*.agda", "*.lagda"]),
(&["aidl"], &["*.aidl"]),

View File

@ -13,24 +13,28 @@
// with non-obvious failure modes. Alas, such things haven't been documented
// well.
use std::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::fs::{File, FileType};
use std::io::{self, BufRead};
use std::path::{Path, PathBuf};
use std::sync::{Arc, RwLock};
use std::{
collections::HashMap,
ffi::{OsStr, OsString},
fs::{File, FileType},
io::{self, BufRead},
path::{Path, PathBuf},
sync::{Arc, RwLock},
};
use crate::gitignore::{self, Gitignore, GitignoreBuilder};
use crate::overrides::{self, Override};
use crate::pathutil::{is_hidden, strip_prefix};
use crate::types::{self, Types};
use crate::walk::DirEntry;
use crate::{Error, Match, PartialErrorBuilder};
use crate::{
gitignore::{self, Gitignore, GitignoreBuilder},
overrides::{self, Override},
pathutil::{is_hidden, strip_prefix},
types::{self, Types},
walk::DirEntry,
{Error, Match, PartialErrorBuilder},
};
/// IgnoreMatch represents information about where a match came from when using
/// the `Ignore` matcher.
#[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.
/// 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.
#[derive(Clone, Debug)]
pub struct Ignore(Arc<IgnoreInner>);
pub(crate) struct Ignore(Arc<IgnoreInner>);
#[derive(Clone, Debug)]
struct IgnoreInner {
@ -134,22 +138,22 @@ struct IgnoreInner {
impl Ignore {
/// Return the directory path of this matcher.
pub fn path(&self) -> &Path {
pub(crate) fn path(&self) -> &Path {
&self.0.dir
}
/// 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()
}
/// 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
}
/// 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()
}
@ -157,7 +161,7 @@ impl Ignore {
///
/// Note that this can only be called on an `Ignore` matcher with no
/// 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,
path: P,
) -> (Ignore, Option<Error>) {
@ -222,7 +226,7 @@ impl Ignore {
/// returned if it exists.
///
/// 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,
dir: P,
) -> (Ignore, Option<Error>) {
@ -335,7 +339,7 @@ impl Ignore {
}
/// Like `matched`, but works with a directory entry instead.
pub fn matched_dir_entry<'a>(
pub(crate) fn matched_dir_entry<'a>(
&'a self,
dent: &DirEntry,
) -> Match<IgnoreMatch<'a>> {
@ -520,7 +524,7 @@ impl Ignore {
}
/// Returns an iterator over parent ignore matchers, including this one.
pub fn parents(&self) -> Parents<'_> {
pub(crate) fn parents(&self) -> Parents<'_> {
Parents(Some(self))
}
@ -534,7 +538,7 @@ impl Ignore {
/// An iterator over all parents of an ignore matcher, including itself.
///
/// 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> {
type Item = &'a Ignore;
@ -552,7 +556,7 @@ impl<'a> Iterator for Parents<'a> {
/// A builder for creating an Ignore matcher.
#[derive(Clone, Debug)]
pub struct IgnoreBuilder {
pub(crate) struct IgnoreBuilder {
/// The root directory path for this ignore matcher.
dir: PathBuf,
/// An override matcher (default is empty).
@ -572,7 +576,7 @@ impl IgnoreBuilder {
///
/// All relative file paths are resolved with respect to the current
/// working directory.
pub fn new() -> IgnoreBuilder {
pub(crate) fn new() -> IgnoreBuilder {
IgnoreBuilder {
dir: Path::new("").to_path_buf(),
overrides: Arc::new(Override::empty()),
@ -596,7 +600,7 @@ impl IgnoreBuilder {
///
/// The matcher returned won't match anything until ignore rules from
/// 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 {
Gitignore::empty()
} else {
@ -638,7 +642,10 @@ impl IgnoreBuilder {
/// By default, no override matcher is used.
///
/// 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
}
@ -648,13 +655,13 @@ impl IgnoreBuilder {
/// By default, no file type matcher is used.
///
/// 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
}
/// 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
}
@ -665,7 +672,7 @@ impl IgnoreBuilder {
///
/// When specifying multiple names, earlier names have lower precedence than
/// later names.
pub fn add_custom_ignore_filename<S: AsRef<OsStr>>(
pub(crate) fn add_custom_ignore_filename<S: AsRef<OsStr>>(
&mut self,
file_name: S,
) -> &mut IgnoreBuilder {
@ -676,7 +683,7 @@ impl IgnoreBuilder {
/// Enables ignoring hidden files.
///
/// 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
}
@ -687,7 +694,7 @@ impl IgnoreBuilder {
/// supported by search tools such as ripgrep and The Silver Searcher.
///
/// 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
}
@ -698,7 +705,7 @@ impl IgnoreBuilder {
/// file path given are respected. Otherwise, they are ignored.
///
/// 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
}
@ -711,7 +718,7 @@ impl IgnoreBuilder {
/// This overwrites any previous global gitignore setting.
///
/// 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
}
@ -722,7 +729,7 @@ impl IgnoreBuilder {
/// man page.
///
/// 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
}
@ -733,7 +740,7 @@ impl IgnoreBuilder {
/// `gitignore` man page.
///
/// 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
}
@ -743,7 +750,7 @@ impl IgnoreBuilder {
///
/// When disabled, git-related ignore rules are applied even when searching
/// 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
}
@ -751,7 +758,7 @@ impl IgnoreBuilder {
/// Process ignore files case insensitively
///
/// This is disabled by default.
pub fn ignore_case_insensitive(
pub(crate) fn ignore_case_insensitive(
&mut self,
yes: bool,
) -> &mut IgnoreBuilder {
@ -768,7 +775,7 @@ impl IgnoreBuilder {
/// precedence than later names).
///
/// I/O errors are ignored.
pub fn create_gitignore<T: AsRef<OsStr>>(
pub(crate) fn create_gitignore<T: AsRef<OsStr>>(
dir: &Path,
dir_for_ignorefile: &Path,
names: &[T],
@ -861,22 +868,19 @@ fn resolve_git_commondir(
#[cfg(test)]
mod tests {
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use std::{io::Write, path::Path};
use crate::dir::IgnoreBuilder;
use crate::gitignore::Gitignore;
use crate::tests::TempDir;
use crate::Error;
use crate::{
dir::IgnoreBuilder, gitignore::Gitignore, tests::TempDir, Error,
};
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();
}
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> {
@ -1193,7 +1197,7 @@ mod tests {
assert!(ignore.matched("ignore_me", false).is_ignore());
// 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"));
// We squash the error in this case, because it occurs in repositories
// 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.
*/
use std::cell::RefCell;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, Read};
use std::path::{Path, PathBuf};
use std::str;
use std::sync::Arc;
use std::{
cell::RefCell,
fs::File,
io::{BufRead, BufReader, Read},
path::{Path, PathBuf},
sync::Arc,
};
use globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder};
use regex::bytes::Regex;
use thread_local::ThreadLocal;
use {
globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder},
regex::bytes::Regex,
thread_local::ThreadLocal,
};
use crate::pathutil::{is_file_name, strip_prefix};
use crate::{Error, Match, PartialErrorBuilder};
use crate::{
pathutil::{is_file_name, strip_prefix},
Error, Match, PartialErrorBuilder,
};
/// Glob represents a single glob in a gitignore file.
///
@ -337,7 +341,7 @@ impl GitignoreBuilder {
.build()
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
Ok(Gitignore {
set: set,
set,
root: self.root.clone(),
globs: self.globs.clone(),
num_ignores: nignore as u64,
@ -389,7 +393,7 @@ impl GitignoreBuilder {
Err(err) => return Some(Error::Io(err).with_path(path)),
Ok(file) => file,
};
let rdr = io::BufReader::new(file);
let rdr = BufReader::new(file);
let mut errs = PartialErrorBuilder::default();
for (i, line) in rdr.lines().enumerate() {
let lineno = (i + 1) as u64;
@ -448,7 +452,7 @@ impl GitignoreBuilder {
return Ok(self);
}
let mut glob = Glob {
from: from,
from,
original: line.to_string(),
actual: String::new(),
is_whitelist: false,
@ -558,7 +562,7 @@ fn gitconfig_home_contents() -> Option<Vec<u8>> {
};
let mut file = match File::open(home.join(".gitconfig")) {
Err(_) => return None,
Ok(file) => io::BufReader::new(file),
Ok(file) => BufReader::new(file),
};
let mut contents = vec![];
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
/// the user's XDG_CONFIG_HOME directory.
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)) })
.or_else(|| home_dir().map(|p| p.join(".config")))
.map(|x| x.join("git/config"));
let mut file = match path.and_then(|p| File::open(p).ok()) {
None => return None,
Some(file) => io::BufReader::new(file),
Some(file) => BufReader::new(file),
};
let mut contents = vec![];
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.
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)) })
.or_else(|| home_dir().map(|p| p.join(".config")))
.map(|x| x.join("git/ignore"))
@ -608,7 +612,7 @@ fn parse_excludes_file(data: &[u8]) -> Option<PathBuf> {
None => return None,
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.
@ -622,18 +626,18 @@ fn expand_tilde(path: &str) -> String {
/// Returns the location of the user's home directory.
fn home_dir() -> Option<PathBuf> {
// We're fine with using env::home_dir for now. Its bugs are, IMO, pretty
// minor corner cases. We should still probably eventually migrate to
// the `dirs` crate to get a proper implementation.
// We're fine with using std::env::home_dir for now. Its bugs are, IMO,
// pretty minor corner cases.
#![allow(deprecated)]
env::home_dir()
std::env::home_dir()
}
#[cfg(test)]
mod tests {
use super::{Gitignore, GitignoreBuilder};
use std::path::Path;
use super::{Gitignore, GitignoreBuilder};
fn gi_from_str<P: AsRef<Path>>(root: P, s: &str) -> Gitignore {
let mut builder = GitignoreBuilder::new(root);
builder.add_str(None, s).unwrap();

View File

@ -46,9 +46,6 @@ See the documentation for `WalkBuilder` for many other options.
#![deny(missing_docs)]
use std::error;
use std::fmt;
use std::io;
use std::path::{Path, PathBuf};
pub use crate::walk::{
@ -101,7 +98,7 @@ pub enum Error {
child: PathBuf,
},
/// 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.
Glob {
/// The original glob that caused this error. This glob, when
@ -125,21 +122,23 @@ impl Clone for Error {
match *self {
Error::Partial(ref errs) => Error::Partial(errs.clone()),
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 { path: path.clone(), err: err.clone() }
}
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 {
ancestor: ancestor.clone(),
child: child.clone(),
},
Error::Io(ref err) => match err.raw_os_error() {
Some(e) => Error::Io(io::Error::from_raw_os_error(e)),
None => Error::Io(io::Error::new(err.kind(), err.to_string())),
Some(e) => Error::Io(std::io::Error::from_raw_os_error(e)),
None => {
Error::Io(std::io::Error::new(err.kind(), err.to_string()))
}
},
Error::Glob { ref glob, ref err } => {
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
/// [`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
/// following symbolic links.
///
/// 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.
///
/// > This is the original [`io::Error`] and is _not_ the same as
/// > [`impl From<Error> for std::io::Error`][impl] which contains additional context about the
/// error.
/// > 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 error.
///
/// [`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
/// [`Error`]: struct.Error.html
/// [`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
/// [`io::Error`] if one exists.
/// [`std::io::Error`] if one exists.
///
/// [`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> {
match self {
Error::Partial(mut errs) => {
@ -268,7 +267,7 @@ impl Error {
/// Turn an error into a tagged error with the given depth.
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
@ -287,7 +286,7 @@ impl Error {
let depth = err.depth();
if let (Some(anc), Some(child)) = (err.loop_ancestor(), err.path()) {
return Error::WithDepth {
depth: depth,
depth,
err: Box::new(Error::Loop {
ancestor: anc.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 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 {
ig_err = Error::WithPath { path: path, err: Box::new(ig_err) };
ig_err = Error::WithPath { path, err: Box::new(ig_err) };
}
ig_err
}
}
impl error::Error for Error {
impl std::error::Error for Error {
#[allow(deprecated)]
fn description(&self) -> &str {
match *self {
@ -320,8 +319,8 @@ impl error::Error for Error {
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Error::Partial(ref errs) => {
let msgs: Vec<String> =
@ -359,8 +358,8 @@ impl fmt::Display for Error {
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Error {
Error::Io(err)
}
}
@ -488,19 +487,18 @@ impl<T> Match<T> {
#[cfg(test)]
mod tests {
use std::env;
use std::error;
use std::fs;
use std::path::{Path, PathBuf};
use std::result;
use std::{
env, fs,
path::{Path, PathBuf},
};
/// A convenient result type alias.
pub type Result<T> =
result::Result<T, Box<dyn error::Error + Send + Sync>>;
pub(crate) type Result<T> =
std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
macro_rules! err {
($($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 crate::gitignore::{self, Gitignore, GitignoreBuilder};
use crate::{Error, Match};
use crate::{
gitignore::{self, Gitignore, GitignoreBuilder},
Error, Match,
};
/// Glob represents a single glob in an override matcher.
///

View File

@ -1,5 +1,4 @@
use std::ffi::OsStr;
use std::path::Path;
use std::{ffi::OsStr, path::Path};
use crate::walk::DirEntry;
@ -9,7 +8,7 @@ use crate::walk::DirEntry;
///
/// On Unix, this implements a more optimized check.
#[cfg(unix)]
pub fn is_hidden(dent: &DirEntry) -> bool {
pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
use std::os::unix::ffi::OsStrExt;
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 file attributes have the `HIDDEN` property set.
#[cfg(windows)]
pub fn is_hidden(dent: &DirEntry) -> bool {
pub(crate) fn is_hidden(dent: &DirEntry) -> bool {
use std::os::windows::fs::MetadataExt;
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 `.`.
#[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()) {
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
} else {
@ -61,7 +60,7 @@ pub fn is_hidden(dent: &DirEntry) -> bool {
///
/// If `path` doesn't have a prefix `prefix`, then return `None`.
#[cfg(unix)]
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
pub(crate) fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
prefix: &'a P,
path: &'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`.
#[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,
path: &'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
/// the empty string.
#[cfg(unix)]
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
use memchr::memchr;
pub(crate) fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
use std::os::unix::ffi::OsStrExt;
use memchr::memchr;
let path = path.as_ref().as_os_str().as_bytes();
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
/// the empty string.
#[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)
}
@ -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,
/// file_name will return None.
#[cfg(unix)]
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
pub(crate) fn file_name<'a, P: AsRef<Path> + ?Sized>(
path: &'a P,
) -> Option<&'a OsStr> {
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,
/// file_name will return None.
#[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,
) -> Option<&'a OsStr> {
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::collections::HashMap;
use std::path::Path;
use std::sync::Arc;
use std::{cell::RefCell, collections::HashMap, path::Path, sync::Arc};
use globset::{GlobBuilder, GlobSet, GlobSetBuilder};
use regex::Regex;
use thread_local::ThreadLocal;
use {
globset::{GlobBuilder, GlobSet, GlobSetBuilder},
regex::Regex,
thread_local::ThreadLocal,
};
use crate::default_types::DEFAULT_TYPES;
use crate::pathutil::file_name;
use crate::{Error, Match};
use crate::{default_types::DEFAULT_TYPES, pathutil::file_name, Error, Match};
/// Glob represents a single glob in a set of file type definitions.
///
@ -356,11 +353,11 @@ impl TypesBuilder {
.build()
.map_err(|err| Error::Glob { glob: None, err: err.to_string() })?;
Ok(Types {
defs: defs,
selections: selections,
has_selected: has_selected,
glob_to_selection: glob_to_selection,
set: set,
defs,
selections,
has_selected,
glob_to_selection,
set,
matches: Arc::new(ThreadLocal::default()),
})
}

View File

@ -1,25 +1,26 @@
use std::cmp;
use std::ffi::OsStr;
use std::fmt;
use std::fs::{self, FileType, Metadata};
use std::io;
use std::iter::{self, FusedIterator};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::vec;
use std::{
cmp::Ordering,
ffi::OsStr,
fs::{self, FileType, Metadata},
io,
path::{Path, PathBuf},
sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering},
sync::Arc,
};
use crossbeam_deque::{Stealer, Worker as Deque};
use same_file::Handle;
use walkdir::{self, WalkDir};
use {
crossbeam_deque::{Stealer, Worker as Deque},
same_file::Handle,
walkdir::{self, WalkDir},
};
use crate::dir::{Ignore, IgnoreBuilder};
use crate::gitignore::GitignoreBuilder;
use crate::overrides::Override;
use crate::types::Types;
use crate::{Error, PartialErrorBuilder};
use crate::{
dir::{Ignore, IgnoreBuilder},
gitignore::GitignoreBuilder,
overrides::Override,
types::Types,
Error, PartialErrorBuilder,
};
/// A directory entry with a possible error attached.
///
@ -107,11 +108,11 @@ impl 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 {
DirEntry { dent: DirEntryInner::Raw(dent), err: err }
DirEntry { dent: DirEntryInner::Raw(dent), err }
}
}
@ -251,8 +252,8 @@ struct DirEntryRaw {
metadata: fs::Metadata,
}
impl fmt::Debug for DirEntryRaw {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl std::fmt::Debug for DirEntryRaw {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// 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
// querying each possibly file type. Meh. ---AG
@ -324,7 +325,7 @@ impl DirEntryRaw {
) -> Result<DirEntryRaw, Error> {
let ty = ent.file_type().map_err(|err| {
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)
}
@ -337,13 +338,13 @@ impl DirEntryRaw {
) -> Result<DirEntryRaw, Error> {
let md = ent.metadata().map_err(|err| {
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 {
path: ent.path(),
ty: ty,
ty,
follow_link: false,
depth: depth,
depth,
metadata: md,
})
}
@ -358,9 +359,9 @@ impl DirEntryRaw {
Ok(DirEntryRaw {
path: ent.path(),
ty: ty,
ty,
follow_link: false,
depth: depth,
depth,
ino: ent.ino(),
})
}
@ -391,7 +392,7 @@ impl DirEntryRaw {
path: pb,
ty: md.file_type(),
follow_link: link,
depth: depth,
depth,
metadata: md,
})
}
@ -410,7 +411,7 @@ impl DirEntryRaw {
path: pb,
ty: md.file_type(),
follow_link: link,
depth: depth,
depth,
ino: md.ino(),
})
}
@ -494,17 +495,15 @@ pub struct WalkBuilder {
#[derive(Clone)]
enum Sorter {
ByName(
Arc<dyn Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static>,
),
ByPath(Arc<dyn Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static>),
ByName(Arc<dyn Fn(&OsStr, &OsStr) -> Ordering + Send + Sync + 'static>),
ByPath(Arc<dyn Fn(&Path, &Path) -> Ordering + Send + Sync + 'static>),
}
#[derive(Clone)]
struct Filter(Arc<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>);
impl fmt::Debug for WalkBuilder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl std::fmt::Debug for WalkBuilder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WalkBuilder")
.field("paths", &self.paths)
.field("ig_builder", &self.ig_builder)
@ -578,7 +577,7 @@ impl WalkBuilder {
.into_iter();
let ig_root = self.ig_builder.build();
Walk {
its: its,
its,
it: None,
ig_root: ig_root.clone(),
ig: ig_root.clone(),
@ -828,7 +827,7 @@ impl WalkBuilder {
/// Note that this is not used in the parallel iterator.
pub fn sort_by_file_path<F>(&mut self, cmp: F) -> &mut WalkBuilder
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
@ -847,7 +846,7 @@ impl WalkBuilder {
/// Note that this is not used in the parallel iterator.
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
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
@ -911,7 +910,7 @@ impl WalkBuilder {
/// ignore files like `.gitignore` are respected. The precise matching rules
/// and precedence is explained in the documentation for `WalkBuilder`.
pub struct Walk {
its: vec::IntoIter<(PathBuf, Option<WalkEventIter>)>,
its: std::vec::IntoIter<(PathBuf, Option<WalkEventIter>)>,
it: Option<WalkEventIter>,
ig_root: 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
/// 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.
pub struct WalkParallel {
paths: vec::IntoIter<PathBuf>,
paths: std::vec::IntoIter<PathBuf>,
ig_root: Ignore,
max_filesize: Option<u64>,
max_depth: Option<usize>,
@ -1268,9 +1267,9 @@ impl WalkParallel {
}
};
stack.push(Message::Work(Work {
dent: dent,
dent,
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.
@ -1408,7 +1407,7 @@ impl Stack {
// on wide directories with a lot of gitignores is disastrous (for
// example, searching a directory tree containing all of crates.io).
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(
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
// general, this tends to only occur once the search is
// 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.
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.
fn is_quit_now(&self) -> bool {
self.quit_now.load(Ordering::SeqCst)
self.quit_now.load(AtomicOrdering::SeqCst)
}
/// Returns the number of pending jobs.
fn num_pending(&self) -> usize {
self.num_pending.load(Ordering::SeqCst)
self.num_pending.load(AtomicOrdering::SeqCst)
}
/// Send 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));
}
@ -1747,7 +1747,7 @@ impl<'s> Worker<'s> {
/// Signal that work has been finished.
fn work_done(&self) {
self.num_pending.fetch_sub(1, Ordering::SeqCst);
self.num_pending.fetch_sub(1, AtomicOrdering::SeqCst);
}
}