Commit Graph

421 Commits

Author SHA1 Message Date
Alec Thomas 4e1757c0e8 feat: allow use of providers that don't return errors 2025-01-30 13:41:09 +11:00
Abhinav Gupta 9c08a58eb2 Support hooks on embed:"" fields (#493)
Relates to 840220c (#90)

This change adds support for hooks to be called on fields
that are tagged with `embed:""`.

### Use case

If a command has several subcommands,
many (but not all) of which need the same external resource,
this allows defining the flag-level inputs for that resource centrally,
and then using `embed:""` in any command that needs that resource.

For example, imagine:

```go
type githubClientProvider struct {
    Token string `name:"github-token" env:"GITHUB_TOKEN"`
    URL   string `name:"github-url" env:"GITHUB_URL"`
}

func (g *githubClientProvider) BeforeApply(kctx *kong.Context) error {
  return kctx.BindToProvider(func() (*github.Client, error) {
    return github.NewClient(...), nil
  })
}
```

Then, any command that needs GitHub client will add this field,
any other resource providers it needs,
and add parameters to its `Run` method to accept those resources:

```go
type listUsersCmd struct {
    GitHub githubClientProvider `embed:""`
    S3     s3ClientProvider     `embed:""`
}

func (l *listUsersCmd) Run(gh *github.Client, s3 *s3.Client) error {
    ...
}
```

### Alternatives

It is possible to do the same today if the `*Provider` struct above
is actually a Go embed instead of a Kong embed, *and* it is exported.

```
type GitHubClientProvider struct{ ... }

type listUsersCmd struct {
    GithubClientProvider
    S3ClientProvider
}
```

The difference is whether the struct defining the flags
is required to be exported or not.
2025-01-29 16:04:52 +11:00
Hritik Vijay 042a3258ec Document about binds with example (#491) 2025-01-25 10:51:46 +11:00
renovate[bot] 8d238c88fa chore(deps): update all non-major dependencies (#485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-13 22:13:14 +11:00
Abhinav Gupta 7ca846736c fix(Context.Run): Don't panic on unselected root node (#484) 2025-01-04 11:13:14 +09:00
Alec Thomas b811e32243 fix: whoops, forgot to prefix "and" 2024-12-29 18:02:02 +09:00
Alec Thomas 47b090f2f4 fix: add an xorprefix:"..." option for prefixing xor/and groups
Fixes #343
2024-12-29 17:55:06 +09:00
Alec Thomas cacaace969 fix: don't append ... for fields with an explicit type
Fixes #346
2024-12-29 17:42:20 +09:00
Alec Thomas a32b94b705 chore: interface{} -> any 2024-12-29 08:10:34 +09:00
Alec Thomas 36257680f1 refactor(test): replace os.Setenv() with t.Setenv() 2024-12-29 08:02:45 +09:00
Alec Thomas a14bb2072c fix: don't call Apply() twice
For some reason this was called by `Run()`. All tests pass without it,
so I'm not sure why it was there.

Fixes #481
2024-12-29 07:43:05 +09:00
Alec Thomas 840220c2ed feat: allow hooks to be declared on embedded fields
Specifically, on Go embedded fields, not on fields tagged with `embed`.

Fixes #90.
2024-12-27 22:29:45 +09:00
renovate[bot] 565ae9b740 chore(deps): update all non-major dependencies (#476)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-12 22:32:41 +11:00
Alec Thomas f2fcd34abf docs: fix README TOC 2024-12-07 19:43:01 +11:00
Alec Thomas 388ba35f1a feat: add support for Provide*() (<type>, error) methods on commands 2024-12-07 17:09:03 +11:00
renovate[bot] 87ee7dc3db chore(deps): update all non-major dependencies (#474)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-05 10:29:00 +11:00
Alec Thomas 81d0c29303 fix: regression where all args became passthrough
Fixes #475
2024-12-03 08:22:10 +11:00
Alec Thomas 96647c30af feat: add old "passthrough" behaviour back in as an option
`passthrough:""` or `passthrough:"all"` (the default) will pass through
all further arguments including unrecognised flags.

`passthrough:"partial"` will validate flags up until the `--` or the
first positional argument, then pass through all subsequent flags and
arguments.
2024-12-01 20:02:03 +11:00
Alec Thomas 88e13d750a chore: fix all golangci-lint warnings 2024-12-01 11:12:48 +11:00
renovate[bot] 5221ebb8fb chore(deps): update all non-major dependencies (#469)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-15 17:24:56 +11:00
Alec Thomas f388f6cd39 fix: NPE due to checking if error is nil when it can be a value
Fixes #468
2024-11-06 09:36:22 +11:00
renovate[bot] c90c6732cc chore(deps): update module github.com/alecthomas/kong to v1.3.0 (#467) 2024-11-04 13:51:07 +11:00
Alec Thomas 2544d3f008 feat: add AfterRun() hook
Fixes #288
2024-11-03 14:49:27 +11:00
Alec Thomas d0beaf7df3 fix: update enum+default vars after interpolation
This doesn't recursively apply interpolation, as discussed in the issue,
but that's a much bigger change.

Fixes #337
2024-11-03 14:28:27 +11:00
Alec Thomas 1b9d57eec1 feat: support optionally passing kong.Context to Validate()
Fixes #340
2024-11-03 14:14:55 +11:00
Alec Thomas 64229c9fe7 fix: format enum value
Fixed in #415
2024-11-03 14:02:03 +11:00
Alec Thomas 7bbb0b76ad feat: support recursive injection of provider parameters
This allows provider functions to accept parameters that are injected by other
bindings or binding providers, eg. call the provider function with the root CLI
struct (which is automatically bound by Kong):

  kong.BindToProvider(func(cli *CLI) (*Injected, error) { ... })
2024-11-01 12:25:41 +11:00
Alec Thomas 373692af87 refactor: reuse callAnyFunction for callFunction
Rather than duplicating basically identical calling logic
2024-11-01 11:59:18 +11:00
市川恭佑 (ebi) 07c8821614 Fix broken anchor link in README.md (#464) 2024-10-27 07:54:43 +11:00
renovate[bot] 56e990fc15 chore(deps): update all non-major dependencies (#462)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-07 14:25:31 +11:00
renovate[bot] c9fbc305f4 chore(deps): update module github.com/alecthomas/assert/v2 to v2.11.0 (#459)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 10:05:14 +10:00
Alexey Palazhchenko b34e9952de Fix Markdown in README.md (#458) 2024-09-19 18:27:07 +10:00
Alec Thomas 31301f527c docs: add note about 1.0 to README 2024-09-19 04:10:05 +10:00
renovate[bot] 3b28c2c83a chore(deps): update module github.com/alecthomas/kong to v1 (#457)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-16 19:49:21 +10:00
Alec Thomas 26c1c9ad05 fix: allow duplicate custom negated flags
Fixes #456
2024-09-12 12:05:09 +10:00
Bob Lail 9924ec4461 fix!: Include -- in passthrough args (#436)
Given a grammar like this:

```golang
var cli struct {
        Args []string `arg:"" optional:"" passthrough:""`
}
```

If Kong parses `cli foo -- bar`, it will populate `Args` with `[]string{"foo", "--", "bar"}` (including "`--`").
However, if Kong parses `cli -- foo bar`, will populate `Args` with `[]string{"foo", "bar"}` (leaving off `"--"`).

This differs from the behavior of a passthrough Command, where `"--"` is included with the args in both cases.

There are 3 places where `c.endParsing()` is called
1. When `node.Passthrough` is true: https://github.com/alecthomas/kong/blob/5f9c5cc822bdb888a3671c44d4688a6f602ecb90/context.go#L366-L368
2. When `arg.Passthrough` is true: https://github.com/alecthomas/kong/blob/5f9c5cc822bdb888a3671c44d4688a6f602ecb90/context.go#L451-L453
3. When `"--"` is encountered: https://github.com/alecthomas/kong/blob/5f9c5cc822bdb888a3671c44d4688a6f602ecb90/context.go#L384-L387

The first two do not also pop any tokens. The third one does.

This commit makes `c.scan.Pop()` conditional, skipping it when the next positional argument is passthrough.

I believe this will cause Kong to behave a little more consistently — and from my perspective, `--` is relevant for args intended to be passed through! — but it will change the behavior of existing projects that use `arg:"" passthrough:""`.
2024-09-11 10:51:37 +10:00
Cam Hutchison 4ecb53599b Make negatable flag name customisable (#439)
* fix: Check if negatable duplicates another flag

Add a check for flags with the `negatable` option if the negative flag
conflicts with another tag, such as:

    Flag   bool `negatable:""`
    NoFlag bool

The flag `--no-flag` is ambiguous in this scenario.

* feat: Make negatable flag name customisable

Allow a value on the `negatable` tag to specify a flag name to use for
negation instead of using `--no-<flag-name>` as the flag.

e.g.

    Approve bool `default:"true",negatable:"deny"`

This example will allow `--deny` to set the `Approve` field to false.
2024-09-10 21:02:37 +10:00
Camilla 7d84b95294 Feature: Add check for overlapping xor and and groups (#443)
* Docs: Clean and group description

* Feat: Add check for overlapping xor and and groups

Co-authored-by: inful <jone.marius@vign.es>

* Chore: Rewrite overlap err to avoid duplicated words

---------

Co-authored-by: inful <jone.marius@vign.es>
2024-09-10 21:01:12 +10:00
renovate[bot] b297ae97f2 chore(deps): update all non-major dependencies (#455)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-10 21:00:16 +10:00
Cole Snodgrass 6c216a37ce fix: typo in README (#451) 2024-08-21 11:55:19 +10:00
Alec Thomas 2ad9498bdf chore: bump go + golangci-lint 2024-08-20 08:16:24 +10:00
Jean-Raphaël Matte 6292953645 docs: specify usage of the placeholder tag (#448) 2024-08-13 13:05:45 +10:00
renovate[bot] d113f61e2a chore(deps): update all non-major dependencies (#445)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 16:24:10 +10:00
Camilla ff6d5ba7d5 Feature: Add xand tag (#442)
* Feat: Add xand group and check for missing

* Fix: Split and combine err in TestMultiand for consistency

* Feat: Check missing required flags in xand groups

* Feat: Handle combined xor and xand

* Docs: Add info about combined xand and required use

* Docs: Fix language error in xand description

Co-authored-by: Stautis <thkrst@gmail.com>

* Feat: Rename xand to and

* Refactor: Switch from fmt.Sprintf to err.Error

* Refactor: Get requiredAndGroup map in separate function

---------

Co-authored-by: Stautis <thkrst@gmail.com>
2024-08-08 16:58:22 +10:00
Mitar 5f9c5cc822 Remove extra newline when message contains trailing newlines. (#387) 2024-07-05 22:52:45 +10:00
Leo Antunes e864bb0220 feat: allow non-structs to be used as commands (#428)
* feat: allow non-structs to be used as commands

This small MR allows using the func-to-interface trick to implement a command (see commandFunc in kong_test.go).

This is useful e.g. for commands that have no flags or arguments of their own, but instead receive all required information via bound  parameters.

* fix: check DynamicCommand is runnable when adding
2024-07-05 22:51:38 +10:00
renovate[bot] 605cdd64a9 chore(deps): update all non-major dependencies (#425)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-05 22:49:21 +10:00
Bob Lail fcb5e05c07 fix: When a Grammar combines flags with passthrough args, see if an unrecognized flag may be treated as a positional argument (#435)
* ci: Add a test for positional args that are passthrough on a command that isn't passthrough

* fix: When a Grammar combines flags with passthrough args, see if an unrecognized flag may be treated as a positional argument

Given a grammar like this:
```golang
var cli struct {
	Args []string `arg:"" optional:"" passthrough:""`
}
```

The first positional argument implies that it was preceded by `--`, so subsequent flags are not parsed.

If Kong parses `cli 1 --unknown 3`, it will populate `Args` with `[]string{"1", "--unknown", "3"}`.
However, if Kong parses `cli --unknown 2 3`, it will fail saying that `--unknown` is an unrecognized flag.

This commit changes the parser so that if an unknown flag _could_ be treated as the first passthrough argument, it is.

After this change, if Kong parses `cli --unknown 2 3`, it will populate `Args` with `[]string{"--unknown", "2", "3"}`.

* ci: Skip the `maintidx` linter for `trace()`
2024-07-05 22:48:33 +10:00
Ben Weintraub d315006dca Fix reference to non-existent function in README (#430) 2024-05-29 08:41:28 +10:00
Alex Broad 38e5c6198e Update help example to use vars (#429) 2024-05-27 21:02:24 +10:00