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.
This commit is contained in:
+14
-1
@@ -2413,9 +2413,19 @@ func (e *EmbeddedCallback) AfterApply() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type taggedEmbeddedCallback struct {
|
||||
Tagged bool
|
||||
}
|
||||
|
||||
func (e *taggedEmbeddedCallback) AfterApply() error {
|
||||
e.Tagged = true
|
||||
return nil
|
||||
}
|
||||
|
||||
type EmbeddedRoot struct {
|
||||
EmbeddedCallback
|
||||
Root bool
|
||||
Tagged taggedEmbeddedCallback `embed:""`
|
||||
Root bool
|
||||
}
|
||||
|
||||
func (e *EmbeddedRoot) AfterApply() error {
|
||||
@@ -2432,6 +2442,9 @@ func TestEmbeddedCallbacks(t *testing.T) {
|
||||
EmbeddedCallback: EmbeddedCallback{
|
||||
Embedded: true,
|
||||
},
|
||||
Tagged: taggedEmbeddedCallback{
|
||||
Tagged: true,
|
||||
},
|
||||
Root: true,
|
||||
}
|
||||
assert.Equal(t, expected, actual)
|
||||
|
||||
Reference in New Issue
Block a user