Skip to content

Mutually exclusive flags are not suggested by shell completion #2209

@louisroyer

Description

@louisroyer

My urfave/cli version is

v3.4.1

Checklist

  • Are you running the latest v3 release? The list of releases is here.
  • Did you check the manual for your release? The v3 manual is here
  • 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/toolchain@v0.0.1-go1.25.1.linux-amd64'
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/toolchain@v0.0.1-go1.25.1.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.1'
GOWORK=''
PKG_CONFIG='pkg-config'

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/v3relates to / is being considered for v3kind/bugdescribes or fixes a bugstatus/triagemaintainers still need to look into this

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions