Skip to content

Commit db20094

Browse files
authored
Improve error message for invalid number of arguments to hook-impl (#1196)
1 parent 6a2f212 commit db20094

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

src/cli/hook_impl.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use std::ffi::OsString;
22
use std::fmt::Write;
33
use std::io::Read;
4+
use std::ops::RangeInclusive;
45
use std::path::PathBuf;
56

67
use anstream::eprintln;
78
use anyhow::Result;
9+
use itertools::Itertools;
810
use owo_colors::OwoColorize;
911

1012
use prek_consts::env_vars::EnvVars;
@@ -99,8 +101,13 @@ pub(crate) async fn hook_impl(
99101
}
100102

101103
if !hook_type.num_args().contains(&args.len()) {
102-
eprintln!("Invalid number of arguments for hook: {}", hook_type);
103-
return Ok(ExitStatus::Failure);
104+
anyhow::bail!(
105+
"hook `{}` expects {} but received {}{}",
106+
hook_type.to_string().cyan(),
107+
format_expected_args(hook_type.num_args()),
108+
format_received_args(args.len()),
109+
format_argument_dump(&args)
110+
);
104111
}
105112

106113
let Some(run_args) = to_run_args(hook_type, &args).await else {
@@ -267,3 +274,31 @@ async fn parse_pre_push_info(remote_name: &str) -> Option<PushInfo> {
267274
// Nothing to push
268275
None
269276
}
277+
278+
fn format_expected_args(range: RangeInclusive<usize>) -> String {
279+
let (start, end) = (*range.start(), *range.end());
280+
match (start, end) {
281+
(0, 0) => "no arguments".to_string(),
282+
(1, 1) => "exactly 1 argument".to_string(),
283+
(s, e) if s == e => format!("exactly {s} arguments"),
284+
(0, e) => format!("up to {e} arguments"),
285+
(s, usize::MAX) => format!("at least {s} arguments"),
286+
(s, e) => format!("between {s} and {e} arguments"),
287+
}
288+
}
289+
290+
fn format_received_args(received: usize) -> String {
291+
match received {
292+
0 => "no arguments".to_string(),
293+
1 => "1 argument".to_string(),
294+
n => format!("{n} arguments"),
295+
}
296+
}
297+
298+
fn format_argument_dump(args: &[OsString]) -> String {
299+
if args.is_empty() {
300+
String::new()
301+
} else {
302+
format!(": `{}`", args.iter().map(|s| s.to_string_lossy()).join(" "))
303+
}
304+
}

0 commit comments

Comments
 (0)