From f16ea0812db1e7218d98ce0a131b6b7aec510c3a Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Thu, 28 Sep 2023 14:17:30 -0400 Subject: [PATCH] ignore: polish Like previous commits, we do a bit of polishing and bring the style up to my current practice. --- Cargo.lock | 1 + crates/globset/Cargo.toml | 2 + crates/ignore/Cargo.toml | 19 +++--- crates/ignore/examples/walk.rs | 28 ++------ crates/ignore/src/default_types.rs | 2 +- crates/ignore/src/dir.rs | 102 ++++++++++++++------------- crates/ignore/src/gitignore.rs | 54 ++++++++------- crates/ignore/src/lib.rs | 64 +++++++++-------- crates/ignore/src/overrides.rs | 6 +- crates/ignore/src/pathutil.rs | 24 +++---- crates/ignore/src/types.rs | 27 ++++---- crates/ignore/src/walk.rs | 106 ++++++++++++++--------------- 12 files changed, 215 insertions(+), 220 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e45d316..1844e4e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,6 +239,7 @@ dependencies = [ name = "ignore" version = "0.4.20" dependencies = [ + "bstr", "crossbeam-channel", "crossbeam-deque", "globset", diff --git a/crates/globset/Cargo.toml b/crates/globset/Cargo.toml index 75486ddb..574db754 100644 --- a/crates/globset/Cargo.toml +++ b/crates/globset/Cargo.toml @@ -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"] diff --git a/crates/ignore/Cargo.toml b/crates/ignore/Cargo.toml index c659bb2d..3696f630 100644 --- a/crates/ignore/Cargo.toml +++ b/crates/ignore/Cargo.toml @@ -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 = [] diff --git a/crates/ignore/examples/walk.rs b/crates/ignore/examples/walk.rs index e064478c..5bbd10f2 100644 --- a/crates/ignore/examples/walk.rs +++ b/crates/ignore/examples/walk.rs @@ -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(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(mut wtr: W, path: &Path) { - wtr.write(path.to_string_lossy().as_bytes()).unwrap(); - wtr.write(b"\n").unwrap(); -} diff --git a/crates/ignore/src/default_types.rs b/crates/ignore/src/default_types.rs index 99749ddd..af71fe8e 100644 --- a/crates/ignore/src/default_types.rs +++ b/crates/ignore/src/default_types.rs @@ -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"]), diff --git a/crates/ignore/src/dir.rs b/crates/ignore/src/dir.rs index c813eb0d..51fc813e 100644 --- a/crates/ignore/src/dir.rs +++ b/crates/ignore/src/dir.rs @@ -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); +pub(crate) struct Ignore(Arc); #[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 { + pub(crate) fn parent(&self) -> Option { 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>( + pub(crate) fn add_parents>( &self, path: P, ) -> (Ignore, Option) { @@ -222,7 +226,7 @@ impl Ignore { /// returned if it exists. /// /// Note that all I/O errors are completely ignored. - pub fn add_child>( + pub(crate) fn add_child>( &self, dir: P, ) -> (Ignore, Option) { @@ -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> { @@ -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>( + pub(crate) fn add_custom_ignore_filename>( &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>( +pub(crate) fn create_gitignore>( 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>(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>(path: P) { - fs::create_dir_all(path).unwrap(); + std::fs::create_dir_all(path).unwrap(); } fn partial(err: Error) -> Vec { @@ -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. diff --git a/crates/ignore/src/gitignore.rs b/crates/ignore/src/gitignore.rs index 9aeef66e..23e024b6 100644 --- a/crates/ignore/src/gitignore.rs +++ b/crates/ignore/src/gitignore.rs @@ -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> { }; 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> { /// 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> { - 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> { /// /// Specifically, this respects XDG_CONFIG_HOME. fn excludes_file_default() -> Option { - 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 { 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 { - // 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>(root: P, s: &str) -> Gitignore { let mut builder = GitignoreBuilder::new(root); builder.add_str(None, s).unwrap(); diff --git a/crates/ignore/src/lib.rs b/crates/ignore/src/lib.rs index 824f7c4d..a5d5ca30 100644 --- a/crates/ignore/src/lib.rs +++ b/crates/ignore/src/lib.rs @@ -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 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 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 { 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 = @@ -359,8 +358,8 @@ impl fmt::Display for Error { } } -impl From for Error { - fn from(err: io::Error) -> Error { +impl From for Error { + fn from(err: std::io::Error) -> Error { Error::Io(err) } } @@ -488,19 +487,18 @@ impl Match { #[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 = - result::Result>; + pub(crate) type Result = + std::result::Result>; macro_rules! err { ($($tt:tt)*) => { - Box::::from(format!($($tt)*)) + Box::::from(format!($($tt)*)) } } diff --git a/crates/ignore/src/overrides.rs b/crates/ignore/src/overrides.rs index e96b8e0b..fd8af95d 100644 --- a/crates/ignore/src/overrides.rs +++ b/crates/ignore/src/overrides.rs @@ -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. /// diff --git a/crates/ignore/src/pathutil.rs b/crates/ignore/src/pathutil.rs index f21b4f5a..1e2e812c 100644 --- a/crates/ignore/src/pathutil.rs +++ b/crates/ignore/src/pathutil.rs @@ -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 + ?Sized>( +pub(crate) fn strip_prefix<'a, P: AsRef + ?Sized>( prefix: &'a P, path: &'a Path, ) -> Option<&'a Path> { @@ -80,7 +79,7 @@ pub fn strip_prefix<'a, P: AsRef + ?Sized>( /// /// If `path` doesn't have a prefix `prefix`, then return `None`. #[cfg(not(unix))] -pub fn strip_prefix<'a, P: AsRef + ?Sized>( +pub(crate) fn strip_prefix<'a, P: AsRef + ?Sized>( prefix: &'a P, path: &'a Path, ) -> Option<&'a Path> { @@ -90,10 +89,11 @@ pub fn strip_prefix<'a, P: AsRef + ?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>(path: P) -> bool { - use memchr::memchr; +pub(crate) fn is_file_name>(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>(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>(path: P) -> bool { +pub(crate) fn is_file_name>(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>(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 + ?Sized>( +pub(crate) fn file_name<'a, P: AsRef + ?Sized>( path: &'a P, ) -> Option<&'a OsStr> { use memchr::memrchr; @@ -135,7 +135,7 @@ pub fn file_name<'a, P: AsRef + ?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 + ?Sized>( +pub(crate) fn file_name<'a, P: AsRef + ?Sized>( path: &'a P, ) -> Option<&'a OsStr> { path.as_ref().file_name() diff --git a/crates/ignore/src/types.rs b/crates/ignore/src/types.rs index fc1c35d7..9db2f4b3 100644 --- a/crates/ignore/src/types.rs +++ b/crates/ignore/src/types.rs @@ -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()), }) } diff --git a/crates/ignore/src/walk.rs b/crates/ignore/src/walk.rs index eead9ffa..2d754da1 100644 --- a/crates/ignore/src/walk.rs +++ b/crates/ignore/src/walk.rs @@ -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) -> DirEntry { - DirEntry { dent: DirEntryInner::Walkdir(dent), err: err } + DirEntry { dent: DirEntryInner::Walkdir(dent), err } } fn new_raw(dent: DirEntryRaw, err: Option) -> 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 { 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 { 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 cmp::Ordering + Send + Sync + 'static>, - ), - ByPath(Arc cmp::Ordering + Send + Sync + 'static>), + ByName(Arc Ordering + Send + Sync + 'static>), + ByPath(Arc Ordering + Send + Sync + 'static>), } #[derive(Clone)] struct Filter(Arc 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(&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(&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)>, + its: std::vec::IntoIter<(PathBuf, Option)>, it: Option, 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, + paths: std::vec::IntoIter, ig_root: Ignore, max_filesize: Option, max_depth: Option, @@ -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> = - iter::repeat_with(Deque::new_lifo).take(threads).collect(); + std::iter::repeat_with(Deque::new_lifo).take(threads).collect(); let stealers = Arc::<[Stealer]>::from( deques.iter().map(Deque::stealer).collect::>(), ); @@ -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); } }