ls: Reduce binary size of ls by removing regex crate (#2781)

This commit is contained in:
kimono-koans 2021-12-22 11:31:45 -06:00 committed by GitHub
parent f2f582aa14
commit fd64e01d92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 46 deletions

16
Cargo.lock generated
View file

@ -1,5 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "Inflector"
@ -868,19 +869,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "globset"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd"
dependencies = [
"aho-corasick",
"bstr",
"fnv",
"log",
"regex",
]
[[package]]
name = "half"
version = "1.8.2"
@ -2603,7 +2591,7 @@ dependencies = [
"atty",
"chrono",
"clap",
"globset",
"glob",
"lazy_static",
"lscolors",
"number_prefix",

View file

@ -21,7 +21,7 @@ unicode-width = "0.1.8"
number_prefix = "0.4"
term_grid = "0.1.5"
termsize = "0.1.6"
globset = "0.4.6"
glob = "0.3.0"
lscolors = { version = "0.7.1", features = ["ansi_term"] }
uucore = { version = ">=0.0.8", package = "uucore", path = "../../uucore", features = ["entries", "fs"] }
uucore_procs = { version=">=0.0.7", package = "uucore_procs", path = "../../uucore_procs" }

View file

@ -16,7 +16,7 @@ extern crate lazy_static;
mod quoting_style;
use clap::{crate_version, App, Arg};
use globset::{self, Glob, GlobSet, GlobSetBuilder};
use glob::Pattern;
use lscolors::LsColors;
use number_prefix::NumberPrefix;
use once_cell::unsync::OnceCell;
@ -233,7 +233,7 @@ struct Config {
recursive: bool,
reverse: bool,
dereference: Dereference,
ignore_patterns: GlobSet,
ignore_patterns: Vec<Pattern>,
size_format: SizeFormat,
directory: bool,
time: Time,
@ -547,16 +547,18 @@ impl Config {
} else {
TimeStyle::Locale
};
let mut ignore_patterns = GlobSetBuilder::new();
let mut ignore_patterns: Vec<Pattern> = Vec::new();
if options.is_present(options::IGNORE_BACKUPS) {
ignore_patterns.add(Glob::new("*~").unwrap());
ignore_patterns.add(Glob::new(".*~").unwrap());
ignore_patterns.push(Pattern::new("*~").unwrap());
ignore_patterns.push(Pattern::new(".*~").unwrap());
}
for pattern in options.values_of(options::IGNORE).into_iter().flatten() {
match Glob::new(pattern) {
match Pattern::new(pattern) {
Ok(p) => {
ignore_patterns.add(p);
ignore_patterns.push(p);
}
Err(_) => show_warning!("Invalid pattern for ignore: {}", pattern.quote()),
}
@ -564,21 +566,15 @@ impl Config {
if files == Files::Normal {
for pattern in options.values_of(options::HIDE).into_iter().flatten() {
match Glob::new(pattern) {
match Pattern::new(pattern) {
Ok(p) => {
ignore_patterns.add(p);
ignore_patterns.push(p);
}
Err(_) => show_warning!("Invalid pattern for hide: {}", pattern.quote()),
}
}
}
if files == Files::Normal {
ignore_patterns.add(Glob::new(".*").unwrap());
}
let ignore_patterns = ignore_patterns.build().unwrap();
let dereference = if options.is_present(options::dereference::ALL) {
Dereference::All
} else if options.is_present(options::dereference::ARGS) {
@ -1372,26 +1368,39 @@ fn sort_entries(entries: &mut Vec<PathData>, config: &Config) {
}
}
#[cfg(windows)]
fn is_hidden(file_path: &DirEntry) -> bool {
let path = file_path.path();
let metadata = fs::metadata(&path).unwrap_or_else(|_| fs::symlink_metadata(&path).unwrap());
let attr = metadata.file_attributes();
(attr & 0x2) > 0
#[cfg(windows)]
{
let path = file_path.path();
let metadata = fs::metadata(&path).unwrap_or_else(|_| fs::symlink_metadata(&path).unwrap());
let attr = metadata.file_attributes();
(attr & 0x2) > 0
}
#[cfg(unix)]
{
file_path
.file_name()
.to_str()
.map(|res| res.starts_with('.'))
.unwrap_or(false)
}
}
fn should_display(entry: &DirEntry, config: &Config) -> bool {
let ffi_name = entry.file_name();
// For unix, the hidden files are already included in the ignore pattern
#[cfg(windows)]
{
if config.files == Files::Normal && is_hidden(entry) {
return false;
}
// check if hidden
if config.files == Files::Normal && is_hidden(entry) {
return false;
}
!config.ignore_patterns.is_match(&ffi_name)
// check if explicitly ignored
for pattern in &config.ignore_patterns {
if pattern.matches(entry.file_name().to_str().unwrap()) {
return false;
};
continue;
}
// else default to display
true
}
fn enter_directory(dir: &PathData, config: &Config, out: &mut BufWriter<Stdout>) {
@ -1412,8 +1421,16 @@ fn enter_directory(dir: &PathData, config: &Config, out: &mut BufWriter<Stdout>)
let mut temp: Vec<_> = crash_if_err!(1, fs::read_dir(&dir.p_buf))
.map(|res| crash_if_err!(1, res))
.filter(|e| should_display(e, config))
.map(|e| PathData::new(DirEntry::path(&e), Some(e.file_type()), None, config, false))
.filter(|res| should_display(res, config))
.map(|res| {
PathData::new(
DirEntry::path(&res),
Some(res.file_type()),
None,
config,
false,
)
})
.collect();
sort_entries(&mut temp, config);

View file

@ -40,6 +40,35 @@ fn test_ls_i() {
}
#[test]
fn test_ls_walk_glob() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.touch(".test-1");
at.mkdir("some-dir");
at.touch(
Path::new("some-dir")
.join("test-2~")
.as_os_str()
.to_str()
.unwrap(),
);
#[allow(clippy::trivial_regex)]
let re_pwd = Regex::new(r"^\.\n").unwrap();
scene
.ucmd()
.arg("-1")
.arg("--ignore-backups")
.arg("some-dir")
.succeeds()
.stdout_does_not_contain("test-2~")
.stdout_does_not_contain("..")
.stdout_does_not_match(&re_pwd);
}
#[test]
#[cfg(unix)]
fn test_ls_a() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
@ -1903,6 +1932,7 @@ fn test_ls_ignore_hide() {
}
#[test]
#[cfg(unix)]
fn test_ls_ignore_backups() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;