Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions console/cli_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,31 @@ func onUsageError(_ context.Context, _ *cli.Command, err error, _ bool) error {
return nil
}
}
if errMsg := err.Error(); strings.HasPrefix(errMsg, "invalid value") && strings.Contains(errMsg, "for argument") {
var value, argument string
if _, parseErr := fmt.Sscanf(errMsg, "invalid value %q for argument %s", &value, &argument); parseErr == nil {
var subErrMsg string
subErrMsgPos := strings.Index(errMsg, ":")
if subErrMsgPos != -1 {
subErrMsg = errMsg[subErrMsgPos+2:]
}
color.Red().Printfln("Invalid value '%s' for argument '%s'. Error: %s", value, strings.TrimSuffix(argument, ":"), subErrMsg)
return nil
}
}

if errMsg := err.Error(); strings.HasPrefix(errMsg, "sufficient count of arg") && strings.Contains(errMsg, "not provided") {
var argument string
var given, expected int
if _, parseErr := fmt.Sscanf(errMsg, "sufficient count of arg %s not provided, given %d expected %d", &argument, &given, &expected); parseErr == nil {
if expected == 1 {
color.Red().Printfln("The '%s' argument requires a value.", argument)
} else {
color.Red().Printfln("The '%s' argument requires at least %d values.", argument, expected)
}
return nil
}
}

return err
}
Expand Down
35 changes: 31 additions & 4 deletions console/cli_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ func TestShowCommandHelp_HelpPrinterCustom(t *testing.T) {
Test command

Usage:
test [global options] test:foo [options] <string_arg> [uint16_arg] [string_args...]
test [global options] test:foo [options] <string_arg> <two_string_args...> [uint16_arg] [any_count_string_args...]

Global options:
-h, --help Show help
--no-ansi Force disable ANSI output
-v, --version Print the version

Options:
-b, --bool Bool flag [default: false]
-i, --int int flag [default: 0]
-b, --bool Bool flag
-i, --int int flag
-h, --help Show help`,
},
},
Expand Down Expand Up @@ -124,6 +124,27 @@ Options:
color.Red().Sprint("Invalid value 'not-a-number' for option 'int'."),
},
},
{
name: "argument need a value",
call: "test:foo --int 0",
containsOutput: []string{
color.Red().Sprint("The 'string_arg' argument requires a value."),
},
},
{
name: "argument need a few values",
call: "test:foo --int 0 string_arg",
containsOutput: []string{
color.Red().Sprint("The 'two_string_args' argument requires at least 2 values."),
},
},
{
name: "argument value is not valid",
call: "test:foo --int 0 string_arg string_args1 string_args2 not-a-number",
containsOutput: []string{
color.Red().Sprint("Invalid value 'not-a-number' for argument 'uint16_arg'. Error: strconv.ParseUint: parsing \"not-a-number\": invalid syntax"),
},
},
{
name: "no ansi color",
call: "--no-ansi",
Expand Down Expand Up @@ -192,12 +213,18 @@ func (receiver *TestFooCommand) Extend() command.Extend {
Usage: "string argument",
Required: true,
},
&command.ArgumentStringSlice{
Name: "two_string_args",
Usage: "string arguments",
Min: 2,
Max: 2,
},
&command.ArgumentUint16{
Name: "uint16_arg",
Usage: "uint16 argument",
},
&command.ArgumentStringSlice{
Name: "string_args",
Name: "any_count_string_args",
Usage: "string arguments",
Min: 0,
Max: -1,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ require (
github.com/spf13/cast v1.10.0
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
github.com/urfave/cli/v3 v3.4.1
github.com/urfave/cli/v3 v3.5.0
golang.org/x/crypto v0.43.0
golang.org/x/exp v0.0.0-20251017212417-90e834f514db
google.golang.org/grpc v1.76.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/urfave/cli/v3 v3.4.1 h1:1M9UOCy5bLmGnuu1yn3t3CB4rG79Rtoxuv1sPhnm6qM=
github.com/urfave/cli/v3 v3.4.1/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
github.com/urfave/cli/v3 v3.5.0 h1:qCuFMmdayTF3zmjG8TSsoBzrDqszNrklYg2x3g4MSgw=
github.com/urfave/cli/v3 v3.5.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/vektra/mockery/v2 v2.53.5 h1:iktAY68pNiMvLoHxKqlSNSv/1py0QF/17UGrrAMYDI8=
github.com/vektra/mockery/v2 v2.53.5/go.mod h1:hIFFb3CvzPdDJJiU7J4zLRblUMv7OuezWsHPmswriwo=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
Expand Down
Loading