Skip to content

Commit

Permalink
change help hook and call Reset later
Browse files Browse the repository at this point in the history
change to BeforeResolve hook to catch calls to '--help' earlier;
call reset later in Kong.Parse() to allow help hook to get hooked;
add test;
  • Loading branch information
pyqlsa authored and alecthomas committed May 3, 2022
1 parent 7c6ff10 commit 5538b7f
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func main() {

If a node in the grammar has a `BeforeResolve(...)`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those methods will be called before validation/assignment and after validation/assignment, respectively.

The `--help` flag is implemented with a `BeforeApply` hook.
The `--help` flag is implemented with a `BeforeResolve` hook.

Arguments to hooks are provided via the `Run(...)` method or `Bind(...)` option. `*Kong`, `*Context` and `*Path` are also bound and finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.

Expand Down
2 changes: 1 addition & 1 deletion help.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (
// Help flag.
type helpValue bool

func (h helpValue) BeforeApply(ctx *Context) error {
func (h helpValue) BeforeResolve(ctx *Context) error {
options := ctx.Kong.helpOptions
options.Summary = false
err := ctx.Kong.help(options, ctx)
Expand Down
6 changes: 3 additions & 3 deletions kong.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,15 @@ func (k *Kong) Parse(args []string) (ctx *Context, err error) {
if ctx.Error != nil {
return nil, &ParseError{error: ctx.Error, Context: ctx}
}
if err = ctx.Reset(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = k.applyHook(ctx, "BeforeResolve"); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = ctx.Resolve(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = ctx.Reset(); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
if err = k.applyHook(ctx, "BeforeApply"); err != nil {
return nil, &ParseError{error: err, Context: ctx}
}
Expand Down
19 changes: 19 additions & 0 deletions kong_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1542,3 +1542,22 @@ func TestPassthroughCmdOnlyStringArgs(t *testing.T) {
_, err := kong.New(&cli)
require.EqualError(t, err, "<anonymous struct>.Command: passthrough command command [<args> ...] must contain exactly one positional argument of []string type")
}

func TestHelpShouldStillWork(t *testing.T) {
type CLI struct {
Dir string `type:"existingdir" default:"missing-dir"`
}
var cli CLI
k := mustNew(t, &cli)
rc := -1 // init nonzero to help assert help hook was called
k.Exit = func(i int) {
rc = i
}
_, err := k.Parse([]string{"--help"})
// checking return code validates the help hook was called
require.Zero(t, rc)
// allow for error propagation from other validation (only for the
// sake of this test, due to the exit function not actually exiting the
// program; errors will not propagate in the real world).
require.Error(t, err)
}

0 comments on commit 5538b7f

Please sign in to comment.