Bind Vars.
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
1. [Slices](#slices)
|
||||
1. [Maps](#maps)
|
||||
1. [Custom named decoders](#custom-named-decoders)
|
||||
1. [Custom decoders](#custom-decoders)
|
||||
1. [Custom decoders \(mappers\)](#custom-decoders-mappers)
|
||||
1. [Supported tags](#supported-tags)
|
||||
1. [Variable interpolation](#variable-interpolation)
|
||||
1. [Modifying Kong's behaviour](#modifying-kongs-behaviour)
|
||||
@@ -162,11 +162,13 @@ This has the advantage that it is convenient, but the downside that if you modif
|
||||
A more robust approach is to break each command out into their own structs:
|
||||
|
||||
1. Break leaf commands out into separate structs.
|
||||
2. Attach a `Run(...) error` method to all leaf commands (`Run()` signatures must match).
|
||||
2. Attach a `Run(...) error` method to all leaf commands.
|
||||
3. Call `kong.Kong.Parse()` to obtain a `kong.Context`.
|
||||
4. Call `kong.Context.Run(params...)` to call the selected parsed command.
|
||||
4. Call `kong.Context.Run(bindings...)` to call the selected parsed command.
|
||||
|
||||
Note that `Run()` method arguments may also be provided by the `Bind(...)` option (see below).
|
||||
In addition to values bound with the `kong.Bind(...)` option, any values
|
||||
passed through to `kong.Context.Run(...)` are also bindable to the target's
|
||||
`Run()` arguments.
|
||||
|
||||
There's a full example emulating part of the Docker CLI [here](https://github.com/alecthomas/kong/tree/master/_examples/docker).
|
||||
|
||||
@@ -362,7 +364,7 @@ specifies the element type. For maps, the tag has the format
|
||||
`tag:"[<key>]:[<value>]"` where either may be omitted.
|
||||
|
||||
|
||||
## Custom decoders
|
||||
## Custom decoders (mappers)
|
||||
|
||||
If a field implements the [MapperValue](https://godoc.org/github.com/alecthomas/kong#MapperValue)
|
||||
interface it will be used to decode arguments into the field.
|
||||
|
||||
+31
-16
@@ -2,24 +2,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
)
|
||||
|
||||
type Globals struct {
|
||||
Config string `help:"Location of client config files" default:"~/.docker" type:"path"`
|
||||
Debug bool `short:"D" help:"Enable debug mode"`
|
||||
Host []string `short:"H" help:"Daemon socket(s) to connect to"`
|
||||
LogLevel string `short:"l" help:"Set the logging level (debug|info|warn|error|fatal)" default:"info"`
|
||||
TLS bool `help:"Use TLS; implied by --tls-verify"`
|
||||
TLSCACert string `name:"tls-ca-cert" help:"Trust certs signed only by this CA" default:"~/.docker/ca.pem" type:"path"`
|
||||
TLSCert string `help:"Path to TLS certificate file" default:"~/.docker/cert.pem" type:"path"`
|
||||
TLSKey string `help:"Path to TLS key file" default:"~/.docker/key.pem" type:"path"`
|
||||
TLSVerify bool `help:"Use TLS and verify the remote"`
|
||||
Config string `help:"Location of client config files" default:"~/.docker" type:"path"`
|
||||
Debug bool `short:"D" help:"Enable debug mode"`
|
||||
Host []string `short:"H" help:"Daemon socket(s) to connect to"`
|
||||
LogLevel string `short:"l" help:"Set the logging level (debug|info|warn|error|fatal)" default:"info"`
|
||||
TLS bool `help:"Use TLS; implied by --tls-verify"`
|
||||
TLSCACert string `name:"tls-ca-cert" help:"Trust certs signed only by this CA" default:"~/.docker/ca.pem" type:"path"`
|
||||
TLSCert string `help:"Path to TLS certificate file" default:"~/.docker/cert.pem" type:"path"`
|
||||
TLSKey string `help:"Path to TLS key file" default:"~/.docker/key.pem" type:"path"`
|
||||
TLSVerify bool `help:"Use TLS and verify the remote"`
|
||||
Version VersionFlag `name:"version" help:"Print version information and quit"`
|
||||
}
|
||||
|
||||
type VersionFlag string
|
||||
|
||||
func (v VersionFlag) Decode(ctx *kong.DecodeContext) error { return nil }
|
||||
func (v VersionFlag) IsBool() bool { return true }
|
||||
func (v VersionFlag) BeforeHook(app *kong.Kong, vars kong.Vars) error {
|
||||
fmt.Println(vars["version"])
|
||||
app.Exit(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
type CLI struct {
|
||||
Globals
|
||||
VersionFlag bool `name:"version" help:"Print version information and quit"`
|
||||
|
||||
Attach AttachCmd `cmd help:"Attach local standard input, output, and error streams to a running container"`
|
||||
Build BuildCmd `cmd help:"Build an image from a Dockerfile"`
|
||||
@@ -65,7 +77,12 @@ type CLI struct {
|
||||
}
|
||||
|
||||
func main() {
|
||||
cli := CLI{}
|
||||
cli := CLI{
|
||||
Globals: Globals{
|
||||
Version: VersionFlag("0.1.1"),
|
||||
},
|
||||
}
|
||||
|
||||
ctx := kong.Parse(&cli,
|
||||
kong.Name("docker"),
|
||||
kong.Description("A self-sufficient runtime for containers"),
|
||||
@@ -73,11 +90,9 @@ func main() {
|
||||
kong.ConfigureHelp(kong.HelpOptions{
|
||||
Compact: true,
|
||||
}),
|
||||
//
|
||||
kong.Hook(&cli.VersionFlag, func(ctx *kong.Context, path *kong.Path) error {
|
||||
ctx.Printf("1.0.0").Exit(0)
|
||||
return nil
|
||||
}))
|
||||
kong.Vars{
|
||||
"version": "0.0.1",
|
||||
})
|
||||
err := ctx.Run(&cli.Globals)
|
||||
ctx.FatalIfErrorf(err)
|
||||
}
|
||||
|
||||
+4
-4
@@ -470,10 +470,10 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
|
||||
return findPotentialCandidates(match, candidates, "unknown flag %s", match)
|
||||
}
|
||||
|
||||
// Run executes the corresponding Run(params...) method on the target command selected by the parsed args.
|
||||
// Run executes the Run() method on the selected command, which must exist.
|
||||
//
|
||||
// The target Run() method must exist and have the type signature "Run(params...) error".
|
||||
func (c *Context) Run(params ...interface{}) (err error) {
|
||||
// Any passed values will be bindable to arguments of the target Run() method.
|
||||
func (c *Context) Run(bindings ...interface{}) (err error) {
|
||||
defer catch(&err)
|
||||
node := c.Selected()
|
||||
if node == nil {
|
||||
@@ -487,7 +487,7 @@ func (c *Context) Run(params ...interface{}) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
binds := c.Kong.bindings.clone().add(params...).add(c)
|
||||
binds := c.Kong.bindings.clone().add(bindings...).add(c)
|
||||
return callMethod("Run", node.Target, method, binds)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ type Kong struct {
|
||||
help HelpPrinter
|
||||
helpOptions HelpOptions
|
||||
helpFlag *Flag
|
||||
vars map[string]string
|
||||
vars Vars
|
||||
|
||||
// Set temporarily by Options. These are applied after build().
|
||||
postBuildOptions []Option
|
||||
@@ -67,7 +67,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
|
||||
Stderr: os.Stderr,
|
||||
registry: NewRegistry().RegisterDefaults(),
|
||||
resolvers: []ResolverFunc{Envars()},
|
||||
vars: map[string]string{},
|
||||
vars: Vars{},
|
||||
bindings: bindings{},
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.bindings.add(k.vars)
|
||||
|
||||
return k, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user