getopt icon indicating copy to clipboard operation
getopt copied to clipboard

Flags don't parse after encountering positional parameter

Open tlhunter opened this issue 2 years ago • 1 comments

Based on what I've read in the documentation I would expect the following to work, but I might have misconfigured something. Essentially I would like to support syntax like what git exposes, ala git status --short command.

Here's some sample code:

	connection := ""
	migrations := ""

	getopt.FlagLong(&connection, "connection", 'c', "SQL connection string")
	getopt.FlagLong(&migrations, "migrations", 'm', "Migrations directory")

	getopt.Parse()

	config := MigConfig{
		Connection: connection,
		Migrations: migrations,
	}

	args := getopt.Args()

	fmt.Println("CONFIG")
	fmt.Println(config)
	fmt.Println("ARGS")
	fmt.Println(args)

	return config, nil

Next, I'm invoking the program in two ways:

$ app status --connection="foo"    
CONFIG
{ }
ARGS
[status --connection=foo]

$ app --connection="foo" status
CONFIG
{foo }
ARGS
[status]

The second invocation works as expected, pulling the flag data out and providing the remaining non-flag arguments via .Args(). However the first invocation, in the style of the git command, wasn't able to parse the flags. Have I configured this wrong or is this expected behavior?

tlhunter avatar Dec 30 '22 06:12 tlhunter

There's nothing misconfigured. That's just how this library has been written to work. There's precedent for it; it's how the corresponding GNU function works when the POSIXLY_CORRECT environment variable is set.

It can be useful when the argument list allows subcommands. Arguments to the "main" program aren't necessarily valid for the subcommand. You mention git as inspiration for your use case. The "main" git command accepts -c to specify config options that apply for the current command. But git commit interprets -c to specify a commit ID to populate the commit message from. If we were implementing git using this library, we'd want parsing to stop when it reached the first non-option so we could do subcommand-specific parsing.

I wonder how much effort it would take to make this library support both the POSIX and default GNU behaviors.

rkennedy avatar Nov 12 '23 16:11 rkennedy