-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
my urfave/cli version is
v1.22.1
was the last working version, and all versions up to v1.22.4
are broken.
Checklist
- Are you running the latest v1 release? The list of releases is here.
- Did you check the manual for your release? The v1 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.
- My project is using vendoring.
- My project is automatically downloading the latest version.
- I am unsure of what my dependency management setup is.
Describe the bug
If you try to use a flag-like argument to a string slice argument that is not a valid flag, the argument gets ignored and instead the next argument is used instead (which, if it is a valid string slice argument it is swallowed as a flag value).
To reproduce
First, set up a basic Go dev environment for the test:
% mkdir -p /tmp/testcli
% cd /tmp/testcli
% go mod init example.com/testcli
go: creating new go.mod: module example.com/testcli
% go get github.com/urfave/cli@v1.22.4
go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
And then try to run the following program:
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Commands = []cli.Command{
{
Name: "config",
Flags: []cli.Flag{
cli.StringSliceFlag{
Name: "config.cmd",
},
},
Action: func(ctx *cli.Context) error {
fmt.Printf("args: %v\n", os.Args)
fmt.Printf("leftover args: %v\n", ctx.Args())
fmt.Printf("config.cmd: %v\n", ctx.StringSlice("config.cmd"))
return nil
},
},
}
err := app.Run(os.Args)
if err != nil {
fmt.Printf("err: %v\n", err)
}
}
Like so:
% go run main.go config --config.cmd "-c" --config.cmd "ls -la"
Observed behavior
If you use 1.22.2
or later of github.com/urfave/cli
, you find:
% go run main.go config --config.cmd "-c" --config.cmd "ls -la"
args: [/tmp/go-build948656450/b001/exe/main config --config.cmd -c --config.cmd ls -la]
leftover args: [ls -la -c]
config.cmd: [--config.cmd]
What appears to be happening is that the -c
argument to the --config.cmd
flag is being skipped -- though it's not being treated as an unknown flag (there's no error about unknown flags) and instead is being treated as a positional argument. As as result, --config.cmd
is being used as an argument (presumably because it's a known flag?) and the rest of the arguments are treated as positional arguments.
However, if you instead call the program like so you get the correct output:
% go run main.go config --config.cmd="-c" --config.cmd "ls -la"
args: [/tmp/go-build358735402/b001/exe/main config --config.cmd=-c --config.cmd ls -la]
leftover args: []
config.cmd: [-c ls -la]
Expected behavior
If you use 1.22.1
or earlier of github.com/urfave/cli
, you find:
% go run main.go config --config.cmd "-c" --config.cmd "ls -la"
args: [/tmp/go-build278409428/b001/exe/main config --config.cmd -c --config.cmd ls -la]
leftover args: []
config.cmd: [-c ls -la]
Additional context
I am trying to update my version of github.com/urfave/cli
in umoci and this is an issue I hit almost immediately when trying to do the update.
N.B. This issue doesn't happen unless you use subcommands. If you try to do this with the top-level app.Flags
then it works as expected.
Run go version
and paste its output here
go version go1.14.4 linux/amd64
Run go env
and paste its output here
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/cyphar/.cache/go-build"
GOENV="/home/cyphar/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/cyphar/.local"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib64/go/1.14"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib64/go/1.14/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/cyphar/tmp/testcli/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build827330497=/tmp/go-build -gno-record-gcc-switches"