Skip to content

Commit 062f993

Browse files
committed
feat(tsort): reject multiple input arguments with custom error
- Change FILE arg to accept zero or more inputs (appended), defaulting to "-" if none - Add validation to error on more than one input with "extra operand" message - Update test to expect new error format, matching GNU tsort behavior - Unignore test_only_one_input_file after error message correction
1 parent 37cc210 commit 062f993

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

src/uu/tsort/src/tsort.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::ffi::OsString;
1010
use std::path::Path;
1111
use thiserror::Error;
1212
use uucore::display::Quotable;
13-
use uucore::error::{UError, UResult};
13+
use uucore::error::{UError, UResult, USimpleError};
1414
use uucore::{format_usage, show};
1515

1616
use uucore::translate;
@@ -49,15 +49,33 @@ impl UError for LoopNode<'_> {}
4949
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
5050
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
5151

52-
let input = matches
53-
.get_one::<OsString>(options::FILE)
54-
.expect("Value is required by clap");
52+
let mut inputs: Vec<OsString> = matches
53+
.get_many::<OsString>(options::FILE)
54+
.map(|vals| vals.cloned().collect())
55+
.unwrap_or_default();
56+
57+
if inputs.is_empty() {
58+
inputs.push(OsString::from("-"));
59+
}
60+
61+
if inputs.len() > 1 {
62+
return Err(USimpleError::new(
63+
1,
64+
format!(
65+
"extra operand {}\nTry 'tsort --help' for more information.",
66+
inputs[1].quote()
67+
),
68+
)
69+
.into());
70+
}
71+
72+
let input = inputs.into_iter().next().expect("at least one input");
5573

5674
let data = if input == "-" {
5775
let stdin = std::io::stdin();
5876
std::io::read_to_string(stdin)?
5977
} else {
60-
let path = Path::new(input);
78+
let path = Path::new(&input);
6179
if path.is_dir() {
6280
return Err(TsortError::IsDir(input.to_string_lossy().to_string()).into());
6381
}
@@ -104,10 +122,11 @@ pub fn uu_app() -> Command {
104122
)
105123
.arg(
106124
Arg::new(options::FILE)
107-
.default_value("-")
108125
.hide(true)
109126
.value_parser(clap::value_parser!(OsString))
110-
.value_hint(clap::ValueHint::FilePath),
127+
.value_hint(clap::ValueHint::FilePath)
128+
.num_args(0..)
129+
.action(ArgAction::Append),
111130
)
112131
}
113132

tests/by-util/test_tsort.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn test_multiple_arguments() {
7777
.arg("call_graph.txt")
7878
.arg("invalid_file")
7979
.fails()
80-
.stderr_contains("unexpected argument 'invalid_file' found");
80+
.stderr_contains("extra operand 'invalid_file'");
8181
}
8282

8383
#[test]
@@ -157,7 +157,7 @@ fn test_loop_for_iterative_dfs_correctness() {
157157
const TSORT_LOOP_STDERR: &str = "tsort: f: input contains a loop:\ntsort: s\ntsort: t\n";
158158
const TSORT_LOOP_STDERR_AC: &str = "tsort: f: input contains a loop:\ntsort: a\ntsort: b\ntsort: f: input contains a loop:\ntsort: a\ntsort: c\n";
159159
const TSORT_ODD_ERROR: &str = "tsort: -: input contains an odd number of tokens\n";
160-
const TSORT_UNEXPECTED_ARG_ERROR: &str = "tsort: error: unexpected argument 'g' found\n\nUsage: tsort [OPTIONS] FILE\n\nFor more information, try '--help'.\n";
160+
const TSORT_EXTRA_OPERAND_ERROR: &str = "tsort: extra operand 'g'\nTry 'tsort --help' for more information.\n";
161161

162162
#[test]
163163
fn test_cycle_loop_from_file() {
@@ -233,7 +233,6 @@ fn test_odd_number_of_tokens() {
233233
}
234234

235235
#[test]
236-
#[ignore = "After correcting the error message, execute."]
237236
fn test_only_one_input_file() {
238237
let (at, mut ucmd) = at_and_ucmd!();
239238
at.write("f", "");
@@ -243,5 +242,5 @@ fn test_only_one_input_file() {
243242
.arg("g")
244243
.fails_with_code(1)
245244
.stdout_is("")
246-
.stderr_is(TSORT_UNEXPECTED_ARG_ERROR);
245+
.stderr_is(TSORT_EXTRA_OPERAND_ERROR);
247246
}

0 commit comments

Comments
 (0)