Cli: v2 bug: Flags are treated as Args

Created on 17 Dec 2019  路  9Comments  路  Source: urfave/cli

my urfave/cli version is

2(recently updated with the master)

Checklist

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

Dependency Management

  • [x] 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

I am using some flags in the command.

app.Commands = []*cli.Command{
        {
            Name:            "init",
            Usage:           "Establish a connection",
            ArgsUsage:       "<host url>",
            SkipFlagParsing: false,
            Flags: []cli.Flag{
                &cli.BoolFlag{
                    Name:    "verbose",
                    Aliases: []string{"V"},
                    Usage:   "Be verbose",
                },
                &cli.IntFlag{
                    Name:  "retry, n",
                    Usage: "Number of tries to connect to the URL provided",
                    Value: 0,
                },
            },
            Action: func(c *cli.Context) error {
                return Init(c)
            },
        },

The Init() method:

func Init(c *cli.Context) error {
    log.Println(c.Args())
    log.Println(c.NArg())
    if c.Args().Len() != 1 {
        return errors.New("cli init requires exactly one argument: cli init <host_url>\nExample: cli init https://localhost:8090")
    }
    return nil
}

If I run cli init http://localhost:8090 -V, I get the length of the arguments as 2 which shouldn't be the case as I would be checking if the user has passed the correct number of arguments for the command.
I have been using V1 earlier. I have read the V2 docs, but didn't find any way other than using SkipFlagParsing: false. For V1 it was working perfectly as expected.

To reproduce

Try creating any command, which requires an argument as above, with the flags.

Expected behavior

When used Context.Args(), it should not include any flags.
For example when run with cli init http://localhost:8090 -V, Context.c.NArg() should return 1 instead of 2.

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, free free to create a pull request for it.

Run go version and paste its output here

go version go1.11.4 darwin/amd64

Run go env and paste its output here

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/akashdobaria/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/akashdobaria/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/l4/5v8nwx5n3s38659nx9frn2780000gn/T/go-build949260286=/tmp/go-build -gno-record-gcc-switches -fno-common"
arev2 help wanted kinbug statuconfirmed statustale

Most helpful comment

This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant.

All 9 comments

馃憤 @akashdobaria this issue here makes sense, marking it was help wanted for anyone to work on 馃憤

@akashdobaria if you have some extra time on your hands, you're totally free to work on the fix for this issue yourself! otherwise, I'm sure someone will swing around to work on it eventually 馃憖

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

This is still waiting for someone to help out with it 馃檹

This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant.

Did a little bit of investigation on this issue

The problem here is that if the first value passed is an arg not a flag, the flag won't even be parsed as a flag, but as an argument.
Example

package main

import (
    "log"
    "os"

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

func main() {
    app := cli.NewApp()

    app.Commands = []*cli.Command{
        {
            Name:      "init",
            Usage:     "Establish a connection",
            ArgsUsage: "<host url>",
            Flags: []cli.Flag{
                &cli.BoolFlag{
                    Name:    "verbose",
                    Aliases: []string{"V"},
                    Usage:   "Be verbose",
                },
            },
            Action: func(c *cli.Context) error {
                fmt.Printf("Args : %v\n", c.Args())
                fmt.Println(c.Bool("verbose"))
                return nil
            },
        },
    }
    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }
}

Running with flag first works fine :

go run main.go init -V bar 
Args : &[bar]
true

If the argument is passed first, the flag is not even parsed:

go run main.go init bar -V 
Args : &[bar -V]
false

On V1 it did work with flag being at the end, but the question here would be, isn't current behavior intended?

USAGE:
   main [global options] command [command options] [arguments...]

Help message in usage shows that options(flags) come before arguments, so it's working as intended?

i have same issue, i can't parse a flag in command

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

Closing this as it has become stale.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blackrez picture blackrez  路  5Comments

millken picture millken  路  5Comments

LeonB picture LeonB  路  5Comments

oleorhagen picture oleorhagen  路  4Comments

mponton picture mponton  路  5Comments