From af97f3f1c1f7fb09870ab3a07ce2e333e644fef9 Mon Sep 17 00:00:00 2001 From: ladysamantha <35412203+ladysamantha@users.noreply.github.com> Date: Sat, 3 Nov 2018 15:51:06 -0600 Subject: [PATCH] Print recipe signature if missing arguments (#369) --- src/justfile.rs | 31 +++++++++++++++++++++++++++++++ src/runtime_error.rs | 12 ++++++++++-- tests/integration.rs | 6 +++--- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/justfile.rs b/src/justfile.rs index bcb37c0..cbedf02 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -99,6 +99,7 @@ impl<'a> Justfile<'a> where { if !argument_range.range_contains(argument_count) { return Err(RuntimeError::ArgumentCountMismatch { recipe: recipe.name, + parameters: recipe.parameters.iter().collect(), found: tail.len(), min: recipe.min_arguments(), max: recipe.max_arguments(), @@ -307,11 +308,17 @@ a return code: { ArgumentCountMismatch { recipe, + parameters, found, min, max, } => { + let param_names = parameters + .iter() + .map(|p| p.name) + .collect::>(); assert_eq!(recipe, "a"); + assert_eq!(param_names, ["b", "c", "d"]); assert_eq!(found, 2); assert_eq!(min, 3); assert_eq!(max, 3); @@ -328,11 +335,17 @@ a return code: { ArgumentCountMismatch { recipe, + parameters, found, min, max, } => { + let param_names = parameters + .iter() + .map(|p| p.name) + .collect::>(); assert_eq!(recipe, "a"); + assert_eq!(param_names, ["b", "c", "d"]); assert_eq!(found, 2); assert_eq!(min, 3); assert_eq!(max, usize::MAX - 1); @@ -349,11 +362,17 @@ a return code: { ArgumentCountMismatch { recipe, + parameters, found, min, max, } => { + let param_names = parameters + .iter() + .map(|p| p.name) + .collect::>(); assert_eq!(recipe, "a"); + assert_eq!(param_names, ["b", "c", "d"]); assert_eq!(found, 0); assert_eq!(min, 3); assert_eq!(max, 3); @@ -370,11 +389,17 @@ a return code: { ArgumentCountMismatch { recipe, + parameters, found, min, max, } => { + let param_names = parameters + .iter() + .map(|p| p.name) + .collect::>(); assert_eq!(recipe, "a"); + assert_eq!(param_names, ["b", "c", "d"]); assert_eq!(found, 1); assert_eq!(min, 2); assert_eq!(max, 3); @@ -391,11 +416,17 @@ a return code: { ArgumentCountMismatch { recipe, + parameters, found, min, max, } => { + let param_names = parameters + .iter() + .map(|p| p.name) + .collect::>(); assert_eq!(recipe, "a"); + assert_eq!(param_names, ["b", "c", "d"]); assert_eq!(found, 0); assert_eq!(min, 1); assert_eq!(max, 3); diff --git a/src/runtime_error.rs b/src/runtime_error.rs index 3b2513a..277f4e4 100644 --- a/src/runtime_error.rs +++ b/src/runtime_error.rs @@ -23,7 +23,7 @@ fn write_token_error_context(f: &mut fmt::Formatter, token: &Token) -> Result<() #[derive(Debug)] pub enum RuntimeError<'a> { - ArgumentCountMismatch{recipe: &'a str, found: usize, min: usize, max: usize}, + ArgumentCountMismatch{recipe: &'a str, parameters: Vec<&'a Parameter<'a>>, found: usize, min: usize, max: usize}, Backtick{token: Token<'a>, output_error: OutputError}, Code{recipe: &'a str, line_number: Option, code: i32}, Cygpath{recipe: &'a str, output_error: OutputError}, @@ -71,7 +71,7 @@ impl<'a> Display for RuntimeError<'a> { maybe_s(overrides.len()), And(&overrides.iter().map(Tick).collect::>()))?; }, - ArgumentCountMismatch{recipe, found, min, max} => { + ArgumentCountMismatch{recipe, ref parameters, found, min, max} => { if min == max { let expected = min; write!(f, "Recipe `{}` got {} argument{} but {}takes {}", @@ -84,6 +84,14 @@ impl<'a> Display for RuntimeError<'a> { write!(f, "Recipe `{}` got {} argument{} but takes at most {}", recipe, found, maybe_s(found), max)?; } + write!(f, "\nusage:\n just {}", recipe)?; + for param in parameters { + if color.stderr().active() { + write!(f, " {:#}", param)?; + } else { + write!(f, " {}", param)?; + } + } }, Code{recipe, line_number, code} => { if let Some(n) = line_number { diff --git a/tests/integration.rs b/tests/integration.rs index 62412fb..a8d85b3 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -779,7 +779,7 @@ foo A B: ", args: ("foo", "ONE"), stdout: "", - stderr: "error: Recipe `foo` got 1 argument but takes 2\n", + stderr: "error: Recipe `foo` got 1 argument but takes 2\nusage:\n just foo A B\n", status: EXIT_FAILURE, } @@ -803,7 +803,7 @@ foo A B C='C': ", args: ("foo", "bar"), stdout: "", - stderr: "error: Recipe `foo` got 1 argument but takes at least 2\n", + stderr: "error: Recipe `foo` got 1 argument but takes at least 2\nusage:\n just foo A B C='C'\n", status: EXIT_FAILURE, } @@ -1670,7 +1670,7 @@ a x y +z: ", args: ("a", "0", "1"), stdout: "", - stderr: "error: Recipe `a` got 2 arguments but takes at least 3\n", + stderr: "error: Recipe `a` got 2 arguments but takes at least 3\nusage:\n just a x y +z\n", status: EXIT_FAILURE, }