mirror of
https://github.com/uutils/coreutils
synced 2024-11-15 01:17:09 +00:00
ls: align --ignore behavior with that of GNU ls
This commit is contained in:
parent
0f98bd01e1
commit
d84803b72f
2 changed files with 83 additions and 13 deletions
|
@ -14,7 +14,7 @@ use clap::{
|
||||||
builder::{NonEmptyStringValueParser, ValueParser},
|
builder::{NonEmptyStringValueParser, ValueParser},
|
||||||
crate_version, Arg, Command,
|
crate_version, Arg, Command,
|
||||||
};
|
};
|
||||||
use glob::Pattern;
|
use glob::{MatchOptions, Pattern};
|
||||||
use lscolors::LsColors;
|
use lscolors::LsColors;
|
||||||
use number_prefix::NumberPrefix;
|
use number_prefix::NumberPrefix;
|
||||||
use once_cell::unsync::OnceCell;
|
use once_cell::unsync::OnceCell;
|
||||||
|
@ -41,6 +41,7 @@ use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use uucore::libc::{S_IXGRP, S_IXOTH, S_IXUSR};
|
use uucore::libc::{S_IXGRP, S_IXOTH, S_IXUSR};
|
||||||
|
use uucore::parse_glob;
|
||||||
use uucore::quoting_style::{escape_name, QuotingStyle};
|
use uucore::quoting_style::{escape_name, QuotingStyle};
|
||||||
use uucore::{
|
use uucore::{
|
||||||
display::Quotable,
|
display::Quotable,
|
||||||
|
@ -765,7 +766,7 @@ impl Config {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
{
|
{
|
||||||
match Pattern::new(pattern) {
|
match parse_glob::from_str(pattern) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
ignore_patterns.push(p);
|
ignore_patterns.push(p);
|
||||||
}
|
}
|
||||||
|
@ -779,7 +780,7 @@ impl Config {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
{
|
{
|
||||||
match Pattern::new(pattern) {
|
match parse_glob::from_str(pattern) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
ignore_patterns.push(p);
|
ignore_patterns.push(p);
|
||||||
}
|
}
|
||||||
|
@ -1877,16 +1878,18 @@ fn should_display(entry: &DirEntry, config: &Config) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if explicitly ignored
|
// check if it is among ignore_patterns
|
||||||
for pattern in &config.ignore_patterns {
|
let options = MatchOptions {
|
||||||
if pattern.matches(entry.file_name().to_str().unwrap()) {
|
// setting require_literal_leading_dot to match behavior in GNU ls
|
||||||
return false;
|
require_literal_leading_dot: true,
|
||||||
};
|
require_literal_separator: false,
|
||||||
continue;
|
case_sensitive: true,
|
||||||
}
|
};
|
||||||
|
let file_name = entry.file_name().into_string().unwrap();
|
||||||
// else default to display
|
!config
|
||||||
true
|
.ignore_patterns
|
||||||
|
.iter()
|
||||||
|
.any(|p| p.matches_with(&file_name, options))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_directory(
|
fn enter_directory(
|
||||||
|
|
|
@ -2681,6 +2681,73 @@ fn test_ls_ignore_backups() {
|
||||||
.stdout_does_not_contain(".somehiddenbackup~");
|
.stdout_does_not_contain(".somehiddenbackup~");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test fails on windows, see details at #3985
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[test]
|
||||||
|
fn test_ls_ignore_explicit_period() {
|
||||||
|
// In ls ignore patterns, leading periods must be explicitly specified
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
at.touch(".hidden.yml");
|
||||||
|
at.touch("regular.yml");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-a")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("?hidden.yml")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains(".hidden.yml")
|
||||||
|
.stdout_contains("regular.yml");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-a")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("*.yml")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains(".hidden.yml")
|
||||||
|
.stdout_does_not_contain("regular.yml");
|
||||||
|
|
||||||
|
// Leading period is explicitly specified
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-a")
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg(".*.yml")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_does_not_contain(".hidden.yml")
|
||||||
|
.stdout_contains("regular.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test fails on windows, see details at #3985
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[test]
|
||||||
|
fn test_ls_ignore_negation() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
at.touch("apple");
|
||||||
|
at.touch("boy");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("[!a]*")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("apple")
|
||||||
|
.stdout_does_not_contain("boy");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--ignore")
|
||||||
|
.arg("[^a]*")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("apple")
|
||||||
|
.stdout_does_not_contain("boy");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ls_directory() {
|
fn test_ls_directory() {
|
||||||
let scene = TestScenario::new(util_name!());
|
let scene = TestScenario::new(util_name!());
|
||||||
|
|
Loading…
Reference in a new issue