diff --git a/.golangci.yml b/.golangci.yml index 0d2c6f8..0f7ad82 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -34,6 +34,7 @@ linters: - interfacer - tagliatelle - thelper + - godox linters-settings: govet: diff --git a/context.go b/context.go index 1e5ae75..1a2ed15 100644 --- a/context.go +++ b/context.go @@ -820,7 +820,18 @@ func checkMissingPositionals(positional int, values []*Value) error { missing := []string{} for ; positional < len(values); positional++ { - missing = append(missing, "<"+values[positional].Name+">") + arg := values[positional] + // TODO(aat): Fix hardcoding of these env checks all over the place :\ + if arg.Tag.Env != "" { + _, ok := os.LookupEnv(arg.Tag.Env) + if ok { + continue + } + } + missing = append(missing, "<"+arg.Name+">") + } + if len(missing) == 0 { + return nil } return fmt.Errorf("missing positional arguments %s", strings.Join(missing, " ")) } diff --git a/kong_test.go b/kong_test.go index 66fbe1b..30dd7a5 100644 --- a/kong_test.go +++ b/kong_test.go @@ -902,6 +902,43 @@ func TestIssue40EnumAcrossCommands(t *testing.T) { require.NoError(t, err) } +func TestIssue179(t *testing.T) { + type A struct { + Enum string `required:"" enum:"1,2"` + } + + type B struct{} + + var root struct { + A A `cmd` + B B `cmd` + } + + p := mustNew(t, &root) + _, err := p.Parse([]string{"b"}) + require.NoError(t, err) +} + +func TestIssue153(t *testing.T) { + type LsCmd struct { + Paths []string `arg required name:"path" help:"Paths to list." env:"CMD_PATHS"` + } + + var cli struct { + Debug bool `help:"Enable debug mode."` + + Ls LsCmd `cmd help:"List paths."` + } + + p, revert := newEnvParser(t, &cli, envMap{ + "CMD_PATHS": "hello", + }) + defer revert() + _, err := p.Parse([]string{"ls"}) + require.NoError(t, err) + require.Equal(t, []string{"hello"}, cli.Ls.Paths) +} + func TestEnumArg(t *testing.T) { var cli struct { Nested struct {