mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
Merge pull request #2026 from tertsdiepraam/ls/hide_and_ignore
ls: --hide and --ignore
This commit is contained in:
commit
7cdeb18dff
4 changed files with 214 additions and 10 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -644,6 +644,19 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "globset"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"bstr",
|
||||||
|
"fnv",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
|
@ -1951,6 +1964,7 @@ version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap",
|
"clap",
|
||||||
|
"globset",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"term_grid",
|
"term_grid",
|
||||||
|
|
|
@ -22,6 +22,7 @@ term_grid = "0.1.5"
|
||||||
termsize = "0.1.6"
|
termsize = "0.1.6"
|
||||||
time = "0.1.40"
|
time = "0.1.40"
|
||||||
unicode-width = "0.1.5"
|
unicode-width = "0.1.5"
|
||||||
|
globset = "0.4.6"
|
||||||
uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ mod quoting_style;
|
||||||
mod version_cmp;
|
mod version_cmp;
|
||||||
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
|
use globset::{self, Glob, GlobSet, GlobSetBuilder};
|
||||||
use number_prefix::NumberPrefix;
|
use number_prefix::NumberPrefix;
|
||||||
use quoting_style::{escape_name, QuotingStyle};
|
use quoting_style::{escape_name, QuotingStyle};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -139,6 +140,8 @@ pub mod options {
|
||||||
pub static COLOR: &str = "color";
|
pub static COLOR: &str = "color";
|
||||||
pub static PATHS: &str = "paths";
|
pub static PATHS: &str = "paths";
|
||||||
pub static INDICATOR_STYLE: &str = "indicator-style";
|
pub static INDICATOR_STYLE: &str = "indicator-style";
|
||||||
|
pub static HIDE: &str = "hide";
|
||||||
|
pub static IGNORE: &str = "ignore";
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
|
@ -192,7 +195,7 @@ struct Config {
|
||||||
recursive: bool,
|
recursive: bool,
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
dereference: bool,
|
dereference: bool,
|
||||||
ignore_backups: bool,
|
ignore_patterns: GlobSet,
|
||||||
size_format: SizeFormat,
|
size_format: SizeFormat,
|
||||||
directory: bool,
|
directory: bool,
|
||||||
time: Time,
|
time: Time,
|
||||||
|
@ -451,6 +454,34 @@ impl Config {
|
||||||
IndicatorStyle::None
|
IndicatorStyle::None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut ignore_patterns = GlobSetBuilder::new();
|
||||||
|
if options.is_present(options::IGNORE_BACKUPS) {
|
||||||
|
ignore_patterns.add(Glob::new("*~").unwrap());
|
||||||
|
ignore_patterns.add(Glob::new(".*~").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
for pattern in options.values_of(options::IGNORE).into_iter().flatten() {
|
||||||
|
match Glob::new(pattern) {
|
||||||
|
Ok(p) => {
|
||||||
|
ignore_patterns.add(p);
|
||||||
|
}
|
||||||
|
Err(_) => show_warning!("Invalid pattern for ignore: '{}'", pattern),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if files == Files::Normal {
|
||||||
|
for pattern in options.values_of(options::HIDE).into_iter().flatten() {
|
||||||
|
match Glob::new(pattern) {
|
||||||
|
Ok(p) => {
|
||||||
|
ignore_patterns.add(p);
|
||||||
|
}
|
||||||
|
Err(_) => show_warning!("Invalid pattern for hide: '{}'", pattern),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ignore_patterns = ignore_patterns.build().unwrap();
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
format,
|
format,
|
||||||
files,
|
files,
|
||||||
|
@ -458,7 +489,7 @@ impl Config {
|
||||||
recursive: options.is_present(options::RECURSIVE),
|
recursive: options.is_present(options::RECURSIVE),
|
||||||
reverse: options.is_present(options::REVERSE),
|
reverse: options.is_present(options::REVERSE),
|
||||||
dereference: options.is_present(options::DEREFERENCE),
|
dereference: options.is_present(options::DEREFERENCE),
|
||||||
ignore_backups: options.is_present(options::IGNORE_BACKUPS),
|
ignore_patterns,
|
||||||
size_format,
|
size_format,
|
||||||
directory: options.is_present(options::DIRECTORY),
|
directory: options.is_present(options::DIRECTORY),
|
||||||
time,
|
time,
|
||||||
|
@ -699,6 +730,26 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Hide and ignore
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::HIDE)
|
||||||
|
.long(options::HIDE)
|
||||||
|
.takes_value(true)
|
||||||
|
.multiple(true)
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::IGNORE)
|
||||||
|
.long(options::IGNORE)
|
||||||
|
.takes_value(true)
|
||||||
|
.multiple(true)
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::IGNORE_BACKUPS)
|
||||||
|
.short("B")
|
||||||
|
.long(options::IGNORE_BACKUPS)
|
||||||
|
.help("Ignore entries which end with ~."),
|
||||||
|
)
|
||||||
|
|
||||||
// Sort arguments
|
// Sort arguments
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(options::SORT)
|
Arg::with_name(options::SORT)
|
||||||
|
@ -796,12 +847,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
'.' and '..'.",
|
'.' and '..'.",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name(options::IGNORE_BACKUPS)
|
|
||||||
.short("B")
|
|
||||||
.long(options::IGNORE_BACKUPS)
|
|
||||||
.help("Ignore entries which end with ~."),
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(options::DIRECTORY)
|
Arg::with_name(options::DIRECTORY)
|
||||||
.short("d")
|
.short("d")
|
||||||
|
@ -1019,11 +1064,12 @@ fn is_hidden(file_path: &DirEntry) -> bool {
|
||||||
|
|
||||||
fn should_display(entry: &DirEntry, config: &Config) -> bool {
|
fn should_display(entry: &DirEntry, config: &Config) -> bool {
|
||||||
let ffi_name = entry.file_name();
|
let ffi_name = entry.file_name();
|
||||||
let name = ffi_name.to_string_lossy();
|
|
||||||
if config.files == Files::Normal && is_hidden(entry) {
|
if config.files == Files::Normal && is_hidden(entry) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if config.ignore_backups && name.ends_with('~') {
|
|
||||||
|
if config.ignore_patterns.is_match(&ffi_name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
|
|
@ -1245,3 +1245,146 @@ fn test_ls_quoting_style() {
|
||||||
assert_eq!(result.stdout, format!("{}\n", correct));
|
assert_eq!(result.stdout, format!("{}\n", correct));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ls_ignore_hide() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
|
||||||
|
at.touch("README.md");
|
||||||
|
at.touch("CONTRIBUTING.md");
|
||||||
|
at.touch("some_other_file");
|
||||||
|
at.touch("READMECAREFULLY.md");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("*")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("*")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("irrelevant pattern")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("README*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("CONTRIBUTING.md\nsome_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("README*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("CONTRIBUTING.md\nsome_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("some_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-a")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(".\n..\nsome_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-a")
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is(".\n..\nCONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-A")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("some_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-A")
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("*.md")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n");
|
||||||
|
|
||||||
|
// Stacking multiple patterns
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("README*")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("CONTRIBUTING*")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("some_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("README*")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("CONTRIBUTING*")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("some_other_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("README*")
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("CONTRIBUTING*")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("some_other_file\n");
|
||||||
|
|
||||||
|
// Invalid patterns
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("READ[ME")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stderr_contains(&"Invalid pattern");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--hide")
|
||||||
|
.arg("READ[ME")
|
||||||
|
.arg("-1")
|
||||||
|
.succeeds()
|
||||||
|
.stderr_contains(&"Invalid pattern");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue