From 4cba342aaec67ced332759edf58970d58528b910 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Fri, 12 Jan 2024 08:49:07 +0100 Subject: [PATCH] feat: Add the `WithUsage` function. --- args.go | 13 +++++++++++++ args_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/args.go b/args.go index ed1e70ce..08f92f1c 100644 --- a/args.go +++ b/args.go @@ -129,3 +129,16 @@ func MatchAll(pargs ...PositionalArgs) PositionalArgs { func ExactValidArgs(n int) PositionalArgs { return MatchAll(ExactArgs(n), OnlyValidArgs) } + +// WithUsage wraps another PositionalArgs function. If the function fails +// (returns a non-nil error), the error is supplemented with the command's +// usage message, providing the user with the information required to run the +// command correctly. +func WithUsage(wrapped PositionalArgs) PositionalArgs { + return func(cmd *Command, args []string) error { + if err := wrapped(cmd, args); err != nil { + return fmt.Errorf("%w\n\n%s", err, cmd.UsageString()) + } + return nil + } +} diff --git a/args_test.go b/args_test.go index 90d174cc..077a2f3f 100644 --- a/args_test.go +++ b/args_test.go @@ -539,3 +539,27 @@ func TestLegacyArgsSubcmdAcceptsArgs(t *testing.T) { t.Fatalf("Unexpected error: %v", err) } } + +// WithUsage + +func TestWithUsage(t *testing.T) { + c := getCommand(WithUsage(ExactArgs(1)), false) + + _, err := executeCommand(c /* no args */) + if err == nil { + t.Fatalf("Expected error, got nil") + } + + got, want := err.Error(), c.UsageString() + if !strings.Contains(got, want) { + t.Errorf("Expected error containing %q, got %q", want, got) + } +} + +func ExampleWithUsage() { + cmd := &Command{ + Use: "example ", + Args: WithUsage(ExactArgs(1)), + } + _ = cmd // ignore unused +}