Skip to content

Commit a3dc214

Browse files
committed
--typo 2>/dev/full does not abort
1 parent f828549 commit a3dc214

File tree

1 file changed

+42
-36
lines changed

1 file changed

+42
-36
lines changed

src/uucore/src/lib/mods/clap_localization.rs

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ use clap::{ArgMatches, Command, Error};
2020
use std::error::Error as StdError;
2121
use std::ffi::OsString;
2222

23+
use std::io::Write as _;
24+
use std::io::stderr;
25+
2326
/// Color enum for consistent styling
2427
#[derive(Debug, Clone, Copy)]
2528
pub enum Color {
@@ -66,7 +69,7 @@ struct ColorManager(bool);
6669
impl ColorManager {
6770
/// Create a new ColorManager based on environment variables
6871
fn from_env() -> Self {
69-
Self(should_use_color_for_stream(&std::io::stderr()))
72+
Self(should_use_color_for_stream(&stderr()))
7073
}
7174

7275
/// Apply color to text if colors are enabled
@@ -124,7 +127,7 @@ impl<'a> ErrorFormatter<'a> {
124127
ErrorKind::MissingRequiredArgument => self.handle_missing_required(err, exit_code),
125128
ErrorKind::TooFewValues | ErrorKind::TooManyValues | ErrorKind::WrongNumberOfValues => {
126129
// These need full clap formatting
127-
eprint!("{}", err.render());
130+
let _ = write!(stderr(), "{}", err.render());
128131
exit_code
129132
}
130133
_ => self.handle_generic_error(err, exit_code),
@@ -144,28 +147,28 @@ impl<'a> ErrorFormatter<'a> {
144147
let error_word = translate!("common-error");
145148

146149
// Print main error
147-
eprintln!(
148-
"{}",
150+
let _ = write!(
151+
stderr(),
152+
"{}\n\n",
149153
translate!(
150154
"clap-error-unexpected-argument",
151155
"arg" => self.color_mgr.colorize(&arg_str, Color::Yellow),
152156
"error_word" => self.color_mgr.colorize(&error_word, Color::Red)
153157
)
154158
);
155-
eprintln!();
156159

157160
// Show suggestion if available
158161
if let Some(suggested_arg) = err.get(ContextKind::SuggestedArg) {
159162
let tip_word = translate!("common-tip");
160-
eprintln!(
161-
"{}",
163+
let _ = write!(
164+
stderr(),
165+
"{}\n\n",
162166
translate!(
163167
"clap-error-similar-argument",
164168
"tip_word" => self.color_mgr.colorize(&tip_word, Color::Green),
165169
"suggestion" => self.color_mgr.colorize(&suggested_arg.to_string(), Color::Green)
166170
)
167171
);
168-
eprintln!();
169172
} else {
170173
// Look for other tips from clap
171174
self.print_clap_tips(err);
@@ -190,7 +193,8 @@ impl<'a> ErrorFormatter<'a> {
190193
if value.is_empty() {
191194
// Value required but not provided
192195
let error_word = translate!("common-error");
193-
eprintln!(
196+
let _ = writeln!(
197+
stderr(),
194198
"{}",
195199
translate!("clap-error-value-required",
196200
"error_word" => self.color_mgr.colorize(&error_word, Color::Red),
@@ -208,7 +212,7 @@ impl<'a> ErrorFormatter<'a> {
208212
// Include validation error if present
209213
match err.source() {
210214
Some(source) if matches!(err.kind(), ErrorKind::ValueValidation) => {
211-
eprintln!("{error_msg}: {source}");
215+
let _ = writeln!(stderr(), "{error_msg}: {source}");
212216
}
213217
_ => eprintln!("{error_msg}"),
214218
}
@@ -218,17 +222,15 @@ impl<'a> ErrorFormatter<'a> {
218222
if matches!(err.kind(), ErrorKind::InvalidValue) {
219223
if let Some(valid_values) = err.get(ContextKind::ValidValue) {
220224
if !valid_values.to_string().is_empty() {
221-
eprintln!();
222-
eprintln!(
223-
" [{}: {valid_values}]",
225+
let _ = writeln!(
226+
stderr(),
227+
"\n [{}: {valid_values}]",
224228
translate!("clap-error-possible-values")
225229
);
226230
}
227231
}
228232
}
229-
230-
eprintln!();
231-
eprintln!("{}", translate!("common-help-suggestion"));
233+
let _ = writeln!(stderr(), "\n{}", translate!("common-help-suggestion"));
232234
} else {
233235
self.print_simple_error_msg(&err.render().to_string());
234236
}
@@ -255,7 +257,8 @@ impl<'a> ErrorFormatter<'a> {
255257
.starts_with("error: the following required arguments were not provided:") =>
256258
{
257259
let error_word = translate!("common-error");
258-
eprintln!(
260+
let _ = writeln!(
261+
stderr(),
259262
"{}",
260263
translate!(
261264
"clap-error-missing-required-arguments",
@@ -266,23 +269,23 @@ impl<'a> ErrorFormatter<'a> {
266269
// Print the missing arguments
267270
for line in lines.iter().skip(1) {
268271
if line.starts_with(" ") {
269-
eprintln!("{line}");
272+
let _ = writeln!(stderr(), "{line}");
270273
} else if line.starts_with("Usage:") || line.starts_with("For more information")
271274
{
272275
break;
273276
}
274277
}
275-
eprintln!();
278+
let _ = write!(stderr(), "\n");
276279

277280
// Print usage
278281
lines
279282
.iter()
280283
.skip_while(|line| !line.starts_with("Usage:"))
281284
.for_each(|line| {
282285
if line.starts_with("For more information, try '--help'.") {
283-
eprintln!("{}", translate!("common-help-suggestion"));
286+
let _ = writeln!(stderr(), "{}", translate!("common-help-suggestion"));
284287
} else {
285-
eprintln!("{line}");
288+
let _ = writeln!(stderr(), "{line}");
286289
}
287290
});
288291
}
@@ -296,18 +299,18 @@ impl<'a> ErrorFormatter<'a> {
296299
let rendered_str = err.render().to_string();
297300
if let Some(main_error_line) = rendered_str.lines().next() {
298301
self.print_localized_error_line(main_error_line);
299-
eprintln!();
300-
eprintln!("{}", translate!("common-help-suggestion"));
302+
let _ = writeln!(stderr(), "\n{}", translate!("common-help-suggestion"));
301303
} else {
302-
eprint!("{}", err.render());
304+
let _ = write!(stderr(), "{}", err.render());
303305
}
304306
exit_code
305307
}
306308

307309
/// Print a simple error message (no exit)
308310
fn print_simple_error_msg(&self, message: &str) {
309311
let error_word = translate!("common-error");
310-
eprintln!(
312+
let _ = writeln!(
313+
stderr(),
311314
"{}: {message}",
312315
self.color_mgr.colorize(&error_word, Color::Red)
313316
);
@@ -320,9 +323,9 @@ impl<'a> ErrorFormatter<'a> {
320323

321324
if let Some(colon_pos) = line.find(':') {
322325
let after_colon = &line[colon_pos..];
323-
eprintln!("{colored_error}{after_colon}");
326+
let _ = writeln!(stderr(), "{colored_error}{after_colon}");
324327
} else {
325-
eprintln!("{line}");
328+
let _ = writeln!(stderr(), "{line}");
326329
}
327330
}
328331

@@ -335,14 +338,15 @@ impl<'a> ErrorFormatter<'a> {
335338
let tip_word = translate!("common-tip");
336339
if let Some(colon_pos) = trimmed.find(':') {
337340
let after_colon = &trimmed[colon_pos..];
338-
eprintln!(
341+
let _ = writeln!(
342+
stderr(),
339343
" {}{after_colon}",
340344
self.color_mgr.colorize(&tip_word, Color::Green)
341345
);
342346
} else {
343-
eprintln!("{line}");
347+
let _ = writeln!(stderr(), "{line}");
344348
}
345-
eprintln!();
349+
let _ = write!(stderr(), "\n");
346350
}
347351
}
348352
}
@@ -353,9 +357,11 @@ impl<'a> ErrorFormatter<'a> {
353357
let usage_text = translate!(&usage_key);
354358
let formatted_usage = crate::format_usage(&usage_text);
355359
let usage_label = translate!("common-usage");
356-
eprintln!("{usage_label}: {formatted_usage}");
357-
eprintln!();
358-
eprintln!("{}", translate!("common-help-suggestion"));
360+
let _ = writeln!(
361+
stderr(),
362+
"{usage_label}: {formatted_usage}\n\n{}",
363+
translate!("common-help-suggestion")
364+
);
359365
}
360366
}
361367

@@ -609,7 +615,7 @@ mod tests {
609615
env::set_var("NO_COLOR", "1");
610616
}
611617
assert_eq!(get_color_choice(), clap::ColorChoice::Never);
612-
assert!(!should_use_color_for_stream(&std::io::stderr()));
618+
assert!(!should_use_color_for_stream(&stderr()));
613619
let mgr = ColorManager::from_env();
614620
assert!(!mgr.0);
615621
unsafe {
@@ -621,7 +627,7 @@ mod tests {
621627
env::set_var("CLICOLOR_FORCE", "1");
622628
}
623629
assert_eq!(get_color_choice(), clap::ColorChoice::Always);
624-
assert!(should_use_color_for_stream(&std::io::stderr()));
630+
assert!(should_use_color_for_stream(&stderr()));
625631
let mgr = ColorManager::from_env();
626632
assert!(mgr.0);
627633
unsafe {
@@ -633,7 +639,7 @@ mod tests {
633639
env::set_var("FORCE_COLOR", "1");
634640
}
635641
assert_eq!(get_color_choice(), clap::ColorChoice::Always);
636-
assert!(should_use_color_for_stream(&std::io::stderr()));
642+
assert!(should_use_color_for_stream(&stderr()));
637643
unsafe {
638644
env::remove_var("FORCE_COLOR");
639645
}

0 commit comments

Comments
 (0)