mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
du: add support of --dereference-args
Should fix tests/du/deref.sh
This commit is contained in:
parent
5a1d9cec7e
commit
eea8d40e78
2 changed files with 55 additions and 13 deletions
|
@ -68,6 +68,7 @@ mod options {
|
||||||
pub const TIME_STYLE: &str = "time-style";
|
pub const TIME_STYLE: &str = "time-style";
|
||||||
pub const ONE_FILE_SYSTEM: &str = "one-file-system";
|
pub const ONE_FILE_SYSTEM: &str = "one-file-system";
|
||||||
pub const DEREFERENCE: &str = "dereference";
|
pub const DEREFERENCE: &str = "dereference";
|
||||||
|
pub const DEREFERENCE_ARGS: &str = "dereference-args";
|
||||||
pub const INODES: &str = "inodes";
|
pub const INODES: &str = "inodes";
|
||||||
pub const EXCLUDE: &str = "exclude";
|
pub const EXCLUDE: &str = "exclude";
|
||||||
pub const EXCLUDE_FROM: &str = "exclude-from";
|
pub const EXCLUDE_FROM: &str = "exclude-from";
|
||||||
|
@ -89,6 +90,7 @@ struct Options {
|
||||||
separate_dirs: bool,
|
separate_dirs: bool,
|
||||||
one_file_system: bool,
|
one_file_system: bool,
|
||||||
dereference: bool,
|
dereference: bool,
|
||||||
|
dereference_args: Vec<PathBuf>,
|
||||||
inodes: bool,
|
inodes: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
}
|
}
|
||||||
|
@ -113,7 +115,7 @@ struct Stat {
|
||||||
|
|
||||||
impl Stat {
|
impl Stat {
|
||||||
fn new(path: PathBuf, options: &Options) -> Result<Self> {
|
fn new(path: PathBuf, options: &Options) -> Result<Self> {
|
||||||
let metadata = if options.dereference {
|
let metadata = if options.dereference || options.dereference_args.contains(&path) {
|
||||||
fs::metadata(&path)?
|
fs::metadata(&path)?
|
||||||
} else {
|
} else {
|
||||||
fs::symlink_metadata(&path)?
|
fs::symlink_metadata(&path)?
|
||||||
|
@ -505,17 +507,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
summarize,
|
summarize,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let options = Options {
|
|
||||||
all: matches.get_flag(options::ALL),
|
|
||||||
max_depth,
|
|
||||||
total: matches.get_flag(options::TOTAL),
|
|
||||||
separate_dirs: matches.get_flag(options::SEPARATE_DIRS),
|
|
||||||
one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM),
|
|
||||||
dereference: matches.get_flag(options::DEREFERENCE),
|
|
||||||
inodes: matches.get_flag(options::INODES),
|
|
||||||
verbose: matches.get_flag(options::VERBOSE),
|
|
||||||
};
|
|
||||||
|
|
||||||
let files = match matches.get_one::<String>(options::FILE) {
|
let files = match matches.get_one::<String>(options::FILE) {
|
||||||
Some(_) => matches
|
Some(_) => matches
|
||||||
.get_many::<String>(options::FILE)
|
.get_many::<String>(options::FILE)
|
||||||
|
@ -525,6 +516,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
None => vec!["."],
|
None => vec!["."],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let options = Options {
|
||||||
|
all: matches.get_flag(options::ALL),
|
||||||
|
max_depth,
|
||||||
|
total: matches.get_flag(options::TOTAL),
|
||||||
|
separate_dirs: matches.get_flag(options::SEPARATE_DIRS),
|
||||||
|
one_file_system: matches.get_flag(options::ONE_FILE_SYSTEM),
|
||||||
|
dereference: matches.get_flag(options::DEREFERENCE),
|
||||||
|
dereference_args: if matches.get_flag(options::DEREFERENCE_ARGS) {
|
||||||
|
// Convert into a pathbuf as we will use it in a function using Pathbuf
|
||||||
|
// We don't care about the cost as it is rarely used
|
||||||
|
files.iter().map(PathBuf::from).collect()
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
|
inodes: matches.get_flag(options::INODES),
|
||||||
|
verbose: matches.get_flag(options::VERBOSE),
|
||||||
|
};
|
||||||
|
|
||||||
if options.inodes
|
if options.inodes
|
||||||
&& (matches.get_flag(options::APPARENT_SIZE) || matches.get_flag(options::BYTES))
|
&& (matches.get_flag(options::APPARENT_SIZE) || matches.get_flag(options::BYTES))
|
||||||
{
|
{
|
||||||
|
@ -789,6 +798,13 @@ pub fn uu_app() -> Command {
|
||||||
.help("dereference all symbolic links")
|
.help("dereference all symbolic links")
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::SetTrue)
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new(options::DEREFERENCE_ARGS)
|
||||||
|
.short('D')
|
||||||
|
.long(options::DEREFERENCE_ARGS)
|
||||||
|
.help("dereference only symlinks that are listed on the command line")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
)
|
||||||
// .arg(
|
// .arg(
|
||||||
// Arg::new("no-dereference")
|
// Arg::new("no-dereference")
|
||||||
// .short('P')
|
// .short('P')
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// * For the full copyright and license information, please view the LICENSE
|
// * For the full copyright and license information, please view the LICENSE
|
||||||
// * file that was distributed with this source code.
|
// * file that was distributed with this source code.
|
||||||
|
|
||||||
// spell-checker:ignore (paths) sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty
|
// spell-checker:ignore (paths) sublink subwords azerty azeaze xcwww azeaz amaz azea qzerty tazerty tsublink
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -285,6 +285,30 @@ fn test_du_dereference() {
|
||||||
_du_dereference(result.stdout_str());
|
_du_dereference(result.stdout_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[test]
|
||||||
|
fn test_du_dereference_args() {
|
||||||
|
let ts = TestScenario::new(util_name!());
|
||||||
|
let at = &ts.fixtures;
|
||||||
|
|
||||||
|
at.mkdir_all("subdir");
|
||||||
|
let mut file1 = at.make_file("subdir/file-ignore1");
|
||||||
|
file1.write_all(b"azeaze").unwrap();
|
||||||
|
let mut file2 = at.make_file("subdir/file-ignore1");
|
||||||
|
file2.write_all(b"amaz?ng").unwrap();
|
||||||
|
at.symlink_dir("subdir", "sublink");
|
||||||
|
|
||||||
|
let result = ts.ucmd().arg("-D").arg("-s").arg("sublink").succeeds();
|
||||||
|
let stdout = result.stdout_str();
|
||||||
|
|
||||||
|
assert!(!stdout.starts_with("0"));
|
||||||
|
assert!(stdout.contains("sublink"));
|
||||||
|
|
||||||
|
// Without the option
|
||||||
|
let result = ts.ucmd().arg("-s").arg("sublink").succeeds();
|
||||||
|
result.stdout_contains("0\tsublink\n");
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
fn _du_dereference(s: &str) {
|
fn _du_dereference(s: &str) {
|
||||||
assert_eq!(s, "4\tsubdir/links/deeper_dir\n16\tsubdir/links\n");
|
assert_eq!(s, "4\tsubdir/links/deeper_dir\n16\tsubdir/links\n");
|
||||||
|
@ -851,6 +875,7 @@ fn test_du_exclude_invalid_syntax() {
|
||||||
.stderr_contains("du: Invalid exclude syntax");
|
.stderr_contains("du: Invalid exclude syntax");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_du_symlink_fail() {
|
fn test_du_symlink_fail() {
|
||||||
let ts = TestScenario::new(util_name!());
|
let ts = TestScenario::new(util_name!());
|
||||||
|
@ -861,6 +886,7 @@ fn test_du_symlink_fail() {
|
||||||
ts.ucmd().arg("-L").arg("target.txt").fails().code_is(1);
|
ts.ucmd().arg("-L").arg("target.txt").fails().code_is(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_du_symlink_multiple_fail() {
|
fn test_du_symlink_multiple_fail() {
|
||||||
let ts = TestScenario::new(util_name!());
|
let ts = TestScenario::new(util_name!());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue