mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #2077 from tertsdiepraam/ls/dereference-command-line
ls: dereference command line
This commit is contained in:
commit
481d1ee659
2 changed files with 335 additions and 34 deletions
|
@ -120,6 +120,11 @@ pub mod options {
|
||||||
pub static FILE_TYPE: &str = "file-type";
|
pub static FILE_TYPE: &str = "file-type";
|
||||||
pub static CLASSIFY: &str = "classify";
|
pub static CLASSIFY: &str = "classify";
|
||||||
}
|
}
|
||||||
|
pub mod dereference {
|
||||||
|
pub static ALL: &str = "dereference";
|
||||||
|
pub static ARGS: &str = "dereference-command-line";
|
||||||
|
pub static DIR_ARGS: &str = "dereference-command-line-symlink-to-dir";
|
||||||
|
}
|
||||||
pub static HIDE_CONTROL_CHARS: &str = "hide-control-chars";
|
pub static HIDE_CONTROL_CHARS: &str = "hide-control-chars";
|
||||||
pub static SHOW_CONTROL_CHARS: &str = "show-control-chars";
|
pub static SHOW_CONTROL_CHARS: &str = "show-control-chars";
|
||||||
pub static WIDTH: &str = "width";
|
pub static WIDTH: &str = "width";
|
||||||
|
@ -134,7 +139,6 @@ pub mod options {
|
||||||
pub static FILE_TYPE: &str = "file-type";
|
pub static FILE_TYPE: &str = "file-type";
|
||||||
pub static SLASH: &str = "p";
|
pub static SLASH: &str = "p";
|
||||||
pub static INODE: &str = "inode";
|
pub static INODE: &str = "inode";
|
||||||
pub static DEREFERENCE: &str = "dereference";
|
|
||||||
pub static REVERSE: &str = "reverse";
|
pub static REVERSE: &str = "reverse";
|
||||||
pub static RECURSIVE: &str = "recursive";
|
pub static RECURSIVE: &str = "recursive";
|
||||||
pub static COLOR: &str = "color";
|
pub static COLOR: &str = "color";
|
||||||
|
@ -180,6 +184,13 @@ enum Time {
|
||||||
Change,
|
Change,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Dereference {
|
||||||
|
None,
|
||||||
|
DirArgs,
|
||||||
|
Args,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
enum IndicatorStyle {
|
enum IndicatorStyle {
|
||||||
None,
|
None,
|
||||||
|
@ -194,7 +205,7 @@ struct Config {
|
||||||
sort: Sort,
|
sort: Sort,
|
||||||
recursive: bool,
|
recursive: bool,
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
dereference: bool,
|
dereference: Dereference,
|
||||||
ignore_patterns: GlobSet,
|
ignore_patterns: GlobSet,
|
||||||
size_format: SizeFormat,
|
size_format: SizeFormat,
|
||||||
directory: bool,
|
directory: bool,
|
||||||
|
@ -483,13 +494,28 @@ impl Config {
|
||||||
|
|
||||||
let ignore_patterns = ignore_patterns.build().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) {
|
||||||
|
Dereference::Args
|
||||||
|
} else if options.is_present(options::dereference::DIR_ARGS) {
|
||||||
|
Dereference::DirArgs
|
||||||
|
} else if options.is_present(options::DIRECTORY)
|
||||||
|
|| indicator_style == IndicatorStyle::Classify
|
||||||
|
|| format == Format::Long
|
||||||
|
{
|
||||||
|
Dereference::None
|
||||||
|
} else {
|
||||||
|
Dereference::DirArgs
|
||||||
|
};
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
format,
|
format,
|
||||||
files,
|
files,
|
||||||
sort,
|
sort,
|
||||||
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,
|
||||||
ignore_patterns,
|
ignore_patterns,
|
||||||
size_format,
|
size_format,
|
||||||
directory: options.is_present(options::DIRECTORY),
|
directory: options.is_present(options::DIRECTORY),
|
||||||
|
@ -820,6 +846,48 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Dereferencing
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::dereference::ALL)
|
||||||
|
.short("L")
|
||||||
|
.long(options::dereference::ALL)
|
||||||
|
.help(
|
||||||
|
"When showing file information for a symbolic link, show information for the \
|
||||||
|
file the link references rather than the link itself.",
|
||||||
|
)
|
||||||
|
.overrides_with_all(&[
|
||||||
|
options::dereference::ALL,
|
||||||
|
options::dereference::DIR_ARGS,
|
||||||
|
options::dereference::ARGS,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::dereference::DIR_ARGS)
|
||||||
|
.long(options::dereference::DIR_ARGS)
|
||||||
|
.help(
|
||||||
|
"Do not dereference symlinks except when they link to directories and are \
|
||||||
|
given as command line arguments.",
|
||||||
|
)
|
||||||
|
.overrides_with_all(&[
|
||||||
|
options::dereference::ALL,
|
||||||
|
options::dereference::DIR_ARGS,
|
||||||
|
options::dereference::ARGS,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(options::dereference::ARGS)
|
||||||
|
.short("H")
|
||||||
|
.long(options::dereference::ARGS)
|
||||||
|
.help(
|
||||||
|
"Do not dereference symlinks except when given as command line arguments.",
|
||||||
|
)
|
||||||
|
.overrides_with_all(&[
|
||||||
|
options::dereference::ALL,
|
||||||
|
options::dereference::DIR_ARGS,
|
||||||
|
options::dereference::ARGS,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
|
||||||
// Long format options
|
// Long format options
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(options::NO_GROUP)
|
Arg::with_name(options::NO_GROUP)
|
||||||
|
@ -878,15 +946,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
.long(options::INODE)
|
.long(options::INODE)
|
||||||
.help("print the index number of each file"),
|
.help("print the index number of each file"),
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name(options::DEREFERENCE)
|
|
||||||
.short("L")
|
|
||||||
.long(options::DEREFERENCE)
|
|
||||||
.help(
|
|
||||||
"When showing file information for a symbolic link, show information for the \
|
|
||||||
file the link references rather than the link itself.",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(options::REVERSE)
|
Arg::with_name(options::REVERSE)
|
||||||
.short("r")
|
.short("r")
|
||||||
|
@ -994,26 +1053,32 @@ fn list(locs: Vec<String>, config: Config) -> i32 {
|
||||||
has_failed = true;
|
has_failed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut dir = false;
|
|
||||||
|
|
||||||
if p.is_dir() && !config.directory {
|
let show_dir_contents = if !config.directory {
|
||||||
dir = true;
|
match config.dereference {
|
||||||
if config.format == Format::Long && !config.dereference {
|
Dereference::None => {
|
||||||
if let Ok(md) = p.symlink_metadata() {
|
if let Ok(md) = p.symlink_metadata() {
|
||||||
if md.file_type().is_symlink() && !p.ends_with("/") {
|
md.is_dir()
|
||||||
dir = false;
|
} else {
|
||||||
|
show_error!("'{}': {}", &loc, "No such file or directory");
|
||||||
|
has_failed = true;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => p.is_dir(),
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if dir {
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if show_dir_contents {
|
||||||
dirs.push(p);
|
dirs.push(p);
|
||||||
} else {
|
} else {
|
||||||
files.push(p);
|
files.push(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort_entries(&mut files, &config);
|
sort_entries(&mut files, &config);
|
||||||
display_items(&files, None, &config);
|
display_items(&files, None, &config, true);
|
||||||
|
|
||||||
sort_entries(&mut dirs, &config);
|
sort_entries(&mut dirs, &config);
|
||||||
for dir in dirs {
|
for dir in dirs {
|
||||||
|
@ -1033,14 +1098,15 @@ fn sort_entries(entries: &mut Vec<PathBuf>, config: &Config) {
|
||||||
match config.sort {
|
match config.sort {
|
||||||
Sort::Time => entries.sort_by_key(|k| {
|
Sort::Time => entries.sort_by_key(|k| {
|
||||||
Reverse(
|
Reverse(
|
||||||
get_metadata(k, config)
|
get_metadata(k, false)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|md| get_system_time(&md, config))
|
.and_then(|md| get_system_time(&md, config))
|
||||||
.unwrap_or(UNIX_EPOCH),
|
.unwrap_or(UNIX_EPOCH),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
Sort::Size => entries
|
Sort::Size => {
|
||||||
.sort_by_key(|k| Reverse(get_metadata(k, config).map(|md| md.len()).unwrap_or(0))),
|
entries.sort_by_key(|k| Reverse(get_metadata(k, false).map(|md| md.len()).unwrap_or(0)))
|
||||||
|
}
|
||||||
// The default sort in GNU ls is case insensitive
|
// The default sort in GNU ls is case insensitive
|
||||||
Sort::Name => entries.sort_by_key(|k| k.to_string_lossy().to_lowercase()),
|
Sort::Name => entries.sort_by_key(|k| k.to_string_lossy().to_lowercase()),
|
||||||
Sort::Version => entries.sort_by(|a, b| version_cmp::version_cmp(a, b)),
|
Sort::Version => entries.sort_by(|a, b| version_cmp::version_cmp(a, b)),
|
||||||
|
@ -1089,9 +1155,9 @@ fn enter_directory(dir: &Path, config: &Config) {
|
||||||
let mut display_entries = entries.clone();
|
let mut display_entries = entries.clone();
|
||||||
display_entries.insert(0, dir.join(".."));
|
display_entries.insert(0, dir.join(".."));
|
||||||
display_entries.insert(0, dir.join("."));
|
display_entries.insert(0, dir.join("."));
|
||||||
display_items(&display_entries, Some(dir), config);
|
display_items(&display_entries, Some(dir), config, false);
|
||||||
} else {
|
} else {
|
||||||
display_items(&entries, Some(dir), config);
|
display_items(&entries, Some(dir), config, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.recursive {
|
if config.recursive {
|
||||||
|
@ -1102,8 +1168,8 @@ fn enter_directory(dir: &Path, config: &Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_metadata(entry: &Path, config: &Config) -> std::io::Result<Metadata> {
|
fn get_metadata(entry: &Path, dereference: bool) -> std::io::Result<Metadata> {
|
||||||
if config.dereference {
|
if dereference {
|
||||||
entry.metadata().or_else(|_| entry.symlink_metadata())
|
entry.metadata().or_else(|_| entry.symlink_metadata())
|
||||||
} else {
|
} else {
|
||||||
entry.symlink_metadata()
|
entry.symlink_metadata()
|
||||||
|
@ -1111,7 +1177,7 @@ fn get_metadata(entry: &Path, config: &Config) -> std::io::Result<Metadata> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_dir_entry_size(entry: &Path, config: &Config) -> (usize, usize) {
|
fn display_dir_entry_size(entry: &Path, config: &Config) -> (usize, usize) {
|
||||||
if let Ok(md) = get_metadata(entry, config) {
|
if let Ok(md) = get_metadata(entry, false) {
|
||||||
(
|
(
|
||||||
display_symlink_count(&md).len(),
|
display_symlink_count(&md).len(),
|
||||||
display_file_size(&md, config).len(),
|
display_file_size(&md, config).len(),
|
||||||
|
@ -1125,7 +1191,7 @@ fn pad_left(string: String, count: usize) -> String {
|
||||||
format!("{:>width$}", string, width = count)
|
format!("{:>width$}", string, width = count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_items(items: &[PathBuf], strip: Option<&Path>, config: &Config) {
|
fn display_items(items: &[PathBuf], strip: Option<&Path>, config: &Config, command_line: bool) {
|
||||||
if config.format == Format::Long {
|
if config.format == Format::Long {
|
||||||
let (mut max_links, mut max_size) = (1, 1);
|
let (mut max_links, mut max_size) = (1, 1);
|
||||||
for item in items {
|
for item in items {
|
||||||
|
@ -1134,11 +1200,11 @@ fn display_items(items: &[PathBuf], strip: Option<&Path>, config: &Config) {
|
||||||
max_size = size.max(max_size);
|
max_size = size.max(max_size);
|
||||||
}
|
}
|
||||||
for item in items {
|
for item in items {
|
||||||
display_item_long(item, strip, max_links, max_size, config);
|
display_item_long(item, strip, max_links, max_size, config, command_line);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let names = items.iter().filter_map(|i| {
|
let names = items.iter().filter_map(|i| {
|
||||||
let md = get_metadata(i, config);
|
let md = get_metadata(i, false);
|
||||||
match md {
|
match md {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let filename = get_file_name(i, strip);
|
let filename = get_file_name(i, strip);
|
||||||
|
@ -1210,8 +1276,26 @@ fn display_item_long(
|
||||||
max_links: usize,
|
max_links: usize,
|
||||||
max_size: usize,
|
max_size: usize,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
command_line: bool,
|
||||||
) {
|
) {
|
||||||
let md = match get_metadata(item, config) {
|
let dereference = match &config.dereference {
|
||||||
|
Dereference::All => true,
|
||||||
|
Dereference::Args => command_line,
|
||||||
|
Dereference::DirArgs => {
|
||||||
|
if command_line {
|
||||||
|
if let Ok(md) = item.metadata() {
|
||||||
|
md.is_dir()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dereference::None => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let md = match get_metadata(item, dereference) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let filename = get_file_name(&item, strip);
|
let filename = get_file_name(&item, strip);
|
||||||
show_error!("{}: {}", filename, e);
|
show_error!("{}: {}", filename, e);
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::common::util::*;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
use self::regex::Regex;
|
use self::regex::Regex;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -1314,3 +1315,219 @@ fn test_ls_ignore_hide() {
|
||||||
.stderr_contains(&"Invalid pattern")
|
.stderr_contains(&"Invalid pattern")
|
||||||
.stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n");
|
.stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ls_directory() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
|
||||||
|
at.mkdir("some_dir");
|
||||||
|
at.symlink_dir("some_dir", "sym_dir");
|
||||||
|
|
||||||
|
at.touch(Path::new("some_dir").join("nested_file").to_str().unwrap());
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("some_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("nested_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--directory")
|
||||||
|
.arg("some_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("some_dir\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("nested_file\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ls_deref_command_line() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
|
||||||
|
at.touch("some_file");
|
||||||
|
at.symlink_file("some_file", "sym_file");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("sym_file")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("sym_file\n");
|
||||||
|
|
||||||
|
// -l changes the default to no dereferencing
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("sym_file")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_file ->");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.arg("sym_file")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("sym_file\n");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.arg("sym_file")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_file ->");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--dereference-command-line")
|
||||||
|
.arg("sym_file")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_is("sym_file\n");
|
||||||
|
|
||||||
|
let result = scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line")
|
||||||
|
.arg("sym_file")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
assert!(!result.stdout_str().contains("->"));
|
||||||
|
|
||||||
|
let result = scene.ucmd().arg("-lH").arg("sym_file").succeeds();
|
||||||
|
|
||||||
|
assert!(!result.stdout_str().contains("sym_file ->"));
|
||||||
|
|
||||||
|
// If the symlink is not a command line argument, it must be shown normally
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_file ->");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ls_deref_command_line_dir() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
|
||||||
|
at.mkdir("some_dir");
|
||||||
|
at.symlink_dir("some_dir", "sym_dir");
|
||||||
|
|
||||||
|
at.touch(Path::new("some_dir").join("nested_file").to_str().unwrap());
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("nested_file");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_dir ->");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("nested_file");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("nested_file");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("--dereference-command-line")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("nested_file");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("nested_file");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-lH")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("nested_file");
|
||||||
|
|
||||||
|
// If the symlink is not a command line argument, it must be shown normally
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_dir ->");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-lH")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_dir ->");
|
||||||
|
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_dir ->");
|
||||||
|
|
||||||
|
// --directory does not dereference anything by default
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--directory")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_dir ->");
|
||||||
|
|
||||||
|
let result = scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--directory")
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
assert!(!result.stdout_str().ends_with("sym_dir"));
|
||||||
|
|
||||||
|
// --classify does not dereference anything by default
|
||||||
|
scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--directory")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_contains("sym_dir ->");
|
||||||
|
|
||||||
|
let result = scene
|
||||||
|
.ucmd()
|
||||||
|
.arg("-l")
|
||||||
|
.arg("--directory")
|
||||||
|
.arg("--dereference-command-line-symlink-to-dir")
|
||||||
|
.arg("sym_dir")
|
||||||
|
.succeeds();
|
||||||
|
|
||||||
|
assert!(!result.stdout_str().ends_with("sym_dir"));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue