cli icon indicating copy to clipboard operation
cli copied to clipboard

Mutually exclusive flags are not suggested by shell completion

Open louisroyer opened this issue 2 months ago • 1 comments

My urfave/cli version is

v3.4.1

Checklist

  • [x] Are you running the latest v3 release? The list of releases is here.
  • [x] Did you check the manual for your release? The v3 manual is here
  • [x] Did you perform a search about this problem? Here's the GitHub guide about searching.

Dependency Management

  • My project is using go modules.

Describe the bug

Mutually exclusive flags are not suggested by shell completion.

To reproduce

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/urfave/cli/v3"
)

func main() {
	app := &cli.Command{
		Name:                  "mutually-exclusive-flags",
		EnableShellCompletion: true,
		Commands: []*cli.Command{
			{
				Name: "cmd1",
				Flags: []cli.Flag{
					&cli.BoolFlag{
						Name: "b0",
					},
				},
				Action: func(ctx context.Context, cmd *cli.Command) error {
					fmt.Println("Command 1:", cmd.Bool("b0"))
					return nil
				},
			},
			{
				Name: "cmd2",
				MutuallyExclusiveFlags: []cli.MutuallyExclusiveFlags{{
					Flags: [][]cli.Flag{
						{
							&cli.BoolFlag{
								Name: "b1",
							},
						},
						{
							&cli.BoolFlag{
								Name: "b2",
							},
						},
					},
				}},
				Action: func(ctx context.Context, cmd *cli.Command) error {
					fmt.Println("Command 2:", cmd.Bool("b1"), cmd.Bool("b2"))
					return nil
				},
			},
		},
	}
	if err := app.Run(context.TODO(), os.Args); err != nil {
		fmt.Println(err)
	}
}

Test it using the following:

go run . cmd1 - --generate-shell-completion
go run . cmd2 - --generate-shell-completion
go run . cmd2 --b1 - --generate-shell-completion
go run . cmd2 --b2 - --generate-shell-completion

Observed behavior

$ go run . cmd1 - --generate-shell-completion
--b0
--help
$ go run . cmd2 - --generate-shell-completion
--help
$ go run . cmd2 --b1 - --generate-shell-completion
--help
$ go run . cmd2 --b2 - --generate-shell-completion
--help

Mutually exclusive flags are ignored by the shell completion suggestions.

Expected behavior

$ go run . cmd1 - --generate-shell-completion
--b0
--help
$ go run . cmd2 - --generate-shell-completion
--help
--b1
--b2
$ go run . cmd2 --b1 - --generate-shell-completion
--help
$ go run . cmd2 --b2 - --generate-shell-completion
--help

The second command should suggest --b1 and --b2 flags. The first, third and fourth commands results are already correct.

Additional context

Add any other context about the problem here.

If the issue relates to a specific open source GitHub repo, please link that repo here.

If you can reproduce this issue with a public CI system, please link a failing build here.

Want to fix this yourself?

We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, feel free to create a pull request for it.

Run go version and paste its output here

# paste `go version` output in here
go version go1.25.1 linux/amd64     

Run go env and paste its output here

# paste `go env` output in here
AR='ar'                                  
CC='gcc'                                                                                                                                
CGO_CFLAGS='-O2 -g'     
CGO_CPPFLAGS=''     
CGO_CXXFLAGS='-O2 -g'                            
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'                                                                                                                    
CXX='g++'     
GCCGO='gccgo'       
GO111MODULE=''
GOAMD64='v1'                         
GOARCH='amd64'                                            
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/louis/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/louis/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1463017817=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/louis/Téléchargements/mutuallyexclusiveflags/go.mod'
GOMODCACHE='/home/louis/.local/share/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/louis/.local/share/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/louis/.local/share/go/pkg/mod/golang.org/[email protected]'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/louis/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/louis/.local/share/go/pkg/mod/golang.org/[email protected]/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.1'
GOWORK=''
PKG_CONFIG='pkg-config'

louisroyer avatar Oct 15 '25 10:10 louisroyer

@louisroyer can you review the PR ?

dearchap avatar Nov 02 '25 14:11 dearchap