Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to put generic arguments before flags in v2 #1481

Closed
yirez-tc opened this issue Sep 6, 2022 · 6 comments
Closed

How to put generic arguments before flags in v2 #1481

yirez-tc opened this issue Sep 6, 2022 · 6 comments
Labels
area/v2 relates to / is being considered for v2 kind/question someone asking a question status/triage maintainers still need to look into this

Comments

@yirez-tc
Copy link

yirez-tc commented Sep 6, 2022

I've been trying to place generic arguments first when running a cli command, like this:
testrun aaa -lang spanish

Following along the spanish example in the tutorial here

What I get back is everything has become an argument. If I do it the other way round, with the argument at the back everything works fine. Is there a flag I'm missing to set for it to work in the initial way. I put up a stackoverflow question up too but didn't get any responses to that.

urfave/cli version: v2.14.1
golang v: 1.18
stackoverflow question link: https://stackoverflow.com/questions/73587275/urfave-cli-argument-placement-prevents-flag-parsing

@yirez-tc yirez-tc added area/v2 relates to / is being considered for v2 kind/question someone asking a question status/triage maintainers still need to look into this labels Sep 6, 2022
@yirez-tc yirez-tc changed the title Putting generic arguments first before flags in v2 How to put generic arguments before flags in v2 Sep 6, 2022
@abousselmi
Copy link
Member

Hi @yirez-tc

Why would you put flags/options at the end ? The usual way of running a cli would be the other way around, flags/options first and then arguments.

I can think about few examples from the linux world:

mkdir.exe r --help
Usage: mkdir [OPTION]... DIRECTORY...
...

or

rmdir --help
Usage: rmdir [OPTION]... DIRECTORY...

or

ls --help
Usage: ls [OPTION]... [FILE]...

I'm not saying that it should not be possible, but the standard way is options first, then args.

@yirez-tc
Copy link
Author

yirez-tc commented Sep 7, 2022

Hey @abousselmi ,

We can make do with putting it at the end but there was a specific requirement for a cli tool we were building. It had several flags and one of the flags was to be the first argument implicitly since it will be used the most often. The intention was to be a bit like an sql command.

something like below where this,that argument could be used without explicitly typing -oftenUsedFlag instead.
find this,that -oftenUsedFlag value -otherflag value ...

@abousselmi
Copy link
Member

abousselmi commented Sep 7, 2022

Hey @yirez-tc ,

The CLI help is pretty clear about the order of flags and args. You cannot have args before global options or command options.
A dummy find cli would print the following:

NAME:
   find - Usage of my cli

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

To achieve what you are asking, you can do something like :

func main() {
	app := &cli.App{
		Name:  "find",
		Usage: "Usage of my cli",

		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:  "oftenUsedFlag",
				Value: "val",
				Usage: "My flag 1",
			},
			&cli.StringFlag{
				Name:  "otherflag",
				Value: "other val",
				Usage: "My flag 2",
			},
			&cli.StringFlag{
				Name:  "arg",
				Value: "false arg",
				Usage: "My false arg",
			},
		},

		Action: func(cCtx *cli.Context) error {
			fmt.Println(cCtx.String("oftenUsedFlag"))
			fmt.Println(cCtx.String("otherflag"))

			fmt.Println("Hello", cCtx.String("arg"))
			return nil
		},
	}
        if err := app.Run(os.Args); err != nil {
		log.Fatal(err)
	}
}

Then you can create an alias and execute it like this:

$ alias find="./find -arg"

which gives you the requested behavior, using only flags, with no args around

$ find this,that -oftenUsedFlag f1 -otherflag f2
f1
f2
Hello this,that

@tschaub
Copy link

tschaub commented Sep 12, 2022

Why would you put flags/options at the end ? The usual way of running a cli

Both

git push origin main --force

and

git push --force origin main

work equally well.

I guess the limitation in this package is due to the behavior of flagSet.Parse() (see also golang/go#4513, golang/go#24107, golang/go#36744).

@zhujintao
Copy link

use gopkg.in/alecthomas/kingpin.v2

@dearchap
Copy link
Contributor

dearchap commented Oct 21, 2022

Duplicate of #1113

@dearchap dearchap closed this as not planned Won't fix, can't repro, duplicate, stale Oct 21, 2022
@dearchap dearchap marked this as a duplicate of #1113 Oct 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/v2 relates to / is being considered for v2 kind/question someone asking a question status/triage maintainers still need to look into this
Projects
None yet
Development

No branches or pull requests

5 participants