mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 09:48:03 +00:00
Add -e/-m to realpath
This commit is contained in:
parent
68e89c7ea3
commit
625c3f2330
2 changed files with 79 additions and 3 deletions
|
@ -21,6 +21,8 @@ static OPT_STRIP: &str = "strip";
|
||||||
static OPT_ZERO: &str = "zero";
|
static OPT_ZERO: &str = "zero";
|
||||||
static OPT_PHYSICAL: &str = "physical";
|
static OPT_PHYSICAL: &str = "physical";
|
||||||
static OPT_LOGICAL: &str = "logical";
|
static OPT_LOGICAL: &str = "logical";
|
||||||
|
const OPT_CANONICALIZE_MISSING: &str = "canonicalize-missing";
|
||||||
|
const OPT_CANONICALIZE_EXISTING: &str = "canonicalize-existing";
|
||||||
|
|
||||||
static ARG_FILES: &str = "files";
|
static ARG_FILES: &str = "files";
|
||||||
|
|
||||||
|
@ -45,9 +47,16 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
let zero = matches.is_present(OPT_ZERO);
|
let zero = matches.is_present(OPT_ZERO);
|
||||||
let quiet = matches.is_present(OPT_QUIET);
|
let quiet = matches.is_present(OPT_QUIET);
|
||||||
let logical = matches.is_present(OPT_LOGICAL);
|
let logical = matches.is_present(OPT_LOGICAL);
|
||||||
|
let can_mode = if matches.is_present(OPT_CANONICALIZE_EXISTING) {
|
||||||
|
MissingHandling::Existing
|
||||||
|
} else if matches.is_present(OPT_CANONICALIZE_MISSING) {
|
||||||
|
MissingHandling::Missing
|
||||||
|
} else {
|
||||||
|
MissingHandling::Normal
|
||||||
|
};
|
||||||
let mut retcode = 0;
|
let mut retcode = 0;
|
||||||
for path in &paths {
|
for path in &paths {
|
||||||
if let Err(e) = resolve_path(path, strip, zero, logical) {
|
if let Err(e) = resolve_path(path, strip, zero, logical, can_mode) {
|
||||||
if !quiet {
|
if !quiet {
|
||||||
show_error!("{}: {}", e, path.display());
|
show_error!("{}: {}", e, path.display());
|
||||||
}
|
}
|
||||||
|
@ -92,6 +101,24 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
.overrides_with_all(&[OPT_STRIP, OPT_LOGICAL])
|
.overrides_with_all(&[OPT_STRIP, OPT_LOGICAL])
|
||||||
.help("resolve symlinks as encountered (default)"),
|
.help("resolve symlinks as encountered (default)"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(OPT_CANONICALIZE_EXISTING)
|
||||||
|
.short("e")
|
||||||
|
.long(OPT_CANONICALIZE_EXISTING)
|
||||||
|
.help(
|
||||||
|
"canonicalize by following every symlink in every component of the \
|
||||||
|
given name recursively, all components must exist",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name(OPT_CANONICALIZE_MISSING)
|
||||||
|
.short("m")
|
||||||
|
.long(OPT_CANONICALIZE_MISSING)
|
||||||
|
.help(
|
||||||
|
"canonicalize by following every symlink in every component of the \
|
||||||
|
given name recursively, without requirements on components existence",
|
||||||
|
),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(ARG_FILES)
|
Arg::with_name(ARG_FILES)
|
||||||
.multiple(true)
|
.multiple(true)
|
||||||
|
@ -112,7 +139,13 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
///
|
///
|
||||||
/// This function returns an error if there is a problem resolving
|
/// This function returns an error if there is a problem resolving
|
||||||
/// symbolic links.
|
/// symbolic links.
|
||||||
fn resolve_path(p: &Path, strip: bool, zero: bool, logical: bool) -> std::io::Result<()> {
|
fn resolve_path(
|
||||||
|
p: &Path,
|
||||||
|
strip: bool,
|
||||||
|
zero: bool,
|
||||||
|
logical: bool,
|
||||||
|
can_mode: MissingHandling,
|
||||||
|
) -> std::io::Result<()> {
|
||||||
let resolve = if strip {
|
let resolve = if strip {
|
||||||
ResolveMode::None
|
ResolveMode::None
|
||||||
} else if logical {
|
} else if logical {
|
||||||
|
@ -120,7 +153,7 @@ fn resolve_path(p: &Path, strip: bool, zero: bool, logical: bool) -> std::io::Re
|
||||||
} else {
|
} else {
|
||||||
ResolveMode::Physical
|
ResolveMode::Physical
|
||||||
};
|
};
|
||||||
let abs = canonicalize(p, MissingHandling::Normal, resolve)?;
|
let abs = canonicalize(p, can_mode, resolve)?;
|
||||||
let line_ending = if zero { '\0' } else { '\n' };
|
let line_ending = if zero { '\0' } else { '\n' };
|
||||||
|
|
||||||
print!("{}{}", abs.display(), line_ending);
|
print!("{}{}", abs.display(), line_ending);
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
use crate::common::util::*;
|
use crate::common::util::*;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
static GIBBERISH: &str = "supercalifragilisticexpialidocious";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_realpath_current_directory() {
|
fn test_realpath_current_directory() {
|
||||||
let (at, mut ucmd) = at_and_ucmd!();
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
@ -159,3 +163,42 @@ fn test_realpath_loop() {
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stdout_only(at.plus_as_string("2\n"));
|
.stdout_only(at.plus_as_string("2\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_realpath_default_allows_final_non_existent() {
|
||||||
|
let p = Path::new("").join(GIBBERISH);
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let expect = path_concat!(at.root_dir_resolved(), p.to_str().unwrap()) + "\n";
|
||||||
|
ucmd.arg(p.as_os_str()).succeeds().stdout_only(expect);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_realpath_default_forbids_non_final_non_existent() {
|
||||||
|
let p = Path::new("").join(GIBBERISH).join(GIBBERISH);
|
||||||
|
new_ucmd!().arg(p.to_str().unwrap()).fails();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_realpath_existing() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
ucmd.arg("-e")
|
||||||
|
.arg(".")
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only(at.plus_as_string(&format!("{}\n", at.root_dir_resolved())));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_realpath_existing_error() {
|
||||||
|
new_ucmd!().arg("-e").arg(GIBBERISH).fails();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_realpath_missing() {
|
||||||
|
let p = Path::new("").join(GIBBERISH).join(GIBBERISH);
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let expect = path_concat!(at.root_dir_resolved(), p.to_str().unwrap()) + "\n";
|
||||||
|
ucmd.arg("-m")
|
||||||
|
.arg(p.as_os_str())
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only(expect);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue