kingpin icon indicating copy to clipboard operation
kingpin copied to clipboard

Incorrect handling of commands with arguments (v3 unstable)

Open matthewdunsdon opened this issue 8 years ago • 1 comments

When using kingpin, I was expecting to be able to write the following code to parse a command:

	args := os.Args[1:]
	switch kingpin.MustParse(app.Parse(args)) {
	case initCmd.FullCommand():
		initAction(*initCmdArg)
	// ...
	default:
		app.Usage(args)
	}

Given the CLI args myapp init file.txt, I got the usage message displayed, when I wanted initAction to be called.

Currently in kingpin (v3 unstable) I am working around this issue using:

	args := os.Args[1:]
	switch kingpin.MustParse(app.Parse(args)) {
	case "init":
		initData(*initCmdArg)
	// ...
	default:
		app.Usage(args)
	}

Expected Behavior

As stated above, I am expecting the output of kingpin.MustParse(app.Parse(args)) to equal the result of .FullCommand() function of a command, rather than to have to define my own strings in the switch statement.

Below is an example block of test code that I would expect to passed.

package main

import (
	"testing"

	kingpin "gopkg.in/alecthomas/kingpin.v3-unstable"
)

func TestParse(t *testing.T) {
	app := kingpin.New("myApp", "Lorem ipsum.")
	initCmd := app.Command("init", "Lorem init.")
	_ = initCmd.Arg("file", "Lorem file.").String()

	importCmd := app.Command("import", "Lorem import")

	testCases := []struct {
		testName string
		args     []string
		want     *kingpin.CmdClause
	}{
		{"SimpleCommand", []string{"import"}, importCmd},
		{"CommandWithArg", []string{"init", "file.txt"}, initCmd},
	}

	for _, tc := range testCases {
		t.Run(tc.testName, func(t *testing.T) {
			parsed := kingpin.MustParse(app.Parse(tc.args))

			if parsed != tc.want.FullCommand() {
				t.Errorf("Expected %q to equal %q", parsed, tc.want.FullCommand())
			}
		})
	}
}

Current Behavior

Test Output:

Running tool: /usr/bin/go test -timeout 30s -tags  -run ^TestParse$

--- FAIL: TestParse (0.00s)
    --- FAIL: TestParse/CommandWithArg (0.00s)
    	/home/matthewdunsdon/go/src/github.com/matthewdunsdon/explore-kingpin-3/main_test.go:38: Expected "init" to equal "init [<file>]"
FAIL
exit status 1
FAIL	github.com/matthewdunsdon/explore-kingpin-3	0.005s
Error: Tests failed.

I do not mind whether the parsed output is changed to "init [<file>]" or whether importCmd.FullCommand() returns "init", however I would like the test to pass.

Context

My reasons for using (v3 unstable) are that:

  1. I want to be able to write apps where I can use the app.UsageContext to include examples in the usage context. I have written github.com/matthewdunsdon/egcmd GoDoc and github.com/matthewdunsdon/egcmd/egkingpin GoDoc to make this possible.
  2. I have no intention to take the apps I write with (v3 unstable) into any production environment. I am using them for my own learning and own use.

Environment

  • Package source: "gopkg.in/alecthomas/kingpin.v3-unstable"
  • Go version used: 1.8
  • Operating System and version (desktop or mobile): Solus (Linux x64)
> lsb_release -a
LSB Version:	1.4
Distributor ID:	Solus
Description:	Solus
Release:	2017.04.18.0
Codename:	shannon

matthewdunsdon avatar Aug 14 '17 21:08 matthewdunsdon

Ah. Good catch, thanks. I'll try to fix that this week.

alecthomas avatar Aug 16 '17 22:08 alecthomas