readlink: Set silent mode as default (#10711)

* readlink: Set silent mode as default

* readlink: Add tests for verbose and silent options

* readlink: Change test to work with Windows-specific error message

* readlink: Add additional test cases

---------

Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
This commit is contained in:
lyra
2026-02-12 02:51:28 -08:00
committed by GitHub
co-authored by Sylvestre Ledru
parent 74b13c0fd0
commit 1c023bfad9
2 changed files with 64 additions and 4 deletions
+7 -4
View File
@@ -6,6 +6,7 @@
// spell-checker:ignore (ToDO) errno
use clap::{Arg, ArgAction, Command};
use std::env;
use std::ffi::OsString;
use std::fs;
use std::io::{Write, stdout};
@@ -35,8 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let mut no_trailing_delimiter = matches.get_flag(OPT_NO_NEWLINE);
let use_zero = matches.get_flag(OPT_ZERO);
let silent = matches.get_flag(OPT_SILENT) || matches.get_flag(OPT_QUIET);
let verbose = matches.get_flag(OPT_VERBOSE);
let verbose = matches.get_flag(OPT_VERBOSE) || env::var("POSIXLY_CORRECT").is_ok();
// GNU readlink -f/-e/-m follows symlinks first and then applies `..` (physical resolution).
// ResolveMode::Logical collapses `..` before following links, which yields the opposite order,
@@ -70,7 +70,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
));
}
if no_trailing_delimiter && files.len() > 1 && !silent {
if no_trailing_delimiter && files.len() > 1 {
show_error!("{}", translate!("readlink-error-ignoring-no-newline"));
no_trailing_delimiter = false;
}
@@ -93,7 +93,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
show(&path, line_ending).map_err_context(String::new)?;
}
Err(err) => {
if silent && !verbose {
if !verbose {
return Err(1.into());
}
@@ -151,6 +151,7 @@ pub fn uu_app() -> Command {
.short('q')
.long(OPT_QUIET)
.help(translate!("readlink-help-quiet"))
.overrides_with_all([OPT_QUIET, OPT_SILENT, OPT_VERBOSE])
.action(ArgAction::SetTrue),
)
.arg(
@@ -158,6 +159,7 @@ pub fn uu_app() -> Command {
.short('s')
.long(OPT_SILENT)
.help(translate!("readlink-help-silent"))
.overrides_with_all([OPT_QUIET, OPT_SILENT, OPT_VERBOSE])
.action(ArgAction::SetTrue),
)
.arg(
@@ -165,6 +167,7 @@ pub fn uu_app() -> Command {
.short('v')
.long(OPT_VERBOSE)
.help(translate!("readlink-help-verbose"))
.overrides_with_all([OPT_QUIET, OPT_SILENT, OPT_VERBOSE])
.action(ArgAction::SetTrue),
)
.arg(
+57
View File
@@ -138,6 +138,22 @@ fn test_posixly_correct_regular_file() {
.fails_with_code(1)
.stderr_contains("Invalid argument")
.no_stdout();
// GNU behavior is to ignore -s and -q when POSIXLY_CORRECT is set.
scene
.ucmd()
.env("POSIXLY_CORRECT", "1")
.args(&["-s", "regfile"])
.fails_with_code(1)
.stderr_contains("Invalid argument")
.no_stdout();
scene
.ucmd()
.env("POSIXLY_CORRECT", "1")
.args(&["-q", "regfile"])
.fails_with_code(1)
.stderr_contains("Invalid argument")
.no_stdout();
}
#[test]
@@ -433,3 +449,44 @@ fn test_readlink_non_utf8_paths() {
let output = result.stdout_str_lossy();
assert!(output.contains(file_name));
}
#[test]
fn test_verbose_or_silent() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
at.touch("regfile");
scene
.ucmd()
.arg("regfile")
.fails_with_code(1)
.no_stderr()
.no_stdout();
scene
.ucmd()
.args(&["-v", "regfile"])
.fails_with_code(1)
.stderr_contains(
#[cfg(not(windows))]
"Invalid argument",
#[cfg(windows)]
"regfile: The file or directory is not a reparse point.",
)
.no_stdout();
scene
.ucmd()
.args(&["-vs", "regfile"])
.fails_with_code(1)
.no_stderr()
.no_stdout();
scene
.ucmd()
.args(&["-sv", "regfile"])
.fails_with_code(1)
.stderr_contains(
#[cfg(not(windows))]
"Invalid argument",
#[cfg(windows)]
"regfile: The file or directory is not a reparse point.",
)
.no_stdout();
}