Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(cli): show error/hide help for unsupported subcommands (#10760)#12624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall 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
24 changes: 21 additions & 3 deletionscli/help.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,9 @@ import (
"bufio"
_"embed"
"fmt"
"os"
"regexp"
"slices"
"sort"
"strings"
"text/tabwriter"
Expand DownExpand Up@@ -320,6 +322,25 @@ var usageWantsArgRe = regexp.MustCompile(`<.*>`)
// output for a given command.
funchelpFn() serpent.HandlerFunc {
returnfunc(inv*serpent.Invocation)error {
// Check for invalid subcommands before printing help.
iflen(inv.Args)>0&&!usageWantsArgRe.MatchString(inv.Command.Use) {
_,_=fmt.Fprintf(inv.Stderr,"---\nerror: unrecognized subcommand %q\n",inv.Args[0])
}
iflen(inv.Args)>0 {
// Return an error so that exit status is non-zero when
// a subcommand is not found.
err:=xerrors.Errorf("unrecognized subcommand %q",strings.Join(inv.Args," "))
ifslices.Contains(os.Args,"--help") {
// Subcommand error is not wrapped in RunCommandErr if command
// is invoked with --help with no HelpHandler
return&serpent.RunCommandError{
Cmd:inv.Command,
Err:err,
}
}
returnerr
}

// We use stdout for help and not stderr since there's no straightforward
// way to distinguish between a user error and a help request.
//
Expand All@@ -340,9 +361,6 @@ func helpFn() serpent.HandlerFunc {
iferr!=nil {
returnerr
}
iflen(inv.Args)>0&&!usageWantsArgRe.MatchString(inv.Command.Use) {
_,_=fmt.Fprintf(inv.Stderr,"---\nerror: unknown subcommand %q\n",inv.Args[0])
}
returnnil
}
}
4 changes: 0 additions & 4 deletionscli/portforward.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -69,10 +69,6 @@ func (r *RootCmd) portForward() *serpent.Command {
returnxerrors.Errorf("parse port-forward specs: %w",err)
}
iflen(specs)==0 {
err=inv.Command.HelpHandler(inv)
iferr!=nil {
returnxerrors.Errorf("generate help output: %w",err)
}
returnxerrors.New("no port-forwards requested")
}

Expand Down
5 changes: 0 additions & 5 deletionscli/portforward_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,15 +35,10 @@ func TestPortForward_None(t *testing.T) {

inv,root:=clitest.New(t,"port-forward","blah")
clitest.SetupConfig(t,member,root)
pty:=ptytest.New(t).Attach(inv)
inv.Stderr=pty.Output()

err:=inv.Run()
require.Error(t,err)
require.ErrorContains(t,err,"no port-forwards")

// Check that the help was printed.
pty.ExpectMatch("port-forward <workspace>")
}

funcTestPortForward(t*testing.T) {
Expand Down
7 changes: 5 additions & 2 deletionscli/root.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1196,10 +1196,13 @@ func formatMultiError(from string, multi []error, opts *formatOpts) string {
// formatter and add it to cliHumanFormatError function.
funcformatRunCommandError(err*serpent.RunCommandError,opts*formatOpts)string {
varstr strings.Builder
_,_=str.WriteString(pretty.Sprint(headLineStyle(),fmt.Sprintf("Encountered an error running %q",err.Cmd.FullName())))
_,_=str.WriteString(pretty.Sprint(headLineStyle(),
fmt.Sprintf(
`Encountered an error running %q, see "%s --help" for more information`,
err.Cmd.FullName(),err.Cmd.FullName())))
_,_=str.WriteString(pretty.Sprint(headLineStyle(),"\nerror: "))

msgString,special:=cliHumanFormatError("",err.Err,opts)
_,_=str.WriteString("\n")
ifspecial {
_,_=str.WriteString(msgString)
}else {
Expand Down
43 changes: 43 additions & 0 deletionscli/root_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,6 +60,49 @@ func TestCommandHelp(t *testing.T) {

funcTestRoot(t*testing.T) {
t.Parallel()
t.Run("MissingRootCommand",func(t*testing.T) {
t.Parallel()

out:=new(bytes.Buffer)

inv,_:=clitest.New(t,"idontexist")
inv.Stdout=out

err:=inv.Run()
assert.ErrorContains(t,err,
`unrecognized subcommand "idontexist"`)
require.Empty(t,out.String())
})

t.Run("MissingSubcommand",func(t*testing.T) {
t.Parallel()

out:=new(bytes.Buffer)

inv,_:=clitest.New(t,"server","idontexist")
inv.Stdout=out

err:=inv.Run()
// subcommand error only when command has subcommands
assert.ErrorContains(t,err,
`unrecognized subcommand "idontexist"`)
require.Empty(t,out.String())
})

t.Run("BadSubcommandArgs",func(t*testing.T) {
t.Parallel()

out:=new(bytes.Buffer)

inv,_:=clitest.New(t,"list","idontexist")
inv.Stdout=out

err:=inv.Run()
assert.ErrorContains(t,err,
`wanted no args but got 1 [idontexist]`)
require.Empty(t,out.String())
})

t.Run("Version",func(t*testing.T) {
t.Parallel()

Expand Down
2 changes: 0 additions & 2 deletionsgo.sum
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -214,8 +214,6 @@ github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx
github.com/coder/prettyv0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc=
github.com/coder/retryv1.5.1 h1:iWu8YnD8YqHs3XwqrqsjoBTAVqT9ml6z9ViJ2wlMiqc=
github.com/coder/retryv1.5.1/go.mod h1:blHMk9vs6LkoRT9ZHyuZo360cufXEhrxqvEzeMtRGoY=
github.com/coder/serpentv0.4.0 h1:L/itwnCxfhLutxQ2mScP3tH1ro8z8+Kc/iKKyZZxEMk=
github.com/coder/serpentv0.4.0/go.mod h1:Wud83ikZF/ulbdMcEMAwqvkEIQx7+l47+ef69M/arAA=
github.com/coder/serpentv0.4.1-0.20240315163851-a0148c87ea3f h1:nqJ/Mvm+nLI22n5BIYhvSmTZ6CD+MRo/aGVZwVQgr1k=
github.com/coder/serpentv0.4.1-0.20240315163851-a0148c87ea3f/go.mod h1:REkJ5ZFHQUWFTPLExhXYZ1CaHFjxvGNRlLXLdsI08YA=
github.com/coder/sshv0.0.0-20231128192721-70855dedb788 h1:YoUSJ19E8AtuUFVYBpXuOD6a/zVP3rcxezNsoDseTUw=
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp