diff options
author | Andrew Gallant <jamslam@gmail.com> | 2023-09-28 16:01:59 -0400 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2023-10-09 20:29:52 -0400 |
commit | 6d17b3ed6810a46fd89925c4f96cd88883224083 (patch) | |
tree | fe92d588f17f3148ad425de1f60bb9dd95eca495 | |
parent | f16ea0812db1e7218d98ce0a131b6b7aec510c3a (diff) |
deps: drop thread_local, lazy_static and once_cell
This is largely made possible by the addition of std::sync::OnceLock to
the standard library, and the memory pool available in regex-automata.
-rw-r--r-- | Cargo.lock | 33 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | crates/core/app.rs | 10 | ||||
-rw-r--r-- | crates/globset/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ignore/Cargo.toml | 8 | ||||
-rw-r--r-- | crates/ignore/src/gitignore.rs | 44 | ||||
-rw-r--r-- | crates/ignore/src/types.rs | 18 |
7 files changed, 43 insertions, 75 deletions
@@ -143,7 +143,6 @@ dependencies = [ "aho-corasick", "bstr", "glob", - "lazy_static", "log", "regex-automata", "regex-syntax", @@ -243,12 +242,10 @@ dependencies = [ "crossbeam-channel", "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata", "same-file", - "thread_local", "walkdir", "winapi-util", ] @@ -289,12 +286,6 @@ dependencies = [ ] [[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] name = "libc" version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -347,12 +338,6 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] name = "packed_simd" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -364,14 +349,13 @@ dependencies = [ [[package]] name = "pcre2" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486aca7e74edb8cab09a48d461177f450a5cca3b55e61d139f7552190e2bbcf5" +checksum = "9deb1d02d6a373ee392128ba86087352a986359f32a106e2e3b08cc90cc659c9" dependencies = [ "libc", "log", "pcre2-sys", - "thread_local", ] [[package]] @@ -447,7 +431,6 @@ dependencies = [ "grep", "ignore", "jemallocator", - "lazy_static", "log", "serde", "serde_derive", @@ -544,16 +527,6 @@ dependencies = [ ] [[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -52,7 +52,6 @@ members = [ bstr = "1.6.0" grep = { version = "0.2.12", path = "crates/grep" } ignore = { version = "0.4.19", path = "crates/ignore" } -lazy_static = "1.1.0" log = "0.4.5" serde_json = "1.0.23" termcolor = "1.1.0" @@ -65,9 +64,6 @@ features = ["suggestions"] [target.'cfg(all(target_env = "musl", target_pointer_width = "64"))'.dependencies.jemallocator] version = "0.5.0" -[build-dependencies] -lazy_static = "1.1.0" - [build-dependencies.clap] version = "2.33.0" default-features = false diff --git a/crates/core/app.rs b/crates/core/app.rs index 78c55963..ae97a2b5 100644 --- a/crates/core/app.rs +++ b/crates/core/app.rs @@ -10,7 +10,6 @@ // it into a ripgrep-specific configuration type that is not coupled with clap. use clap::{self, crate_authors, crate_version, App, AppSettings}; -use lazy_static::lazy_static; const ABOUT: &str = " ripgrep (rg) recursively searches the current directory for a regex pattern. @@ -47,18 +46,19 @@ OPTIONS: /// Build a clap application parameterized by usage strings. pub fn app() -> App<'static, 'static> { + use std::sync::OnceLock; + // We need to specify our version in a static because we've painted clap // into a corner. We've told it that every string we give it will be // 'static, but we need to build the version string dynamically. We can // fake the 'static lifetime with lazy_static. - lazy_static! { - static ref LONG_VERSION: String = long_version(None, true); - } + static LONG_VERSION: OnceLock<String> = OnceLock::new(); + let long_version = LONG_VERSION.get_or_init(|| long_version(None, true)); let mut app = App::new("ripgrep") .author(crate_authors!()) .version(crate_version!()) - .long_version(LONG_VERSION.as_str()) + .long_version(long_version.as_str()) .about(ABOUT) .max_term_width(100) .setting(AppSettings::UnifiedHelpMessage) diff --git a/crates/globset/Cargo.toml b/crates/globset/Cargo.toml index 574db754..b0602239 100644 --- a/crates/globset/Cargo.toml +++ b/crates/globset/Cargo.toml @@ -37,7 +37,6 @@ features = ["std", "perf", "syntax", "meta", "nfa", "hybrid"] [dev-dependencies] glob = "0.3.1" -lazy_static = "1" serde_json = "1.0.107" [features] diff --git a/crates/ignore/Cargo.toml b/crates/ignore/Cargo.toml index 3696f630..31771f17 100644 --- a/crates/ignore/Cargo.toml +++ b/crates/ignore/Cargo.toml @@ -21,14 +21,16 @@ bench = false [dependencies] crossbeam-deque = "0.8.3" globset = { version = "0.4.10", path = "../globset" } -lazy_static = "1.1" 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.4.0" +[dependencies.regex-automata] +version = "0.3.8" +default-features = false +features = ["std", "perf", "syntax", "meta", "nfa", "hybrid", "dfa-onepass"] + [target.'cfg(windows)'.dependencies.winapi-util] version = "0.1.2" diff --git a/crates/ignore/src/gitignore.rs b/crates/ignore/src/gitignore.rs index 23e024b6..da007298 100644 --- a/crates/ignore/src/gitignore.rs +++ b/crates/ignore/src/gitignore.rs @@ -8,7 +8,6 @@ the `git` command line tool. */ use std::{ - cell::RefCell, fs::File, io::{BufRead, BufReader, Read}, path::{Path, PathBuf}, @@ -17,8 +16,7 @@ use std::{ use { globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder}, - regex::bytes::Regex, - thread_local::ThreadLocal, + regex_automata::util::pool::Pool, }; use crate::{ @@ -86,7 +84,7 @@ pub struct Gitignore { globs: Vec<Glob>, num_ignores: u64, num_whitelists: u64, - matches: Option<Arc<ThreadLocal<RefCell<Vec<usize>>>>>, + matches: Option<Arc<Pool<Vec<usize>>>>, } impl Gitignore { @@ -253,8 +251,7 @@ impl Gitignore { return Match::None; } let path = path.as_ref(); - let _matches = self.matches.as_ref().unwrap().get_or_default(); - let mut matches = _matches.borrow_mut(); + let mut matches = self.matches.as_ref().unwrap().get(); let candidate = Candidate::new(path); self.set.matches_candidate_into(&candidate, &mut *matches); for &i in matches.iter().rev() { @@ -346,7 +343,7 @@ impl GitignoreBuilder { globs: self.globs.clone(), num_ignores: nignore as u64, num_whitelists: nwhite as u64, - matches: Some(Arc::new(ThreadLocal::default())), + matches: Some(Arc::new(Pool::new(|| vec![]))), }) } @@ -596,23 +593,28 @@ fn excludes_file_default() -> Option<PathBuf> { /// Extract git's `core.excludesfile` config setting from the raw file contents /// given. fn parse_excludes_file(data: &[u8]) -> Option<PathBuf> { + use std::sync::OnceLock; + + use regex_automata::{meta::Regex, util::syntax}; + // N.B. This is the lazy approach, and isn't technically correct, but // probably works in more circumstances. I guess we would ideally have // a full INI parser. Yuck. - lazy_static::lazy_static! { - static ref RE: Regex = Regex::new( - r"(?xim-u) - ^[[:space:]]*excludesfile[[:space:]]* - = - [[:space:]]*(.+)[[:space:]]*$ - " - ).unwrap(); - }; - let caps = match RE.captures(data) { - None => return None, - Some(caps) => caps, - }; - std::str::from_utf8(&caps[1]).ok().map(|s| PathBuf::from(expand_tilde(s))) + static RE: OnceLock<Regex> = OnceLock::new(); + let re = RE.get_or_init(|| { + Regex::builder() + .configure(Regex::config().utf8_empty(false)) + .syntax(syntax::Config::new().utf8(false)) + .build(r"(?im-u)^\s*excludesfile\s*=\s*(\S+)\s*$") + .unwrap() + }); + // We don't care about amortizing allocs here I think. This should only + // be called ~once per traversal or so? (Although it's not guaranteed...) + let mut caps = re.create_captures(); + re.captures(data, &mut caps); + let span = caps.get_group(1)?; + let candidate = &data[span]; + std::str::from_utf8(candidate).ok().map(|s| PathBuf::from(expand_tilde(s))) } /// Expands ~ in file paths to the value of $HOME. diff --git a/crates/ignore/src/types.rs b/crates/ignore/src/types.rs index 9db2f4b3..308b784d 100644 --- a/crates/ignore/src/types.rs +++ b/crates/ignore/src/types.rs @@ -84,12 +84,11 @@ assert!(matcher.matched("y.cpp", false).is_whitelist()); ``` */ -use std::{cell::RefCell, collections::HashMap, path::Path, sync::Arc}; +use std::{collections::HashMap, path::Path, sync::Arc}; use { globset::{GlobBuilder, GlobSet, GlobSetBuilder}, - regex::Regex, - thread_local::ThreadLocal, + regex_automata::util::pool::Pool, }; use crate::{default_types::DEFAULT_TYPES, pathutil::file_name, Error, Match}; @@ -178,7 +177,7 @@ pub struct Types { /// The set of all glob selections, used for actual matching. set: GlobSet, /// Temporary storage for globs that match. - matches: Arc<ThreadLocal<RefCell<Vec<usize>>>>, + matches: Arc<Pool<Vec<usize>>>, } /// Indicates the type of a selection for a particular file type. @@ -232,7 +231,7 @@ impl Types { has_selected: false, glob_to_selection: vec![], set: GlobSetBuilder::new().build().unwrap(), - matches: Arc::new(ThreadLocal::default()), + matches: Arc::new(Pool::new(|| vec![])), } } @@ -280,7 +279,7 @@ impl Types { return Match::None; } }; - let mut matches = self.matches.get_or_default().borrow_mut(); + let mut matches = self.matches.get(); self.set.matches_into(name, &mut *matches); // The highest precedent match is the last one. if let Some(&i) = matches.last() { @@ -358,7 +357,7 @@ impl TypesBuilder { has_selected, glob_to_selection, set, - matches: Arc::new(ThreadLocal::default()), + matches: Arc::new(Pool::new(|| vec![])), }) } @@ -416,10 +415,7 @@ impl TypesBuilder { /// If `name` is `all` or otherwise contains any character that is not a /// Unicode letter or number, then an error is returned. pub fn add(&mut self, name: &str, glob: &str) -> Result<(), Error> { - lazy_static::lazy_static! { - static ref RE: Regex = Regex::new(r"^[\pL\pN]+$").unwrap(); - }; - if name == "all" || !RE.is_match(name) { + if name == "all" || !name.chars().all(|c| c.is_alphanumeric()) { return Err(Error::InvalidDefinition); } let (key, glob) = (name.to_string(), glob.to_string()); |