update vendored deps

This commit is contained in:
Danny van Kooten 2017-01-24 20:27:30 +01:00
parent 9d0bee4372
commit 6161442487
22 changed files with 5081 additions and 0 deletions

19
vendor/gopkg.in/alecthomas/kingpin.v2/COPYING generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (C) 2014 Alec Thomas
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

671
vendor/gopkg.in/alecthomas/kingpin.v2/README.md generated vendored Normal file
View File

@ -0,0 +1,671 @@
# Kingpin - A Go (golang) command line and flag parser [![](https://godoc.org/github.com/alecthomas/kingpin?status.svg)](http://godoc.org/github.com/alecthomas/kingpin) [![Build Status](https://travis-ci.org/alecthomas/kingpin.svg?branch=master)](https://travis-ci.org/alecthomas/kingpin)
<!-- MarkdownTOC -->
- [Overview](#overview)
- [Features](#features)
- [User-visible changes between v1 and v2](#user-visible-changes-between-v1-and-v2)
- [Flags can be used at any point after their definition.](#flags-can-be-used-at-any-point-after-their-definition)
- [Short flags can be combined with their parameters](#short-flags-can-be-combined-with-their-parameters)
- [API changes between v1 and v2](#api-changes-between-v1-and-v2)
- [Versions](#versions)
- [V2 is the current stable version](#v2-is-the-current-stable-version)
- [V1 is the OLD stable version](#v1-is-the-old-stable-version)
- [Change History](#change-history)
- [Examples](#examples)
- [Simple Example](#simple-example)
- [Complex Example](#complex-example)
- [Reference Documentation](#reference-documentation)
- [Displaying errors and usage information](#displaying-errors-and-usage-information)
- [Sub-commands](#sub-commands)
- [Custom Parsers](#custom-parsers)
- [Repeatable flags](#repeatable-flags)
- [Boolean Values](#boolean-values)
- [Default Values](#default-values)
- [Place-holders in Help](#place-holders-in-help)
- [Consuming all remaining arguments](#consuming-all-remaining-arguments)
- [Bash/ZSH Shell Completion](#bashzsh-shell-completion)
- [Supporting -h for help](#supporting--h-for-help)
- [Custom help](#custom-help)
<!-- /MarkdownTOC -->
## Overview
Kingpin is a [fluent-style](http://en.wikipedia.org/wiki/Fluent_interface),
type-safe command-line parser. It supports flags, nested commands, and
positional arguments.
Install it with:
$ go get gopkg.in/alecthomas/kingpin.v2
It looks like this:
```go
var (
verbose = kingpin.Flag("verbose", "Verbose mode.").Short('v').Bool()
name = kingpin.Arg("name", "Name of user.").Required().String()
)
func main() {
kingpin.Parse()
fmt.Printf("%v, %s\n", *verbose, *name)
}
```
More [examples](https://github.com/alecthomas/kingpin/tree/master/_examples) are available.
Second to parsing, providing the user with useful help is probably the most
important thing a command-line parser does. Kingpin tries to provide detailed
contextual help if `--help` is encountered at any point in the command line
(excluding after `--`).
## Features
- Help output that isn't as ugly as sin.
- Fully [customisable help](#custom-help), via Go templates.
- Parsed, type-safe flags (`kingpin.Flag("f", "help").Int()`)
- Parsed, type-safe positional arguments (`kingpin.Arg("a", "help").Int()`).
- Parsed, type-safe, arbitrarily deep commands (`kingpin.Command("c", "help")`).
- Support for required flags and required positional arguments (`kingpin.Flag("f", "").Required().Int()`).
- Support for arbitrarily nested default commands (`command.Default()`).
- Callbacks per command, flag and argument (`kingpin.Command("c", "").Action(myAction)`).
- POSIX-style short flag combining (`-a -b` -> `-ab`).
- Short-flag+parameter combining (`-a parm` -> `-aparm`).
- Read command-line from files (`@<file>`).
- Automatically generate man pages (`--help-man`).
## User-visible changes between v1 and v2
### Flags can be used at any point after their definition.
Flags can be specified at any point after their definition, not just
*immediately after their associated command*. From the chat example below, the
following used to be required:
```
$ chat --server=chat.server.com:8080 post --image=~/Downloads/owls.jpg pics
```
But the following will now work:
```
$ chat post --server=chat.server.com:8080 --image=~/Downloads/owls.jpg pics
```
### Short flags can be combined with their parameters
Previously, if a short flag was used, any argument to that flag would have to
be separated by a space. That is no longer the case.
## API changes between v1 and v2
- `ParseWithFileExpansion()` is gone. The new parser directly supports expanding `@<file>`.
- Added `FatalUsage()` and `FatalUsageContext()` for displaying an error + usage and terminating.
- `Dispatch()` renamed to `Action()`.
- Added `ParseContext()` for parsing a command line into its intermediate context form without executing.
- Added `Terminate()` function to override the termination function.
- Added `UsageForContextWithTemplate()` for printing usage via a custom template.
- Added `UsageTemplate()` for overriding the default template to use. Two templates are included:
1. `DefaultUsageTemplate` - default template.
2. `CompactUsageTemplate` - compact command template for larger applications.
## Versions
Kingpin uses [gopkg.in](https://gopkg.in/alecthomas/kingpin) for versioning.
The current stable version is [gopkg.in/alecthomas/kingpin.v2](https://gopkg.in/alecthomas/kingpin.v2). The previous version, [gopkg.in/alecthomas/kingpin.v1](https://gopkg.in/alecthomas/kingpin.v1), is deprecated and in maintenance mode.
### [V2](https://gopkg.in/alecthomas/kingpin.v2) is the current stable version
Installation:
```sh
$ go get gopkg.in/alecthomas/kingpin.v2
```
### [V1](https://gopkg.in/alecthomas/kingpin.v1) is the OLD stable version
Installation:
```sh
$ go get gopkg.in/alecthomas/kingpin.v1
```
## Change History
- *2015-09-19* -- Stable v2.1.0 release.
- Added `command.Default()` to specify a default command to use if no other
command matches. This allows for convenient user shortcuts.
- Exposed `HelpFlag` and `VersionFlag` for further customisation.
- `Action()` and `PreAction()` added and both now support an arbitrary
number of callbacks.
- `kingpin.SeparateOptionalFlagsUsageTemplate`.
- `--help-long` and `--help-man` (hidden by default) flags.
- Flags are "interspersed" by default, but can be disabled with `app.Interspersed(false)`.
- Added flags for all simple builtin types (int8, uint16, etc.) and slice variants.
- Use `app.Writer(os.Writer)` to specify the default writer for all output functions.
- Dropped `os.Writer` prefix from all printf-like functions.
- *2015-05-22* -- Stable v2.0.0 release.
- Initial stable release of v2.0.0.
- Fully supports interspersed flags, commands and arguments.
- Flags can be present at any point after their logical definition.
- Application.Parse() terminates if commands are present and a command is not parsed.
- Dispatch() -> Action().
- Actions are dispatched after all values are populated.
- Override termination function (defaults to os.Exit).
- Override output stream (defaults to os.Stderr).
- Templatised usage help, with default and compact templates.
- Make error/usage functions more consistent.
- Support argument expansion from files by default (with @<file>).
- Fully public data model is available via .Model().
- Parser has been completely refactored.
- Parsing and execution has been split into distinct stages.
- Use `go generate` to generate repeated flags.
- Support combined short-flag+argument: -fARG.
- *2015-01-23* -- Stable v1.3.4 release.
- Support "--" for separating flags from positional arguments.
- Support loading flags from files (ParseWithFileExpansion()). Use @FILE as an argument.
- Add post-app and post-cmd validation hooks. This allows arbitrary validation to be added.
- A bunch of improvements to help usage and formatting.
- Support arbitrarily nested sub-commands.
- *2014-07-08* -- Stable v1.2.0 release.
- Pass any value through to `Strings()` when final argument.
Allows for values that look like flags to be processed.
- Allow `--help` to be used with commands.
- Support `Hidden()` flags.
- Parser for [units.Base2Bytes](https://github.com/alecthomas/units)
type. Allows for flags like `--ram=512MB` or `--ram=1GB`.
- Add an `Enum()` value, allowing only one of a set of values
to be selected. eg. `Flag(...).Enum("debug", "info", "warning")`.
- *2014-06-27* -- Stable v1.1.0 release.
- Bug fixes.
- Always return an error (rather than panicing) when misconfigured.
- `OpenFile(flag, perm)` value type added, for finer control over opening files.
- Significantly improved usage formatting.
- *2014-06-19* -- Stable v1.0.0 release.
- Support [cumulative positional](#consuming-all-remaining-arguments) arguments.
- Return error rather than panic when there are fatal errors not caught by
the type system. eg. when a default value is invalid.
- Use gokpg.in.
- *2014-06-10* -- Place-holder streamlining.
- Renamed `MetaVar` to `PlaceHolder`.
- Removed `MetaVarFromDefault`. Kingpin now uses [heuristics](#place-holders-in-help)
to determine what to display.
## Examples
### Simple Example
Kingpin can be used for simple flag+arg applications like so:
```
$ ping --help
usage: ping [<flags>] <ip> [<count>]
Flags:
--debug Enable debug mode.
--help Show help.
-t, --timeout=5s Timeout waiting for ping.
Args:
<ip> IP address to ping.
[<count>] Number of packets to send
$ ping 1.2.3.4 5
Would ping: 1.2.3.4 with timeout 5s and count 0
```
From the following source:
```go
package main
import (
"fmt"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
debug = kingpin.Flag("debug", "Enable debug mode.").Bool()
timeout = kingpin.Flag("timeout", "Timeout waiting for ping.").Default("5s").OverrideDefaultFromEnvar("PING_TIMEOUT").Short('t').Duration()
ip = kingpin.Arg("ip", "IP address to ping.").Required().IP()
count = kingpin.Arg("count", "Number of packets to send").Int()
)
func main() {
kingpin.Version("0.0.1")
kingpin.Parse()
fmt.Printf("Would ping: %s with timeout %s and count %d", *ip, *timeout, *count)
}
```
### Complex Example
Kingpin can also produce complex command-line applications with global flags,
subcommands, and per-subcommand flags, like this:
```
$ chat --help
usage: chat [<flags>] <command> [<flags>] [<args> ...]
A command-line chat application.
Flags:
--help Show help.
--debug Enable debug mode.
--server=127.0.0.1 Server address.
Commands:
help [<command>]
Show help for a command.
register <nick> <name>
Register a new user.
post [<flags>] <channel> [<text>]
Post a message to a channel.
$ chat help post
usage: chat [<flags>] post [<flags>] <channel> [<text>]
Post a message to a channel.
Flags:
--image=IMAGE Image to post.
Args:
<channel> Channel to post to.
[<text>] Text to post.
$ chat post --image=~/Downloads/owls.jpg pics
...
```
From this code:
```go
package main
import (
"os"
"strings"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
app = kingpin.New("chat", "A command-line chat application.")
debug = app.Flag("debug", "Enable debug mode.").Bool()
serverIP = app.Flag("server", "Server address.").Default("127.0.0.1").IP()
register = app.Command("register", "Register a new user.")
registerNick = register.Arg("nick", "Nickname for user.").Required().String()
registerName = register.Arg("name", "Name of user.").Required().String()
post = app.Command("post", "Post a message to a channel.")
postImage = post.Flag("image", "Image to post.").File()
postChannel = post.Arg("channel", "Channel to post to.").Required().String()
postText = post.Arg("text", "Text to post.").Strings()
)
func main() {
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
// Register user
case register.FullCommand():
println(*registerNick)
// Post message
case post.FullCommand():
if *postImage != nil {
}
text := strings.Join(*postText, " ")
println("Post:", text)
}
}
```
## Reference Documentation
### Displaying errors and usage information
Kingpin exports a set of functions to provide consistent errors and usage
information to the user.
Error messages look something like this:
<app>: error: <message>
The functions on `Application` are:
Function | Purpose
---------|--------------
`Errorf(format, args)` | Display a printf formatted error to the user.
`Fatalf(format, args)` | As with Errorf, but also call the termination handler.
`FatalUsage(format, args)` | As with Fatalf, but also print contextual usage information.
`FatalUsageContext(context, format, args)` | As with Fatalf, but also print contextual usage information from a `ParseContext`.
`FatalIfError(err, format, args)` | Conditionally print an error prefixed with format+args, then call the termination handler
There are equivalent global functions in the kingpin namespace for the default
`kingpin.CommandLine` instance.
### Sub-commands
Kingpin supports nested sub-commands, with separate flag and positional
arguments per sub-command. Note that positional arguments may only occur after
sub-commands.
For example:
```go
var (
deleteCommand = kingpin.Command("delete", "Delete an object.")
deleteUserCommand = deleteCommand.Command("user", "Delete a user.")
deleteUserUIDFlag = deleteUserCommand.Flag("uid", "Delete user by UID rather than username.")
deleteUserUsername = deleteUserCommand.Arg("username", "Username to delete.")
deletePostCommand = deleteCommand.Command("post", "Delete a post.")
)
func main() {
switch kingpin.Parse() {
case "delete user":
case "delete post":
}
}
```
### Custom Parsers
Kingpin supports both flag and positional argument parsers for converting to
Go types. For example, some included parsers are `Int()`, `Float()`,
`Duration()` and `ExistingFile()`.
Parsers conform to Go's [`flag.Value`](http://godoc.org/flag#Value)
interface, so any existing implementations will work.
For example, a parser for accumulating HTTP header values might look like this:
```go
type HTTPHeaderValue http.Header
func (h *HTTPHeaderValue) Set(value string) error {
parts := strings.SplitN(value, ":", 2)
if len(parts) != 2 {
return fmt.Errorf("expected HEADER:VALUE got '%s'", value)
}
(*http.Header)(h).Add(parts[0], parts[1])
return nil
}
func (h *HTTPHeaderValue) String() string {
return ""
}
```
As a convenience, I would recommend something like this:
```go
func HTTPHeader(s Settings) (target *http.Header) {
target = new(http.Header)
s.SetValue((*HTTPHeaderValue)(target))
return
}
```
You would use it like so:
```go
headers = HTTPHeader(kingpin.Flag("header", "Add a HTTP header to the request.").Short('H'))
```
### Repeatable flags
Depending on the `Value` they hold, some flags may be repeated. The
`IsCumulative() bool` function on `Value` tells if it's safe to call `Set()`
multiple times or if an error should be raised if several values are passed.
The built-in `Value`s returning slices and maps, as well as `Counter` are
examples of `Value`s that make a flag repeatable.
### Boolean values
Boolean values are uniquely managed by Kingpin. Each boolean flag will have a negative complement:
`--<name>` and `--no-<name>`.
### Default Values
The default value is the zero value for a type. This can be overridden with
the `Default(value...)` function on flags and arguments. This function accepts
one or several strings, which are parsed by the value itself, so they *must*
be compliant with the format expected.
### Place-holders in Help
The place-holder value for a flag is the value used in the help to describe
the value of a non-boolean flag.
The value provided to PlaceHolder() is used if provided, then the value
provided by Default() if provided, then finally the capitalised flag name is
used.
Here are some examples of flags with various permutations:
--name=NAME // Flag(...).String()
--name="Harry" // Flag(...).Default("Harry").String()
--name=FULL-NAME // flag(...).PlaceHolder("FULL-NAME").Default("Harry").String()
### Consuming all remaining arguments
A common command-line idiom is to use all remaining arguments for some
purpose. eg. The following command accepts an arbitrary number of
IP addresses as positional arguments:
./cmd ping 10.1.1.1 192.168.1.1
Such arguments are similar to [repeatable flags](#repeatable-flags), but for
arguments. Therefore they use the same `IsCumulative() bool` function on the
underlying `Value`, so the built-in `Value`s for which the `Set()` function
can be called several times will consume multiple arguments.
To implement the above example with a custom `Value`, we might do something
like this:
```go
type ipList []net.IP
func (i *ipList) Set(value string) error {
if ip := net.ParseIP(value); ip == nil {
return fmt.Errorf("'%s' is not an IP address", value)
} else {
*i = append(*i, ip)
return nil
}
}
func (i *ipList) String() string {
return ""
}
func (i *ipList) IsCumulative() bool {
return true
}
func IPList(s Settings) (target *[]net.IP) {
target = new([]net.IP)
s.SetValue((*ipList)(target))
return
}
```
And use it like so:
```go
ips := IPList(kingpin.Arg("ips", "IP addresses to ping."))
```
### Bash/ZSH Shell Completion
By default, all flags and commands/subcommands generate completions
internally.
Out of the box, CLI tools using kingpin should be able to take advantage
of completion hinting for flags and commands. By specifying
`--completion-bash` as the first argument, your CLI tool will show
possible subcommands. By ending your argv with `--`, hints for flags
will be shown.
To allow your end users to take advantage you must package a
`/etc/bash_completion.d` script with your distribution (or the equivalent
for your target platform/shell). An alternative is to instruct your end
user to source a script from their `bash_profile` (or equivalent).
Fortunately Kingpin makes it easy to generate or source a script for use
with end users shells. `./yourtool --completion-script-bash` and
`./yourtool --completion-script-zsh` will generate these scripts for you.
**Installation by Package**
For the best user experience, you should bundle your pre-created
completion script with your CLI tool and install it inside
`/etc/bash_completion.d` (or equivalent). A good suggestion is to add
this as an automated step to your build pipeline, in the implementation
is improved for bug fixed.
**Installation by `bash_profile`**
Alternatively, instruct your users to add an additional statement to
their `bash_profile` (or equivalent):
```
eval "$(your-cli-tool --completion-script-bash)"
```
Or for ZSH
```
eval "$(your-cli-tool --completion-script-zsh)"
```
#### Additional API
To provide more flexibility, a completion option API has been
exposed for flags to allow user defined completion options, to extend
completions further than just EnumVar/Enum.
**Provide Static Options**
When using an `Enum` or `EnumVar`, users are limited to only the options
given. Maybe we wish to hint possible options to the user, but also
allow them to provide their own custom option. `HintOptions` gives
this functionality to flags.
```
app := kingpin.New("completion", "My application with bash completion.")
app.Flag("port", "Provide a port to connect to").
Required().
HintOptions("80", "443", "8080").
IntVar(&c.port)
```
**Provide Dynamic Options**
Consider the case that you needed to read a local database or a file to
provide suggestions. You can dynamically generate the options
```
func listHosts(args []string) []string {
// Provide a dynamic list of hosts from a hosts file or otherwise
// for bash completion. In this example we simply return static slice.
// You could use this functionality to reach into a hosts file to provide
// completion for a list of known hosts.
return []string{"sshhost.example", "webhost.example", "ftphost.example"}
}
app := kingpin.New("completion", "My application with bash completion.")
app.Flag("flag-1", "").HintAction(listHosts).String()
```
**EnumVar/Enum**
When using `Enum` or `EnumVar`, any provided options will be automatically
used for bash autocompletion. However, if you wish to provide a subset or
different options, you can use `HintOptions` or `HintAction` which will override
the default completion options for `Enum`/`EnumVar`.
**Examples**
You can see an in depth example of the completion API within
`examples/completion/main.go`
### Supporting -h for help
`kingpin.CommandLine.HelpFlag.Short('h')`
### Custom help
Kingpin v2 supports templatised help using the text/template library (actually, [a fork](https://github.com/alecthomas/template)).
You can specify the template to use with the [Application.UsageTemplate()](http://godoc.org/gopkg.in/alecthomas/kingpin.v2#Application.UsageTemplate) function.
There are four included templates: `kingpin.DefaultUsageTemplate` is the default,
`kingpin.CompactUsageTemplate` provides a more compact representation for more complex command-line structures,
`kingpin.SeparateOptionalFlagsUsageTemplate` looks like the default template, but splits required
and optional command flags into separate lists, and `kingpin.ManPageTemplate` is used to generate man pages.
See the above templates for examples of usage, and the the function [UsageForContextWithTemplate()](https://github.com/alecthomas/kingpin/blob/master/usage.go#L198) method for details on the context.
#### Default help template
```
$ go run ./examples/curl/curl.go --help
usage: curl [<flags>] <command> [<args> ...]
An example implementation of curl.
Flags:
--help Show help.
-t, --timeout=5s Set connection timeout.
-H, --headers=HEADER=VALUE
Add HTTP headers to the request.
Commands:
help [<command>...]
Show help.
get url <url>
Retrieve a URL.
get file <file>
Retrieve a file.
post [<flags>] <url>
POST a resource.
```
#### Compact help template
```
$ go run ./examples/curl/curl.go --help
usage: curl [<flags>] <command> [<args> ...]
An example implementation of curl.
Flags:
--help Show help.
-t, --timeout=5s Set connection timeout.
-H, --headers=HEADER=VALUE
Add HTTP headers to the request.
Commands:
help [<command>...]
get [<flags>]
url <url>
file <file>
post [<flags>] <url>
```

42
vendor/gopkg.in/alecthomas/kingpin.v2/actions.go generated vendored Normal file
View File

@ -0,0 +1,42 @@
package kingpin
// Action callback executed at various stages after all values are populated.
// The application, commands, arguments and flags all have corresponding
// actions.
type Action func(*ParseContext) error
type actionMixin struct {
actions []Action
preActions []Action
}
type actionApplier interface {
applyActions(*ParseContext) error
applyPreActions(*ParseContext) error
}
func (a *actionMixin) addAction(action Action) {
a.actions = append(a.actions, action)
}
func (a *actionMixin) addPreAction(action Action) {
a.preActions = append(a.preActions, action)
}
func (a *actionMixin) applyActions(context *ParseContext) error {
for _, action := range a.actions {
if err := action(context); err != nil {
return err
}
}
return nil
}
func (a *actionMixin) applyPreActions(context *ParseContext) error {
for _, preAction := range a.preActions {
if err := preAction(context); err != nil {
return err
}
}
return nil
}

685
vendor/gopkg.in/alecthomas/kingpin.v2/app.go generated vendored Normal file
View File

@ -0,0 +1,685 @@
package kingpin
import (
"fmt"
"io"
"os"
"regexp"
"strings"
)
var (
ErrCommandNotSpecified = fmt.Errorf("command not specified")
)
var (
envarTransformRegexp = regexp.MustCompile(`[^a-zA-Z0-9_]+`)
)
type ApplicationValidator func(*Application) error
// An Application contains the definitions of flags, arguments and commands
// for an application.
type Application struct {
cmdMixin
initialized bool
Name string
Help string
author string
version string
errorWriter io.Writer // Destination for errors.
usageWriter io.Writer // Destination for usage
usageTemplate string
validator ApplicationValidator
terminate func(status int) // See Terminate()
noInterspersed bool // can flags be interspersed with args (or must they come first)
defaultEnvars bool
completion bool
// Help flag. Exposed for user customisation.
HelpFlag *FlagClause
// Help command. Exposed for user customisation. May be nil.
HelpCommand *CmdClause
// Version flag. Exposed for user customisation. May be nil.
VersionFlag *FlagClause
}
// New creates a new Kingpin application instance.
func New(name, help string) *Application {
a := &Application{
Name: name,
Help: help,
errorWriter: os.Stderr, // Left for backwards compatibility purposes.
usageWriter: os.Stderr,
usageTemplate: DefaultUsageTemplate,
terminate: os.Exit,
}
a.flagGroup = newFlagGroup()
a.argGroup = newArgGroup()
a.cmdGroup = newCmdGroup(a)
a.HelpFlag = a.Flag("help", "Show context-sensitive help (also try --help-long and --help-man).")
a.HelpFlag.Bool()
a.Flag("help-long", "Generate long help.").Hidden().PreAction(a.generateLongHelp).Bool()
a.Flag("help-man", "Generate a man page.").Hidden().PreAction(a.generateManPage).Bool()
a.Flag("completion-bash", "Output possible completions for the given args.").Hidden().BoolVar(&a.completion)
a.Flag("completion-script-bash", "Generate completion script for bash.").Hidden().PreAction(a.generateBashCompletionScript).Bool()
a.Flag("completion-script-zsh", "Generate completion script for ZSH.").Hidden().PreAction(a.generateZSHCompletionScript).Bool()
return a
}
func (a *Application) generateLongHelp(c *ParseContext) error {
a.Writer(os.Stdout)
if err := a.UsageForContextWithTemplate(c, 2, LongHelpTemplate); err != nil {
return err
}
a.terminate(0)
return nil
}
func (a *Application) generateManPage(c *ParseContext) error {
a.Writer(os.Stdout)
if err := a.UsageForContextWithTemplate(c, 2, ManPageTemplate); err != nil {
return err
}
a.terminate(0)
return nil
}
func (a *Application) generateBashCompletionScript(c *ParseContext) error {
a.Writer(os.Stdout)
if err := a.UsageForContextWithTemplate(c, 2, BashCompletionTemplate); err != nil {
return err
}
a.terminate(0)
return nil
}
func (a *Application) generateZSHCompletionScript(c *ParseContext) error {
a.Writer(os.Stdout)
if err := a.UsageForContextWithTemplate(c, 2, ZshCompletionTemplate); err != nil {
return err
}
a.terminate(0)
return nil
}
// DefaultEnvars configures all flags (that do not already have an associated
// envar) to use a default environment variable in the form "<app>_<flag>".
//
// For example, if the application is named "foo" and a flag is named "bar-
// waz" the environment variable: "FOO_BAR_WAZ".
func (a *Application) DefaultEnvars() *Application {
a.defaultEnvars = true
return a
}
// Terminate specifies the termination handler. Defaults to os.Exit(status).
// If nil is passed, a no-op function will be used.
func (a *Application) Terminate(terminate func(int)) *Application {
if terminate == nil {
terminate = func(int) {}
}
a.terminate = terminate
return a
}
// Writer specifies the writer to use for usage and errors. Defaults to os.Stderr.
// DEPRECATED: See ErrorWriter and UsageWriter.
func (a *Application) Writer(w io.Writer) *Application {
a.errorWriter = w
a.usageWriter = w
return a
}
// ErrorWriter sets the io.Writer to use for errors.
func (a *Application) ErrorWriter(w io.Writer) *Application {
a.usageWriter = w
return a
}
// UsageWriter sets the io.Writer to use for errors.
func (a *Application) UsageWriter(w io.Writer) *Application {
a.usageWriter = w
return a
}
// UsageTemplate specifies the text template to use when displaying usage
// information. The default is UsageTemplate.
func (a *Application) UsageTemplate(template string) *Application {
a.usageTemplate = template
return a
}
// Validate sets a validation function to run when parsing.
func (a *Application) Validate(validator ApplicationValidator) *Application {
a.validator = validator
return a
}
// ParseContext parses the given command line and returns the fully populated
// ParseContext.
func (a *Application) ParseContext(args []string) (*ParseContext, error) {
return a.parseContext(false, args)
}
func (a *Application) parseContext(ignoreDefault bool, args []string) (*ParseContext, error) {
if err := a.init(); err != nil {
return nil, err
}
context := tokenize(args, ignoreDefault)
err := parse(context, a)
return context, err
}
// Parse parses command-line arguments. It returns the selected command and an
// error. The selected command will be a space separated subcommand, if
// subcommands have been configured.
//
// This will populate all flag and argument values, call all callbacks, and so
// on.
func (a *Application) Parse(args []string) (command string, err error) {
context, parseErr := a.ParseContext(args)
selected := []string{}
var setValuesErr error
if context == nil {
// Since we do not throw error immediately, there could be a case
// where a context returns nil. Protect against that.
return "", parseErr
}
if err = a.setDefaults(context); err != nil {
return "", err
}
selected, setValuesErr = a.setValues(context)
if err = a.applyPreActions(context, !a.completion); err != nil {
return "", err
}
if a.completion {
a.generateBashCompletion(context)
a.terminate(0)
} else {
if parseErr != nil {
return "", parseErr
}
a.maybeHelp(context)
if !context.EOL() {
return "", fmt.Errorf("unexpected argument '%s'", context.Peek())
}
if setValuesErr != nil {
return "", setValuesErr
}
command, err = a.execute(context, selected)
if err == ErrCommandNotSpecified {
a.writeUsage(context, nil)
}
}
return command, err
}
func (a *Application) writeUsage(context *ParseContext, err error) {
if err != nil {
a.Errorf("%s", err)
}
if err := a.UsageForContext(context); err != nil {
panic(err)
}
if err != nil {
a.terminate(1)
} else {
a.terminate(0)
}
}
func (a *Application) maybeHelp(context *ParseContext) {
for _, element := range context.Elements {
if flag, ok := element.Clause.(*FlagClause); ok && flag == a.HelpFlag {
// Re-parse the command-line ignoring defaults, so that help works correctly.
context, _ = a.parseContext(true, context.rawArgs)
a.writeUsage(context, nil)
}
}
}
// Version adds a --version flag for displaying the application version.
func (a *Application) Version(version string) *Application {
a.version = version
a.VersionFlag = a.Flag("version", "Show application version.").PreAction(func(*ParseContext) error {
fmt.Fprintln(a.usageWriter, version)
a.terminate(0)
return nil
})
a.VersionFlag.Bool()
return a
}
// Author sets the author output by some help templates.
func (a *Application) Author(author string) *Application {
a.author = author
return a
}
// Action callback to call when all values are populated and parsing is
// complete, but before any command, flag or argument actions.
//
// All Action() callbacks are called in the order they are encountered on the
// command line.
func (a *Application) Action(action Action) *Application {
a.addAction(action)
return a
}
// Action called after parsing completes but before validation and execution.
func (a *Application) PreAction(action Action) *Application {
a.addPreAction(action)
return a
}
// Command adds a new top-level command.
func (a *Application) Command(name, help string) *CmdClause {
return a.addCommand(name, help)
}
// Interspersed control if flags can be interspersed with positional arguments
//
// true (the default) means that they can, false means that all the flags must appear before the first positional arguments.
func (a *Application) Interspersed(interspersed bool) *Application {
a.noInterspersed = !interspersed
return a
}
func (a *Application) defaultEnvarPrefix() string {
if a.defaultEnvars {
return a.Name
}
return ""
}
func (a *Application) init() error {
if a.initialized {
return nil
}
if a.cmdGroup.have() && a.argGroup.have() {
return fmt.Errorf("can't mix top-level Arg()s with Command()s")
}
// If we have subcommands, add a help command at the top-level.
if a.cmdGroup.have() {
var command []string
a.HelpCommand = a.Command("help", "Show help.").PreAction(func(context *ParseContext) error {
a.Usage(command)
a.terminate(0)
return nil
})
a.HelpCommand.Arg("command", "Show help on command.").StringsVar(&command)
// Make help first command.
l := len(a.commandOrder)
a.commandOrder = append(a.commandOrder[l-1:l], a.commandOrder[:l-1]...)
}
if err := a.flagGroup.init(a.defaultEnvarPrefix()); err != nil {
return err
}
if err := a.cmdGroup.init(); err != nil {
return err
}
if err := a.argGroup.init(); err != nil {
return err
}
for _, cmd := range a.commands {
if err := cmd.init(); err != nil {
return err
}
}
flagGroups := []*flagGroup{a.flagGroup}
for _, cmd := range a.commandOrder {
if err := checkDuplicateFlags(cmd, flagGroups); err != nil {
return err
}
}
a.initialized = true
return nil
}
// Recursively check commands for duplicate flags.
func checkDuplicateFlags(current *CmdClause, flagGroups []*flagGroup) error {
// Check for duplicates.
for _, flags := range flagGroups {
for _, flag := range current.flagOrder {
if flag.shorthand != 0 {
if _, ok := flags.short[string(flag.shorthand)]; ok {
return fmt.Errorf("duplicate short flag -%c", flag.shorthand)
}
}
if _, ok := flags.long[flag.name]; ok {
return fmt.Errorf("duplicate long flag --%s", flag.name)
}
}
}
flagGroups = append(flagGroups, current.flagGroup)
// Check subcommands.
for _, subcmd := range current.commandOrder {
if err := checkDuplicateFlags(subcmd, flagGroups); err != nil {
return err
}
}
return nil
}
func (a *Application) execute(context *ParseContext, selected []string) (string, error) {
var err error
if err = a.validateRequired(context); err != nil {
return "", err
}
if err = a.applyValidators(context); err != nil {
return "", err
}
if err = a.applyActions(context); err != nil {
return "", err
}
command := strings.Join(selected, " ")
if command == "" && a.cmdGroup.have() {
return "", ErrCommandNotSpecified
}
return command, err
}
func (a *Application) setDefaults(context *ParseContext) error {
flagElements := map[string]*ParseElement{}
for _, element := range context.Elements {
if flag, ok := element.Clause.(*FlagClause); ok {
flagElements[flag.name] = element
}
}
argElements := map[string]*ParseElement{}
for _, element := range context.Elements {
if arg, ok := element.Clause.(*ArgClause); ok {
argElements[arg.name] = element
}
}
// Check required flags and set defaults.
for _, flag := range context.flags.long {
if flagElements[flag.name] == nil {
if err := flag.setDefault(); err != nil {
return err
}
}
}
for _, arg := range context.arguments.args {
if argElements[arg.name] == nil {
if err := arg.setDefault(); err != nil {
return err
}
}
}
return nil
}
func (a *Application) validateRequired(context *ParseContext) error {
flagElements := map[string]*ParseElement{}
for _, element := range context.Elements {
if flag, ok := element.Clause.(*FlagClause); ok {
flagElements[flag.name] = element
}
}
argElements := map[string]*ParseElement{}
for _, element := range context.Elements {
if arg, ok := element.Clause.(*ArgClause); ok {
argElements[arg.name] = element
}
}
// Check required flags and set defaults.
for _, flag := range context.flags.long {
if flagElements[flag.name] == nil {
// Check required flags were provided.
if flag.needsValue() {
return fmt.Errorf("required flag --%s not provided", flag.name)
}
}
}
for _, arg := range context.arguments.args {
if argElements[arg.name] == nil {
if arg.needsValue() {
return fmt.Errorf("required argument '%s' not provided", arg.name)
}
}
}
return nil
}
func (a *Application) setValues(context *ParseContext) (selected []string, err error) {
// Set all arg and flag values.
var (
lastCmd *CmdClause
flagSet = map[string]struct{}{}
)
for _, element := range context.Elements {
switch clause := element.Clause.(type) {
case *FlagClause:
if _, ok := flagSet[clause.name]; ok {
if v, ok := clause.value.(repeatableFlag); !ok || !v.IsCumulative() {
return nil, fmt.Errorf("flag '%s' cannot be repeated", clause.name)
}
}
if err = clause.value.Set(*element.Value); err != nil {
return
}
flagSet[clause.name] = struct{}{}
case *ArgClause:
if err = clause.value.Set(*element.Value); err != nil {
return
}
case *CmdClause:
if clause.validator != nil {
if err = clause.validator(clause); err != nil {
return
}
}
selected = append(selected, clause.name)
lastCmd = clause
}
}
if lastCmd != nil && len(lastCmd.commands) > 0 {
return nil, fmt.Errorf("must select a subcommand of '%s'", lastCmd.FullCommand())
}
return
}
func (a *Application) applyValidators(context *ParseContext) (err error) {
// Call command validation functions.
for _, element := range context.Elements {
if cmd, ok := element.Clause.(*CmdClause); ok && cmd.validator != nil {
if err = cmd.validator(cmd); err != nil {
return err
}
}
}
if a.validator != nil {
err = a.validator(a)
}
return err
}
func (a *Application) applyPreActions(context *ParseContext, dispatch bool) error {
if err := a.actionMixin.applyPreActions(context); err != nil {
return err
}
// Dispatch to actions.
if dispatch {
for _, element := range context.Elements {
if applier, ok := element.Clause.(actionApplier); ok {
if err := applier.applyPreActions(context); err != nil {
return err
}
}
}
}
return nil
}
func (a *Application) applyActions(context *ParseContext) error {
if err := a.actionMixin.applyActions(context); err != nil {
return err
}
// Dispatch to actions.
for _, element := range context.Elements {
if applier, ok := element.Clause.(actionApplier); ok {
if err := applier.applyActions(context); err != nil {
return err
}
}
}
return nil
}
// Errorf prints an error message to w in the format "<appname>: error: <message>".
func (a *Application) Errorf(format string, args ...interface{}) {
fmt.Fprintf(a.errorWriter, a.Name+": error: "+format+"\n", args...)
}
// Fatalf writes a formatted error to w then terminates with exit status 1.
func (a *Application) Fatalf(format string, args ...interface{}) {
a.Errorf(format, args...)
a.terminate(1)
}
// FatalUsage prints an error message followed by usage information, then
// exits with a non-zero status.
func (a *Application) FatalUsage(format string, args ...interface{}) {
a.Errorf(format, args...)
// Force usage to go to error output.
a.usageWriter = a.errorWriter
a.Usage([]string{})
a.terminate(1)
}
// FatalUsageContext writes a printf formatted error message to w, then usage
// information for the given ParseContext, before exiting.
func (a *Application) FatalUsageContext(context *ParseContext, format string, args ...interface{}) {
a.Errorf(format, args...)
if err := a.UsageForContext(context); err != nil {
panic(err)
}
a.terminate(1)
}
// FatalIfError prints an error and exits if err is not nil. The error is printed
// with the given formatted string, if any.
func (a *Application) FatalIfError(err error, format string, args ...interface{}) {
if err != nil {
prefix := ""
if format != "" {
prefix = fmt.Sprintf(format, args...) + ": "
}
a.Errorf(prefix+"%s", err)
a.terminate(1)
}
}
func (a *Application) completionOptions(context *ParseContext) []string {
args := context.rawArgs
var (
currArg string
prevArg string
target cmdMixin
)
numArgs := len(args)
if numArgs > 1 {
args = args[1:]
currArg = args[len(args)-1]
}
if numArgs > 2 {
prevArg = args[len(args)-2]
}
target = a.cmdMixin
if context.SelectedCommand != nil {
// A subcommand was in use. We will use it as the target
target = context.SelectedCommand.cmdMixin
}
if (currArg != "" && strings.HasPrefix(currArg, "--")) || strings.HasPrefix(prevArg, "--") {
// Perform completion for A flag. The last/current argument started with "-"
var (
flagName string // The name of a flag if given (could be half complete)
flagValue string // The value assigned to a flag (if given) (could be half complete)
)
if strings.HasPrefix(prevArg, "--") && !strings.HasPrefix(currArg, "--") {
// Matches: ./myApp --flag value
// Wont Match: ./myApp --flag --
flagName = prevArg[2:] // Strip the "--"
flagValue = currArg
} else if strings.HasPrefix(currArg, "--") {
// Matches: ./myApp --flag --
// Matches: ./myApp --flag somevalue --
// Matches: ./myApp --
flagName = currArg[2:] // Strip the "--"
}
options, flagMatched, valueMatched := target.FlagCompletion(flagName, flagValue)
if valueMatched {
// Value Matched. Show cmdCompletions
return target.CmdCompletion(context)
}
// Add top level flags if we're not at the top level and no match was found.
if context.SelectedCommand != nil && !flagMatched {
topOptions, topFlagMatched, topValueMatched := a.FlagCompletion(flagName, flagValue)
if topValueMatched {
// Value Matched. Back to cmdCompletions
return target.CmdCompletion(context)
}
if topFlagMatched {
// Top level had a flag which matched the input. Return it's options.
options = topOptions
} else {
// Add top level flags
options = append(options, topOptions...)
}
}
return options
}
// Perform completion for sub commands and arguments.
return target.CmdCompletion(context)
}
func (a *Application) generateBashCompletion(context *ParseContext) {
options := a.completionOptions(context)
fmt.Printf("%s", strings.Join(options, "\n"))
}
func envarTransform(name string) string {
return strings.ToUpper(envarTransformRegexp.ReplaceAllString(name, "_"))
}

185
vendor/gopkg.in/alecthomas/kingpin.v2/args.go generated vendored Normal file
View File

@ -0,0 +1,185 @@
package kingpin
import (
"fmt"
)
type argGroup struct {
args []*ArgClause
}
func newArgGroup() *argGroup {
return &argGroup{}
}
func (a *argGroup) have() bool {
return len(a.args) > 0
}
// GetArg gets an argument definition.
//
// This allows existing arguments to be modified after definition but before parsing. Useful for
// modular applications.
func (a *argGroup) GetArg(name string) *ArgClause {
for _, arg := range a.args {
if arg.name == name {
return arg
}
}
return nil
}
func (a *argGroup) Arg(name, help string) *ArgClause {
arg := newArg(name, help)
a.args = append(a.args, arg)
return arg
}
func (a *argGroup) init() error {
required := 0
seen := map[string]struct{}{}
previousArgMustBeLast := false
for i, arg := range a.args {
if previousArgMustBeLast {
return fmt.Errorf("Args() can't be followed by another argument '%s'", arg.name)
}
if arg.consumesRemainder() {
previousArgMustBeLast = true
}
if _, ok := seen[arg.name]; ok {
return fmt.Errorf("duplicate argument '%s'", arg.name)
}
seen[arg.name] = struct{}{}
if arg.required && required != i {
return fmt.Errorf("required arguments found after non-required")
}
if arg.required {
required++
}
if err := arg.init(); err != nil {
return err
}
}
return nil
}
type ArgClause struct {
actionMixin
parserMixin
completionsMixin
envarMixin
name string
help string
defaultValues []string
required bool
}
func newArg(name, help string) *ArgClause {
a := &ArgClause{
name: name,
help: help,
}
return a
}
func (a *ArgClause) setDefault() error {
if a.HasEnvarValue() {
if v, ok := a.value.(remainderArg); !ok || !v.IsCumulative() {
// Use the value as-is
return a.value.Set(a.GetEnvarValue())
} else {
for _, value := range a.GetSplitEnvarValue() {
if err := a.value.Set(value); err != nil {
return err
}
}
return nil
}
}
if len(a.defaultValues) > 0 {
for _, defaultValue := range a.defaultValues {
if err := a.value.Set(defaultValue); err != nil {
return err
}
}
return nil
}
return nil
}
func (a *ArgClause) needsValue() bool {
haveDefault := len(a.defaultValues) > 0
return a.required && !(haveDefault || a.HasEnvarValue())
}
func (a *ArgClause) consumesRemainder() bool {
if r, ok := a.value.(remainderArg); ok {
return r.IsCumulative()
}
return false
}
// Required arguments must be input by the user. They can not have a Default() value provided.
func (a *ArgClause) Required() *ArgClause {
a.required = true
return a
}
// Default values for this argument. They *must* be parseable by the value of the argument.
func (a *ArgClause) Default(values ...string) *ArgClause {
a.defaultValues = values
return a
}
// Envar overrides the default value(s) for a flag from an environment variable,
// if it is set. Several default values can be provided by using new lines to
// separate them.
func (a *ArgClause) Envar(name string) *ArgClause {
a.envar = name
a.noEnvar = false
return a
}
// NoEnvar forces environment variable defaults to be disabled for this flag.
// Most useful in conjunction with app.DefaultEnvars().
func (a *ArgClause) NoEnvar() *ArgClause {
a.envar = ""
a.noEnvar = true
return a
}
func (a *ArgClause) Action(action Action) *ArgClause {
a.addAction(action)
return a
}
func (a *ArgClause) PreAction(action Action) *ArgClause {
a.addPreAction(action)
return a
}
// HintAction registers a HintAction (function) for the arg to provide completions
func (a *ArgClause) HintAction(action HintAction) *ArgClause {
a.addHintAction(action)
return a
}
// HintOptions registers any number of options for the flag to provide completions
func (a *ArgClause) HintOptions(options ...string) *ArgClause {
a.addHintAction(func() []string {
return options
})
return a
}
func (a *ArgClause) init() error {
if a.required && len(a.defaultValues) > 0 {
return fmt.Errorf("required argument '%s' with unusable default value", a.name)
}
if a.value == nil {
return fmt.Errorf("no parser defined for arg '%s'", a.name)
}
return nil
}

274
vendor/gopkg.in/alecthomas/kingpin.v2/cmd.go generated vendored Normal file
View File

@ -0,0 +1,274 @@
package kingpin
import (
"fmt"
"strings"
)
type cmdMixin struct {
*flagGroup
*argGroup
*cmdGroup
actionMixin
}
// CmdCompletion returns completion options for arguments, if that's where
// parsing left off, or commands if there aren't any unsatisfied args.
func (c *cmdMixin) CmdCompletion(context *ParseContext) []string {
var options []string
// Count args already satisfied - we won't complete those, and add any
// default commands' alternatives, since they weren't listed explicitly
// and the user may want to explicitly list something else.
argsSatisfied := 0
for _, el := range context.Elements {
switch clause := el.Clause.(type) {
case *ArgClause:
if el.Value != nil && *el.Value != "" {
argsSatisfied++
}
case *CmdClause:
options = append(options, clause.completionAlts...)
default:
}
}
if argsSatisfied < len(c.argGroup.args) {
// Since not all args have been satisfied, show options for the current one
options = append(options, c.argGroup.args[argsSatisfied].resolveCompletions()...)
} else {
// If all args are satisfied, then go back to completing commands
for _, cmd := range c.cmdGroup.commandOrder {
if !cmd.hidden {
options = append(options, cmd.name)
}
}
}
return options
}
func (c *cmdMixin) FlagCompletion(flagName string, flagValue string) (choices []string, flagMatch bool, optionMatch bool) {
// Check if flagName matches a known flag.
// If it does, show the options for the flag
// Otherwise, show all flags
options := []string{}
for _, flag := range c.flagGroup.flagOrder {
// Loop through each flag and determine if a match exists
if flag.name == flagName {
// User typed entire flag. Need to look for flag options.
options = flag.resolveCompletions()
if len(options) == 0 {
// No Options to Choose From, Assume Match.
return options, true, true
}
// Loop options to find if the user specified value matches
isPrefix := false
matched := false
for _, opt := range options {
if flagValue == opt {
matched = true
} else if strings.HasPrefix(opt, flagValue) {
isPrefix = true
}
}
// Matched Flag Directly
// Flag Value Not Prefixed, and Matched Directly
return options, true, !isPrefix && matched
}
if !flag.hidden {
options = append(options, "--"+flag.name)
}
}
// No Flag directly matched.
return options, false, false
}
type cmdGroup struct {
app *Application
parent *CmdClause
commands map[string]*CmdClause
commandOrder []*CmdClause
}
func (c *cmdGroup) defaultSubcommand() *CmdClause {
for _, cmd := range c.commandOrder {
if cmd.isDefault {
return cmd
}
}
return nil
}
func (c *cmdGroup) cmdNames() []string {
names := make([]string, 0, len(c.commandOrder))
for _, cmd := range c.commandOrder {
names = append(names, cmd.name)
}
return names
}
// GetArg gets a command definition.
//
// This allows existing commands to be modified after definition but before parsing. Useful for
// modular applications.
func (c *cmdGroup) GetCommand(name string) *CmdClause {
return c.commands[name]
}
func newCmdGroup(app *Application) *cmdGroup {
return &cmdGroup{
app: app,
commands: make(map[string]*CmdClause),
}
}
func (c *cmdGroup) flattenedCommands() (out []*CmdClause) {
for _, cmd := range c.commandOrder {
if len(cmd.commands) == 0 {
out = append(out, cmd)
}
out = append(out, cmd.flattenedCommands()...)
}
return
}
func (c *cmdGroup) addCommand(name, help string) *CmdClause {
cmd := newCommand(c.app, name, help)
c.commands[name] = cmd
c.commandOrder = append(c.commandOrder, cmd)
return cmd
}
func (c *cmdGroup) init() error {
seen := map[string]bool{}
if c.defaultSubcommand() != nil && !c.have() {
return fmt.Errorf("default subcommand %q provided but no subcommands defined", c.defaultSubcommand().name)
}
defaults := []string{}
for _, cmd := range c.commandOrder {
if cmd.isDefault {
defaults = append(defaults, cmd.name)
}
if seen[cmd.name] {
return fmt.Errorf("duplicate command %q", cmd.name)
}
seen[cmd.name] = true
for _, alias := range cmd.aliases {
if seen[alias] {
return fmt.Errorf("alias duplicates existing command %q", alias)
}
c.commands[alias] = cmd
}
if err := cmd.init(); err != nil {
return err
}
}
if len(defaults) > 1 {
return fmt.Errorf("more than one default subcommand exists: %s", strings.Join(defaults, ", "))
}
return nil
}
func (c *cmdGroup) have() bool {
return len(c.commands) > 0
}
type CmdClauseValidator func(*CmdClause) error
// A CmdClause is a single top-level command. It encapsulates a set of flags
// and either subcommands or positional arguments.
type CmdClause struct {
cmdMixin
app *Application
name string
aliases []string
help string
isDefault bool
validator CmdClauseValidator
hidden bool
completionAlts []string
}
func newCommand(app *Application, name, help string) *CmdClause {
c := &CmdClause{
app: app,
name: name,
help: help,
}
c.flagGroup = newFlagGroup()
c.argGroup = newArgGroup()
c.cmdGroup = newCmdGroup(app)
return c
}
// Add an Alias for this command.
func (c *CmdClause) Alias(name string) *CmdClause {
c.aliases = append(c.aliases, name)
return c
}
// Validate sets a validation function to run when parsing.
func (c *CmdClause) Validate(validator CmdClauseValidator) *CmdClause {
c.validator = validator
return c
}
func (c *CmdClause) FullCommand() string {
out := []string{c.name}
for p := c.parent; p != nil; p = p.parent {
out = append([]string{p.name}, out...)
}
return strings.Join(out, " ")
}
// Command adds a new sub-command.
func (c *CmdClause) Command(name, help string) *CmdClause {
cmd := c.addCommand(name, help)
cmd.parent = c
return cmd
}
// Default makes this command the default if commands don't match.
func (c *CmdClause) Default() *CmdClause {
c.isDefault = true
return c
}
func (c *CmdClause) Action(action Action) *CmdClause {
c.addAction(action)
return c
}
func (c *CmdClause) PreAction(action Action) *CmdClause {
c.addPreAction(action)
return c
}
func (c *CmdClause) init() error {
if err := c.flagGroup.init(c.app.defaultEnvarPrefix()); err != nil {
return err
}
if c.argGroup.have() && c.cmdGroup.have() {
return fmt.Errorf("can't mix Arg()s with Command()s")
}
if err := c.argGroup.init(); err != nil {
return err
}
if err := c.cmdGroup.init(); err != nil {
return err
}
return nil
}
func (c *CmdClause) Hidden() *CmdClause {
c.hidden = true
return c
}

33
vendor/gopkg.in/alecthomas/kingpin.v2/completions.go generated vendored Normal file
View File

@ -0,0 +1,33 @@
package kingpin
// HintAction is a function type who is expected to return a slice of possible
// command line arguments.
type HintAction func() []string
type completionsMixin struct {
hintActions []HintAction
builtinHintActions []HintAction
}
func (a *completionsMixin) addHintAction(action HintAction) {
a.hintActions = append(a.hintActions, action)
}
// Allow adding of HintActions which are added internally, ie, EnumVar
func (a *completionsMixin) addHintActionBuiltin(action HintAction) {
a.builtinHintActions = append(a.builtinHintActions, action)
}
func (a *completionsMixin) resolveCompletions() []string {
var hints []string
options := a.builtinHintActions
if len(a.hintActions) > 0 {
// User specified their own hintActions. Use those instead.
options = a.hintActions
}
for _, hintAction := range options {
hints = append(hints, hintAction()...)
}
return hints
}

68
vendor/gopkg.in/alecthomas/kingpin.v2/doc.go generated vendored Normal file
View File

@ -0,0 +1,68 @@
// Package kingpin provides command line interfaces like this:
//
// $ chat
// usage: chat [<flags>] <command> [<flags>] [<args> ...]
//
// Flags:
// --debug enable debug mode
// --help Show help.
// --server=127.0.0.1 server address
//
// Commands:
// help <command>
// Show help for a command.
//
// post [<flags>] <channel>
// Post a message to a channel.
//
// register <nick> <name>
// Register a new user.
//
// $ chat help post
// usage: chat [<flags>] post [<flags>] <channel> [<text>]
//
// Post a message to a channel.
//
// Flags:
// --image=IMAGE image to post
//
// Args:
// <channel> channel to post to
// [<text>] text to post
// $ chat post --image=~/Downloads/owls.jpg pics
//
// From code like this:
//
// package main
//
// import "gopkg.in/alecthomas/kingpin.v1"
//
// var (
// debug = kingpin.Flag("debug", "enable debug mode").Default("false").Bool()
// serverIP = kingpin.Flag("server", "server address").Default("127.0.0.1").IP()
//
// register = kingpin.Command("register", "Register a new user.")
// registerNick = register.Arg("nick", "nickname for user").Required().String()
// registerName = register.Arg("name", "name of user").Required().String()
//
// post = kingpin.Command("post", "Post a message to a channel.")
// postImage = post.Flag("image", "image to post").ExistingFile()
// postChannel = post.Arg("channel", "channel to post to").Required().String()
// postText = post.Arg("text", "text to post").String()
// )
//
// func main() {
// switch kingpin.Parse() {
// // Register user
// case "register":
// println(*registerNick)
//
// // Post message
// case "post":
// if *postImage != nil {
// }
// if *postText != "" {
// }
// }
// }
package kingpin

45
vendor/gopkg.in/alecthomas/kingpin.v2/envar.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
package kingpin
import (
"os"
"regexp"
)
var (
envVarValuesSeparator = "\r?\n"
envVarValuesTrimmer = regexp.MustCompile(envVarValuesSeparator + "$")
envVarValuesSplitter = regexp.MustCompile(envVarValuesSeparator)
)
type envarMixin struct {
envar string
noEnvar bool
}
func (e *envarMixin) HasEnvarValue() bool {
return e.GetEnvarValue() != ""
}
func (e *envarMixin) GetEnvarValue() string {
if e.noEnvar || e.envar == "" {
return ""
}
return os.Getenv(e.envar)
}
func (e *envarMixin) GetSplitEnvarValue() []string {
values := make([]string, 0)
envarValue := e.GetEnvarValue()
if envarValue == "" {
return values
}
// Split by new line to extract multiple values, if any.
trimmed := envVarValuesTrimmer.ReplaceAllString(envarValue, "")
for _, value := range envVarValuesSplitter.Split(trimmed, -1) {
values = append(values, value)
}
return values
}

308
vendor/gopkg.in/alecthomas/kingpin.v2/flags.go generated vendored Normal file
View File

@ -0,0 +1,308 @@
package kingpin
import (
"fmt"
"strings"
)
type flagGroup struct {
short map[string]*FlagClause
long map[string]*FlagClause
flagOrder []*FlagClause
}
func newFlagGroup() *flagGroup {
return &flagGroup{
short: map[string]*FlagClause{},
long: map[string]*FlagClause{},
}
}
// GetFlag gets a flag definition.
//
// This allows existing flags to be modified after definition but before parsing. Useful for
// modular applications.
func (f *flagGroup) GetFlag(name string) *FlagClause {
return f.long[name]
}
// Flag defines a new flag with the given long name and help.
func (f *flagGroup) Flag(name, help string) *FlagClause {
flag := newFlag(name, help)
f.long[name] = flag
f.flagOrder = append(f.flagOrder, flag)
return flag
}
func (f *flagGroup) init(defaultEnvarPrefix string) error {
if err := f.checkDuplicates(); err != nil {
return err
}
for _, flag := range f.long {
if defaultEnvarPrefix != "" && !flag.noEnvar && flag.envar == "" {
flag.envar = envarTransform(defaultEnvarPrefix + "_" + flag.name)
}
if err := flag.init(); err != nil {
return err
}
if flag.shorthand != 0 {
f.short[string(flag.shorthand)] = flag
}
}
return nil
}
func (f *flagGroup) checkDuplicates() error {
seenShort := map[byte]bool{}
seenLong := map[string]bool{}
for _, flag := range f.flagOrder {
if flag.shorthand != 0 {
if _, ok := seenShort[flag.shorthand]; ok {
return fmt.Errorf("duplicate short flag -%c", flag.shorthand)
}
seenShort[flag.shorthand] = true
}
if _, ok := seenLong[flag.name]; ok {
return fmt.Errorf("duplicate long flag --%s", flag.name)
}
seenLong[flag.name] = true
}
return nil
}
func (f *flagGroup) parse(context *ParseContext) (*FlagClause, error) {
var token *Token
loop:
for {
token = context.Peek()
switch token.Type {
case TokenEOL:
break loop
case TokenLong, TokenShort:
flagToken := token
defaultValue := ""
var flag *FlagClause
var ok bool
invert := false
name := token.Value
if token.Type == TokenLong {
flag, ok = f.long[name]
if !ok {
if strings.HasPrefix(name, "no-") {
name = name[3:]
invert = true
}
flag, ok = f.long[name]
}
if !ok {
return nil, fmt.Errorf("unknown long flag '%s'", flagToken)
}
} else {
flag, ok = f.short[name]
if !ok {
return nil, fmt.Errorf("unknown short flag '%s'", flagToken)
}
}
context.Next()
fb, ok := flag.value.(boolFlag)
if ok && fb.IsBoolFlag() {
if invert {
defaultValue = "false"
} else {
defaultValue = "true"
}
} else {
if invert {
context.Push(token)
return nil, fmt.Errorf("unknown long flag '%s'", flagToken)
}
token = context.Peek()
if token.Type != TokenArg {
context.Push(token)
return nil, fmt.Errorf("expected argument for flag '%s'", flagToken)
}
context.Next()
defaultValue = token.Value
}
context.matchedFlag(flag, defaultValue)
return flag, nil
default:
break loop
}
}
return nil, nil
}
// FlagClause is a fluid interface used to build flags.
type FlagClause struct {
parserMixin
actionMixin
completionsMixin
envarMixin
name string
shorthand byte
help string
defaultValues []string
placeholder string
hidden bool
}
func newFlag(name, help string) *FlagClause {
f := &FlagClause{
name: name,
help: help,
}
return f
}
func (f *FlagClause) setDefault() error {
if f.HasEnvarValue() {
if v, ok := f.value.(repeatableFlag); !ok || !v.IsCumulative() {
// Use the value as-is
return f.value.Set(f.GetEnvarValue())
} else {
for _, value := range f.GetSplitEnvarValue() {
if err := f.value.Set(value); err != nil {
return err
}
}
return nil
}
}
if len(f.defaultValues) > 0 {
for _, defaultValue := range f.defaultValues {
if err := f.value.Set(defaultValue); err != nil {
return err
}
}
return nil
}
return nil
}
func (f *FlagClause) needsValue() bool {
haveDefault := len(f.defaultValues) > 0
return f.required && !(haveDefault || f.HasEnvarValue())
}
func (f *FlagClause) init() error {
if f.required && len(f.defaultValues) > 0 {
return fmt.Errorf("required flag '--%s' with default value that will never be used", f.name)
}
if f.value == nil {
return fmt.Errorf("no type defined for --%s (eg. .String())", f.name)
}
if v, ok := f.value.(repeatableFlag); (!ok || !v.IsCumulative()) && len(f.defaultValues) > 1 {
return fmt.Errorf("invalid default for '--%s', expecting single value", f.name)
}
return nil
}
// Dispatch to the given function after the flag is parsed and validated.
func (f *FlagClause) Action(action Action) *FlagClause {
f.addAction(action)
return f
}
func (f *FlagClause) PreAction(action Action) *FlagClause {
f.addPreAction(action)
return f
}
// HintAction registers a HintAction (function) for the flag to provide completions
func (a *FlagClause) HintAction(action HintAction) *FlagClause {
a.addHintAction(action)
return a
}
// HintOptions registers any number of options for the flag to provide completions
func (a *FlagClause) HintOptions(options ...string) *FlagClause {
a.addHintAction(func() []string {
return options
})
return a
}
func (a *FlagClause) EnumVar(target *string, options ...string) {
a.parserMixin.EnumVar(target, options...)
a.addHintActionBuiltin(func() []string {
return options
})
}
func (a *FlagClause) Enum(options ...string) (target *string) {
a.addHintActionBuiltin(func() []string {
return options
})
return a.parserMixin.Enum(options...)
}
// Default values for this flag. They *must* be parseable by the value of the flag.
func (f *FlagClause) Default(values ...string) *FlagClause {
f.defaultValues = values
return f
}
// DEPRECATED: Use Envar(name) instead.
func (f *FlagClause) OverrideDefaultFromEnvar(envar string) *FlagClause {
return f.Envar(envar)
}
// Envar overrides the default value(s) for a flag from an environment variable,
// if it is set. Several default values can be provided by using new lines to
// separate them.
func (f *FlagClause) Envar(name string) *FlagClause {
f.envar = name
f.noEnvar = false
return f
}
// NoEnvar forces environment variable defaults to be disabled for this flag.
// Most useful in conjunction with app.DefaultEnvars().
func (f *FlagClause) NoEnvar() *FlagClause {
f.envar = ""
f.noEnvar = true
return f
}
// PlaceHolder sets the place-holder string used for flag values in the help. The
// default behaviour is to use the value provided by Default() if provided,
// then fall back on the capitalized flag name.
func (f *FlagClause) PlaceHolder(placeholder string) *FlagClause {
f.placeholder = placeholder
return f
}
// Hidden hides a flag from usage but still allows it to be used.
func (f *FlagClause) Hidden() *FlagClause {
f.hidden = true
return f
}
// Required makes the flag required. You can not provide a Default() value to a Required() flag.
func (f *FlagClause) Required() *FlagClause {
f.required = true
return f
}
// Short sets the short flag name.
func (f *FlagClause) Short(name byte) *FlagClause {
f.shorthand = name
return f
}
// Bool makes this flag a boolean flag.
func (f *FlagClause) Bool() (target *bool) {
target = new(bool)
f.SetValue(newBoolValue(target))
return
}

94
vendor/gopkg.in/alecthomas/kingpin.v2/global.go generated vendored Normal file
View File

@ -0,0 +1,94 @@
package kingpin
import (
"os"
"path/filepath"
)
var (
// CommandLine is the default Kingpin parser.
CommandLine = New(filepath.Base(os.Args[0]), "")
// Global help flag. Exposed for user customisation.
HelpFlag = CommandLine.HelpFlag
// Top-level help command. Exposed for user customisation. May be nil.
HelpCommand = CommandLine.HelpCommand
// Global version flag. Exposed for user customisation. May be nil.
VersionFlag = CommandLine.VersionFlag
)
// Command adds a new command to the default parser.
func Command(name, help string) *CmdClause {
return CommandLine.Command(name, help)
}
// Flag adds a new flag to the default parser.
func Flag(name, help string) *FlagClause {
return CommandLine.Flag(name, help)
}
// Arg adds a new argument to the top-level of the default parser.
func Arg(name, help string) *ArgClause {
return CommandLine.Arg(name, help)
}
// Parse and return the selected command. Will call the termination handler if
// an error is encountered.
func Parse() string {
selected := MustParse(CommandLine.Parse(os.Args[1:]))
if selected == "" && CommandLine.cmdGroup.have() {
Usage()
CommandLine.terminate(0)
}
return selected
}
// Errorf prints an error message to stderr.
func Errorf(format string, args ...interface{}) {
CommandLine.Errorf(format, args...)
}
// Fatalf prints an error message to stderr and exits.
func Fatalf(format string, args ...interface{}) {
CommandLine.Fatalf(format, args...)
}
// FatalIfError prints an error and exits if err is not nil. The error is printed
// with the given prefix.
func FatalIfError(err error, format string, args ...interface{}) {
CommandLine.FatalIfError(err, format, args...)
}
// FatalUsage prints an error message followed by usage information, then
// exits with a non-zero status.
func FatalUsage(format string, args ...interface{}) {
CommandLine.FatalUsage(format, args...)
}
// FatalUsageContext writes a printf formatted error message to stderr, then
// usage information for the given ParseContext, before exiting.
func FatalUsageContext(context *ParseContext, format string, args ...interface{}) {
CommandLine.FatalUsageContext(context, format, args...)
}
// Usage prints usage to stderr.
func Usage() {
CommandLine.Usage(os.Args[1:])
}
// Set global usage template to use (defaults to DefaultUsageTemplate).
func UsageTemplate(template string) *Application {
return CommandLine.UsageTemplate(template)
}
// MustParse can be used with app.Parse(args) to exit with an error if parsing fails.
func MustParse(command string, err error) string {
if err != nil {
Fatalf("%s, try --help", err)
}
return command
}
// Version adds a flag for displaying the application version number.
func Version(version string) *Application {
return CommandLine.Version(version)
}

9
vendor/gopkg.in/alecthomas/kingpin.v2/guesswidth.go generated vendored Normal file
View File

@ -0,0 +1,9 @@
// +build appengine !linux,!freebsd,!darwin,!dragonfly,!netbsd,!openbsd
package kingpin
import "io"
func guessWidth(w io.Writer) int {
return 80
}

View File

@ -0,0 +1,38 @@
// +build !appengine,linux freebsd darwin dragonfly netbsd openbsd
package kingpin
import (
"io"
"os"
"strconv"
"syscall"
"unsafe"
)
func guessWidth(w io.Writer) int {
// check if COLUMNS env is set to comply with
// http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap08.html
colsStr := os.Getenv("COLUMNS")
if colsStr != "" {
if cols, err := strconv.Atoi(colsStr); err == nil {
return cols
}
}
if t, ok := w.(*os.File); ok {
fd := t.Fd()
var dimensions [4]uint16
if _, _, err := syscall.Syscall6(
syscall.SYS_IOCTL,
uintptr(fd),
uintptr(syscall.TIOCGWINSZ),
uintptr(unsafe.Pointer(&dimensions)),
0, 0, 0,
); err == 0 {
return int(dimensions[1])
}
}
return 80
}

227
vendor/gopkg.in/alecthomas/kingpin.v2/model.go generated vendored Normal file
View File

@ -0,0 +1,227 @@
package kingpin
import (
"fmt"
"strconv"
"strings"
)
// Data model for Kingpin command-line structure.
type FlagGroupModel struct {
Flags []*FlagModel
}
func (f *FlagGroupModel) FlagSummary() string {
out := []string{}
count := 0
for _, flag := range f.Flags {
if flag.Name != "help" {
count++
}
if flag.Required {
if flag.IsBoolFlag() {
out = append(out, fmt.Sprintf("--[no-]%s", flag.Name))
} else {
out = append(out, fmt.Sprintf("--%s=%s", flag.Name, flag.FormatPlaceHolder()))
}
}
}
if count != len(out) {
out = append(out, "[<flags>]")
}
return strings.Join(out, " ")
}
type FlagModel struct {
Name string
Help string
Short rune
Default []string
Envar string
PlaceHolder string
Required bool
Hidden bool
Value Value
}
func (f *FlagModel) String() string {
return f.Value.String()
}
func (f *FlagModel) IsBoolFlag() bool {
if fl, ok := f.Value.(boolFlag); ok {
return fl.IsBoolFlag()
}
return false
}
func (f *FlagModel) FormatPlaceHolder() string {
if f.PlaceHolder != "" {
return f.PlaceHolder
}
if len(f.Default) > 0 {
ellipsis := ""
if len(f.Default) > 1 {
ellipsis = "..."
}
if _, ok := f.Value.(*stringValue); ok {
return strconv.Quote(f.Default[0]) + ellipsis
}
return f.Default[0] + ellipsis
}
return strings.ToUpper(f.Name)
}
type ArgGroupModel struct {
Args []*ArgModel
}
func (a *ArgGroupModel) ArgSummary() string {
depth := 0
out := []string{}
for _, arg := range a.Args {
h := "<" + arg.Name + ">"
if !arg.Required {
h = "[" + h
depth++
}
out = append(out, h)
}
out[len(out)-1] = out[len(out)-1] + strings.Repeat("]", depth)
return strings.Join(out, " ")
}
type ArgModel struct {
Name string
Help string
Default []string
Envar string
Required bool
Value Value
}
func (a *ArgModel) String() string {
return a.Value.String()
}
type CmdGroupModel struct {
Commands []*CmdModel
}
func (c *CmdGroupModel) FlattenedCommands() (out []*CmdModel) {
for _, cmd := range c.Commands {
if len(cmd.Commands) == 0 {
out = append(out, cmd)
}
out = append(out, cmd.FlattenedCommands()...)
}
return
}
type CmdModel struct {
Name string
Aliases []string
Help string
FullCommand string
Depth int
Hidden bool
Default bool
*FlagGroupModel
*ArgGroupModel
*CmdGroupModel
}
func (c *CmdModel) String() string {
return c.FullCommand
}
type ApplicationModel struct {
Name string
Help string
Version string
Author string
*ArgGroupModel
*CmdGroupModel
*FlagGroupModel
}
func (a *Application) Model() *ApplicationModel {
return &ApplicationModel{
Name: a.Name,
Help: a.Help,
Version: a.version,
Author: a.author,
FlagGroupModel: a.flagGroup.Model(),
ArgGroupModel: a.argGroup.Model(),
CmdGroupModel: a.cmdGroup.Model(),
}
}
func (a *argGroup) Model() *ArgGroupModel {
m := &ArgGroupModel{}
for _, arg := range a.args {
m.Args = append(m.Args, arg.Model())
}
return m
}
func (a *ArgClause) Model() *ArgModel {
return &ArgModel{
Name: a.name,
Help: a.help,
Default: a.defaultValues,
Envar: a.envar,
Required: a.required,
Value: a.value,
}
}
func (f *flagGroup) Model() *FlagGroupModel {
m := &FlagGroupModel{}
for _, fl := range f.flagOrder {
m.Flags = append(m.Flags, fl.Model())
}
return m
}
func (f *FlagClause) Model() *FlagModel {
return &FlagModel{
Name: f.name,
Help: f.help,
Short: rune(f.shorthand),
Default: f.defaultValues,
Envar: f.envar,
PlaceHolder: f.placeholder,
Required: f.required,
Hidden: f.hidden,
Value: f.value,
}
}
func (c *cmdGroup) Model() *CmdGroupModel {
m := &CmdGroupModel{}
for _, cm := range c.commandOrder {
m.Commands = append(m.Commands, cm.Model())
}
return m
}
func (c *CmdClause) Model() *CmdModel {
depth := 0
for i := c; i != nil; i = i.parent {
depth++
}
return &CmdModel{
Name: c.name,
Aliases: c.aliases,
Help: c.help,
Depth: depth,
Hidden: c.hidden,
Default: c.isDefault,
FullCommand: c.FullCommand(),
FlagGroupModel: c.flagGroup.Model(),
ArgGroupModel: c.argGroup.Model(),
CmdGroupModel: c.cmdGroup.Model(),
}
}

380
vendor/gopkg.in/alecthomas/kingpin.v2/parser.go generated vendored Normal file
View File

@ -0,0 +1,380 @@
package kingpin
import (
"bufio"
"fmt"
"os"
"strings"
)
type TokenType int
// Token types.
const (
TokenShort TokenType = iota
TokenLong
TokenArg
TokenError
TokenEOL
)
func (t TokenType) String() string {
switch t {
case TokenShort:
return "short flag"
case TokenLong:
return "long flag"
case TokenArg:
return "argument"
case TokenError:
return "error"
case TokenEOL:
return "<EOL>"
}
return "?"
}
var (
TokenEOLMarker = Token{-1, TokenEOL, ""}
)
type Token struct {
Index int
Type TokenType
Value string
}
func (t *Token) Equal(o *Token) bool {
return t.Index == o.Index
}
func (t *Token) IsFlag() bool {
return t.Type == TokenShort || t.Type == TokenLong
}
func (t *Token) IsEOF() bool {
return t.Type == TokenEOL
}
func (t *Token) String() string {
switch t.Type {
case TokenShort:
return "-" + t.Value
case TokenLong:
return "--" + t.Value
case TokenArg:
return t.Value
case TokenError:
return "error: " + t.Value
case TokenEOL:
return "<EOL>"
default:
panic("unhandled type")
}
}
// A union of possible elements in a parse stack.
type ParseElement struct {
// Clause is either *CmdClause, *ArgClause or *FlagClause.
Clause interface{}
// Value is corresponding value for an ArgClause or FlagClause (if any).
Value *string
}
// ParseContext holds the current context of the parser. When passed to
// Action() callbacks Elements will be fully populated with *FlagClause,
// *ArgClause and *CmdClause values and their corresponding arguments (if
// any).
type ParseContext struct {
SelectedCommand *CmdClause
ignoreDefault bool
argsOnly bool
peek []*Token
argi int // Index of current command-line arg we're processing.
args []string
rawArgs []string
flags *flagGroup
arguments *argGroup
argumenti int // Cursor into arguments
// Flags, arguments and commands encountered and collected during parse.
Elements []*ParseElement
}
func (p *ParseContext) nextArg() *ArgClause {
if p.argumenti >= len(p.arguments.args) {
return nil
}
arg := p.arguments.args[p.argumenti]
if !arg.consumesRemainder() {
p.argumenti++
}
return arg
}
func (p *ParseContext) next() {
p.argi++
p.args = p.args[1:]
}
// HasTrailingArgs returns true if there are unparsed command-line arguments.
// This can occur if the parser can not match remaining arguments.
func (p *ParseContext) HasTrailingArgs() bool {
return len(p.args) > 0
}
func tokenize(args []string, ignoreDefault bool) *ParseContext {
return &ParseContext{
ignoreDefault: ignoreDefault,
args: args,
rawArgs: args,
flags: newFlagGroup(),
arguments: newArgGroup(),
}
}
func (p *ParseContext) mergeFlags(flags *flagGroup) {
for _, flag := range flags.flagOrder {
if flag.shorthand != 0 {
p.flags.short[string(flag.shorthand)] = flag
}
p.flags.long[flag.name] = flag
p.flags.flagOrder = append(p.flags.flagOrder, flag)
}
}
func (p *ParseContext) mergeArgs(args *argGroup) {
for _, arg := range args.args {
p.arguments.args = append(p.arguments.args, arg)
}
}
func (p *ParseContext) EOL() bool {
return p.Peek().Type == TokenEOL
}
// Next token in the parse context.
func (p *ParseContext) Next() *Token {
if len(p.peek) > 0 {
return p.pop()
}
// End of tokens.
if len(p.args) == 0 {
return &Token{Index: p.argi, Type: TokenEOL}
}
arg := p.args[0]
p.next()
if p.argsOnly {
return &Token{p.argi, TokenArg, arg}
}
// All remaining args are passed directly.
if arg == "--" {
p.argsOnly = true
return p.Next()
}
if strings.HasPrefix(arg, "--") {
parts := strings.SplitN(arg[2:], "=", 2)
token := &Token{p.argi, TokenLong, parts[0]}
if len(parts) == 2 {
p.Push(&Token{p.argi, TokenArg, parts[1]})
}
return token
}
if strings.HasPrefix(arg, "-") {
if len(arg) == 1 {
return &Token{Index: p.argi, Type: TokenShort}
}
short := arg[1:2]
flag, ok := p.flags.short[short]
// Not a known short flag, we'll just return it anyway.
if !ok {
} else if fb, ok := flag.value.(boolFlag); ok && fb.IsBoolFlag() {
// Bool short flag.
} else {
// Short flag with combined argument: -fARG
token := &Token{p.argi, TokenShort, short}
if len(arg) > 2 {
p.Push(&Token{p.argi, TokenArg, arg[2:]})
}
return token
}
if len(arg) > 2 {
p.args = append([]string{"-" + arg[2:]}, p.args...)
}
return &Token{p.argi, TokenShort, short}
} else if strings.HasPrefix(arg, "@") {
expanded, err := ExpandArgsFromFile(arg[1:])
if err != nil {
return &Token{p.argi, TokenError, err.Error()}
}
if p.argi >= len(p.args) {
p.args = append(p.args[:p.argi-1], expanded...)
} else {
p.args = append(p.args[:p.argi-1], append(expanded, p.args[p.argi+1:]...)...)
}
return p.Next()
}
return &Token{p.argi, TokenArg, arg}
}
func (p *ParseContext) Peek() *Token {
if len(p.peek) == 0 {
return p.Push(p.Next())
}
return p.peek[len(p.peek)-1]
}
func (p *ParseContext) Push(token *Token) *Token {
p.peek = append(p.peek, token)
return token
}
func (p *ParseContext) pop() *Token {
end := len(p.peek) - 1
token := p.peek[end]
p.peek = p.peek[0:end]
return token
}
func (p *ParseContext) String() string {
return p.SelectedCommand.FullCommand()
}
func (p *ParseContext) matchedFlag(flag *FlagClause, value string) {
p.Elements = append(p.Elements, &ParseElement{Clause: flag, Value: &value})
}
func (p *ParseContext) matchedArg(arg *ArgClause, value string) {
p.Elements = append(p.Elements, &ParseElement{Clause: arg, Value: &value})
}
func (p *ParseContext) matchedCmd(cmd *CmdClause) {
p.Elements = append(p.Elements, &ParseElement{Clause: cmd})
p.mergeFlags(cmd.flagGroup)
p.mergeArgs(cmd.argGroup)
p.SelectedCommand = cmd
}
// Expand arguments from a file. Lines starting with # will be treated as comments.
func ExpandArgsFromFile(filename string) (out []string, err error) {
r, err := os.Open(filename)
if err != nil {
return nil, err
}
defer r.Close()
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "#") {
continue
}
out = append(out, line)
}
err = scanner.Err()
return
}
func parse(context *ParseContext, app *Application) (err error) {
context.mergeFlags(app.flagGroup)
context.mergeArgs(app.argGroup)
cmds := app.cmdGroup
ignoreDefault := context.ignoreDefault
loop:
for !context.EOL() {
token := context.Peek()
switch token.Type {
case TokenLong, TokenShort:
if flag, err := context.flags.parse(context); err != nil {
if !ignoreDefault {
if cmd := cmds.defaultSubcommand(); cmd != nil {
cmd.completionAlts = cmds.cmdNames()
context.matchedCmd(cmd)
cmds = cmd.cmdGroup
break
}
}
return err
} else if flag == HelpFlag {
ignoreDefault = true
}
case TokenArg:
if cmds.have() {
selectedDefault := false
cmd, ok := cmds.commands[token.String()]
if !ok {
if !ignoreDefault {
if cmd = cmds.defaultSubcommand(); cmd != nil {
cmd.completionAlts = cmds.cmdNames()
selectedDefault = true
}
}
if cmd == nil {
return fmt.Errorf("expected command but got %q", token)
}
}
if cmd == HelpCommand {
ignoreDefault = true
}
cmd.completionAlts = nil
context.matchedCmd(cmd)
cmds = cmd.cmdGroup
if !selectedDefault {
context.Next()
}
} else if context.arguments.have() {
if app.noInterspersed {
// no more flags
context.argsOnly = true
}
arg := context.nextArg()
if arg == nil {
break loop
}
context.matchedArg(arg, token.String())
context.Next()
} else {
break loop
}
case TokenEOL:
break loop
}
}
// Move to innermost default command.
for !ignoreDefault {
if cmd := cmds.defaultSubcommand(); cmd != nil {
cmd.completionAlts = cmds.cmdNames()
context.matchedCmd(cmd)
cmds = cmd.cmdGroup
} else {
break
}
}
if !context.EOL() {
return fmt.Errorf("unexpected %s", context.Peek())
}
// Set defaults for all remaining args.
for arg := context.nextArg(); arg != nil && !arg.consumesRemainder(); arg = context.nextArg() {
for _, defaultValue := range arg.defaultValues {
if err := arg.value.Set(defaultValue); err != nil {
return fmt.Errorf("invalid default value '%s' for argument '%s'", defaultValue, arg.name)
}
}
}
return
}

212
vendor/gopkg.in/alecthomas/kingpin.v2/parsers.go generated vendored Normal file
View File

@ -0,0 +1,212 @@
package kingpin
import (
"net"
"net/url"
"os"
"time"
"github.com/alecthomas/units"
)
type Settings interface {
SetValue(value Value)
}
type parserMixin struct {
value Value
required bool
}
func (p *parserMixin) SetValue(value Value) {
p.value = value
}
// StringMap provides key=value parsing into a map.
func (p *parserMixin) StringMap() (target *map[string]string) {
target = &(map[string]string{})
p.StringMapVar(target)
return
}
// Duration sets the parser to a time.Duration parser.
func (p *parserMixin) Duration() (target *time.Duration) {
target = new(time.Duration)
p.DurationVar(target)
return
}
// Bytes parses numeric byte units. eg. 1.5KB
func (p *parserMixin) Bytes() (target *units.Base2Bytes) {
target = new(units.Base2Bytes)
p.BytesVar(target)
return
}
// IP sets the parser to a net.IP parser.
func (p *parserMixin) IP() (target *net.IP) {
target = new(net.IP)
p.IPVar(target)
return
}
// TCP (host:port) address.
func (p *parserMixin) TCP() (target **net.TCPAddr) {
target = new(*net.TCPAddr)
p.TCPVar(target)
return
}
// TCPVar (host:port) address.
func (p *parserMixin) TCPVar(target **net.TCPAddr) {
p.SetValue(newTCPAddrValue(target))
}
// ExistingFile sets the parser to one that requires and returns an existing file.
func (p *parserMixin) ExistingFile() (target *string) {
target = new(string)
p.ExistingFileVar(target)
return
}
// ExistingDir sets the parser to one that requires and returns an existing directory.
func (p *parserMixin) ExistingDir() (target *string) {
target = new(string)
p.ExistingDirVar(target)
return
}
// ExistingFileOrDir sets the parser to one that requires and returns an existing file OR directory.
func (p *parserMixin) ExistingFileOrDir() (target *string) {
target = new(string)
p.ExistingFileOrDirVar(target)
return
}
// File returns an os.File against an existing file.
func (p *parserMixin) File() (target **os.File) {
target = new(*os.File)
p.FileVar(target)
return
}
// File attempts to open a File with os.OpenFile(flag, perm).
func (p *parserMixin) OpenFile(flag int, perm os.FileMode) (target **os.File) {
target = new(*os.File)
p.OpenFileVar(target, flag, perm)
return
}
// URL provides a valid, parsed url.URL.
func (p *parserMixin) URL() (target **url.URL) {
target = new(*url.URL)
p.URLVar(target)
return
}
// StringMap provides key=value parsing into a map.
func (p *parserMixin) StringMapVar(target *map[string]string) {
p.SetValue(newStringMapValue(target))
}
// Float sets the parser to a float64 parser.
func (p *parserMixin) Float() (target *float64) {
return p.Float64()
}
// Float sets the parser to a float64 parser.
func (p *parserMixin) FloatVar(target *float64) {
p.Float64Var(target)
}
// Duration sets the parser to a time.Duration parser.
func (p *parserMixin) DurationVar(target *time.Duration) {
p.SetValue(newDurationValue(target))
}
// BytesVar parses numeric byte units. eg. 1.5KB
func (p *parserMixin) BytesVar(target *units.Base2Bytes) {
p.SetValue(newBytesValue(target))
}
// IP sets the parser to a net.IP parser.
func (p *parserMixin) IPVar(target *net.IP) {
p.SetValue(newIPValue(target))
}
// ExistingFile sets the parser to one that requires and returns an existing file.
func (p *parserMixin) ExistingFileVar(target *string) {
p.SetValue(newExistingFileValue(target))
}
// ExistingDir sets the parser to one that requires and returns an existing directory.
func (p *parserMixin) ExistingDirVar(target *string) {
p.SetValue(newExistingDirValue(target))
}
// ExistingDir sets the parser to one that requires and returns an existing directory.
func (p *parserMixin) ExistingFileOrDirVar(target *string) {
p.SetValue(newExistingFileOrDirValue(target))
}
// FileVar opens an existing file.
func (p *parserMixin) FileVar(target **os.File) {
p.SetValue(newFileValue(target, os.O_RDONLY, 0))
}
// OpenFileVar calls os.OpenFile(flag, perm)
func (p *parserMixin) OpenFileVar(target **os.File, flag int, perm os.FileMode) {
p.SetValue(newFileValue(target, flag, perm))
}
// URL provides a valid, parsed url.URL.
func (p *parserMixin) URLVar(target **url.URL) {
p.SetValue(newURLValue(target))
}
// URLList provides a parsed list of url.URL values.
func (p *parserMixin) URLList() (target *[]*url.URL) {
target = new([]*url.URL)
p.URLListVar(target)
return
}
// URLListVar provides a parsed list of url.URL values.
func (p *parserMixin) URLListVar(target *[]*url.URL) {
p.SetValue(newURLListValue(target))
}
// Enum allows a value from a set of options.
func (p *parserMixin) Enum(options ...string) (target *string) {
target = new(string)
p.EnumVar(target, options...)
return
}
// EnumVar allows a value from a set of options.
func (p *parserMixin) EnumVar(target *string, options ...string) {
p.SetValue(newEnumFlag(target, options...))
}
// Enums allows a set of values from a set of options.
func (p *parserMixin) Enums(options ...string) (target *[]string) {
target = new([]string)
p.EnumsVar(target, options...)
return
}
// EnumVar allows a value from a set of options.
func (p *parserMixin) EnumsVar(target *[]string, options ...string) {
p.SetValue(newEnumsFlag(target, options...))
}
// A Counter increments a number each time it is encountered.
func (p *parserMixin) Counter() (target *int) {
target = new(int)
p.CounterVar(target)
return
}
func (p *parserMixin) CounterVar(target *int) {
p.SetValue(newCounterValue(target))
}

262
vendor/gopkg.in/alecthomas/kingpin.v2/templates.go generated vendored Normal file
View File

@ -0,0 +1,262 @@
package kingpin
// Default usage template.
var DefaultUsageTemplate = `{{define "FormatCommand"}}\
{{if .FlagSummary}} {{.FlagSummary}}{{end}}\
{{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\
{{end}}\
{{define "FormatCommands"}}\
{{range .FlattenedCommands}}\
{{if not .Hidden}}\
{{.FullCommand}}{{if .Default}}*{{end}}{{template "FormatCommand" .}}
{{.Help|Wrap 4}}
{{end}}\
{{end}}\
{{end}}\
{{define "FormatUsage"}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}
{{if .Help}}
{{.Help|Wrap 0}}\
{{end}}\
{{end}}\
{{if .Context.SelectedCommand}}\
usage: {{.App.Name}} {{.Context.SelectedCommand}}{{template "FormatUsage" .Context.SelectedCommand}}
{{else}}\
usage: {{.App.Name}}{{template "FormatUsage" .App}}
{{end}}\
{{if .Context.Flags}}\
Flags:
{{.Context.Flags|FlagsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.Args}}\
Args:
{{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.SelectedCommand}}\
{{if len .Context.SelectedCommand.Commands}}\
Subcommands:
{{template "FormatCommands" .Context.SelectedCommand}}
{{end}}\
{{else if .App.Commands}}\
Commands:
{{template "FormatCommands" .App}}
{{end}}\
`
// Usage template where command's optional flags are listed separately
var SeparateOptionalFlagsUsageTemplate = `{{define "FormatCommand"}}\
{{if .FlagSummary}} {{.FlagSummary}}{{end}}\
{{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\
{{end}}\
{{define "FormatCommands"}}\
{{range .FlattenedCommands}}\
{{if not .Hidden}}\
{{.FullCommand}}{{if .Default}}*{{end}}{{template "FormatCommand" .}}
{{.Help|Wrap 4}}
{{end}}\
{{end}}\
{{end}}\
{{define "FormatUsage"}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}
{{if .Help}}
{{.Help|Wrap 0}}\
{{end}}\
{{end}}\
{{if .Context.SelectedCommand}}\
usage: {{.App.Name}} {{.Context.SelectedCommand}}{{template "FormatUsage" .Context.SelectedCommand}}
{{else}}\
usage: {{.App.Name}}{{template "FormatUsage" .App}}
{{end}}\
{{if .Context.Flags|RequiredFlags}}\
Required flags:
{{.Context.Flags|RequiredFlags|FlagsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.Flags|OptionalFlags}}\
Optional flags:
{{.Context.Flags|OptionalFlags|FlagsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.Args}}\
Args:
{{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.SelectedCommand}}\
Subcommands:
{{if .Context.SelectedCommand.Commands}}\
{{template "FormatCommands" .Context.SelectedCommand}}
{{end}}\
{{else if .App.Commands}}\
Commands:
{{template "FormatCommands" .App}}
{{end}}\
`
// Usage template with compactly formatted commands.
var CompactUsageTemplate = `{{define "FormatCommand"}}\
{{if .FlagSummary}} {{.FlagSummary}}{{end}}\
{{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\
{{end}}\
{{define "FormatCommandList"}}\
{{range .}}\
{{if not .Hidden}}\
{{.Depth|Indent}}{{.Name}}{{if .Default}}*{{end}}{{template "FormatCommand" .}}
{{end}}\
{{template "FormatCommandList" .Commands}}\
{{end}}\
{{end}}\
{{define "FormatUsage"}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}
{{if .Help}}
{{.Help|Wrap 0}}\
{{end}}\
{{end}}\
{{if .Context.SelectedCommand}}\
usage: {{.App.Name}} {{.Context.SelectedCommand}}{{template "FormatUsage" .Context.SelectedCommand}}
{{else}}\
usage: {{.App.Name}}{{template "FormatUsage" .App}}
{{end}}\
{{if .Context.Flags}}\
Flags:
{{.Context.Flags|FlagsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.Args}}\
Args:
{{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.SelectedCommand}}\
{{if .Context.SelectedCommand.Commands}}\
Commands:
{{.Context.SelectedCommand}}
{{template "FormatCommandList" .Context.SelectedCommand.Commands}}
{{end}}\
{{else if .App.Commands}}\
Commands:
{{template "FormatCommandList" .App.Commands}}
{{end}}\
`
var ManPageTemplate = `{{define "FormatFlags"}}\
{{range .Flags}}\
{{if not .Hidden}}\
.TP
\fB{{if .Short}}-{{.Short|Char}}, {{end}}--{{.Name}}{{if not .IsBoolFlag}}={{.FormatPlaceHolder}}{{end}}\\fR
{{.Help}}
{{end}}\
{{end}}\
{{end}}\
{{define "FormatCommand"}}\
{{if .FlagSummary}} {{.FlagSummary}}{{end}}\
{{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}{{if .Default}}*{{end}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\
{{end}}\
{{define "FormatCommands"}}\
{{range .FlattenedCommands}}\
{{if not .Hidden}}\
.SS
\fB{{.FullCommand}}{{template "FormatCommand" .}}\\fR
.PP
{{.Help}}
{{template "FormatFlags" .}}\
{{end}}\
{{end}}\
{{end}}\
{{define "FormatUsage"}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}\\fR
{{end}}\
.TH {{.App.Name}} 1 {{.App.Version}} "{{.App.Author}}"
.SH "NAME"
{{.App.Name}}
.SH "SYNOPSIS"
.TP
\fB{{.App.Name}}{{template "FormatUsage" .App}}
.SH "DESCRIPTION"
{{.App.Help}}
.SH "OPTIONS"
{{template "FormatFlags" .App}}\
{{if .App.Commands}}\
.SH "COMMANDS"
{{template "FormatCommands" .App}}\
{{end}}\
`
// Default usage template.
var LongHelpTemplate = `{{define "FormatCommand"}}\
{{if .FlagSummary}} {{.FlagSummary}}{{end}}\
{{range .Args}} {{if not .Required}}[{{end}}<{{.Name}}>{{if .Value|IsCumulative}}...{{end}}{{if not .Required}}]{{end}}{{end}}\
{{end}}\
{{define "FormatCommands"}}\
{{range .FlattenedCommands}}\
{{if not .Hidden}}\
{{.FullCommand}}{{template "FormatCommand" .}}
{{.Help|Wrap 4}}
{{with .Flags|FlagsToTwoColumns}}{{FormatTwoColumnsWithIndent . 4 2}}{{end}}
{{end}}\
{{end}}\
{{end}}\
{{define "FormatUsage"}}\
{{template "FormatCommand" .}}{{if .Commands}} <command> [<args> ...]{{end}}
{{if .Help}}
{{.Help|Wrap 0}}\
{{end}}\
{{end}}\
usage: {{.App.Name}}{{template "FormatUsage" .App}}
{{if .Context.Flags}}\
Flags:
{{.Context.Flags|FlagsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .Context.Args}}\
Args:
{{.Context.Args|ArgsToTwoColumns|FormatTwoColumns}}
{{end}}\
{{if .App.Commands}}\
Commands:
{{template "FormatCommands" .App}}
{{end}}\
`
var BashCompletionTemplate = `
_{{.App.Name}}_bash_autocomplete() {
local cur prev opts base
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
opts=$( ${COMP_WORDS[0]} --completion-bash ${COMP_WORDS[@]:1:$COMP_CWORD} )
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _{{.App.Name}}_bash_autocomplete {{.App.Name}}
`
var ZshCompletionTemplate = `
#compdef {{.App.Name}}
autoload -U compinit && compinit
autoload -U bashcompinit && bashcompinit
_{{.App.Name}}_bash_autocomplete() {
local cur prev opts base
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
opts=$( ${COMP_WORDS[0]} --completion-bash ${COMP_WORDS[@]:1:$COMP_CWORD} )
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _{{.App.Name}}_bash_autocomplete {{.App.Name}}
`

211
vendor/gopkg.in/alecthomas/kingpin.v2/usage.go generated vendored Normal file
View File

@ -0,0 +1,211 @@
package kingpin
import (
"bytes"
"fmt"
"go/doc"
"io"
"strings"
"github.com/alecthomas/template"
)
var (
preIndent = " "
)
func formatTwoColumns(w io.Writer, indent, padding, width int, rows [][2]string) {
// Find size of first column.
s := 0
for _, row := range rows {
if c := len(row[0]); c > s && c < 30 {
s = c
}
}
indentStr := strings.Repeat(" ", indent)
offsetStr := strings.Repeat(" ", s+padding)
for _, row := range rows {
buf := bytes.NewBuffer(nil)
doc.ToText(buf, row[1], "", preIndent, width-s-padding-indent)
lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
fmt.Fprintf(w, "%s%-*s%*s", indentStr, s, row[0], padding, "")
if len(row[0]) >= 30 {
fmt.Fprintf(w, "\n%s%s", indentStr, offsetStr)
}
fmt.Fprintf(w, "%s\n", lines[0])
for _, line := range lines[1:] {
fmt.Fprintf(w, "%s%s%s\n", indentStr, offsetStr, line)
}
}
}
// Usage writes application usage to w. It parses args to determine
// appropriate help context, such as which command to show help for.
func (a *Application) Usage(args []string) {
context, err := a.parseContext(true, args)
a.FatalIfError(err, "")
if err := a.UsageForContextWithTemplate(context, 2, a.usageTemplate); err != nil {
panic(err)
}
}
func formatAppUsage(app *ApplicationModel) string {
s := []string{app.Name}
if len(app.Flags) > 0 {
s = append(s, app.FlagSummary())
}
if len(app.Args) > 0 {
s = append(s, app.ArgSummary())
}
return strings.Join(s, " ")
}
func formatCmdUsage(app *ApplicationModel, cmd *CmdModel) string {
s := []string{app.Name, cmd.String()}
if len(app.Flags) > 0 {
s = append(s, app.FlagSummary())
}
if len(app.Args) > 0 {
s = append(s, app.ArgSummary())
}
return strings.Join(s, " ")
}
func formatFlag(haveShort bool, flag *FlagModel) string {
flagString := ""
if flag.Short != 0 {
flagString += fmt.Sprintf("-%c, --%s", flag.Short, flag.Name)
} else {
if haveShort {
flagString += fmt.Sprintf(" --%s", flag.Name)
} else {
flagString += fmt.Sprintf("--%s", flag.Name)
}
}
if !flag.IsBoolFlag() {
flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder())
}
if v, ok := flag.Value.(repeatableFlag); ok && v.IsCumulative() {
flagString += " ..."
}
return flagString
}
type templateParseContext struct {
SelectedCommand *CmdModel
*FlagGroupModel
*ArgGroupModel
}
type templateContext struct {
App *ApplicationModel
Width int
Context *templateParseContext
}
// UsageForContext displays usage information from a ParseContext (obtained from
// Application.ParseContext() or Action(f) callbacks).
func (a *Application) UsageForContext(context *ParseContext) error {
return a.UsageForContextWithTemplate(context, 2, a.usageTemplate)
}
// UsageForContextWithTemplate is the base usage function. You generally don't need to use this.
func (a *Application) UsageForContextWithTemplate(context *ParseContext, indent int, tmpl string) error {
width := guessWidth(a.usageWriter)
funcs := template.FuncMap{
"Indent": func(level int) string {
return strings.Repeat(" ", level*indent)
},
"Wrap": func(indent int, s string) string {
buf := bytes.NewBuffer(nil)
indentText := strings.Repeat(" ", indent)
doc.ToText(buf, s, indentText, " "+indentText, width-indent)
return buf.String()
},
"FormatFlag": formatFlag,
"FlagsToTwoColumns": func(f []*FlagModel) [][2]string {
rows := [][2]string{}
haveShort := false
for _, flag := range f {
if flag.Short != 0 {
haveShort = true
break
}
}
for _, flag := range f {
if !flag.Hidden {
rows = append(rows, [2]string{formatFlag(haveShort, flag), flag.Help})
}
}
return rows
},
"RequiredFlags": func(f []*FlagModel) []*FlagModel {
requiredFlags := []*FlagModel{}
for _, flag := range f {
if flag.Required {
requiredFlags = append(requiredFlags, flag)
}
}
return requiredFlags
},
"OptionalFlags": func(f []*FlagModel) []*FlagModel {
optionalFlags := []*FlagModel{}
for _, flag := range f {
if !flag.Required {
optionalFlags = append(optionalFlags, flag)
}
}
return optionalFlags
},
"ArgsToTwoColumns": func(a []*ArgModel) [][2]string {
rows := [][2]string{}
for _, arg := range a {
s := "<" + arg.Name + ">"
if !arg.Required {
s = "[" + s + "]"
}
rows = append(rows, [2]string{s, arg.Help})
}
return rows
},
"FormatTwoColumns": func(rows [][2]string) string {
buf := bytes.NewBuffer(nil)
formatTwoColumns(buf, indent, indent, width, rows)
return buf.String()
},
"FormatTwoColumnsWithIndent": func(rows [][2]string, indent, padding int) string {
buf := bytes.NewBuffer(nil)
formatTwoColumns(buf, indent, padding, width, rows)
return buf.String()
},
"FormatAppUsage": formatAppUsage,
"FormatCommandUsage": formatCmdUsage,
"IsCumulative": func(value Value) bool {
r, ok := value.(remainderArg)
return ok && r.IsCumulative()
},
"Char": func(c rune) string {
return string(c)
},
}
t, err := template.New("usage").Funcs(funcs).Parse(tmpl)
if err != nil {
return err
}
var selectedCommand *CmdModel
if context.SelectedCommand != nil {
selectedCommand = context.SelectedCommand.Model()
}
ctx := templateContext{
App: a.Model(),
Width: width,
Context: &templateParseContext{
SelectedCommand: selectedCommand,
FlagGroupModel: context.flags.Model(),
ArgGroupModel: context.arguments.Model(),
},
}
return t.Execute(a.usageWriter, ctx)
}

466
vendor/gopkg.in/alecthomas/kingpin.v2/values.go generated vendored Normal file
View File

@ -0,0 +1,466 @@
package kingpin
//go:generate go run ./cmd/genvalues/main.go
import (
"fmt"
"net"
"net/url"
"os"
"reflect"
"regexp"
"strings"
"time"
"github.com/alecthomas/units"
)
// NOTE: Most of the base type values were lifted from:
// http://golang.org/src/pkg/flag/flag.go?s=20146:20222
// Value is the interface to the dynamic value stored in a flag.
// (The default value is represented as a string.)
//
// If a Value has an IsBoolFlag() bool method returning true, the command-line
// parser makes --name equivalent to -name=true rather than using the next
// command-line argument, and adds a --no-name counterpart for negating the
// flag.
type Value interface {
String() string
Set(string) error
}
// Getter is an interface that allows the contents of a Value to be retrieved.
// It wraps the Value interface, rather than being part of it, because it
// appeared after Go 1 and its compatibility rules. All Value types provided
// by this package satisfy the Getter interface.
type Getter interface {
Value
Get() interface{}
}
// Optional interface to indicate boolean flags that don't accept a value, and
// implicitly have a --no-<x> negation counterpart.
type boolFlag interface {
Value
IsBoolFlag() bool
}
// Optional interface for arguments that cumulatively consume all remaining
// input.
type remainderArg interface {
Value
IsCumulative() bool
}
// Optional interface for flags that can be repeated.
type repeatableFlag interface {
Value
IsCumulative() bool
}
type accumulator struct {
element func(value interface{}) Value
typ reflect.Type
slice reflect.Value
}
// Use reflection to accumulate values into a slice.
//
// target := []string{}
// newAccumulator(&target, func (value interface{}) Value {
// return newStringValue(value.(*string))
// })
func newAccumulator(slice interface{}, element func(value interface{}) Value) *accumulator {
typ := reflect.TypeOf(slice)
if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Slice {
panic("expected a pointer to a slice")
}
return &accumulator{
element: element,
typ: typ.Elem().Elem(),
slice: reflect.ValueOf(slice),
}
}
func (a *accumulator) String() string {
out := []string{}
s := a.slice.Elem()
for i := 0; i < s.Len(); i++ {
out = append(out, a.element(s.Index(i).Addr().Interface()).String())
}
return strings.Join(out, ",")
}
func (a *accumulator) Set(value string) error {
e := reflect.New(a.typ)
if err := a.element(e.Interface()).Set(value); err != nil {
return err
}
slice := reflect.Append(a.slice.Elem(), e.Elem())
a.slice.Elem().Set(slice)
return nil
}
func (a *accumulator) Get() interface{} {
return a.slice.Interface()
}
func (a *accumulator) IsCumulative() bool {
return true
}
func (b *boolValue) IsBoolFlag() bool { return true }
// -- time.Duration Value
type durationValue time.Duration
func newDurationValue(p *time.Duration) *durationValue {
return (*durationValue)(p)
}
func (d *durationValue) Set(s string) error {
v, err := time.ParseDuration(s)
*d = durationValue(v)
return err
}
func (d *durationValue) Get() interface{} { return time.Duration(*d) }
func (d *durationValue) String() string { return (*time.Duration)(d).String() }
// -- map[string]string Value
type stringMapValue map[string]string
func newStringMapValue(p *map[string]string) *stringMapValue {
return (*stringMapValue)(p)
}
var stringMapRegex = regexp.MustCompile("[:=]")
func (s *stringMapValue) Set(value string) error {
parts := stringMapRegex.Split(value, 2)
if len(parts) != 2 {
return fmt.Errorf("expected KEY=VALUE got '%s'", value)
}
(*s)[parts[0]] = parts[1]
return nil
}
func (s *stringMapValue) Get() interface{} {
return (map[string]string)(*s)
}
func (s *stringMapValue) String() string {
return fmt.Sprintf("%s", map[string]string(*s))
}
func (s *stringMapValue) IsCumulative() bool {
return true
}
// -- net.IP Value
type ipValue net.IP
func newIPValue(p *net.IP) *ipValue {
return (*ipValue)(p)
}
func (i *ipValue) Set(value string) error {
if ip := net.ParseIP(value); ip == nil {
return fmt.Errorf("'%s' is not an IP address", value)
} else {
*i = *(*ipValue)(&ip)
return nil
}
}
func (i *ipValue) Get() interface{} {
return (net.IP)(*i)
}
func (i *ipValue) String() string {
return (*net.IP)(i).String()
}
// -- *net.TCPAddr Value
type tcpAddrValue struct {
addr **net.TCPAddr
}
func newTCPAddrValue(p **net.TCPAddr) *tcpAddrValue {
return &tcpAddrValue{p}
}
func (i *tcpAddrValue) Set(value string) error {
if addr, err := net.ResolveTCPAddr("tcp", value); err != nil {
return fmt.Errorf("'%s' is not a valid TCP address: %s", value, err)
} else {
*i.addr = addr
return nil
}
}
func (t *tcpAddrValue) Get() interface{} {
return (*net.TCPAddr)(*t.addr)
}
func (i *tcpAddrValue) String() string {
return (*i.addr).String()
}
// -- existingFile Value
type fileStatValue struct {
path *string
predicate func(os.FileInfo) error
}
func newFileStatValue(p *string, predicate func(os.FileInfo) error) *fileStatValue {
return &fileStatValue{
path: p,
predicate: predicate,
}
}
func (e *fileStatValue) Set(value string) error {
if s, err := os.Stat(value); os.IsNotExist(err) {
return fmt.Errorf("path '%s' does not exist", value)
} else if err != nil {
return err
} else if err := e.predicate(s); err != nil {
return err
}
*e.path = value
return nil
}
func (f *fileStatValue) Get() interface{} {
return (string)(*f.path)
}
func (e *fileStatValue) String() string {
return *e.path
}
// -- os.File value
type fileValue struct {
f **os.File
flag int
perm os.FileMode
}
func newFileValue(p **os.File, flag int, perm os.FileMode) *fileValue {
return &fileValue{p, flag, perm}
}
func (f *fileValue) Set(value string) error {
if fd, err := os.OpenFile(value, f.flag, f.perm); err != nil {
return err
} else {
*f.f = fd
return nil
}
}
func (f *fileValue) Get() interface{} {
return (*os.File)(*f.f)
}
func (f *fileValue) String() string {
if *f.f == nil {
return "<nil>"
}
return (*f.f).Name()
}
// -- url.URL Value
type urlValue struct {
u **url.URL
}
func newURLValue(p **url.URL) *urlValue {
return &urlValue{p}
}
func (u *urlValue) Set(value string) error {
if url, err := url.Parse(value); err != nil {
return fmt.Errorf("invalid URL: %s", err)
} else {
*u.u = url
return nil
}
}
func (u *urlValue) Get() interface{} {
return (*url.URL)(*u.u)
}
func (u *urlValue) String() string {
if *u.u == nil {
return "<nil>"
}
return (*u.u).String()
}
// -- []*url.URL Value
type urlListValue []*url.URL
func newURLListValue(p *[]*url.URL) *urlListValue {
return (*urlListValue)(p)
}
func (u *urlListValue) Set(value string) error {
if url, err := url.Parse(value); err != nil {
return fmt.Errorf("invalid URL: %s", err)
} else {
*u = append(*u, url)
return nil
}
}
func (u *urlListValue) Get() interface{} {
return ([]*url.URL)(*u)
}
func (u *urlListValue) String() string {
out := []string{}
for _, url := range *u {
out = append(out, url.String())
}
return strings.Join(out, ",")
}
// A flag whose value must be in a set of options.
type enumValue struct {
value *string
options []string
}
func newEnumFlag(target *string, options ...string) *enumValue {
return &enumValue{
value: target,
options: options,
}
}
func (a *enumValue) String() string {
return *a.value
}
func (a *enumValue) Set(value string) error {
for _, v := range a.options {
if v == value {
*a.value = value
return nil
}
}
return fmt.Errorf("enum value must be one of %s, got '%s'", strings.Join(a.options, ","), value)
}
func (e *enumValue) Get() interface{} {
return (string)(*e.value)
}
// -- []string Enum Value
type enumsValue struct {
value *[]string
options []string
}
func newEnumsFlag(target *[]string, options ...string) *enumsValue {
return &enumsValue{
value: target,
options: options,
}
}
func (s *enumsValue) Set(value string) error {
for _, v := range s.options {
if v == value {
*s.value = append(*s.value, value)
return nil
}
}
return fmt.Errorf("enum value must be one of %s, got '%s'", strings.Join(s.options, ","), value)
}
func (e *enumsValue) Get() interface{} {
return ([]string)(*e.value)
}
func (s *enumsValue) String() string {
return strings.Join(*s.value, ",")
}
func (s *enumsValue) IsCumulative() bool {
return true
}
// -- units.Base2Bytes Value
type bytesValue units.Base2Bytes
func newBytesValue(p *units.Base2Bytes) *bytesValue {
return (*bytesValue)(p)
}
func (d *bytesValue) Set(s string) error {
v, err := units.ParseBase2Bytes(s)
*d = bytesValue(v)
return err
}
func (d *bytesValue) Get() interface{} { return units.Base2Bytes(*d) }
func (d *bytesValue) String() string { return (*units.Base2Bytes)(d).String() }
func newExistingFileValue(target *string) *fileStatValue {
return newFileStatValue(target, func(s os.FileInfo) error {
if s.IsDir() {
return fmt.Errorf("'%s' is a directory", s.Name())
}
return nil
})
}
func newExistingDirValue(target *string) *fileStatValue {
return newFileStatValue(target, func(s os.FileInfo) error {
if !s.IsDir() {
return fmt.Errorf("'%s' is a file", s.Name())
}
return nil
})
}
func newExistingFileOrDirValue(target *string) *fileStatValue {
return newFileStatValue(target, func(s os.FileInfo) error { return nil })
}
type counterValue int
func newCounterValue(n *int) *counterValue {
return (*counterValue)(n)
}
func (c *counterValue) Set(s string) error {
*c++
return nil
}
func (c *counterValue) Get() interface{} { return (int)(*c) }
func (c *counterValue) IsBoolFlag() bool { return true }
func (c *counterValue) String() string { return fmt.Sprintf("%d", *c) }
func (c *counterValue) IsCumulative() bool { return true }
func resolveHost(value string) (net.IP, error) {
if ip := net.ParseIP(value); ip != nil {
return ip, nil
} else {
if addr, err := net.ResolveIPAddr("ip", value); err != nil {
return nil, err
} else {
return addr.IP, nil
}
}
}

25
vendor/gopkg.in/alecthomas/kingpin.v2/values.json generated vendored Normal file
View File

@ -0,0 +1,25 @@
[
{"type": "bool", "parser": "strconv.ParseBool(s)"},
{"type": "string", "parser": "s, error(nil)", "format": "string(*f.v)", "plural": "Strings"},
{"type": "uint", "parser": "strconv.ParseUint(s, 0, 64)", "plural": "Uints"},
{"type": "uint8", "parser": "strconv.ParseUint(s, 0, 8)"},
{"type": "uint16", "parser": "strconv.ParseUint(s, 0, 16)"},
{"type": "uint32", "parser": "strconv.ParseUint(s, 0, 32)"},
{"type": "uint64", "parser": "strconv.ParseUint(s, 0, 64)"},
{"type": "int", "parser": "strconv.ParseFloat(s, 64)", "plural": "Ints"},
{"type": "int8", "parser": "strconv.ParseInt(s, 0, 8)"},
{"type": "int16", "parser": "strconv.ParseInt(s, 0, 16)"},
{"type": "int32", "parser": "strconv.ParseInt(s, 0, 32)"},
{"type": "int64", "parser": "strconv.ParseInt(s, 0, 64)"},
{"type": "float64", "parser": "strconv.ParseFloat(s, 64)"},
{"type": "float32", "parser": "strconv.ParseFloat(s, 32)"},
{"name": "Duration", "type": "time.Duration", "no_value_parser": true},
{"name": "IP", "type": "net.IP", "no_value_parser": true},
{"name": "TCPAddr", "Type": "*net.TCPAddr", "plural": "TCPList", "no_value_parser": true},
{"name": "ExistingFile", "Type": "string", "plural": "ExistingFiles", "no_value_parser": true},
{"name": "ExistingDir", "Type": "string", "plural": "ExistingDirs", "no_value_parser": true},
{"name": "ExistingFileOrDir", "Type": "string", "plural": "ExistingFilesOrDirs", "no_value_parser": true},
{"name": "Regexp", "Type": "*regexp.Regexp", "parser": "regexp.Compile(s)"},
{"name": "ResolvedIP", "Type": "net.IP", "parser": "resolveHost(s)", "help": "Resolve a hostname or IP to an IP."},
{"name": "HexBytes", "Type": "[]byte", "parser": "hex.DecodeString(s)", "help": "Bytes as a hex string."}
]

View File

@ -0,0 +1,821 @@
package kingpin
import (
"encoding/hex"
"fmt"
"net"
"regexp"
"strconv"
"time"
)
// This file is autogenerated by "go generate .". Do not modify.
// -- bool Value
type boolValue struct{ v *bool }
func newBoolValue(p *bool) *boolValue {
return &boolValue{p}
}
func (f *boolValue) Set(s string) error {
v, err := strconv.ParseBool(s)
if err == nil {
*f.v = (bool)(v)
}
return err
}
func (f *boolValue) Get() interface{} { return (bool)(*f.v) }
func (f *boolValue) String() string { return fmt.Sprintf("%v", *f) }
// Bool parses the next command-line value as bool.
func (p *parserMixin) Bool() (target *bool) {
target = new(bool)
p.BoolVar(target)
return
}
func (p *parserMixin) BoolVar(target *bool) {
p.SetValue(newBoolValue(target))
}
// BoolList accumulates bool values into a slice.
func (p *parserMixin) BoolList() (target *[]bool) {
target = new([]bool)
p.BoolListVar(target)
return
}
func (p *parserMixin) BoolListVar(target *[]bool) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newBoolValue(v.(*bool))
}))
}
// -- string Value
type stringValue struct{ v *string }
func newStringValue(p *string) *stringValue {
return &stringValue{p}
}
func (f *stringValue) Set(s string) error {
v, err := s, error(nil)
if err == nil {
*f.v = (string)(v)
}
return err
}
func (f *stringValue) Get() interface{} { return (string)(*f.v) }
func (f *stringValue) String() string { return string(*f.v) }
// String parses the next command-line value as string.
func (p *parserMixin) String() (target *string) {
target = new(string)
p.StringVar(target)
return
}
func (p *parserMixin) StringVar(target *string) {
p.SetValue(newStringValue(target))
}
// Strings accumulates string values into a slice.
func (p *parserMixin) Strings() (target *[]string) {
target = new([]string)
p.StringsVar(target)
return
}
func (p *parserMixin) StringsVar(target *[]string) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newStringValue(v.(*string))
}))
}
// -- uint Value
type uintValue struct{ v *uint }
func newUintValue(p *uint) *uintValue {
return &uintValue{p}
}
func (f *uintValue) Set(s string) error {
v, err := strconv.ParseUint(s, 0, 64)
if err == nil {
*f.v = (uint)(v)
}
return err
}
func (f *uintValue) Get() interface{} { return (uint)(*f.v) }
func (f *uintValue) String() string { return fmt.Sprintf("%v", *f) }
// Uint parses the next command-line value as uint.
func (p *parserMixin) Uint() (target *uint) {
target = new(uint)
p.UintVar(target)
return
}
func (p *parserMixin) UintVar(target *uint) {
p.SetValue(newUintValue(target))
}
// Uints accumulates uint values into a slice.
func (p *parserMixin) Uints() (target *[]uint) {
target = new([]uint)
p.UintsVar(target)
return
}
func (p *parserMixin) UintsVar(target *[]uint) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newUintValue(v.(*uint))
}))
}
// -- uint8 Value
type uint8Value struct{ v *uint8 }
func newUint8Value(p *uint8) *uint8Value {
return &uint8Value{p}
}
func (f *uint8Value) Set(s string) error {
v, err := strconv.ParseUint(s, 0, 8)
if err == nil {
*f.v = (uint8)(v)
}
return err
}
func (f *uint8Value) Get() interface{} { return (uint8)(*f.v) }
func (f *uint8Value) String() string { return fmt.Sprintf("%v", *f) }
// Uint8 parses the next command-line value as uint8.
func (p *parserMixin) Uint8() (target *uint8) {
target = new(uint8)
p.Uint8Var(target)
return
}
func (p *parserMixin) Uint8Var(target *uint8) {
p.SetValue(newUint8Value(target))
}
// Uint8List accumulates uint8 values into a slice.
func (p *parserMixin) Uint8List() (target *[]uint8) {
target = new([]uint8)
p.Uint8ListVar(target)
return
}
func (p *parserMixin) Uint8ListVar(target *[]uint8) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newUint8Value(v.(*uint8))
}))
}
// -- uint16 Value
type uint16Value struct{ v *uint16 }
func newUint16Value(p *uint16) *uint16Value {
return &uint16Value{p}
}
func (f *uint16Value) Set(s string) error {
v, err := strconv.ParseUint(s, 0, 16)
if err == nil {
*f.v = (uint16)(v)
}
return err
}
func (f *uint16Value) Get() interface{} { return (uint16)(*f.v) }
func (f *uint16Value) String() string { return fmt.Sprintf("%v", *f) }
// Uint16 parses the next command-line value as uint16.
func (p *parserMixin) Uint16() (target *uint16) {
target = new(uint16)
p.Uint16Var(target)
return
}
func (p *parserMixin) Uint16Var(target *uint16) {
p.SetValue(newUint16Value(target))
}
// Uint16List accumulates uint16 values into a slice.
func (p *parserMixin) Uint16List() (target *[]uint16) {
target = new([]uint16)
p.Uint16ListVar(target)
return
}
func (p *parserMixin) Uint16ListVar(target *[]uint16) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newUint16Value(v.(*uint16))
}))
}
// -- uint32 Value
type uint32Value struct{ v *uint32 }
func newUint32Value(p *uint32) *uint32Value {
return &uint32Value{p}
}
func (f *uint32Value) Set(s string) error {
v, err := strconv.ParseUint(s, 0, 32)
if err == nil {
*f.v = (uint32)(v)
}
return err
}
func (f *uint32Value) Get() interface{} { return (uint32)(*f.v) }
func (f *uint32Value) String() string { return fmt.Sprintf("%v", *f) }
// Uint32 parses the next command-line value as uint32.
func (p *parserMixin) Uint32() (target *uint32) {
target = new(uint32)
p.Uint32Var(target)
return
}
func (p *parserMixin) Uint32Var(target *uint32) {
p.SetValue(newUint32Value(target))
}
// Uint32List accumulates uint32 values into a slice.
func (p *parserMixin) Uint32List() (target *[]uint32) {
target = new([]uint32)
p.Uint32ListVar(target)
return
}
func (p *parserMixin) Uint32ListVar(target *[]uint32) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newUint32Value(v.(*uint32))
}))
}
// -- uint64 Value
type uint64Value struct{ v *uint64 }
func newUint64Value(p *uint64) *uint64Value {
return &uint64Value{p}
}
func (f *uint64Value) Set(s string) error {
v, err := strconv.ParseUint(s, 0, 64)
if err == nil {
*f.v = (uint64)(v)
}
return err
}
func (f *uint64Value) Get() interface{} { return (uint64)(*f.v) }
func (f *uint64Value) String() string { return fmt.Sprintf("%v", *f) }
// Uint64 parses the next command-line value as uint64.
func (p *parserMixin) Uint64() (target *uint64) {
target = new(uint64)
p.Uint64Var(target)
return
}
func (p *parserMixin) Uint64Var(target *uint64) {
p.SetValue(newUint64Value(target))
}
// Uint64List accumulates uint64 values into a slice.
func (p *parserMixin) Uint64List() (target *[]uint64) {
target = new([]uint64)
p.Uint64ListVar(target)
return
}
func (p *parserMixin) Uint64ListVar(target *[]uint64) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newUint64Value(v.(*uint64))
}))
}
// -- int Value
type intValue struct{ v *int }
func newIntValue(p *int) *intValue {
return &intValue{p}
}
func (f *intValue) Set(s string) error {
v, err := strconv.ParseFloat(s, 64)
if err == nil {
*f.v = (int)(v)
}
return err
}
func (f *intValue) Get() interface{} { return (int)(*f.v) }
func (f *intValue) String() string { return fmt.Sprintf("%v", *f) }
// Int parses the next command-line value as int.
func (p *parserMixin) Int() (target *int) {
target = new(int)
p.IntVar(target)
return
}
func (p *parserMixin) IntVar(target *int) {
p.SetValue(newIntValue(target))
}
// Ints accumulates int values into a slice.
func (p *parserMixin) Ints() (target *[]int) {
target = new([]int)
p.IntsVar(target)
return
}
func (p *parserMixin) IntsVar(target *[]int) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newIntValue(v.(*int))
}))
}
// -- int8 Value
type int8Value struct{ v *int8 }
func newInt8Value(p *int8) *int8Value {
return &int8Value{p}
}
func (f *int8Value) Set(s string) error {
v, err := strconv.ParseInt(s, 0, 8)
if err == nil {
*f.v = (int8)(v)
}
return err
}
func (f *int8Value) Get() interface{} { return (int8)(*f.v) }
func (f *int8Value) String() string { return fmt.Sprintf("%v", *f) }
// Int8 parses the next command-line value as int8.
func (p *parserMixin) Int8() (target *int8) {
target = new(int8)
p.Int8Var(target)
return
}
func (p *parserMixin) Int8Var(target *int8) {
p.SetValue(newInt8Value(target))
}
// Int8List accumulates int8 values into a slice.
func (p *parserMixin) Int8List() (target *[]int8) {
target = new([]int8)
p.Int8ListVar(target)
return
}
func (p *parserMixin) Int8ListVar(target *[]int8) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newInt8Value(v.(*int8))
}))
}
// -- int16 Value
type int16Value struct{ v *int16 }
func newInt16Value(p *int16) *int16Value {
return &int16Value{p}
}
func (f *int16Value) Set(s string) error {
v, err := strconv.ParseInt(s, 0, 16)
if err == nil {
*f.v = (int16)(v)
}
return err
}
func (f *int16Value) Get() interface{} { return (int16)(*f.v) }
func (f *int16Value) String() string { return fmt.Sprintf("%v", *f) }
// Int16 parses the next command-line value as int16.
func (p *parserMixin) Int16() (target *int16) {
target = new(int16)
p.Int16Var(target)
return
}
func (p *parserMixin) Int16Var(target *int16) {
p.SetValue(newInt16Value(target))
}
// Int16List accumulates int16 values into a slice.
func (p *parserMixin) Int16List() (target *[]int16) {
target = new([]int16)
p.Int16ListVar(target)
return
}
func (p *parserMixin) Int16ListVar(target *[]int16) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newInt16Value(v.(*int16))
}))
}
// -- int32 Value
type int32Value struct{ v *int32 }
func newInt32Value(p *int32) *int32Value {
return &int32Value{p}
}
func (f *int32Value) Set(s string) error {
v, err := strconv.ParseInt(s, 0, 32)
if err == nil {
*f.v = (int32)(v)
}
return err
}
func (f *int32Value) Get() interface{} { return (int32)(*f.v) }
func (f *int32Value) String() string { return fmt.Sprintf("%v", *f) }
// Int32 parses the next command-line value as int32.
func (p *parserMixin) Int32() (target *int32) {
target = new(int32)
p.Int32Var(target)
return
}
func (p *parserMixin) Int32Var(target *int32) {
p.SetValue(newInt32Value(target))
}
// Int32List accumulates int32 values into a slice.
func (p *parserMixin) Int32List() (target *[]int32) {
target = new([]int32)
p.Int32ListVar(target)
return
}
func (p *parserMixin) Int32ListVar(target *[]int32) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newInt32Value(v.(*int32))
}))
}
// -- int64 Value
type int64Value struct{ v *int64 }
func newInt64Value(p *int64) *int64Value {
return &int64Value{p}
}
func (f *int64Value) Set(s string) error {
v, err := strconv.ParseInt(s, 0, 64)
if err == nil {
*f.v = (int64)(v)
}
return err
}
func (f *int64Value) Get() interface{} { return (int64)(*f.v) }
func (f *int64Value) String() string { return fmt.Sprintf("%v", *f) }
// Int64 parses the next command-line value as int64.
func (p *parserMixin) Int64() (target *int64) {
target = new(int64)
p.Int64Var(target)
return
}
func (p *parserMixin) Int64Var(target *int64) {
p.SetValue(newInt64Value(target))
}
// Int64List accumulates int64 values into a slice.
func (p *parserMixin) Int64List() (target *[]int64) {
target = new([]int64)
p.Int64ListVar(target)
return
}
func (p *parserMixin) Int64ListVar(target *[]int64) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newInt64Value(v.(*int64))
}))
}
// -- float64 Value
type float64Value struct{ v *float64 }
func newFloat64Value(p *float64) *float64Value {
return &float64Value{p}
}
func (f *float64Value) Set(s string) error {
v, err := strconv.ParseFloat(s, 64)
if err == nil {
*f.v = (float64)(v)
}
return err
}
func (f *float64Value) Get() interface{} { return (float64)(*f.v) }
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
// Float64 parses the next command-line value as float64.
func (p *parserMixin) Float64() (target *float64) {
target = new(float64)
p.Float64Var(target)
return
}
func (p *parserMixin) Float64Var(target *float64) {
p.SetValue(newFloat64Value(target))
}
// Float64List accumulates float64 values into a slice.
func (p *parserMixin) Float64List() (target *[]float64) {
target = new([]float64)
p.Float64ListVar(target)
return
}
func (p *parserMixin) Float64ListVar(target *[]float64) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newFloat64Value(v.(*float64))
}))
}
// -- float32 Value
type float32Value struct{ v *float32 }
func newFloat32Value(p *float32) *float32Value {
return &float32Value{p}
}
func (f *float32Value) Set(s string) error {
v, err := strconv.ParseFloat(s, 32)
if err == nil {
*f.v = (float32)(v)
}
return err
}
func (f *float32Value) Get() interface{} { return (float32)(*f.v) }
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
// Float32 parses the next command-line value as float32.
func (p *parserMixin) Float32() (target *float32) {
target = new(float32)
p.Float32Var(target)
return
}
func (p *parserMixin) Float32Var(target *float32) {
p.SetValue(newFloat32Value(target))
}
// Float32List accumulates float32 values into a slice.
func (p *parserMixin) Float32List() (target *[]float32) {
target = new([]float32)
p.Float32ListVar(target)
return
}
func (p *parserMixin) Float32ListVar(target *[]float32) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newFloat32Value(v.(*float32))
}))
}
// DurationList accumulates time.Duration values into a slice.
func (p *parserMixin) DurationList() (target *[]time.Duration) {
target = new([]time.Duration)
p.DurationListVar(target)
return
}
func (p *parserMixin) DurationListVar(target *[]time.Duration) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newDurationValue(v.(*time.Duration))
}))
}
// IPList accumulates net.IP values into a slice.
func (p *parserMixin) IPList() (target *[]net.IP) {
target = new([]net.IP)
p.IPListVar(target)
return
}
func (p *parserMixin) IPListVar(target *[]net.IP) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newIPValue(v.(*net.IP))
}))
}
// TCPList accumulates *net.TCPAddr values into a slice.
func (p *parserMixin) TCPList() (target *[]*net.TCPAddr) {
target = new([]*net.TCPAddr)
p.TCPListVar(target)
return
}
func (p *parserMixin) TCPListVar(target *[]*net.TCPAddr) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newTCPAddrValue(v.(**net.TCPAddr))
}))
}
// ExistingFiles accumulates string values into a slice.
func (p *parserMixin) ExistingFiles() (target *[]string) {
target = new([]string)
p.ExistingFilesVar(target)
return
}
func (p *parserMixin) ExistingFilesVar(target *[]string) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newExistingFileValue(v.(*string))
}))
}
// ExistingDirs accumulates string values into a slice.
func (p *parserMixin) ExistingDirs() (target *[]string) {
target = new([]string)
p.ExistingDirsVar(target)
return
}
func (p *parserMixin) ExistingDirsVar(target *[]string) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newExistingDirValue(v.(*string))
}))
}
// ExistingFilesOrDirs accumulates string values into a slice.
func (p *parserMixin) ExistingFilesOrDirs() (target *[]string) {
target = new([]string)
p.ExistingFilesOrDirsVar(target)
return
}
func (p *parserMixin) ExistingFilesOrDirsVar(target *[]string) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newExistingFileOrDirValue(v.(*string))
}))
}
// -- *regexp.Regexp Value
type regexpValue struct{ v **regexp.Regexp }
func newRegexpValue(p **regexp.Regexp) *regexpValue {
return &regexpValue{p}
}
func (f *regexpValue) Set(s string) error {
v, err := regexp.Compile(s)
if err == nil {
*f.v = (*regexp.Regexp)(v)
}
return err
}
func (f *regexpValue) Get() interface{} { return (*regexp.Regexp)(*f.v) }
func (f *regexpValue) String() string { return fmt.Sprintf("%v", *f) }
// Regexp parses the next command-line value as *regexp.Regexp.
func (p *parserMixin) Regexp() (target **regexp.Regexp) {
target = new(*regexp.Regexp)
p.RegexpVar(target)
return
}
func (p *parserMixin) RegexpVar(target **regexp.Regexp) {
p.SetValue(newRegexpValue(target))
}
// RegexpList accumulates *regexp.Regexp values into a slice.
func (p *parserMixin) RegexpList() (target *[]*regexp.Regexp) {
target = new([]*regexp.Regexp)
p.RegexpListVar(target)
return
}
func (p *parserMixin) RegexpListVar(target *[]*regexp.Regexp) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newRegexpValue(v.(**regexp.Regexp))
}))
}
// -- net.IP Value
type resolvedIPValue struct{ v *net.IP }
func newResolvedIPValue(p *net.IP) *resolvedIPValue {
return &resolvedIPValue{p}
}
func (f *resolvedIPValue) Set(s string) error {
v, err := resolveHost(s)
if err == nil {
*f.v = (net.IP)(v)
}
return err
}
func (f *resolvedIPValue) Get() interface{} { return (net.IP)(*f.v) }
func (f *resolvedIPValue) String() string { return fmt.Sprintf("%v", *f) }
// Resolve a hostname or IP to an IP.
func (p *parserMixin) ResolvedIP() (target *net.IP) {
target = new(net.IP)
p.ResolvedIPVar(target)
return
}
func (p *parserMixin) ResolvedIPVar(target *net.IP) {
p.SetValue(newResolvedIPValue(target))
}
// ResolvedIPList accumulates net.IP values into a slice.
func (p *parserMixin) ResolvedIPList() (target *[]net.IP) {
target = new([]net.IP)
p.ResolvedIPListVar(target)
return
}
func (p *parserMixin) ResolvedIPListVar(target *[]net.IP) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newResolvedIPValue(v.(*net.IP))
}))
}
// -- []byte Value
type hexBytesValue struct{ v *[]byte }
func newHexBytesValue(p *[]byte) *hexBytesValue {
return &hexBytesValue{p}
}
func (f *hexBytesValue) Set(s string) error {
v, err := hex.DecodeString(s)
if err == nil {
*f.v = ([]byte)(v)
}
return err
}
func (f *hexBytesValue) Get() interface{} { return ([]byte)(*f.v) }
func (f *hexBytesValue) String() string { return fmt.Sprintf("%v", *f) }
// Bytes as a hex string.
func (p *parserMixin) HexBytes() (target *[]byte) {
target = new([]byte)
p.HexBytesVar(target)
return
}
func (p *parserMixin) HexBytesVar(target *[]byte) {
p.SetValue(newHexBytesValue(target))
}
// HexBytesList accumulates []byte values into a slice.
func (p *parserMixin) HexBytesList() (target *[][]byte) {
target = new([][]byte)
p.HexBytesListVar(target)
return
}
func (p *parserMixin) HexBytesListVar(target *[][]byte) {
p.SetValue(newAccumulator(target, func(v interface{}) Value {
return newHexBytesValue(v.(*[]byte))
}))
}

6
vendor/vendor.json vendored
View File

@ -67,6 +67,12 @@
"path": "golang.org/x/crypto/blowfish",
"revision": "f6b343c37ca80bfa8ea539da67a0b621f84fab1d",
"revisionTime": "2016-12-21T04:54:10Z"
},
{
"checksumSHA1": "SeYI7DRWrd0Ku+CLavuwIz3EEmQ=",
"path": "gopkg.in/alecthomas/kingpin.v2",
"revision": "e9044be3ab2a8e11d4e1f418d12f0790d57e8d70",
"revisionTime": "2016-08-29T10:30:05Z"
}
],
"rootPath": "github.com/dannyvankooten/ana"