Skip to content

Inconsistent/wrong list arg parsing #239

@purpleidea

Description

@purpleidea

It seems the parsing of lists is done differently than what is common in some other parsing libraries like urfave/cli. I detected this because some tests in https://github.com/purpleidea/mgmt/ started failing after a direct port to this lib. I investigated the behaviour and I believe what we are doing isn't optimal or correct. Minimally I think it's inconsistent or surprising.

Overall the library is great though! I'm happy to find such issues and report.

TL;DR: extra positional args are "chomped" up when we have a []string arg or similar. For example:

Note how sub is part of the list:

$ go run parsingbug.go --some-list list1 sub input
args: {SomeInt:<nil> SomeList:[list1 sub input] Sub:<nil>}
args.SomeList(3): [list1 sub input]

If we add the equals symbol this works around this:

$ go run parsingbug.go --some-list=list1 sub input
args: {SomeInt:<nil> SomeList:[list1] Sub:0xc0000667b0}
args.Sub: {Input:input}
args.SomeList(1): [list1]

Strange things happen with two list args. Where did list1 go?

$ go run parsingbug.go --some-list list1 --some-list list2 sub input
args: {SomeInt:<nil> SomeList:[list2 sub input] Sub:<nil>}
args.SomeList(3): [list2 sub input]

Three specifiers gives something perhaps inconsistent if the last one has an equals:

$ go run parsingbug.go --some-list list1 --some-list list2 --some-list=list3 sub input
args: {SomeInt:<nil> SomeList:[list3] Sub:0xc000068830}
args.Sub: {Input:input}
args.SomeList(1): [list3]

The below code for this works all by itself:

package main

import (
	"fmt"

	"github.com/alexflint/go-arg"
)

var args struct {
	//Argv0 string `arg:"positional"`

	SomeInt *int `arg:"-i" arg:"--int" help:"some integer"`

	SomeList []string `arg:"--some-list"`

	Sub *cmd `arg:"subcommand:sub"`
}

type cmd struct {
	Input string `arg:"positional"`
}

func main() {
	arg.MustParse(&args)

	fmt.Printf("args: %+v\n", args)
	if sub := args.Sub; sub != nil {
		fmt.Printf("args.Sub: %+v\n", *sub)
	}
	fmt.Printf("args.SomeList(%d): %+v\n", len(args.SomeList), args.SomeList)
}

I'll be happy to test and then convert this into a PR of test cases if someone wants to prepare a patch.

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions