mirror of
https://github.com/Luzifer/git-changerelease.git
synced 2024-12-20 19:11:17 +00:00
Update vendored libraries
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
ffa65b0c68
commit
9a94a0bfe6
55 changed files with 3293 additions and 1226 deletions
19
Gopkg.lock
generated
19
Gopkg.lock
generated
|
@ -4,23 +4,32 @@
|
|||
[[projects]]
|
||||
name = "github.com/Luzifer/rconfig"
|
||||
packages = ["."]
|
||||
revision = "c27bd3a64b5b19556914d9fec69922cf3852d585"
|
||||
version = "v1.1.0"
|
||||
revision = "7aef1d393c1e2d0758901853b59981c7adc67c7e"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/go-homedir"
|
||||
packages = ["."]
|
||||
revision = "981ab348d865cf048eb7d17e78ac7192632d8415"
|
||||
revision = "3864e76763d94a6df2f9960b16a20a33da9f9a66"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "367864438f1b1a3c7db4da06a2f55b144e6784e0"
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/validator.v2"
|
||||
packages = ["."]
|
||||
revision = "135c24b11c19e52befcae2ec3fca5d9b78c4e98e"
|
||||
|
||||
[[projects]]
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "53feefa2559fb8dfa8d81baad31be332c97d6c77"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
|
|
|
@ -30,5 +30,6 @@
|
|||
version = "1.1.0"
|
||||
|
||||
[prune]
|
||||
non-go = true
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
|
8
vendor/github.com/Luzifer/rconfig/.travis.yml
generated
vendored
8
vendor/github.com/Luzifer/rconfig/.travis.yml
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.5
|
||||
- tip
|
||||
|
||||
script: go test -v -race -cover ./...
|
5
vendor/github.com/Luzifer/rconfig/History.md
generated
vendored
5
vendor/github.com/Luzifer/rconfig/History.md
generated
vendored
|
@ -1,5 +0,0 @@
|
|||
# 1.1.0 / 2016-06-28
|
||||
|
||||
* Support time.Duration config parameters
|
||||
* Added goreportcard badge
|
||||
* Added testcase for using bool with ENV and default
|
94
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
94
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
|
@ -1,94 +0,0 @@
|
|||
[![Build Status](https://travis-ci.org/Luzifer/rconfig.svg?branch=master)](https://travis-ci.org/Luzifer/rconfig)
|
||||
[![License: Apache v2.0](https://badge.luzifer.io/v1/badge?color=5d79b5&title=license&text=Apache+v2.0)](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
[![Documentation](https://badge.luzifer.io/v1/badge?title=godoc&text=reference)](https://godoc.org/github.com/Luzifer/rconfig)
|
||||
[![Go Report](http://goreportcard.com/badge/Luzifer/rconfig)](http://goreportcard.com/report/Luzifer/rconfig)
|
||||
|
||||
## Description
|
||||
|
||||
> Package rconfig implements a CLI configuration reader with struct-embedded defaults, environment variables and posix compatible flag parsing using the [pflag](https://github.com/spf13/pflag) library.
|
||||
|
||||
## Installation
|
||||
|
||||
Install by running:
|
||||
|
||||
```
|
||||
go get -u github.com/Luzifer/rconfig
|
||||
```
|
||||
|
||||
OR fetch a specific version:
|
||||
|
||||
```
|
||||
go get -u gopkg.in/luzifer/rconfig.v1
|
||||
```
|
||||
|
||||
Run tests by running:
|
||||
|
||||
```
|
||||
go test -v -race -cover github.com/Luzifer/rconfig
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
As a first step define a struct holding your configuration:
|
||||
|
||||
```go
|
||||
type config struct {
|
||||
Username string `default:"unknown" flag:"user" description:"Your name"`
|
||||
Details struct {
|
||||
Age int `default:"25" flag:"age" env:"age" description:"Your age"`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next create an instance of that struct and let `rconfig` fill that config:
|
||||
|
||||
```go
|
||||
var cfg config
|
||||
func init() {
|
||||
cfg = config{}
|
||||
rconfig.Parse(&cfg)
|
||||
}
|
||||
```
|
||||
|
||||
You're ready to access your configuration:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
||||
cfg.Username,
|
||||
cfg.Details.Age)
|
||||
}
|
||||
```
|
||||
|
||||
### Provide variable defaults by using a file
|
||||
|
||||
Given you have a file `~/.myapp.yml` containing some secrets or usernames (for the example below username is assumed to be "luzifer") as a default configuration for your application you can use this source code to load the defaults from that file using the `vardefault` tag in your configuration struct.
|
||||
|
||||
The order of the directives (lower number = higher precedence):
|
||||
|
||||
1. Flags provided in command line
|
||||
1. Environment variables
|
||||
1. Variable defaults (`vardefault` tag in the struct)
|
||||
1. `default` tag in the struct
|
||||
|
||||
```go
|
||||
type config struct {
|
||||
Username string `vardefault:"username" flag:"username" description:"Your username"`
|
||||
}
|
||||
|
||||
var cfg = config{}
|
||||
|
||||
func init() {
|
||||
rconfig.SetVariableDefaults(rconfig.VarDefaultsFromYAMLFile("~/.myapp.yml"))
|
||||
rconfig.Parse(&cfg)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Username = %s", cfg.Username)
|
||||
// Output: Username = luzifer
|
||||
}
|
||||
```
|
||||
|
||||
## More info
|
||||
|
||||
You can see the full reference documentation of the rconfig package [at godoc.org](https://godoc.org/github.com/Luzifer/rconfig), or through go's standard documentation system by running `godoc -http=:6060` and browsing to [http://localhost:6060/pkg/github.com/Luzifer/rconfig](http://localhost:6060/pkg/github.com/Luzifer/rconfig) after installation.
|
18
vendor/github.com/Luzifer/rconfig/config.go
generated
vendored
18
vendor/github.com/Luzifer/rconfig/config.go
generated
vendored
|
@ -13,6 +13,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
validator "gopkg.in/validator.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -45,6 +46,15 @@ func Parse(config interface{}) error {
|
|||
return parse(config, nil)
|
||||
}
|
||||
|
||||
// ParseAndValidate works exactly like Parse but implements an additional run of
|
||||
// the go-validator package on the configuration struct. Therefore additonal struct
|
||||
// tags are supported like described in the readme file of the go-validator package:
|
||||
//
|
||||
// https://github.com/go-validator/validator/tree/v2#usage
|
||||
func ParseAndValidate(config interface{}) error {
|
||||
return parseAndValidate(config, nil)
|
||||
}
|
||||
|
||||
// Args returns the non-flag command-line arguments.
|
||||
func Args() []string {
|
||||
return fs.Args()
|
||||
|
@ -65,6 +75,14 @@ func SetVariableDefaults(defaults map[string]string) {
|
|||
variableDefaults = defaults
|
||||
}
|
||||
|
||||
func parseAndValidate(in interface{}, args []string) error {
|
||||
if err := parse(in, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validator.Validate(in)
|
||||
}
|
||||
|
||||
func parse(in interface{}, args []string) error {
|
||||
if args == nil {
|
||||
args = os.Args
|
||||
|
|
14
vendor/github.com/mitchellh/go-homedir/README.md
generated
vendored
14
vendor/github.com/mitchellh/go-homedir/README.md
generated
vendored
|
@ -1,14 +0,0 @@
|
|||
# go-homedir
|
||||
|
||||
This is a Go library for detecting the user's home directory without
|
||||
the use of cgo, so the library can be used in cross-compilation environments.
|
||||
|
||||
Usage is incredibly simple, just call `homedir.Dir()` to get the home directory
|
||||
for a user, and `homedir.Expand()` to expand the `~` in a path to the home
|
||||
directory.
|
||||
|
||||
**Why not just use `os/user`?** The built-in `os/user` package requires
|
||||
cgo on Darwin systems. This means that any Go code that uses that package
|
||||
cannot cross compile. But 99% of the time the use for `os/user` is just to
|
||||
retrieve the home directory, which we can do for the current user without
|
||||
cgo. This library does that, enabling cross-compilation.
|
33
vendor/github.com/mitchellh/go-homedir/homedir.go
generated
vendored
33
vendor/github.com/mitchellh/go-homedir/homedir.go
generated
vendored
|
@ -77,18 +77,35 @@ func Expand(path string) (string, error) {
|
|||
}
|
||||
|
||||
func dirUnix() (string, error) {
|
||||
homeEnv := "HOME"
|
||||
if runtime.GOOS == "plan9" {
|
||||
// On plan9, env vars are lowercase.
|
||||
homeEnv = "home"
|
||||
}
|
||||
|
||||
// First prefer the HOME environmental variable
|
||||
if home := os.Getenv("HOME"); home != "" {
|
||||
if home := os.Getenv(homeEnv); home != "" {
|
||||
return home, nil
|
||||
}
|
||||
|
||||
// If that fails, try getent
|
||||
var stdout bytes.Buffer
|
||||
|
||||
// If that fails, try OS specific commands
|
||||
if runtime.GOOS == "darwin" {
|
||||
cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`)
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err == nil {
|
||||
result := strings.TrimSpace(stdout.String())
|
||||
if result != "" {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid()))
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
// If "getent" is missing, ignore it
|
||||
if err == exec.ErrNotFound {
|
||||
// If the error is ErrNotFound, we ignore it. Otherwise, return it.
|
||||
if err != exec.ErrNotFound {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
|
@ -100,10 +117,11 @@ func dirUnix() (string, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all else fails, try the shell
|
||||
stdout.Reset()
|
||||
cmd = exec.Command("sh", "-c", "cd && pwd")
|
||||
cmd := exec.Command("sh", "-c", "cd && pwd")
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
return "", err
|
||||
|
@ -118,6 +136,11 @@ func dirUnix() (string, error) {
|
|||
}
|
||||
|
||||
func dirWindows() (string, error) {
|
||||
// First prefer the HOME environmental variable
|
||||
if home := os.Getenv("HOME"); home != "" {
|
||||
return home, nil
|
||||
}
|
||||
|
||||
drive := os.Getenv("HOMEDRIVE")
|
||||
path := os.Getenv("HOMEPATH")
|
||||
home := drive + path
|
||||
|
|
17
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
17
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
|
@ -1,17 +0,0 @@
|
|||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go get github.com/golang/lint/golint
|
||||
- export PATH=$GOPATH/bin:$PATH
|
||||
- go install ./...
|
||||
|
||||
script:
|
||||
- verify/all.sh -v
|
||||
- go test ./...
|
275
vendor/github.com/spf13/pflag/README.md
generated
vendored
275
vendor/github.com/spf13/pflag/README.md
generated
vendored
|
@ -1,275 +0,0 @@
|
|||
[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)
|
||||
|
||||
## Description
|
||||
|
||||
pflag is a drop-in replacement for Go's flag package, implementing
|
||||
POSIX/GNU-style --flags.
|
||||
|
||||
pflag is compatible with the [GNU extensions to the POSIX recommendations
|
||||
for command-line options][1]. For a more precise description, see the
|
||||
"Command-line flag syntax" section below.
|
||||
|
||||
[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
||||
|
||||
pflag is available under the same style of BSD license as the Go language,
|
||||
which can be found in the LICENSE file.
|
||||
|
||||
## Installation
|
||||
|
||||
pflag is available using the standard `go get` command.
|
||||
|
||||
Install by running:
|
||||
|
||||
go get github.com/spf13/pflag
|
||||
|
||||
Run tests by running:
|
||||
|
||||
go test github.com/spf13/pflag
|
||||
|
||||
## Usage
|
||||
|
||||
pflag is a drop-in replacement of Go's native flag package. If you import
|
||||
pflag under the name "flag" then all code should continue to function
|
||||
with no changes.
|
||||
|
||||
``` go
|
||||
import flag "github.com/spf13/pflag"
|
||||
```
|
||||
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
there is one more field "Shorthand" that you will need to set.
|
||||
Most code never instantiates this struct directly, and instead uses
|
||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||
unaffected.
|
||||
|
||||
Define flags using flag.String(), Bool(), Int(), etc.
|
||||
|
||||
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
|
||||
|
||||
``` go
|
||||
var ip *int = flag.Int("flagname", 1234, "help message for flagname")
|
||||
```
|
||||
|
||||
If you like, you can bind the flag to a variable using the Var() functions.
|
||||
|
||||
``` go
|
||||
var flagvar int
|
||||
func init() {
|
||||
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
|
||||
}
|
||||
```
|
||||
|
||||
Or you can create custom flags that satisfy the Value interface (with
|
||||
pointer receivers) and couple them to flag parsing by
|
||||
|
||||
``` go
|
||||
flag.Var(&flagVal, "name", "help message for flagname")
|
||||
```
|
||||
|
||||
For such flags, the default value is just the initial value of the variable.
|
||||
|
||||
After all flags are defined, call
|
||||
|
||||
``` go
|
||||
flag.Parse()
|
||||
```
|
||||
|
||||
to parse the command line into the defined flags.
|
||||
|
||||
Flags may then be used directly. If you're using the flags themselves,
|
||||
they are all pointers; if you bind to variables, they're values.
|
||||
|
||||
``` go
|
||||
fmt.Println("ip has value ", *ip)
|
||||
fmt.Println("flagvar has value ", flagvar)
|
||||
```
|
||||
|
||||
There are helpers function to get values later if you have the FlagSet but
|
||||
it was difficult to keep up with all of the flag pointers in your code.
|
||||
If you have a pflag.FlagSet with a flag called 'flagname' of type int you
|
||||
can use GetInt() to get the int value. But notice that 'flagname' must exist
|
||||
and it must be an int. GetString("flagname") will fail.
|
||||
|
||||
``` go
|
||||
i, err := flagset.GetInt("flagname")
|
||||
```
|
||||
|
||||
After parsing, the arguments after the flag are available as the
|
||||
slice flag.Args() or individually as flag.Arg(i).
|
||||
The arguments are indexed from 0 through flag.NArg()-1.
|
||||
|
||||
The pflag package also defines some new functions that are not in flag,
|
||||
that give one-letter shorthands for flags. You can use these by appending
|
||||
'P' to the name of any function that defines a flag.
|
||||
|
||||
``` go
|
||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||
var flagvar bool
|
||||
func init() {
|
||||
flag.BoolVarP("boolname", "b", true, "help message")
|
||||
}
|
||||
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
||||
```
|
||||
|
||||
Shorthand letters can be used with single dashes on the command line.
|
||||
Boolean shorthand flags can be combined with other shorthand flags.
|
||||
|
||||
The default set of command-line flags is controlled by
|
||||
top-level functions. The FlagSet type allows one to define
|
||||
independent sets of flags, such as to implement subcommands
|
||||
in a command-line interface. The methods of FlagSet are
|
||||
analogous to the top-level functions for the command-line
|
||||
flag set.
|
||||
|
||||
## Setting no option default values for flags
|
||||
|
||||
After you create a flag it is possible to set the pflag.NoOptDefVal for
|
||||
the given flag. Doing this changes the meaning of the flag slightly. If
|
||||
a flag has a NoOptDefVal and the flag is set on the command line without
|
||||
an option the flag will be set to the NoOptDefVal. For example given:
|
||||
|
||||
``` go
|
||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||
flag.Lookup("flagname").NoOptDefVal = "4321"
|
||||
```
|
||||
|
||||
Would result in something like
|
||||
|
||||
| Parsed Arguments | Resulting Value |
|
||||
| ------------- | ------------- |
|
||||
| --flagname=1357 | ip=1357 |
|
||||
| --flagname | ip=4321 |
|
||||
| [nothing] | ip=1234 |
|
||||
|
||||
## Command line flag syntax
|
||||
|
||||
```
|
||||
--flag // boolean flags, or flags with no option default values
|
||||
--flag x // only on flags without a default value
|
||||
--flag=x
|
||||
```
|
||||
|
||||
Unlike the flag package, a single dash before an option means something
|
||||
different than a double dash. Single dashes signify a series of shorthand
|
||||
letters for flags. All but the last shorthand letter must be boolean flags
|
||||
or a flag with a default value
|
||||
|
||||
```
|
||||
// boolean or flags where the 'no option default value' is set
|
||||
-f
|
||||
-f=true
|
||||
-abc
|
||||
but
|
||||
-b true is INVALID
|
||||
|
||||
// non-boolean and flags without a 'no option default value'
|
||||
-n 1234
|
||||
-n=1234
|
||||
-n1234
|
||||
|
||||
// mixed
|
||||
-abcs "hello"
|
||||
-absd="hello"
|
||||
-abcs1234
|
||||
```
|
||||
|
||||
Flag parsing stops after the terminator "--". Unlike the flag package,
|
||||
flags can be interspersed with arguments anywhere on the command line
|
||||
before this terminator.
|
||||
|
||||
Integer flags accept 1234, 0664, 0x1234 and may be negative.
|
||||
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
|
||||
TRUE, FALSE, True, False.
|
||||
Duration flags accept any input valid for time.ParseDuration.
|
||||
|
||||
## Mutating or "Normalizing" Flag names
|
||||
|
||||
It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.
|
||||
|
||||
**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag
|
||||
|
||||
``` go
|
||||
func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
from := []string{"-", "_"}
|
||||
to := "."
|
||||
for _, sep := range from {
|
||||
name = strings.Replace(name, sep, to, -1)
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
}
|
||||
|
||||
myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)
|
||||
```
|
||||
|
||||
**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name
|
||||
|
||||
``` go
|
||||
func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
switch name {
|
||||
case "old-flag-name":
|
||||
name = "new-flag-name"
|
||||
break
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
}
|
||||
|
||||
myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)
|
||||
```
|
||||
|
||||
## Deprecating a flag or its shorthand
|
||||
It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.
|
||||
|
||||
**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
|
||||
```go
|
||||
// deprecate a flag by specifying its name and a usage message
|
||||
flags.MarkDeprecated("badflag", "please use --good-flag instead")
|
||||
```
|
||||
This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.
|
||||
|
||||
**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
|
||||
```go
|
||||
// deprecate a flag shorthand by specifying its flag name and a usage message
|
||||
flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")
|
||||
```
|
||||
This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.
|
||||
|
||||
Note that usage message is essential here, and it should not be empty.
|
||||
|
||||
## Hidden flags
|
||||
It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.
|
||||
|
||||
**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.
|
||||
```go
|
||||
// hide a flag by specifying its name
|
||||
flags.MarkHidden("secretFlag")
|
||||
```
|
||||
|
||||
## Supporting Go flags when using pflag
|
||||
In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary
|
||||
to support flags defined by third-party dependencies (e.g. `golang/glog`).
|
||||
|
||||
**Example**: You want to add the Go flags to the `CommandLine` flagset
|
||||
```go
|
||||
import (
|
||||
goflag "flag"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var ip *int = flag.Int("flagname", 1234, "help message for flagname")
|
||||
|
||||
func main() {
|
||||
flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
|
||||
flag.Parse()
|
||||
}
|
||||
```
|
||||
|
||||
## More info
|
||||
|
||||
You can see the full reference documentation of the pflag package
|
||||
[at godoc.org][3], or through go's standard documentation system by
|
||||
running `godoc -http=:6060` and browsing to
|
||||
[http://localhost:6060/pkg/github.com/ogier/pflag][2] after
|
||||
installation.
|
||||
|
||||
[2]: http://localhost:6060/pkg/github.com/ogier/pflag
|
||||
[3]: http://godoc.org/github.com/ogier/pflag
|
7
vendor/github.com/spf13/pflag/bool.go
generated
vendored
7
vendor/github.com/spf13/pflag/bool.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// optional interface to indicate boolean flags that can be
|
||||
// supplied without "=value" text
|
||||
|
@ -30,7 +27,7 @@ func (b *boolValue) Type() string {
|
|||
return "bool"
|
||||
}
|
||||
|
||||
func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
|
||||
func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
|
|
147
vendor/github.com/spf13/pflag/bool_slice.go
generated
vendored
Normal file
147
vendor/github.com/spf13/pflag/bool_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- boolSlice Value
|
||||
type boolSliceValue struct {
|
||||
value *[]bool
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue {
|
||||
bsv := new(boolSliceValue)
|
||||
bsv.value = p
|
||||
*bsv.value = val
|
||||
return bsv
|
||||
}
|
||||
|
||||
// Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.
|
||||
// If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.
|
||||
func (s *boolSliceValue) Set(val string) error {
|
||||
|
||||
// remove all quote characters
|
||||
rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
|
||||
|
||||
// read flag arguments with CSV parser
|
||||
boolStrSlice, err := readAsCSV(rmQuote.Replace(val))
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse boolean values into slice
|
||||
out := make([]bool, 0, len(boolStrSlice))
|
||||
for _, boolStr := range boolStrSlice {
|
||||
b, err := strconv.ParseBool(strings.TrimSpace(boolStr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out = append(out, b)
|
||||
}
|
||||
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
|
||||
s.changed = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a string that uniquely represents this flag's type.
|
||||
func (s *boolSliceValue) Type() string {
|
||||
return "boolSlice"
|
||||
}
|
||||
|
||||
// String defines a "native" format for this boolean slice flag value.
|
||||
func (s *boolSliceValue) String() string {
|
||||
|
||||
boolStrSlice := make([]string, len(*s.value))
|
||||
for i, b := range *s.value {
|
||||
boolStrSlice[i] = strconv.FormatBool(b)
|
||||
}
|
||||
|
||||
out, _ := writeAsCSV(boolStrSlice)
|
||||
|
||||
return "[" + out + "]"
|
||||
}
|
||||
|
||||
func boolSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []bool{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]bool, len(ss))
|
||||
for i, t := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.ParseBool(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetBoolSlice returns the []bool value of a flag with the given name.
|
||||
func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {
|
||||
val, err := f.getFlagType(name, "boolSlice", boolSliceConv)
|
||||
if err != nil {
|
||||
return []bool{}, err
|
||||
}
|
||||
return val.([]bool), nil
|
||||
}
|
||||
|
||||
// BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []bool variable in which to store the value of the flag.
|
||||
func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
|
||||
f.VarP(newBoolSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
|
||||
f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BoolSliceVar defines a []bool flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []bool variable in which to store the value of the flag.
|
||||
func BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
|
||||
CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
|
||||
CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BoolSlice defines a []bool flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []bool variable that stores the value of the flag.
|
||||
func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
|
||||
p := []bool{}
|
||||
f.BoolSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
|
||||
p := []bool{}
|
||||
f.BoolSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// BoolSlice defines a []bool flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []bool variable that stores the value of the flag.
|
||||
func BoolSlice(name string, value []bool, usage string) *[]bool {
|
||||
return CommandLine.BoolSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
|
||||
return CommandLine.BoolSliceP(name, shorthand, value, usage)
|
||||
}
|
105
vendor/github.com/spf13/pflag/bytes.go
generated
vendored
Normal file
105
vendor/github.com/spf13/pflag/bytes.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded
|
||||
type bytesHexValue []byte
|
||||
|
||||
func (bytesHex bytesHexValue) String() string {
|
||||
return fmt.Sprintf("%X", []byte(bytesHex))
|
||||
}
|
||||
|
||||
func (bytesHex *bytesHexValue) Set(value string) error {
|
||||
bin, err := hex.DecodeString(strings.TrimSpace(value))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*bytesHex = bin
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*bytesHexValue) Type() string {
|
||||
return "bytesHex"
|
||||
}
|
||||
|
||||
func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {
|
||||
*p = val
|
||||
return (*bytesHexValue)(p)
|
||||
}
|
||||
|
||||
func bytesHexConv(sval string) (interface{}, error) {
|
||||
|
||||
bin, err := hex.DecodeString(sval)
|
||||
|
||||
if err == nil {
|
||||
return bin, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
|
||||
}
|
||||
|
||||
// GetBytesHex return the []byte value of a flag with the given name
|
||||
func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
|
||||
val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
|
||||
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
return val.([]byte), nil
|
||||
}
|
||||
|
||||
// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
|
||||
// The argument p points to an []byte variable in which to store the value of the flag.
|
||||
func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
|
||||
f.VarP(newBytesHexValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
|
||||
f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
|
||||
// The argument p points to an []byte variable in which to store the value of the flag.
|
||||
func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
|
||||
CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
|
||||
CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BytesHex defines an []byte flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an []byte variable that stores the value of the flag.
|
||||
func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
|
||||
p := new([]byte)
|
||||
f.BytesHexVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
|
||||
p := new([]byte)
|
||||
f.BytesHexVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// BytesHex defines an []byte flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an []byte variable that stores the value of the flag.
|
||||
func BytesHex(name string, value []byte, usage string) *[]byte {
|
||||
return CommandLine.BytesHexP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
|
||||
return CommandLine.BytesHexP(name, shorthand, value, usage)
|
||||
}
|
23
vendor/github.com/spf13/pflag/count.go
generated
vendored
23
vendor/github.com/spf13/pflag/count.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- count Value
|
||||
type countValue int
|
||||
|
@ -14,13 +11,13 @@ func newCountValue(val int, p *int) *countValue {
|
|||
}
|
||||
|
||||
func (i *countValue) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 64)
|
||||
// -1 means that no specific value was passed, so increment
|
||||
if v == -1 {
|
||||
// "+1" means that no specific value was passed, so increment
|
||||
if s == "+1" {
|
||||
*i = countValue(*i + 1)
|
||||
} else {
|
||||
*i = countValue(v)
|
||||
return nil
|
||||
}
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
*i = countValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -28,7 +25,7 @@ func (i *countValue) Type() string {
|
|||
return "count"
|
||||
}
|
||||
|
||||
func (i *countValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *countValue) String() string { return strconv.Itoa(int(*i)) }
|
||||
|
||||
func countConv(sval string) (interface{}, error) {
|
||||
i, err := strconv.Atoi(sval)
|
||||
|
@ -57,7 +54,7 @@ func (f *FlagSet) CountVar(p *int, name string, usage string) {
|
|||
// CountVarP is like CountVar only take a shorthand for the flag name.
|
||||
func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
|
||||
flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
|
||||
flag.NoOptDefVal = "-1"
|
||||
flag.NoOptDefVal = "+1"
|
||||
}
|
||||
|
||||
// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
|
||||
|
@ -86,7 +83,9 @@ func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
|
|||
return p
|
||||
}
|
||||
|
||||
// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
|
||||
// Count defines a count flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int variable that stores the value of the flag.
|
||||
// A count flag will add 1 to its value evey time it is found on the command line
|
||||
func Count(name string, usage string) *int {
|
||||
return CommandLine.CountP(name, "", usage)
|
||||
}
|
||||
|
|
128
vendor/github.com/spf13/pflag/duration_slice.go
generated
vendored
Normal file
128
vendor/github.com/spf13/pflag/duration_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// -- durationSlice Value
|
||||
type durationSliceValue struct {
|
||||
value *[]time.Duration
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {
|
||||
dsv := new(durationSliceValue)
|
||||
dsv.value = p
|
||||
*dsv.value = val
|
||||
return dsv
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]time.Duration, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = time.ParseDuration(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) Type() string {
|
||||
return "durationSlice"
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%s", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func durationSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []time.Duration{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]time.Duration, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = time.ParseDuration(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetDurationSlice returns the []time.Duration value of a flag with the given name
|
||||
func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {
|
||||
val, err := f.getFlagType(name, "durationSlice", durationSliceConv)
|
||||
if err != nil {
|
||||
return []time.Duration{}, err
|
||||
}
|
||||
return val.([]time.Duration), nil
|
||||
}
|
||||
|
||||
// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []time.Duration variable in which to store the value of the flag.
|
||||
func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
|
||||
f.VarP(newDurationSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
|
||||
f.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a duration[] variable in which to store the value of the flag.
|
||||
func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
|
||||
CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
|
||||
CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []time.Duration variable that stores the value of the flag.
|
||||
func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
|
||||
p := []time.Duration{}
|
||||
f.DurationSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
|
||||
p := []time.Duration{}
|
||||
f.DurationSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []time.Duration variable that stores the value of the flag.
|
||||
func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
|
||||
return CommandLine.DurationSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
|
||||
return CommandLine.DurationSliceP(name, shorthand, value, usage)
|
||||
}
|
509
vendor/github.com/spf13/pflag/flag.go
generated
vendored
509
vendor/github.com/spf13/pflag/flag.go
generated
vendored
|
@ -16,9 +16,9 @@ pflag is a drop-in replacement of Go's native flag package. If you import
|
|||
pflag under the name "flag" then all code should continue to function
|
||||
with no changes.
|
||||
|
||||
import flag "github.com/ogier/pflag"
|
||||
import flag "github.com/spf13/pflag"
|
||||
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
there is one more field "Shorthand" that you will need to set.
|
||||
Most code never instantiates this struct directly, and instead uses
|
||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||
|
@ -101,6 +101,7 @@ package pflag
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
@ -123,6 +124,12 @@ const (
|
|||
PanicOnError
|
||||
)
|
||||
|
||||
// ParseErrorsWhitelist defines the parsing errors that can be ignored
|
||||
type ParseErrorsWhitelist struct {
|
||||
// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
|
||||
UnknownFlags bool
|
||||
}
|
||||
|
||||
// NormalizedName is a flag name that has been normalized according to rules
|
||||
// for the FlagSet (e.g. making '-' and '_' equivalent).
|
||||
type NormalizedName string
|
||||
|
@ -134,18 +141,30 @@ type FlagSet struct {
|
|||
// a custom error handler.
|
||||
Usage func()
|
||||
|
||||
// SortFlags is used to indicate, if user wants to have sorted flags in
|
||||
// help/usage messages.
|
||||
SortFlags bool
|
||||
|
||||
// ParseErrorsWhitelist is used to configure a whitelist of errors
|
||||
ParseErrorsWhitelist ParseErrorsWhitelist
|
||||
|
||||
name string
|
||||
parsed bool
|
||||
actual map[NormalizedName]*Flag
|
||||
orderedActual []*Flag
|
||||
sortedActual []*Flag
|
||||
formal map[NormalizedName]*Flag
|
||||
orderedFormal []*Flag
|
||||
sortedFormal []*Flag
|
||||
shorthands map[byte]*Flag
|
||||
args []string // arguments after flags
|
||||
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
|
||||
exitOnError bool // does the program exit if there's an error?
|
||||
errorHandling ErrorHandling
|
||||
output io.Writer // nil means stderr; use out() accessor
|
||||
interspersed bool // allow interspersed option/non-option args
|
||||
normalizeNameFunc func(f *FlagSet, name string) NormalizedName
|
||||
|
||||
addedGoFlagSets []*goflag.FlagSet
|
||||
}
|
||||
|
||||
// A Flag represents the state of a flag.
|
||||
|
@ -156,7 +175,7 @@ type Flag struct {
|
|||
Value Value // value as set
|
||||
DefValue string // default value (as text); for usage message
|
||||
Changed bool // If the user set the value (or if left to default)
|
||||
NoOptDefVal string //default value (as text); if the flag is on the command line without any options
|
||||
NoOptDefVal string // default value (as text); if the flag is on the command line without any options
|
||||
Deprecated string // If this flag is deprecated, this string is the new or now thing to use
|
||||
Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
|
||||
ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
|
||||
|
@ -194,11 +213,19 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
|
|||
// "--getUrl" which may also be translated to "geturl" and everything will work.
|
||||
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
|
||||
f.normalizeNameFunc = n
|
||||
for k, v := range f.formal {
|
||||
delete(f.formal, k)
|
||||
nname := f.normalizeFlagName(string(k))
|
||||
f.formal[nname] = v
|
||||
v.Name = string(nname)
|
||||
f.sortedFormal = f.sortedFormal[:0]
|
||||
for fname, flag := range f.formal {
|
||||
nname := f.normalizeFlagName(flag.Name)
|
||||
if fname == nname {
|
||||
continue
|
||||
}
|
||||
flag.Name = string(nname)
|
||||
delete(f.formal, fname)
|
||||
f.formal[nname] = flag
|
||||
if _, set := f.actual[fname]; set {
|
||||
delete(f.actual, fname)
|
||||
f.actual[nname] = flag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,46 +256,78 @@ func (f *FlagSet) SetOutput(output io.Writer) {
|
|||
f.output = output
|
||||
}
|
||||
|
||||
// VisitAll visits the flags in lexicographical order, calling fn for each.
|
||||
// VisitAll visits the flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits all flags, even those not set.
|
||||
func (f *FlagSet) VisitAll(fn func(*Flag)) {
|
||||
for _, flag := range sortFlags(f.formal) {
|
||||
if len(f.formal) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var flags []*Flag
|
||||
if f.SortFlags {
|
||||
if len(f.formal) != len(f.sortedFormal) {
|
||||
f.sortedFormal = sortFlags(f.formal)
|
||||
}
|
||||
flags = f.sortedFormal
|
||||
} else {
|
||||
flags = f.orderedFormal
|
||||
}
|
||||
|
||||
for _, flag := range flags {
|
||||
fn(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
|
||||
// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
|
||||
func (f *FlagSet) HasFlags() bool {
|
||||
return len(f.formal) > 0
|
||||
}
|
||||
|
||||
// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
|
||||
// definied that are not hidden or deprecated.
|
||||
// that are not hidden.
|
||||
func (f *FlagSet) HasAvailableFlags() bool {
|
||||
for _, flag := range f.formal {
|
||||
if !flag.Hidden && len(flag.Deprecated) == 0 {
|
||||
if !flag.Hidden {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// VisitAll visits the command-line flags in lexicographical order, calling
|
||||
// fn for each. It visits all flags, even those not set.
|
||||
// VisitAll visits the command-line flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits all flags, even those not set.
|
||||
func VisitAll(fn func(*Flag)) {
|
||||
CommandLine.VisitAll(fn)
|
||||
}
|
||||
|
||||
// Visit visits the flags in lexicographical order, calling fn for each.
|
||||
// Visit visits the flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits only those flags that have been set.
|
||||
func (f *FlagSet) Visit(fn func(*Flag)) {
|
||||
for _, flag := range sortFlags(f.actual) {
|
||||
if len(f.actual) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var flags []*Flag
|
||||
if f.SortFlags {
|
||||
if len(f.actual) != len(f.sortedActual) {
|
||||
f.sortedActual = sortFlags(f.actual)
|
||||
}
|
||||
flags = f.sortedActual
|
||||
} else {
|
||||
flags = f.orderedActual
|
||||
}
|
||||
|
||||
for _, flag := range flags {
|
||||
fn(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// Visit visits the command-line flags in lexicographical order, calling fn
|
||||
// for each. It visits only those flags that have been set.
|
||||
// Visit visits the command-line flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits only those flags that have been set.
|
||||
func Visit(fn func(*Flag)) {
|
||||
CommandLine.Visit(fn)
|
||||
}
|
||||
|
@ -278,6 +337,22 @@ func (f *FlagSet) Lookup(name string) *Flag {
|
|||
return f.lookup(f.normalizeFlagName(name))
|
||||
}
|
||||
|
||||
// ShorthandLookup returns the Flag structure of the short handed flag,
|
||||
// returning nil if none exists.
|
||||
// It panics, if len(name) > 1.
|
||||
func (f *FlagSet) ShorthandLookup(name string) *Flag {
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
if len(name) > 1 {
|
||||
msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
|
||||
fmt.Fprintf(f.out(), msg)
|
||||
panic(msg)
|
||||
}
|
||||
c := name[0]
|
||||
return f.shorthands[c]
|
||||
}
|
||||
|
||||
// lookup returns the Flag structure of the named flag, returning nil if none exists.
|
||||
func (f *FlagSet) lookup(name NormalizedName) *Flag {
|
||||
return f.formal[name]
|
||||
|
@ -319,10 +394,11 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
|
|||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
if len(usageMessage) == 0 {
|
||||
if usageMessage == "" {
|
||||
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||
}
|
||||
flag.Deprecated = usageMessage
|
||||
flag.Hidden = true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -334,7 +410,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
|
|||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
if len(usageMessage) == 0 {
|
||||
if usageMessage == "" {
|
||||
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||
}
|
||||
flag.ShorthandDeprecated = usageMessage
|
||||
|
@ -358,6 +434,12 @@ func Lookup(name string) *Flag {
|
|||
return CommandLine.Lookup(name)
|
||||
}
|
||||
|
||||
// ShorthandLookup returns the Flag structure of the short handed flag,
|
||||
// returning nil if none exists.
|
||||
func ShorthandLookup(name string) *Flag {
|
||||
return CommandLine.ShorthandLookup(name)
|
||||
}
|
||||
|
||||
// Set sets the value of the named flag.
|
||||
func (f *FlagSet) Set(name, value string) error {
|
||||
normalName := f.normalizeFlagName(name)
|
||||
|
@ -365,17 +447,30 @@ func (f *FlagSet) Set(name, value string) error {
|
|||
if !ok {
|
||||
return fmt.Errorf("no such flag -%v", name)
|
||||
}
|
||||
|
||||
err := flag.Value.Set(value)
|
||||
if err != nil {
|
||||
return err
|
||||
var flagName string
|
||||
if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
|
||||
flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
|
||||
} else {
|
||||
flagName = fmt.Sprintf("--%s", flag.Name)
|
||||
}
|
||||
return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
|
||||
}
|
||||
|
||||
if !flag.Changed {
|
||||
if f.actual == nil {
|
||||
f.actual = make(map[NormalizedName]*Flag)
|
||||
}
|
||||
f.actual[normalName] = flag
|
||||
f.orderedActual = append(f.orderedActual, flag)
|
||||
|
||||
flag.Changed = true
|
||||
if len(flag.Deprecated) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
|
||||
if flag.Deprecated != "" {
|
||||
fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -416,13 +511,28 @@ func Set(name, value string) error {
|
|||
// otherwise, the default values of all defined flags in the set.
|
||||
func (f *FlagSet) PrintDefaults() {
|
||||
usages := f.FlagUsages()
|
||||
fmt.Fprintf(f.out(), "%s", usages)
|
||||
fmt.Fprint(f.out(), usages)
|
||||
}
|
||||
|
||||
// isZeroValue guesses whether the string represents the zero
|
||||
// value for a flag. It is not accurate but in practice works OK.
|
||||
func isZeroValue(value string) bool {
|
||||
switch value {
|
||||
// defaultIsZeroValue returns true if the default value for this flag represents
|
||||
// a zero value.
|
||||
func (f *Flag) defaultIsZeroValue() bool {
|
||||
switch f.Value.(type) {
|
||||
case boolFlag:
|
||||
return f.DefValue == "false"
|
||||
case *durationValue:
|
||||
// Beginning in Go 1.7, duration zero values are "0s"
|
||||
return f.DefValue == "0" || f.DefValue == "0s"
|
||||
case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
|
||||
return f.DefValue == "0"
|
||||
case *stringValue:
|
||||
return f.DefValue == ""
|
||||
case *ipValue, *ipMaskValue, *ipNetValue:
|
||||
return f.DefValue == "<nil>"
|
||||
case *intSliceValue, *stringSliceValue, *stringArrayValue:
|
||||
return f.DefValue == "[]"
|
||||
default:
|
||||
switch f.Value.String() {
|
||||
case "false":
|
||||
return true
|
||||
case "<nil>":
|
||||
|
@ -433,6 +543,7 @@ func isZeroValue(value string) bool {
|
|||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// UnquoteUsage extracts a back-quoted name from the usage
|
||||
|
@ -455,57 +566,136 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
|
|||
break // Only one back quote; use type name.
|
||||
}
|
||||
}
|
||||
// No explicit name, so use type if we can find one.
|
||||
name = "value"
|
||||
switch flag.Value.(type) {
|
||||
case boolFlag:
|
||||
|
||||
name = flag.Value.Type()
|
||||
switch name {
|
||||
case "bool":
|
||||
name = ""
|
||||
case *durationValue:
|
||||
name = "duration"
|
||||
case *float64Value:
|
||||
case "float64":
|
||||
name = "float"
|
||||
case *intValue, *int64Value:
|
||||
case "int64":
|
||||
name = "int"
|
||||
case *stringValue:
|
||||
name = "string"
|
||||
case *uintValue, *uint64Value:
|
||||
case "uint64":
|
||||
name = "uint"
|
||||
case "stringSlice":
|
||||
name = "strings"
|
||||
case "intSlice":
|
||||
name = "ints"
|
||||
case "uintSlice":
|
||||
name = "uints"
|
||||
case "boolSlice":
|
||||
name = "bools"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FlagUsages Returns a string containing the usage information for all flags in
|
||||
// the FlagSet
|
||||
func (f *FlagSet) FlagUsages() string {
|
||||
x := new(bytes.Buffer)
|
||||
// Splits the string `s` on whitespace into an initial substring up to
|
||||
// `i` runes in length and the remainder. Will go `slop` over `i` if
|
||||
// that encompasses the entire string (which allows the caller to
|
||||
// avoid short orphan words on the final line).
|
||||
func wrapN(i, slop int, s string) (string, string) {
|
||||
if i+slop > len(s) {
|
||||
return s, ""
|
||||
}
|
||||
|
||||
w := strings.LastIndexAny(s[:i], " \t\n")
|
||||
if w <= 0 {
|
||||
return s, ""
|
||||
}
|
||||
nlPos := strings.LastIndex(s[:i], "\n")
|
||||
if nlPos > 0 && nlPos < w {
|
||||
return s[:nlPos], s[nlPos+1:]
|
||||
}
|
||||
return s[:w], s[w+1:]
|
||||
}
|
||||
|
||||
// Wraps the string `s` to a maximum width `w` with leading indent
|
||||
// `i`. The first line is not indented (this is assumed to be done by
|
||||
// caller). Pass `w` == 0 to do no wrapping
|
||||
func wrap(i, w int, s string) string {
|
||||
if w == 0 {
|
||||
return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
|
||||
}
|
||||
|
||||
// space between indent i and end of line width w into which
|
||||
// we should wrap the text.
|
||||
wrap := w - i
|
||||
|
||||
var r, l string
|
||||
|
||||
// Not enough space for sensible wrapping. Wrap as a block on
|
||||
// the next line instead.
|
||||
if wrap < 24 {
|
||||
i = 16
|
||||
wrap = w - i
|
||||
r += "\n" + strings.Repeat(" ", i)
|
||||
}
|
||||
// If still not enough space then don't even try to wrap.
|
||||
if wrap < 24 {
|
||||
return strings.Replace(s, "\n", r, -1)
|
||||
}
|
||||
|
||||
// Try to avoid short orphan words on the final line, by
|
||||
// allowing wrapN to go a bit over if that would fit in the
|
||||
// remainder of the line.
|
||||
slop := 5
|
||||
wrap = wrap - slop
|
||||
|
||||
// Handle first line, which is indented by the caller (or the
|
||||
// special case above)
|
||||
l, s = wrapN(wrap, slop, s)
|
||||
r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
|
||||
|
||||
// Now wrap the rest
|
||||
for s != "" {
|
||||
var t string
|
||||
|
||||
t, s = wrapN(wrap, slop, s)
|
||||
r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
}
|
||||
|
||||
// FlagUsagesWrapped returns a string containing the usage information
|
||||
// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
|
||||
// wrapping)
|
||||
func (f *FlagSet) FlagUsagesWrapped(cols int) string {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
lines := make([]string, 0, len(f.formal))
|
||||
|
||||
maxlen := 0
|
||||
f.VisitAll(func(flag *Flag) {
|
||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||
if flag.Hidden {
|
||||
return
|
||||
}
|
||||
|
||||
line := ""
|
||||
if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
|
||||
if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
|
||||
line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
|
||||
} else {
|
||||
line = fmt.Sprintf(" --%s", flag.Name)
|
||||
}
|
||||
|
||||
varname, usage := UnquoteUsage(flag)
|
||||
if len(varname) > 0 {
|
||||
if varname != "" {
|
||||
line += " " + varname
|
||||
}
|
||||
if len(flag.NoOptDefVal) > 0 {
|
||||
if flag.NoOptDefVal != "" {
|
||||
switch flag.Value.Type() {
|
||||
case "string":
|
||||
line += fmt.Sprintf("[=%q]", flag.NoOptDefVal)
|
||||
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
|
||||
case "bool":
|
||||
if flag.NoOptDefVal != "true" {
|
||||
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||
}
|
||||
case "count":
|
||||
if flag.NoOptDefVal != "+1" {
|
||||
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||
}
|
||||
default:
|
||||
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||
}
|
||||
|
@ -519,13 +709,16 @@ func (f *FlagSet) FlagUsages() string {
|
|||
}
|
||||
|
||||
line += usage
|
||||
if !isZeroValue(flag.DefValue) {
|
||||
if !flag.defaultIsZeroValue() {
|
||||
if flag.Value.Type() == "string" {
|
||||
line += fmt.Sprintf(" (default %q)", flag.DefValue)
|
||||
} else {
|
||||
line += fmt.Sprintf(" (default %s)", flag.DefValue)
|
||||
}
|
||||
}
|
||||
if len(flag.Deprecated) != 0 {
|
||||
line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
|
||||
}
|
||||
|
||||
lines = append(lines, line)
|
||||
})
|
||||
|
@ -533,10 +726,17 @@ func (f *FlagSet) FlagUsages() string {
|
|||
for _, line := range lines {
|
||||
sidx := strings.Index(line, "\x00")
|
||||
spacing := strings.Repeat(" ", maxlen-sidx)
|
||||
fmt.Fprintln(x, line[:sidx], spacing, line[sidx+1:])
|
||||
// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
|
||||
fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
|
||||
}
|
||||
|
||||
return x.String()
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// FlagUsages returns a string containing the usage information for all flags in
|
||||
// the FlagSet
|
||||
func (f *FlagSet) FlagUsages() string {
|
||||
return f.FlagUsagesWrapped(0)
|
||||
}
|
||||
|
||||
// PrintDefaults prints to standard error the default values of all defined command-line flags.
|
||||
|
@ -622,16 +822,15 @@ func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
|
|||
|
||||
// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
|
||||
_ = f.VarPF(value, name, shorthand, usage)
|
||||
f.VarPF(value, name, shorthand, usage)
|
||||
}
|
||||
|
||||
// AddFlag will add the flag to the FlagSet
|
||||
func (f *FlagSet) AddFlag(flag *Flag) {
|
||||
// Call normalizeFlagName function only once
|
||||
normalizedFlagName := f.normalizeFlagName(flag.Name)
|
||||
|
||||
_, alreadythere := f.formal[normalizedFlagName]
|
||||
if alreadythere {
|
||||
_, alreadyThere := f.formal[normalizedFlagName]
|
||||
if alreadyThere {
|
||||
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
|
||||
fmt.Fprintln(f.out(), msg)
|
||||
panic(msg) // Happens only if flags are declared with identical names
|
||||
|
@ -642,28 +841,31 @@ func (f *FlagSet) AddFlag(flag *Flag) {
|
|||
|
||||
flag.Name = string(normalizedFlagName)
|
||||
f.formal[normalizedFlagName] = flag
|
||||
f.orderedFormal = append(f.orderedFormal, flag)
|
||||
|
||||
if len(flag.Shorthand) == 0 {
|
||||
if flag.Shorthand == "" {
|
||||
return
|
||||
}
|
||||
if len(flag.Shorthand) > 1 {
|
||||
fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
|
||||
panic("shorthand is more than one character")
|
||||
msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
|
||||
fmt.Fprintf(f.out(), msg)
|
||||
panic(msg)
|
||||
}
|
||||
if f.shorthands == nil {
|
||||
f.shorthands = make(map[byte]*Flag)
|
||||
}
|
||||
c := flag.Shorthand[0]
|
||||
old, alreadythere := f.shorthands[c]
|
||||
if alreadythere {
|
||||
fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
|
||||
panic("shorthand redefinition")
|
||||
used, alreadyThere := f.shorthands[c]
|
||||
if alreadyThere {
|
||||
msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
|
||||
fmt.Fprintf(f.out(), msg)
|
||||
panic(msg)
|
||||
}
|
||||
f.shorthands[c] = flag
|
||||
}
|
||||
|
||||
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
|
||||
// the flag from newSet will be ignored
|
||||
// the flag from newSet will be ignored.
|
||||
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
|
||||
if newSet == nil {
|
||||
return
|
||||
|
@ -694,8 +896,10 @@ func VarP(value Value, name, shorthand, usage string) {
|
|||
// returns the error.
|
||||
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
||||
err := fmt.Errorf(format, a...)
|
||||
if f.errorHandling != ContinueOnError {
|
||||
fmt.Fprintln(f.out(), err)
|
||||
f.usage()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -711,57 +915,61 @@ func (f *FlagSet) usage() {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
|
||||
if err := flag.Value.Set(value); err != nil {
|
||||
return f.failf("invalid argument %q for %s: %v", value, origArg, err)
|
||||
//--unknown (args will be empty)
|
||||
//--unknown --next-flag ... (args will be --next-flag ...)
|
||||
//--unknown arg ... (args will be arg ...)
|
||||
func stripUnknownFlagValue(args []string) []string {
|
||||
if len(args) == 0 {
|
||||
//--unknown
|
||||
return args
|
||||
}
|
||||
// mark as visited for Visit()
|
||||
if f.actual == nil {
|
||||
f.actual = make(map[NormalizedName]*Flag)
|
||||
|
||||
first := args[0]
|
||||
if first[0] == '-' {
|
||||
//--unknown --next-flag ...
|
||||
return args
|
||||
}
|
||||
f.actual[f.normalizeFlagName(flag.Name)] = flag
|
||||
flag.Changed = true
|
||||
if len(flag.Deprecated) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
|
||||
fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
|
||||
}
|
||||
return nil
|
||||
|
||||
//--unknown arg ... (args will be arg ...)
|
||||
return args[1:]
|
||||
}
|
||||
|
||||
func containsShorthand(arg, shorthand string) bool {
|
||||
// filter out flags --<flag_name>
|
||||
if strings.HasPrefix(arg, "-") {
|
||||
return false
|
||||
}
|
||||
arg = strings.SplitN(arg, "=", 2)[0]
|
||||
return strings.Contains(arg, shorthand)
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
|
||||
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
|
||||
a = args
|
||||
name := s[2:]
|
||||
if len(name) == 0 || name[0] == '-' || name[0] == '=' {
|
||||
err = f.failf("bad flag syntax: %s", s)
|
||||
return
|
||||
}
|
||||
|
||||
split := strings.SplitN(name, "=", 2)
|
||||
name = split[0]
|
||||
flag, alreadythere := f.formal[f.normalizeFlagName(name)]
|
||||
if !alreadythere {
|
||||
if name == "help" { // special case for nice help message.
|
||||
flag, exists := f.formal[f.normalizeFlagName(name)]
|
||||
|
||||
if !exists {
|
||||
switch {
|
||||
case name == "help":
|
||||
f.usage()
|
||||
return a, ErrHelp
|
||||
case f.ParseErrorsWhitelist.UnknownFlags:
|
||||
// --unknown=unknownval arg ...
|
||||
// we do not want to lose arg in this case
|
||||
if len(split) >= 2 {
|
||||
return a, nil
|
||||
}
|
||||
|
||||
return stripUnknownFlagValue(a), nil
|
||||
default:
|
||||
err = f.failf("unknown flag: --%s", name)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var value string
|
||||
if len(split) == 2 {
|
||||
// '--flag=arg'
|
||||
value = split[1]
|
||||
} else if len(flag.NoOptDefVal) > 0 {
|
||||
} else if flag.NoOptDefVal != "" {
|
||||
// '--flag' (arg was optional)
|
||||
value = flag.NoOptDefVal
|
||||
} else if len(a) > 0 {
|
||||
|
@ -773,55 +981,86 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
|
|||
err = f.failf("flag needs an argument: %s", s)
|
||||
return
|
||||
}
|
||||
err = f.setFlag(flag, value, s)
|
||||
|
||||
err = fn(flag, value)
|
||||
if err != nil {
|
||||
f.failf(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
|
||||
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
|
||||
if strings.HasPrefix(shorthands, "test.") {
|
||||
return
|
||||
}
|
||||
|
||||
outArgs = args
|
||||
outShorts = shorthands[1:]
|
||||
c := shorthands[0]
|
||||
|
||||
flag, alreadythere := f.shorthands[c]
|
||||
if !alreadythere {
|
||||
if c == 'h' { // special case for nice help message.
|
||||
flag, exists := f.shorthands[c]
|
||||
if !exists {
|
||||
switch {
|
||||
case c == 'h':
|
||||
f.usage()
|
||||
err = ErrHelp
|
||||
return
|
||||
case f.ParseErrorsWhitelist.UnknownFlags:
|
||||
// '-f=arg arg ...'
|
||||
// we do not want to lose arg in this case
|
||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||
outShorts = ""
|
||||
return
|
||||
}
|
||||
//TODO continue on error
|
||||
|
||||
outArgs = stripUnknownFlagValue(outArgs)
|
||||
return
|
||||
default:
|
||||
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var value string
|
||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||
// '-f=arg'
|
||||
value = shorthands[2:]
|
||||
outShorts = ""
|
||||
} else if len(flag.NoOptDefVal) > 0 {
|
||||
} else if flag.NoOptDefVal != "" {
|
||||
// '-f' (arg was optional)
|
||||
value = flag.NoOptDefVal
|
||||
} else if len(shorthands) > 1 {
|
||||
// '-farg'
|
||||
value = shorthands[1:]
|
||||
outShorts = ""
|
||||
} else if len(args) > 0 {
|
||||
// '-f arg'
|
||||
value = args[0]
|
||||
outArgs = args[1:]
|
||||
} else {
|
||||
// '-f' (arg was required)
|
||||
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
|
||||
return
|
||||
}
|
||||
err = f.setFlag(flag, value, shorthands)
|
||||
|
||||
if flag.ShorthandDeprecated != "" {
|
||||
fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
|
||||
}
|
||||
|
||||
err = fn(flag, value)
|
||||
if err != nil {
|
||||
f.failf(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) {
|
||||
func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
|
||||
a = args
|
||||
shorthands := s[1:]
|
||||
|
||||
// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
|
||||
for len(shorthands) > 0 {
|
||||
shorthands, a, err = f.parseSingleShortArg(shorthands, args)
|
||||
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -830,7 +1069,7 @@ func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error)
|
|||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseArgs(args []string) (err error) {
|
||||
func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
|
||||
for len(args) > 0 {
|
||||
s := args[0]
|
||||
args = args[1:]
|
||||
|
@ -850,9 +1089,9 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
|||
f.args = append(f.args, args...)
|
||||
break
|
||||
}
|
||||
args, err = f.parseLongArg(s, args)
|
||||
args, err = f.parseLongArg(s, args, fn)
|
||||
} else {
|
||||
args, err = f.parseShortArg(s, args)
|
||||
args, err = f.parseShortArg(s, args, fn)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -866,9 +1105,50 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
|||
// are defined and before flags are accessed by the program.
|
||||
// The return value will be ErrHelp if -help was set but not defined.
|
||||
func (f *FlagSet) Parse(arguments []string) error {
|
||||
if f.addedGoFlagSets != nil {
|
||||
for _, goFlagSet := range f.addedGoFlagSets {
|
||||
goFlagSet.Parse(nil)
|
||||
}
|
||||
}
|
||||
f.parsed = true
|
||||
|
||||
if len(arguments) < 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.args = make([]string, 0, len(arguments))
|
||||
|
||||
set := func(flag *Flag, value string) error {
|
||||
return f.Set(flag.Name, value)
|
||||
}
|
||||
|
||||
err := f.parseArgs(arguments, set)
|
||||
if err != nil {
|
||||
switch f.errorHandling {
|
||||
case ContinueOnError:
|
||||
return err
|
||||
case ExitOnError:
|
||||
fmt.Println(err)
|
||||
os.Exit(2)
|
||||
case PanicOnError:
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type parseFunc func(flag *Flag, value string) error
|
||||
|
||||
// ParseAll parses flag definitions from the argument list, which should not
|
||||
// include the command name. The arguments for fn are flag and value. Must be
|
||||
// called after all flags in the FlagSet are defined and before flags are
|
||||
// accessed by the program. The return value will be ErrHelp if -help was set
|
||||
// but not defined.
|
||||
func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
|
||||
f.parsed = true
|
||||
f.args = make([]string, 0, len(arguments))
|
||||
err := f.parseArgs(arguments)
|
||||
|
||||
err := f.parseArgs(arguments, fn)
|
||||
if err != nil {
|
||||
switch f.errorHandling {
|
||||
case ContinueOnError:
|
||||
|
@ -894,6 +1174,14 @@ func Parse() {
|
|||
CommandLine.Parse(os.Args[1:])
|
||||
}
|
||||
|
||||
// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
|
||||
// The arguments for fn are flag and value. Must be called after all flags are
|
||||
// defined and before flags are accessed by the program.
|
||||
func ParseAll(fn func(flag *Flag, value string) error) {
|
||||
// Ignore errors; CommandLine is set for ExitOnError.
|
||||
CommandLine.ParseAll(os.Args[1:], fn)
|
||||
}
|
||||
|
||||
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||
func SetInterspersed(interspersed bool) {
|
||||
CommandLine.SetInterspersed(interspersed)
|
||||
|
@ -907,14 +1195,15 @@ func Parsed() bool {
|
|||
// CommandLine is the default set of command-line flags, parsed from os.Args.
|
||||
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
|
||||
|
||||
// NewFlagSet returns a new, empty flag set with the specified name and
|
||||
// error handling property.
|
||||
// NewFlagSet returns a new, empty flag set with the specified name,
|
||||
// error handling property and SortFlags set to true.
|
||||
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
|
||||
f := &FlagSet{
|
||||
name: name,
|
||||
errorHandling: errorHandling,
|
||||
argsLenAtDash: -1,
|
||||
interspersed: true,
|
||||
SortFlags: true,
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
|
7
vendor/github.com/spf13/pflag/float32.go
generated
vendored
7
vendor/github.com/spf13/pflag/float32.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- float32 Value
|
||||
type float32Value float32
|
||||
|
@ -23,7 +20,7 @@ func (f *float32Value) Type() string {
|
|||
return "float32"
|
||||
}
|
||||
|
||||
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
|
||||
func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) }
|
||||
|
||||
func float32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseFloat(sval, 32)
|
||||
|
|
7
vendor/github.com/spf13/pflag/float64.go
generated
vendored
7
vendor/github.com/spf13/pflag/float64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- float64 Value
|
||||
type float64Value float64
|
||||
|
@ -23,7 +20,7 @@ func (f *float64Value) Type() string {
|
|||
return "float64"
|
||||
}
|
||||
|
||||
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
|
||||
func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
|
||||
|
||||
func float64Conv(sval string) (interface{}, error) {
|
||||
return strconv.ParseFloat(sval, 64)
|
||||
|
|
7
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
7
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
|
@ -6,13 +6,10 @@ package pflag
|
|||
|
||||
import (
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
// flagValueWrapper implements pflag.Value around a flag.Value. The main
|
||||
// difference here is the addition of the Type method that returns a string
|
||||
// name of the type. As this is generally unknown, we approximate that with
|
||||
|
@ -101,4 +98,8 @@ func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
|
|||
newSet.VisitAll(func(goflag *goflag.Flag) {
|
||||
f.AddGoFlag(goflag)
|
||||
})
|
||||
if f.addedGoFlagSets == nil {
|
||||
f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
|
||||
}
|
||||
f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
|
||||
}
|
||||
|
|
7
vendor/github.com/spf13/pflag/int.go
generated
vendored
7
vendor/github.com/spf13/pflag/int.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int Value
|
||||
type intValue int
|
||||
|
@ -23,7 +20,7 @@ func (i *intValue) Type() string {
|
|||
return "int"
|
||||
}
|
||||
|
||||
func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
|
||||
|
||||
func intConv(sval string) (interface{}, error) {
|
||||
return strconv.Atoi(sval)
|
||||
|
|
88
vendor/github.com/spf13/pflag/int16.go
generated
vendored
Normal file
88
vendor/github.com/spf13/pflag/int16.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
package pflag
|
||||
|
||||
import "strconv"
|
||||
|
||||
// -- int16 Value
|
||||
type int16Value int16
|
||||
|
||||
func newInt16Value(val int16, p *int16) *int16Value {
|
||||
*p = val
|
||||
return (*int16Value)(p)
|
||||
}
|
||||
|
||||
func (i *int16Value) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 16)
|
||||
*i = int16Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *int16Value) Type() string {
|
||||
return "int16"
|
||||
}
|
||||
|
||||
func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int16Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int16(v), nil
|
||||
}
|
||||
|
||||
// GetInt16 returns the int16 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt16(name string) (int16, error) {
|
||||
val, err := f.getFlagType(name, "int16", int16Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int16), nil
|
||||
}
|
||||
|
||||
// Int16Var defines an int16 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int16 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {
|
||||
f.VarP(newInt16Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
|
||||
f.VarP(newInt16Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int16Var defines an int16 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int16 variable in which to store the value of the flag.
|
||||
func Int16Var(p *int16, name string, value int16, usage string) {
|
||||
CommandLine.VarP(newInt16Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
|
||||
CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int16 defines an int16 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int16 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int16(name string, value int16, usage string) *int16 {
|
||||
p := new(int16)
|
||||
f.Int16VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {
|
||||
p := new(int16)
|
||||
f.Int16VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int16 defines an int16 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int16 variable that stores the value of the flag.
|
||||
func Int16(name string, value int16, usage string) *int16 {
|
||||
return CommandLine.Int16P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int16P(name, shorthand string, value int16, usage string) *int16 {
|
||||
return CommandLine.Int16P(name, shorthand, value, usage)
|
||||
}
|
7
vendor/github.com/spf13/pflag/int32.go
generated
vendored
7
vendor/github.com/spf13/pflag/int32.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int32 Value
|
||||
type int32Value int32
|
||||
|
@ -23,7 +20,7 @@ func (i *int32Value) Type() string {
|
|||
return "int32"
|
||||
}
|
||||
|
||||
func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 32)
|
||||
|
|
7
vendor/github.com/spf13/pflag/int64.go
generated
vendored
7
vendor/github.com/spf13/pflag/int64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int64 Value
|
||||
type int64Value int64
|
||||
|
@ -23,7 +20,7 @@ func (i *int64Value) Type() string {
|
|||
return "int64"
|
||||
}
|
||||
|
||||
func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int64Conv(sval string) (interface{}, error) {
|
||||
return strconv.ParseInt(sval, 0, 64)
|
||||
|
|
7
vendor/github.com/spf13/pflag/int8.go
generated
vendored
7
vendor/github.com/spf13/pflag/int8.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int8 Value
|
||||
type int8Value int8
|
||||
|
@ -23,7 +20,7 @@ func (i *int8Value) Type() string {
|
|||
return "int8"
|
||||
}
|
||||
|
||||
func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int8Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 8)
|
||||
|
|
2
vendor/github.com/spf13/pflag/ip.go
generated
vendored
2
vendor/github.com/spf13/pflag/ip.go
generated
vendored
|
@ -6,8 +6,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var _ = strings.TrimSpace
|
||||
|
||||
// -- net.IP value
|
||||
type ipValue net.IP
|
||||
|
||||
|
|
148
vendor/github.com/spf13/pflag/ip_slice.go
generated
vendored
Normal file
148
vendor/github.com/spf13/pflag/ip_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- ipSlice Value
|
||||
type ipSliceValue struct {
|
||||
value *[]net.IP
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue {
|
||||
ipsv := new(ipSliceValue)
|
||||
ipsv.value = p
|
||||
*ipsv.value = val
|
||||
return ipsv
|
||||
}
|
||||
|
||||
// Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag.
|
||||
// If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended.
|
||||
func (s *ipSliceValue) Set(val string) error {
|
||||
|
||||
// remove all quote characters
|
||||
rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
|
||||
|
||||
// read flag arguments with CSV parser
|
||||
ipStrSlice, err := readAsCSV(rmQuote.Replace(val))
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse ip values into slice
|
||||
out := make([]net.IP, 0, len(ipStrSlice))
|
||||
for _, ipStr := range ipStrSlice {
|
||||
ip := net.ParseIP(strings.TrimSpace(ipStr))
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid string being converted to IP address: %s", ipStr)
|
||||
}
|
||||
out = append(out, ip)
|
||||
}
|
||||
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
|
||||
s.changed = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a string that uniquely represents this flag's type.
|
||||
func (s *ipSliceValue) Type() string {
|
||||
return "ipSlice"
|
||||
}
|
||||
|
||||
// String defines a "native" format for this net.IP slice flag value.
|
||||
func (s *ipSliceValue) String() string {
|
||||
|
||||
ipStrSlice := make([]string, len(*s.value))
|
||||
for i, ip := range *s.value {
|
||||
ipStrSlice[i] = ip.String()
|
||||
}
|
||||
|
||||
out, _ := writeAsCSV(ipStrSlice)
|
||||
|
||||
return "[" + out + "]"
|
||||
}
|
||||
|
||||
func ipSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Emtpy string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []net.IP{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]net.IP, len(ss))
|
||||
for i, sval := range ss {
|
||||
ip := net.ParseIP(strings.TrimSpace(sval))
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
|
||||
}
|
||||
out[i] = ip
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetIPSlice returns the []net.IP value of a flag with the given name
|
||||
func (f *FlagSet) GetIPSlice(name string) ([]net.IP, error) {
|
||||
val, err := f.getFlagType(name, "ipSlice", ipSliceConv)
|
||||
if err != nil {
|
||||
return []net.IP{}, err
|
||||
}
|
||||
return val.([]net.IP), nil
|
||||
}
|
||||
|
||||
// IPSliceVar defines a ipSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []net.IP variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
|
||||
f.VarP(newIPSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
|
||||
f.VarP(newIPSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPSliceVar defines a []net.IP flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []net.IP variable in which to store the value of the flag.
|
||||
func IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
|
||||
CommandLine.VarP(newIPSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
|
||||
CommandLine.VarP(newIPSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []net.IP variable that stores the value of that flag.
|
||||
func (f *FlagSet) IPSlice(name string, value []net.IP, usage string) *[]net.IP {
|
||||
p := []net.IP{}
|
||||
f.IPSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
|
||||
p := []net.IP{}
|
||||
f.IPSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []net.IP variable that stores the value of the flag.
|
||||
func IPSlice(name string, value []net.IP, usage string) *[]net.IP {
|
||||
return CommandLine.IPSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
|
||||
return CommandLine.IPSliceP(name, shorthand, value, usage)
|
||||
}
|
2
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
2
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
|
@ -27,8 +27,6 @@ func (*ipNetValue) Type() string {
|
|||
return "ipNet"
|
||||
}
|
||||
|
||||
var _ = strings.TrimSpace
|
||||
|
||||
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
|
||||
*p = val
|
||||
return (*ipNetValue)(p)
|
||||
|
|
4
vendor/github.com/spf13/pflag/string.go
generated
vendored
4
vendor/github.com/spf13/pflag/string.go
generated
vendored
|
@ -1,7 +1,5 @@
|
|||
package pflag
|
||||
|
||||
import "fmt"
|
||||
|
||||
// -- string Value
|
||||
type stringValue string
|
||||
|
||||
|
@ -18,7 +16,7 @@ func (s *stringValue) Type() string {
|
|||
return "string"
|
||||
}
|
||||
|
||||
func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
|
||||
func (s *stringValue) String() string { return string(*s) }
|
||||
|
||||
func stringConv(sval string) (interface{}, error) {
|
||||
return sval, nil
|
||||
|
|
103
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
Normal file
103
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package pflag
|
||||
|
||||
// -- stringArray Value
|
||||
type stringArrayValue struct {
|
||||
value *[]string
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newStringArrayValue(val []string, p *[]string) *stringArrayValue {
|
||||
ssv := new(stringArrayValue)
|
||||
ssv.value = p
|
||||
*ssv.value = val
|
||||
return ssv
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Set(val string) error {
|
||||
if !s.changed {
|
||||
*s.value = []string{val}
|
||||
s.changed = true
|
||||
} else {
|
||||
*s.value = append(*s.value, val)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Type() string {
|
||||
return "stringArray"
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) String() string {
|
||||
str, _ := writeAsCSV(*s.value)
|
||||
return "[" + str + "]"
|
||||
}
|
||||
|
||||
func stringArrayConv(sval string) (interface{}, error) {
|
||||
sval = sval[1 : len(sval)-1]
|
||||
// An empty string would cause a array with one (empty) string
|
||||
if len(sval) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
return readAsCSV(sval)
|
||||
}
|
||||
|
||||
// GetStringArray return the []string value of a flag with the given name
|
||||
func (f *FlagSet) GetStringArray(name string) ([]string, error) {
|
||||
val, err := f.getFlagType(name, "stringArray", stringArrayConv)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return val.([]string), nil
|
||||
}
|
||||
|
||||
// StringArrayVar defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []string variable in which to store the values of the multiple flags.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
|
||||
f.VarP(newStringArrayValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||
f.VarP(newStringArrayValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringArrayVar defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func StringArrayVar(p *[]string, name string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringArray defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringArrayVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringArrayVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringArray defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func StringArray(name string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringArrayP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringArrayP(name, shorthand string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringArrayP(name, shorthand, value, usage)
|
||||
}
|
56
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
56
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
|
@ -1,13 +1,11 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = fmt.Fprint
|
||||
|
||||
// -- stringSlice Value
|
||||
type stringSliceValue struct {
|
||||
value *[]string
|
||||
|
@ -21,10 +19,28 @@ func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
|
|||
return ssv
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) Set(val string) error {
|
||||
func readAsCSV(val string) ([]string, error) {
|
||||
if val == "" {
|
||||
return []string{}, nil
|
||||
}
|
||||
stringReader := strings.NewReader(val)
|
||||
csvReader := csv.NewReader(stringReader)
|
||||
v, err := csvReader.Read()
|
||||
return csvReader.Read()
|
||||
}
|
||||
|
||||
func writeAsCSV(vals []string) (string, error) {
|
||||
b := &bytes.Buffer{}
|
||||
w := csv.NewWriter(b)
|
||||
err := w.Write(vals)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
w.Flush()
|
||||
return strings.TrimSuffix(b.String(), "\n"), nil
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) Set(val string) error {
|
||||
v, err := readAsCSV(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -41,16 +57,18 @@ func (s *stringSliceValue) Type() string {
|
|||
return "stringSlice"
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) String() string { return "[" + strings.Join(*s.value, ",") + "]" }
|
||||
func (s *stringSliceValue) String() string {
|
||||
str, _ := writeAsCSV(*s.value)
|
||||
return "[" + str + "]"
|
||||
}
|
||||
|
||||
func stringSliceConv(sval string) (interface{}, error) {
|
||||
sval = strings.Trim(sval, "[]")
|
||||
sval = sval[1 : len(sval)-1]
|
||||
// An empty string would cause a slice with one (empty) string
|
||||
if len(sval) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
v := strings.Split(sval, ",")
|
||||
return v, nil
|
||||
return readAsCSV(sval)
|
||||
}
|
||||
|
||||
// GetStringSlice return the []string value of a flag with the given name
|
||||
|
@ -64,6 +82,11 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
|
|||
|
||||
// StringSliceVar defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
f.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
@ -75,6 +98,11 @@ func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []s
|
|||
|
||||
// StringSliceVar defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
@ -86,6 +114,11 @@ func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage
|
|||
|
||||
// StringSlice defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringSliceVarP(&p, name, "", value, usage)
|
||||
|
@ -101,6 +134,11 @@ func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage str
|
|||
|
||||
// StringSlice defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func StringSlice(name string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringSliceP(name, "", value, usage)
|
||||
}
|
||||
|
|
7
vendor/github.com/spf13/pflag/uint.go
generated
vendored
7
vendor/github.com/spf13/pflag/uint.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint Value
|
||||
type uintValue uint
|
||||
|
@ -23,7 +20,7 @@ func (i *uintValue) Type() string {
|
|||
return "uint"
|
||||
}
|
||||
|
||||
func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uintConv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 0)
|
||||
|
|
9
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
9
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint16 value
|
||||
type uint16Value uint16
|
||||
|
@ -12,7 +9,7 @@ func newUint16Value(val uint16, p *uint16) *uint16Value {
|
|||
*p = val
|
||||
return (*uint16Value)(p)
|
||||
}
|
||||
func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) }
|
||||
|
||||
func (i *uint16Value) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 16)
|
||||
*i = uint16Value(v)
|
||||
|
@ -23,6 +20,8 @@ func (i *uint16Value) Type() string {
|
|||
return "uint16"
|
||||
}
|
||||
|
||||
func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint16Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 16)
|
||||
if err != nil {
|
||||
|
|
11
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
11
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
|
@ -1,18 +1,15 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint16 value
|
||||
// -- uint32 value
|
||||
type uint32Value uint32
|
||||
|
||||
func newUint32Value(val uint32, p *uint32) *uint32Value {
|
||||
*p = val
|
||||
return (*uint32Value)(p)
|
||||
}
|
||||
func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) }
|
||||
|
||||
func (i *uint32Value) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 32)
|
||||
*i = uint32Value(v)
|
||||
|
@ -23,6 +20,8 @@ func (i *uint32Value) Type() string {
|
|||
return "uint32"
|
||||
}
|
||||
|
||||
func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 32)
|
||||
if err != nil {
|
||||
|
|
7
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
7
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint64 Value
|
||||
type uint64Value uint64
|
||||
|
@ -23,7 +20,7 @@ func (i *uint64Value) Type() string {
|
|||
return "uint64"
|
||||
}
|
||||
|
||||
func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint64Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 64)
|
||||
|
|
7
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
7
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint8 Value
|
||||
type uint8Value uint8
|
||||
|
@ -23,7 +20,7 @@ func (i *uint8Value) Type() string {
|
|||
return "uint8"
|
||||
}
|
||||
|
||||
func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint8Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 8)
|
||||
|
|
126
vendor/github.com/spf13/pflag/uint_slice.go
generated
vendored
Normal file
126
vendor/github.com/spf13/pflag/uint_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- uintSlice Value
|
||||
type uintSliceValue struct {
|
||||
value *[]uint
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newUintSliceValue(val []uint, p *[]uint) *uintSliceValue {
|
||||
uisv := new(uintSliceValue)
|
||||
uisv.value = p
|
||||
*uisv.value = val
|
||||
return uisv
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]uint, len(ss))
|
||||
for i, d := range ss {
|
||||
u, err := strconv.ParseUint(d, 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out[i] = uint(u)
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) Type() string {
|
||||
return "uintSlice"
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%d", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func uintSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []uint{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]uint, len(ss))
|
||||
for i, d := range ss {
|
||||
u, err := strconv.ParseUint(d, 10, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = uint(u)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetUintSlice returns the []uint value of a flag with the given name.
|
||||
func (f *FlagSet) GetUintSlice(name string) ([]uint, error) {
|
||||
val, err := f.getFlagType(name, "uintSlice", uintSliceConv)
|
||||
if err != nil {
|
||||
return []uint{}, err
|
||||
}
|
||||
return val.([]uint), nil
|
||||
}
|
||||
|
||||
// UintSliceVar defines a uintSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []uint variable in which to store the value of the flag.
|
||||
func (f *FlagSet) UintSliceVar(p *[]uint, name string, value []uint, usage string) {
|
||||
f.VarP(newUintSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// UintSliceVarP is like UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
|
||||
f.VarP(newUintSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// UintSliceVar defines a uint[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint[] variable in which to store the value of the flag.
|
||||
func UintSliceVar(p *[]uint, name string, value []uint, usage string) {
|
||||
CommandLine.VarP(newUintSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// UintSliceVarP is like the UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
|
||||
CommandLine.VarP(newUintSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// UintSlice defines a []uint flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []uint variable that stores the value of the flag.
|
||||
func (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint {
|
||||
p := []uint{}
|
||||
f.UintSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
|
||||
p := []uint{}
|
||||
f.UintSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// UintSlice defines a []uint flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []uint variable that stores the value of the flag.
|
||||
func UintSlice(name string, value []uint, usage string) *[]uint {
|
||||
return CommandLine.UintSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
|
||||
return CommandLine.UintSliceP(name, shorthand, value, usage)
|
||||
}
|
201
vendor/gopkg.in/validator.v2/LICENSE
generated
vendored
Normal file
201
vendor/gopkg.in/validator.v2/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
271
vendor/gopkg.in/validator.v2/builtins.go
generated
vendored
Normal file
271
vendor/gopkg.in/validator.v2/builtins.go
generated
vendored
Normal file
|
@ -0,0 +1,271 @@
|
|||
// Package validator implements value validations
|
||||
//
|
||||
// Copyright 2014 Roberto Teixeira <robteix@robteix.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validator
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// nonzero tests whether a variable value non-zero
|
||||
// as defined by the golang spec.
|
||||
func nonzero(v interface{}, param string) error {
|
||||
st := reflect.ValueOf(v)
|
||||
valid := true
|
||||
switch st.Kind() {
|
||||
case reflect.String:
|
||||
valid = len(st.String()) != 0
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
valid = !st.IsNil()
|
||||
case reflect.Slice, reflect.Map, reflect.Array:
|
||||
valid = st.Len() != 0
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
valid = st.Int() != 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
valid = st.Uint() != 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
valid = st.Float() != 0
|
||||
case reflect.Bool:
|
||||
valid = st.Bool()
|
||||
case reflect.Invalid:
|
||||
valid = false // always invalid
|
||||
case reflect.Struct:
|
||||
valid = true // always valid since only nil pointers are empty
|
||||
default:
|
||||
return ErrUnsupported
|
||||
}
|
||||
|
||||
if !valid {
|
||||
return ErrZeroValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// length tests whether a variable's length is equal to a given
|
||||
// value. For strings it tests the number of characters whereas
|
||||
// for maps and slices it tests the number of items.
|
||||
func length(v interface{}, param string) error {
|
||||
st := reflect.ValueOf(v)
|
||||
valid := true
|
||||
if st.Kind() == reflect.Ptr {
|
||||
if st.IsNil() {
|
||||
return nil
|
||||
}
|
||||
st = st.Elem()
|
||||
}
|
||||
switch st.Kind() {
|
||||
case reflect.String:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
valid = int64(len(st.String())) == p
|
||||
case reflect.Slice, reflect.Map, reflect.Array:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
valid = int64(st.Len()) == p
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
valid = st.Int() == p
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
p, err := asUint(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
valid = st.Uint() == p
|
||||
case reflect.Float32, reflect.Float64:
|
||||
p, err := asFloat(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
valid = st.Float() == p
|
||||
default:
|
||||
return ErrUnsupported
|
||||
}
|
||||
if !valid {
|
||||
return ErrLen
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// min tests whether a variable value is larger or equal to a given
|
||||
// number. For number types, it's a simple lesser-than test; for
|
||||
// strings it tests the number of characters whereas for maps
|
||||
// and slices it tests the number of items.
|
||||
func min(v interface{}, param string) error {
|
||||
st := reflect.ValueOf(v)
|
||||
invalid := false
|
||||
if st.Kind() == reflect.Ptr {
|
||||
if st.IsNil() {
|
||||
return nil
|
||||
}
|
||||
st = st.Elem()
|
||||
}
|
||||
switch st.Kind() {
|
||||
case reflect.String:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = int64(len(st.String())) < p
|
||||
case reflect.Slice, reflect.Map, reflect.Array:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = int64(st.Len()) < p
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = st.Int() < p
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
p, err := asUint(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = st.Uint() < p
|
||||
case reflect.Float32, reflect.Float64:
|
||||
p, err := asFloat(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = st.Float() < p
|
||||
default:
|
||||
return ErrUnsupported
|
||||
}
|
||||
if invalid {
|
||||
return ErrMin
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// max tests whether a variable value is lesser than a given
|
||||
// value. For numbers, it's a simple lesser-than test; for
|
||||
// strings it tests the number of characters whereas for maps
|
||||
// and slices it tests the number of items.
|
||||
func max(v interface{}, param string) error {
|
||||
st := reflect.ValueOf(v)
|
||||
var invalid bool
|
||||
if st.Kind() == reflect.Ptr {
|
||||
if st.IsNil() {
|
||||
return nil
|
||||
}
|
||||
st = st.Elem()
|
||||
}
|
||||
switch st.Kind() {
|
||||
case reflect.String:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = int64(len(st.String())) > p
|
||||
case reflect.Slice, reflect.Map, reflect.Array:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = int64(st.Len()) > p
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
p, err := asInt(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = st.Int() > p
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
p, err := asUint(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = st.Uint() > p
|
||||
case reflect.Float32, reflect.Float64:
|
||||
p, err := asFloat(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
invalid = st.Float() > p
|
||||
default:
|
||||
return ErrUnsupported
|
||||
}
|
||||
if invalid {
|
||||
return ErrMax
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// regex is the builtin validation function that checks
|
||||
// whether the string variable matches a regular expression
|
||||
func regex(v interface{}, param string) error {
|
||||
s, ok := v.(string)
|
||||
if !ok {
|
||||
sptr, ok := v.(*string)
|
||||
if !ok {
|
||||
return ErrUnsupported
|
||||
}
|
||||
if sptr == nil {
|
||||
return nil
|
||||
}
|
||||
s = *sptr
|
||||
}
|
||||
|
||||
re, err := regexp.Compile(param)
|
||||
if err != nil {
|
||||
return ErrBadParameter
|
||||
}
|
||||
|
||||
if !re.MatchString(s) {
|
||||
return ErrRegexp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// asInt retuns the parameter as a int64
|
||||
// or panics if it can't convert
|
||||
func asInt(param string) (int64, error) {
|
||||
i, err := strconv.ParseInt(param, 0, 64)
|
||||
if err != nil {
|
||||
return 0, ErrBadParameter
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// asUint retuns the parameter as a uint64
|
||||
// or panics if it can't convert
|
||||
func asUint(param string) (uint64, error) {
|
||||
i, err := strconv.ParseUint(param, 0, 64)
|
||||
if err != nil {
|
||||
return 0, ErrBadParameter
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// asFloat retuns the parameter as a float64
|
||||
// or panics if it can't convert
|
||||
func asFloat(param string) (float64, error) {
|
||||
i, err := strconv.ParseFloat(param, 64)
|
||||
if err != nil {
|
||||
return 0.0, ErrBadParameter
|
||||
}
|
||||
return i, nil
|
||||
}
|
265
vendor/gopkg.in/validator.v2/doc.go
generated
vendored
Normal file
265
vendor/gopkg.in/validator.v2/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,265 @@
|
|||
// Package validator implements value validations
|
||||
//
|
||||
// Copyright 2014 Roberto Teixeira <robteix@robteix.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
Package validator implements value validations based on struct tags.
|
||||
|
||||
In code it is often necessary to validate that a given value is valid before
|
||||
using it for something. A typical example might be something like this.
|
||||
|
||||
if age < 18 {
|
||||
return error.New("age cannot be under 18")
|
||||
}
|
||||
|
||||
This is a simple enough example, but it can get significantly more complex,
|
||||
especially when dealing with structs.
|
||||
|
||||
l := len(strings.Trim(s.Username))
|
||||
if l < 3 || l > 40 || !regexp.MatchString("^[a-zA-Z]$", s.Username) || s.Age < 18 || s.Password {
|
||||
return errors.New("Invalid request")
|
||||
}
|
||||
|
||||
You get the idea. Package validator allows one to define valid values as
|
||||
struct tags when defining a new struct type.
|
||||
|
||||
type NewUserRequest struct {
|
||||
Username string `validate:"min=3,max=40,regexp=^[a-zA-Z]*$"`
|
||||
Name string `validate:"nonzero"`
|
||||
Age int `validate:"min=18"`
|
||||
Password string `validate:"min=8"`
|
||||
}
|
||||
|
||||
Then validating a variable of type NewUserRequest becomes trivial.
|
||||
|
||||
nur := NewUserRequest{Username: "something", ...}
|
||||
if errs := validator.Validate(nur); errs != nil {
|
||||
// do something
|
||||
}
|
||||
|
||||
Builtin validator functions
|
||||
|
||||
Here is the list of validator functions builtin in the package.
|
||||
|
||||
len
|
||||
For numeric numbers, len will simply make sure that the value is
|
||||
equal to the parameter given. For strings, it checks that
|
||||
the string length is exactly that number of characters. For slices,
|
||||
arrays, and maps, validates the number of items. (Usage: len=10)
|
||||
|
||||
max
|
||||
For numeric numbers, max will simply make sure that the value is
|
||||
lesser or equal to the parameter given. For strings, it checks that
|
||||
the string length is at most that number of characters. For slices,
|
||||
arrays, and maps, validates the number of items. (Usage: max=10)
|
||||
|
||||
min
|
||||
For numeric numbers, min will simply make sure that the value is
|
||||
greater or equal to the parameter given. For strings, it checks that
|
||||
the string length is at least that number of characters. For slices,
|
||||
arrays, and maps, validates the number of items. (Usage: min=10)
|
||||
|
||||
nonzero
|
||||
This validates that the value is not zero. The appropriate zero value
|
||||
is given by the Go spec (e.g. for int it's 0, for string it's "", for
|
||||
pointers is nil, etc.) Usage: nonzero
|
||||
|
||||
regexp
|
||||
Only valid for string types, it will validate that the value matches
|
||||
the regular expression provided as parameter. (Usage: regexp=^a.*b$)
|
||||
|
||||
|
||||
Note that there are no tests to prevent conflicting validator parameters. For
|
||||
instance, these fields will never be valid.
|
||||
|
||||
...
|
||||
A int `validate:"max=0,min=1"`
|
||||
B string `validate:"len=10,regexp=^$"
|
||||
...
|
||||
|
||||
Custom validation functions
|
||||
|
||||
It is possible to define custom validation functions by using SetValidationFunc.
|
||||
First, one needs to create a validation function.
|
||||
|
||||
// Very simple validation func
|
||||
func notZZ(v interface{}, param string) error {
|
||||
st := reflect.ValueOf(v)
|
||||
if st.Kind() != reflect.String {
|
||||
return validate.ErrUnsupported
|
||||
}
|
||||
if st.String() == "ZZ" {
|
||||
return errors.New("value cannot be ZZ")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Then one needs to add it to the list of validation funcs and give it a "tag" name.
|
||||
|
||||
validate.SetValidationFunc("notzz", notZZ)
|
||||
|
||||
Then it is possible to use the notzz validation tag. This will print
|
||||
"Field A error: value cannot be ZZ"
|
||||
|
||||
type T struct {
|
||||
A string `validate:"nonzero,notzz"`
|
||||
}
|
||||
t := T{"ZZ"}
|
||||
if errs := validator.Validate(t); errs != nil {
|
||||
fmt.Printf("Field A error: %s\n", errs["A"][0])
|
||||
}
|
||||
|
||||
To use parameters, it is very similar.
|
||||
|
||||
// Very simple validator with parameter
|
||||
func notSomething(v interface{}, param string) error {
|
||||
st := reflect.ValueOf(v)
|
||||
if st.Kind() != reflect.String {
|
||||
return validate.ErrUnsupported
|
||||
}
|
||||
if st.String() == param {
|
||||
return errors.New("value cannot be " + param)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
And then the code below should print "Field A error: value cannot be ABC".
|
||||
|
||||
validator.SetValidationFunc("notsomething", notSomething)
|
||||
type T struct {
|
||||
A string `validate:"notsomething=ABC"`
|
||||
}
|
||||
t := T{"ABC"}
|
||||
if errs := validator.Validate(t); errs != nil {
|
||||
fmt.Printf("Field A error: %s\n", errs["A"][0])
|
||||
}
|
||||
|
||||
As well, it is possible to overwrite builtin validation functions.
|
||||
|
||||
validate.SetValidationFunc("min", myMinFunc)
|
||||
|
||||
And you can delete a validation function by setting it to nil.
|
||||
|
||||
validate.SetValidationFunc("notzz", nil)
|
||||
validate.SetValidationFunc("nonzero", nil)
|
||||
|
||||
Using a non-existing validation func in a field tag will always return
|
||||
false and with error validate.ErrUnknownTag.
|
||||
|
||||
Finally, package validator also provides a helper function that can be used
|
||||
to validate simple variables/values.
|
||||
|
||||
// errs: nil
|
||||
errs = validator.Valid(42, "min=10, max=50")
|
||||
|
||||
// errs: [validate.ErrZeroValue]
|
||||
errs = validator.Valid(nil, "nonzero")
|
||||
|
||||
// errs: [validate.ErrMin,validate.ErrMax]
|
||||
errs = validator.Valid("hi", "nonzero,min=3,max=2")
|
||||
|
||||
Custom tag name
|
||||
|
||||
In case there is a reason why one would not wish to use tag 'validate' (maybe due to
|
||||
a conflict with a different package), it is possible to tell the package to use
|
||||
a different tag.
|
||||
|
||||
validator.SetTag("valid")
|
||||
|
||||
Then.
|
||||
|
||||
Type T struct {
|
||||
A int `valid:"min=8, max=10"`
|
||||
B string `valid:"nonzero"`
|
||||
}
|
||||
|
||||
SetTag is permanent. The new tag name will be used until it is again changed
|
||||
with a new call to SetTag. A way to temporarily use a different tag exists.
|
||||
|
||||
validator.WithTag("foo").Validate(t)
|
||||
validator.WithTag("bar").Validate(t)
|
||||
// But this will go back to using 'validate'
|
||||
validator.Validate(t)
|
||||
|
||||
Multiple validators
|
||||
|
||||
You may often need to have a different set of validation
|
||||
rules for different situations. In all the examples above,
|
||||
we only used the default validator but you could create a
|
||||
new one and set specific rules for it.
|
||||
|
||||
For instance, you might use the same struct to decode incoming JSON for a REST API
|
||||
but your needs will change when you're using it to, say, create a new instance
|
||||
in storage vs. when you need to change something.
|
||||
|
||||
type User struct {
|
||||
Username string `validate:"nonzero"`
|
||||
Name string `validate:"nonzero"`
|
||||
Age int `validate:"nonzero"`
|
||||
Password string `validate:"nonzero"`
|
||||
}
|
||||
|
||||
Maybe when creating a new user, you need to make sure all values in the struct are filled,
|
||||
but then you use the same struct to handle incoming requests to, say, change the password,
|
||||
in which case you only need the Username and the Password and don't care for the others.
|
||||
You might use two different validators.
|
||||
|
||||
type User struct {
|
||||
Username string `creating:"nonzero" chgpw:"nonzero"`
|
||||
Name string `creating:"nonzero"`
|
||||
Age int `creating:"nonzero"`
|
||||
Password string `creating:"nonzero" chgpw:"nonzero"`
|
||||
}
|
||||
|
||||
var (
|
||||
creationValidator = validator.NewValidator()
|
||||
chgPwValidator = validator.NewValidator()
|
||||
)
|
||||
|
||||
func init() {
|
||||
creationValidator.SetTag("creating")
|
||||
chgPwValidator.SetTag("chgpw")
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var u User
|
||||
json.NewDecoder(r.Body).Decode(&user)
|
||||
if errs := creationValidator.Validate(user); errs != nil {
|
||||
// the request did not include all of the User
|
||||
// struct fields, so send a http.StatusBadRequest
|
||||
// back or something
|
||||
}
|
||||
// create the new user
|
||||
}
|
||||
|
||||
func SetNewUserPasswordHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var u User
|
||||
json.NewDecoder(r.Body).Decode(&user)
|
||||
if errs := chgPwValidator.Validate(user); errs != nil {
|
||||
// the request did not Username and Password,
|
||||
// so send a http.StatusBadRequest
|
||||
// back or something
|
||||
}
|
||||
// save the new password
|
||||
}
|
||||
|
||||
It is also possible to do all of that using only the default validator as long
|
||||
as SetTag is always called before calling validator.Validate() or you chain the
|
||||
with WithTag().
|
||||
|
||||
*/
|
||||
package validator
|
369
vendor/gopkg.in/validator.v2/validator.go
generated
vendored
Normal file
369
vendor/gopkg.in/validator.v2/validator.go
generated
vendored
Normal file
|
@ -0,0 +1,369 @@
|
|||
// Package validator implements value validations
|
||||
//
|
||||
// Copyright 2014 Roberto Teixeira <robteix@robteix.com>
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package validator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// TextErr is an error that also implements the TextMarshaller interface for
|
||||
// serializing out to various plain text encodings. Packages creating their
|
||||
// own custom errors should use TextErr if they're intending to use serializing
|
||||
// formats like json, msgpack etc.
|
||||
type TextErr struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (t TextErr) Error() string {
|
||||
return t.Err.Error()
|
||||
}
|
||||
|
||||
// MarshalText implements the TextMarshaller
|
||||
func (t TextErr) MarshalText() ([]byte, error) {
|
||||
return []byte(t.Err.Error()), nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrZeroValue is the error returned when variable has zero valud
|
||||
// and nonzero was specified
|
||||
ErrZeroValue = TextErr{errors.New("zero value")}
|
||||
// ErrMin is the error returned when variable is less than mininum
|
||||
// value specified
|
||||
ErrMin = TextErr{errors.New("less than min")}
|
||||
// ErrMax is the error returned when variable is more than
|
||||
// maximum specified
|
||||
ErrMax = TextErr{errors.New("greater than max")}
|
||||
// ErrLen is the error returned when length is not equal to
|
||||
// param specified
|
||||
ErrLen = TextErr{errors.New("invalid length")}
|
||||
// ErrRegexp is the error returned when the value does not
|
||||
// match the provided regular expression parameter
|
||||
ErrRegexp = TextErr{errors.New("regular expression mismatch")}
|
||||
// ErrUnsupported is the error error returned when a validation rule
|
||||
// is used with an unsupported variable type
|
||||
ErrUnsupported = TextErr{errors.New("unsupported type")}
|
||||
// ErrBadParameter is the error returned when an invalid parameter
|
||||
// is provided to a validation rule (e.g. a string where an int was
|
||||
// expected (max=foo,len=bar) or missing a parameter when one is required (len=))
|
||||
ErrBadParameter = TextErr{errors.New("bad parameter")}
|
||||
// ErrUnknownTag is the error returned when an unknown tag is found
|
||||
ErrUnknownTag = TextErr{errors.New("unknown tag")}
|
||||
// ErrInvalid is the error returned when variable is invalid
|
||||
// (normally a nil pointer)
|
||||
ErrInvalid = TextErr{errors.New("invalid value")}
|
||||
)
|
||||
|
||||
// ErrorMap is a map which contains all errors from validating a struct.
|
||||
type ErrorMap map[string]ErrorArray
|
||||
|
||||
// ErrorMap implements the Error interface so we can check error against nil.
|
||||
// The returned error is if existent the first error which was added to the map.
|
||||
func (err ErrorMap) Error() string {
|
||||
for k, errs := range err {
|
||||
if len(errs) > 0 {
|
||||
return fmt.Sprintf("%s: %s", k, errs.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// ErrorArray is a slice of errors returned by the Validate function.
|
||||
type ErrorArray []error
|
||||
|
||||
// ErrorArray implements the Error interface and returns the first error as
|
||||
// string if existent.
|
||||
func (err ErrorArray) Error() string {
|
||||
if len(err) > 0 {
|
||||
return err[0].Error()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ValidationFunc is a function that receives the value of a
|
||||
// field and a parameter used for the respective validation tag.
|
||||
type ValidationFunc func(v interface{}, param string) error
|
||||
|
||||
// Validator implements a validator
|
||||
type Validator struct {
|
||||
// Tag name being used.
|
||||
tagName string
|
||||
// validationFuncs is a map of ValidationFuncs indexed
|
||||
// by their name.
|
||||
validationFuncs map[string]ValidationFunc
|
||||
}
|
||||
|
||||
// Helper validator so users can use the
|
||||
// functions directly from the package
|
||||
var defaultValidator = NewValidator()
|
||||
|
||||
// NewValidator creates a new Validator
|
||||
func NewValidator() *Validator {
|
||||
return &Validator{
|
||||
tagName: "validate",
|
||||
validationFuncs: map[string]ValidationFunc{
|
||||
"nonzero": nonzero,
|
||||
"len": length,
|
||||
"min": min,
|
||||
"max": max,
|
||||
"regexp": regex,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// SetTag allows you to change the tag name used in structs
|
||||
func SetTag(tag string) {
|
||||
defaultValidator.SetTag(tag)
|
||||
}
|
||||
|
||||
// SetTag allows you to change the tag name used in structs
|
||||
func (mv *Validator) SetTag(tag string) {
|
||||
mv.tagName = tag
|
||||
}
|
||||
|
||||
// WithTag creates a new Validator with the new tag name. It is
|
||||
// useful to chain-call with Validate so we don't change the tag
|
||||
// name permanently: validator.WithTag("foo").Validate(t)
|
||||
func WithTag(tag string) *Validator {
|
||||
return defaultValidator.WithTag(tag)
|
||||
}
|
||||
|
||||
// WithTag creates a new Validator with the new tag name. It is
|
||||
// useful to chain-call with Validate so we don't change the tag
|
||||
// name permanently: validator.WithTag("foo").Validate(t)
|
||||
func (mv *Validator) WithTag(tag string) *Validator {
|
||||
v := mv.copy()
|
||||
v.SetTag(tag)
|
||||
return v
|
||||
}
|
||||
|
||||
// Copy a validator
|
||||
func (mv *Validator) copy() *Validator {
|
||||
newFuncs := map[string]ValidationFunc{}
|
||||
for k, f := range mv.validationFuncs {
|
||||
newFuncs[k] = f
|
||||
}
|
||||
return &Validator{
|
||||
tagName: mv.tagName,
|
||||
validationFuncs: newFuncs,
|
||||
}
|
||||
}
|
||||
|
||||
// SetValidationFunc sets the function to be used for a given
|
||||
// validation constraint. Calling this function with nil vf
|
||||
// is the same as removing the constraint function from the list.
|
||||
func SetValidationFunc(name string, vf ValidationFunc) error {
|
||||
return defaultValidator.SetValidationFunc(name, vf)
|
||||
}
|
||||
|
||||
// SetValidationFunc sets the function to be used for a given
|
||||
// validation constraint. Calling this function with nil vf
|
||||
// is the same as removing the constraint function from the list.
|
||||
func (mv *Validator) SetValidationFunc(name string, vf ValidationFunc) error {
|
||||
if name == "" {
|
||||
return errors.New("name cannot be empty")
|
||||
}
|
||||
if vf == nil {
|
||||
delete(mv.validationFuncs, name)
|
||||
return nil
|
||||
}
|
||||
mv.validationFuncs[name] = vf
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates the fields of a struct based
|
||||
// on 'validator' tags and returns errors found indexed
|
||||
// by the field name.
|
||||
func Validate(v interface{}) error {
|
||||
return defaultValidator.Validate(v)
|
||||
}
|
||||
|
||||
// Validate validates the fields of a struct based
|
||||
// on 'validator' tags and returns errors found indexed
|
||||
// by the field name.
|
||||
func (mv *Validator) Validate(v interface{}) error {
|
||||
sv := reflect.ValueOf(v)
|
||||
st := reflect.TypeOf(v)
|
||||
if sv.Kind() == reflect.Ptr && !sv.IsNil() {
|
||||
return mv.Validate(sv.Elem().Interface())
|
||||
}
|
||||
if sv.Kind() != reflect.Struct && sv.Kind() != reflect.Interface {
|
||||
return ErrUnsupported
|
||||
}
|
||||
|
||||
nfields := sv.NumField()
|
||||
m := make(ErrorMap)
|
||||
for i := 0; i < nfields; i++ {
|
||||
fname := st.Field(i).Name
|
||||
if !unicode.IsUpper(rune(fname[0])) {
|
||||
continue
|
||||
}
|
||||
|
||||
f := sv.Field(i)
|
||||
// deal with pointers
|
||||
for f.Kind() == reflect.Ptr && !f.IsNil() {
|
||||
f = f.Elem()
|
||||
}
|
||||
tag := st.Field(i).Tag.Get(mv.tagName)
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
var errs ErrorArray
|
||||
|
||||
if tag != "" {
|
||||
err := mv.Valid(f.Interface(), tag)
|
||||
if errors, ok := err.(ErrorArray); ok {
|
||||
errs = errors
|
||||
} else {
|
||||
if err != nil {
|
||||
errs = ErrorArray{err}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mv.deepValidateCollection(f, fname, m) // no-op if field is not a struct, interface, array, slice or map
|
||||
|
||||
if len(errs) > 0 {
|
||||
m[st.Field(i).Name] = errs
|
||||
}
|
||||
}
|
||||
|
||||
if len(m) > 0 {
|
||||
return m
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mv *Validator) deepValidateCollection(f reflect.Value, fname string, m ErrorMap) {
|
||||
switch f.Kind() {
|
||||
case reflect.Struct, reflect.Interface, reflect.Ptr:
|
||||
e := mv.Validate(f.Interface())
|
||||
if e, ok := e.(ErrorMap); ok && len(e) > 0 {
|
||||
for j, k := range e {
|
||||
m[fname+"."+j] = k
|
||||
}
|
||||
}
|
||||
case reflect.Array, reflect.Slice:
|
||||
for i := 0; i < f.Len(); i++ {
|
||||
mv.deepValidateCollection(f.Index(i), fmt.Sprintf("%s[%d]", fname, i), m)
|
||||
}
|
||||
case reflect.Map:
|
||||
for _, key := range f.MapKeys() {
|
||||
mv.deepValidateCollection(key, fmt.Sprintf("%s[%+v](key)", fname, key.Interface()), m) // validate the map key
|
||||
value := f.MapIndex(key)
|
||||
mv.deepValidateCollection(value, fmt.Sprintf("%s[%+v](value)", fname, key.Interface()), m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Valid validates a value based on the provided
|
||||
// tags and returns errors found or nil.
|
||||
func Valid(val interface{}, tags string) error {
|
||||
return defaultValidator.Valid(val, tags)
|
||||
}
|
||||
|
||||
// Valid validates a value based on the provided
|
||||
// tags and returns errors found or nil.
|
||||
func (mv *Validator) Valid(val interface{}, tags string) error {
|
||||
if tags == "-" {
|
||||
return nil
|
||||
}
|
||||
v := reflect.ValueOf(val)
|
||||
if v.Kind() == reflect.Ptr && !v.IsNil() {
|
||||
return mv.Valid(v.Elem().Interface(), tags)
|
||||
}
|
||||
var err error
|
||||
switch v.Kind() {
|
||||
case reflect.Invalid:
|
||||
err = mv.validateVar(nil, tags)
|
||||
default:
|
||||
err = mv.validateVar(val, tags)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// validateVar validates one single variable
|
||||
func (mv *Validator) validateVar(v interface{}, tag string) error {
|
||||
tags, err := mv.parseTags(tag)
|
||||
if err != nil {
|
||||
// unknown tag found, give up.
|
||||
return err
|
||||
}
|
||||
errs := make(ErrorArray, 0, len(tags))
|
||||
for _, t := range tags {
|
||||
if err := t.Fn(v, t.Param); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// tag represents one of the tag items
|
||||
type tag struct {
|
||||
Name string // name of the tag
|
||||
Fn ValidationFunc // validation function to call
|
||||
Param string // parameter to send to the validation function
|
||||
}
|
||||
|
||||
// separate by no escaped commas
|
||||
var sepPattern *regexp.Regexp = regexp.MustCompile(`((?:^|[^\\])(?:\\\\)*),`)
|
||||
|
||||
func splitUnescapedComma(str string) []string {
|
||||
ret := []string{}
|
||||
indexes := sepPattern.FindAllStringIndex(str, -1)
|
||||
last := 0
|
||||
for _, is := range indexes {
|
||||
ret = append(ret, str[last:is[1]-1])
|
||||
last = is[1]
|
||||
}
|
||||
ret = append(ret, str[last:])
|
||||
return ret
|
||||
}
|
||||
|
||||
// parseTags parses all individual tags found within a struct tag.
|
||||
func (mv *Validator) parseTags(t string) ([]tag, error) {
|
||||
tl := splitUnescapedComma(t)
|
||||
tags := make([]tag, 0, len(tl))
|
||||
for _, i := range tl {
|
||||
i = strings.Replace(i, `\,`, ",", -1)
|
||||
tg := tag{}
|
||||
v := strings.SplitN(i, "=", 2)
|
||||
tg.Name = strings.Trim(v[0], " ")
|
||||
if tg.Name == "" {
|
||||
return []tag{}, ErrUnknownTag
|
||||
}
|
||||
if len(v) > 1 {
|
||||
tg.Param = strings.Trim(v[1], " ")
|
||||
}
|
||||
var found bool
|
||||
if tg.Fn, found = mv.validationFuncs[tg.Name]; !found {
|
||||
return []tag{}, ErrUnknownTag
|
||||
}
|
||||
tags = append(tags, tg)
|
||||
|
||||
}
|
||||
return tags, nil
|
||||
}
|
325
vendor/gopkg.in/yaml.v2/LICENSE
generated
vendored
325
vendor/gopkg.in/yaml.v2/LICENSE
generated
vendored
|
@ -1,188 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
Copyright (c) 2011-2014 - Canonical Inc.
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
This software is licensed under the LGPLv3, included below.
|
||||
1. Definitions.
|
||||
|
||||
As a special exception to the GNU Lesser General Public License version 3
|
||||
("LGPL3"), the copyright holders of this Library give you permission to
|
||||
convey to a third party a Combined Work that links statically or dynamically
|
||||
to this Library without providing any Minimal Corresponding Source or
|
||||
Minimal Application Code as set out in 4d or providing the installation
|
||||
information set out in section 4e, provided that you comply with the other
|
||||
provisions of LGPL3 and provided that you meet, for the Application the
|
||||
terms and conditions of the license(s) which apply to the Application.
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
Except as stated in this special exception, the provisions of LGPL3 will
|
||||
continue to comply in full to this Library. If you modify this Library, you
|
||||
may apply this exception to your version of this Library, but you are not
|
||||
obliged to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version. This exception does not (and cannot) modify any
|
||||
license terms which apply to the Application, with which you must still
|
||||
comply.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
0. Additional Definitions.
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
4. Combined Works.
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
13
vendor/gopkg.in/yaml.v2/NOTICE
generated
vendored
Normal file
13
vendor/gopkg.in/yaml.v2/NOTICE
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright 2011-2016 Canonical Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
131
vendor/gopkg.in/yaml.v2/README.md
generated
vendored
131
vendor/gopkg.in/yaml.v2/README.md
generated
vendored
|
@ -1,131 +0,0 @@
|
|||
# YAML support for the Go language
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The yaml package enables Go programs to comfortably encode and decode YAML
|
||||
values. It was developed within [Canonical](https://www.canonical.com) as
|
||||
part of the [juju](https://juju.ubuntu.com) project, and is based on a
|
||||
pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
|
||||
C library to parse and generate YAML data quickly and reliably.
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
|
||||
The yaml package supports most of YAML 1.1 and 1.2, including support for
|
||||
anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
|
||||
implemented, and base-60 floats from YAML 1.1 are purposefully not
|
||||
supported since they're a poor design and are gone in YAML 1.2.
|
||||
|
||||
Installation and usage
|
||||
----------------------
|
||||
|
||||
The import path for the package is *gopkg.in/yaml.v2*.
|
||||
|
||||
To install it, run:
|
||||
|
||||
go get gopkg.in/yaml.v2
|
||||
|
||||
API documentation
|
||||
-----------------
|
||||
|
||||
If opened in a browser, the import path itself leads to the API documentation:
|
||||
|
||||
* [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
|
||||
|
||||
API stability
|
||||
-------------
|
||||
|
||||
The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```Go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var data = `
|
||||
a: Easy!
|
||||
b:
|
||||
c: 2
|
||||
d: [3, 4]
|
||||
`
|
||||
|
||||
type T struct {
|
||||
A string
|
||||
B struct {
|
||||
RenamedC int `yaml:"c"`
|
||||
D []int `yaml:",flow"`
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
t := T{}
|
||||
|
||||
err := yaml.Unmarshal([]byte(data), &t)
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
fmt.Printf("--- t:\n%v\n\n", t)
|
||||
|
||||
d, err := yaml.Marshal(&t)
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
fmt.Printf("--- t dump:\n%s\n\n", string(d))
|
||||
|
||||
m := make(map[interface{}]interface{})
|
||||
|
||||
err = yaml.Unmarshal([]byte(data), &m)
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
fmt.Printf("--- m:\n%v\n\n", m)
|
||||
|
||||
d, err = yaml.Marshal(&m)
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
fmt.Printf("--- m dump:\n%s\n\n", string(d))
|
||||
}
|
||||
```
|
||||
|
||||
This example will generate the following output:
|
||||
|
||||
```
|
||||
--- t:
|
||||
{Easy! {2 [3 4]}}
|
||||
|
||||
--- t dump:
|
||||
a: Easy!
|
||||
b:
|
||||
c: 2
|
||||
d: [3, 4]
|
||||
|
||||
|
||||
--- m:
|
||||
map[a:Easy! b:map[c:2 d:[3 4]]]
|
||||
|
||||
--- m dump:
|
||||
a: Easy!
|
||||
b:
|
||||
c: 2
|
||||
d:
|
||||
- 3
|
||||
- 4
|
||||
```
|
||||
|
55
vendor/gopkg.in/yaml.v2/apic.go
generated
vendored
55
vendor/gopkg.in/yaml.v2/apic.go
generated
vendored
|
@ -2,7 +2,6 @@ package yaml
|
|||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
|
||||
|
@ -48,9 +47,9 @@ func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err
|
|||
return n, nil
|
||||
}
|
||||
|
||||
// File read handler.
|
||||
func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
|
||||
return parser.input_file.Read(buffer)
|
||||
// Reader read handler.
|
||||
func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
|
||||
return parser.input_reader.Read(buffer)
|
||||
}
|
||||
|
||||
// Set a string input.
|
||||
|
@ -64,12 +63,12 @@ func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
|
|||
}
|
||||
|
||||
// Set a file input.
|
||||
func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
|
||||
func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
|
||||
if parser.read_handler != nil {
|
||||
panic("must set the input source only once")
|
||||
}
|
||||
parser.read_handler = yaml_file_read_handler
|
||||
parser.input_file = file
|
||||
parser.read_handler = yaml_reader_read_handler
|
||||
parser.input_reader = r
|
||||
}
|
||||
|
||||
// Set the source encoding.
|
||||
|
@ -81,14 +80,13 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
|
|||
}
|
||||
|
||||
// Create a new emitter object.
|
||||
func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
|
||||
func yaml_emitter_initialize(emitter *yaml_emitter_t) {
|
||||
*emitter = yaml_emitter_t{
|
||||
buffer: make([]byte, output_buffer_size),
|
||||
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
||||
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
||||
events: make([]yaml_event_t, 0, initial_queue_size),
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Destroy an emitter object.
|
||||
|
@ -102,9 +100,10 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// File write handler.
|
||||
func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
||||
_, err := emitter.output_file.Write(buffer)
|
||||
// yaml_writer_write_handler uses emitter.output_writer to write the
|
||||
// emitted text.
|
||||
func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
||||
_, err := emitter.output_writer.Write(buffer)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -118,12 +117,12 @@ func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]by
|
|||
}
|
||||
|
||||
// Set a file output.
|
||||
func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
|
||||
func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
|
||||
if emitter.write_handler != nil {
|
||||
panic("must set the output target only once")
|
||||
}
|
||||
emitter.write_handler = yaml_file_write_handler
|
||||
emitter.output_file = file
|
||||
emitter.write_handler = yaml_writer_write_handler
|
||||
emitter.output_writer = w
|
||||
}
|
||||
|
||||
// Set the output encoding.
|
||||
|
@ -252,41 +251,41 @@ func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
|
|||
//
|
||||
|
||||
// Create STREAM-START.
|
||||
func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
|
||||
func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_STREAM_START_EVENT,
|
||||
encoding: encoding,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create STREAM-END.
|
||||
func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
|
||||
func yaml_stream_end_event_initialize(event *yaml_event_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_STREAM_END_EVENT,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create DOCUMENT-START.
|
||||
func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
|
||||
tag_directives []yaml_tag_directive_t, implicit bool) bool {
|
||||
func yaml_document_start_event_initialize(
|
||||
event *yaml_event_t,
|
||||
version_directive *yaml_version_directive_t,
|
||||
tag_directives []yaml_tag_directive_t,
|
||||
implicit bool,
|
||||
) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_DOCUMENT_START_EVENT,
|
||||
version_directive: version_directive,
|
||||
tag_directives: tag_directives,
|
||||
implicit: implicit,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create DOCUMENT-END.
|
||||
func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
|
||||
func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_DOCUMENT_END_EVENT,
|
||||
implicit: implicit,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
///*
|
||||
|
@ -348,7 +347,7 @@ func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
|
|||
}
|
||||
|
||||
// Create MAPPING-START.
|
||||
func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
|
||||
func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_MAPPING_START_EVENT,
|
||||
anchor: anchor,
|
||||
|
@ -356,15 +355,13 @@ func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte
|
|||
implicit: implicit,
|
||||
style: yaml_style_t(style),
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create MAPPING-END.
|
||||
func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
|
||||
func yaml_mapping_end_event_initialize(event *yaml_event_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_MAPPING_END_EVENT,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Destroy an event object.
|
||||
|
@ -471,7 +468,7 @@ func yaml_event_delete(event *yaml_event_t) {
|
|||
// } context
|
||||
// tag_directive *yaml_tag_directive_t
|
||||
//
|
||||
// context.error = YAML_NO_ERROR // Eliminate a compliler warning.
|
||||
// context.error = YAML_NO_ERROR // Eliminate a compiler warning.
|
||||
//
|
||||
// assert(document) // Non-NULL document object is expected.
|
||||
//
|
||||
|
|
226
vendor/gopkg.in/yaml.v2/decode.go
generated
vendored
226
vendor/gopkg.in/yaml.v2/decode.go
generated
vendored
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
@ -22,6 +23,8 @@ type node struct {
|
|||
kind int
|
||||
line, column int
|
||||
tag string
|
||||
// For an alias node, alias holds the resolved alias.
|
||||
alias *node
|
||||
value string
|
||||
implicit bool
|
||||
children []*node
|
||||
|
@ -35,6 +38,7 @@ type parser struct {
|
|||
parser yaml_parser_t
|
||||
event yaml_event_t
|
||||
doc *node
|
||||
doneInit bool
|
||||
}
|
||||
|
||||
func newParser(b []byte) *parser {
|
||||
|
@ -42,21 +46,30 @@ func newParser(b []byte) *parser {
|
|||
if !yaml_parser_initialize(&p.parser) {
|
||||
panic("failed to initialize YAML emitter")
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
b = []byte{'\n'}
|
||||
}
|
||||
|
||||
yaml_parser_set_input_string(&p.parser, b)
|
||||
|
||||
p.skip()
|
||||
if p.event.typ != yaml_STREAM_START_EVENT {
|
||||
panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
|
||||
}
|
||||
p.skip()
|
||||
return &p
|
||||
}
|
||||
|
||||
func newParserFromReader(r io.Reader) *parser {
|
||||
p := parser{}
|
||||
if !yaml_parser_initialize(&p.parser) {
|
||||
panic("failed to initialize YAML emitter")
|
||||
}
|
||||
yaml_parser_set_input_reader(&p.parser, r)
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p *parser) init() {
|
||||
if p.doneInit {
|
||||
return
|
||||
}
|
||||
p.expect(yaml_STREAM_START_EVENT)
|
||||
p.doneInit = true
|
||||
}
|
||||
|
||||
func (p *parser) destroy() {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
yaml_event_delete(&p.event)
|
||||
|
@ -64,16 +77,35 @@ func (p *parser) destroy() {
|
|||
yaml_parser_delete(&p.parser)
|
||||
}
|
||||
|
||||
func (p *parser) skip() {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
// expect consumes an event from the event stream and
|
||||
// checks that it's of the expected type.
|
||||
func (p *parser) expect(e yaml_event_type_t) {
|
||||
if p.event.typ == yaml_NO_EVENT {
|
||||
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||
p.fail()
|
||||
}
|
||||
}
|
||||
if p.event.typ == yaml_STREAM_END_EVENT {
|
||||
failf("attempted to go past the end of stream; corrupted value?")
|
||||
}
|
||||
if p.event.typ != e {
|
||||
p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
|
||||
p.fail()
|
||||
}
|
||||
yaml_event_delete(&p.event)
|
||||
p.event.typ = yaml_NO_EVENT
|
||||
}
|
||||
|
||||
// peek peeks at the next event in the event stream,
|
||||
// puts the results into p.event and returns the event type.
|
||||
func (p *parser) peek() yaml_event_type_t {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
return p.event.typ
|
||||
}
|
||||
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||
p.fail()
|
||||
}
|
||||
return p.event.typ
|
||||
}
|
||||
|
||||
func (p *parser) fail() {
|
||||
|
@ -81,6 +113,10 @@ func (p *parser) fail() {
|
|||
var line int
|
||||
if p.parser.problem_mark.line != 0 {
|
||||
line = p.parser.problem_mark.line
|
||||
// Scanner errors don't iterate line before returning error
|
||||
if p.parser.error == yaml_SCANNER_ERROR {
|
||||
line++
|
||||
}
|
||||
} else if p.parser.context_mark.line != 0 {
|
||||
line = p.parser.context_mark.line
|
||||
}
|
||||
|
@ -103,7 +139,8 @@ func (p *parser) anchor(n *node, anchor []byte) {
|
|||
}
|
||||
|
||||
func (p *parser) parse() *node {
|
||||
switch p.event.typ {
|
||||
p.init()
|
||||
switch p.peek() {
|
||||
case yaml_SCALAR_EVENT:
|
||||
return p.scalar()
|
||||
case yaml_ALIAS_EVENT:
|
||||
|
@ -118,9 +155,8 @@ func (p *parser) parse() *node {
|
|||
// Happens when attempting to decode an empty buffer.
|
||||
return nil
|
||||
default:
|
||||
panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
|
||||
panic("attempted to parse unknown event: " + p.event.typ.String())
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (p *parser) node(kind int) *node {
|
||||
|
@ -135,19 +171,20 @@ func (p *parser) document() *node {
|
|||
n := p.node(documentNode)
|
||||
n.anchors = make(map[string]*node)
|
||||
p.doc = n
|
||||
p.skip()
|
||||
p.expect(yaml_DOCUMENT_START_EVENT)
|
||||
n.children = append(n.children, p.parse())
|
||||
if p.event.typ != yaml_DOCUMENT_END_EVENT {
|
||||
panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
|
||||
}
|
||||
p.skip()
|
||||
p.expect(yaml_DOCUMENT_END_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) alias() *node {
|
||||
n := p.node(aliasNode)
|
||||
n.value = string(p.event.anchor)
|
||||
p.skip()
|
||||
n.alias = p.doc.anchors[n.value]
|
||||
if n.alias == nil {
|
||||
failf("unknown anchor '%s' referenced", n.value)
|
||||
}
|
||||
p.expect(yaml_ALIAS_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -157,29 +194,29 @@ func (p *parser) scalar() *node {
|
|||
n.tag = string(p.event.tag)
|
||||
n.implicit = p.event.implicit
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
p.expect(yaml_SCALAR_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) sequence() *node {
|
||||
n := p.node(sequenceNode)
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
for p.event.typ != yaml_SEQUENCE_END_EVENT {
|
||||
p.expect(yaml_SEQUENCE_START_EVENT)
|
||||
for p.peek() != yaml_SEQUENCE_END_EVENT {
|
||||
n.children = append(n.children, p.parse())
|
||||
}
|
||||
p.skip()
|
||||
p.expect(yaml_SEQUENCE_END_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) mapping() *node {
|
||||
n := p.node(mappingNode)
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
for p.event.typ != yaml_MAPPING_END_EVENT {
|
||||
p.expect(yaml_MAPPING_START_EVENT)
|
||||
for p.peek() != yaml_MAPPING_END_EVENT {
|
||||
n.children = append(n.children, p.parse(), p.parse())
|
||||
}
|
||||
p.skip()
|
||||
p.expect(yaml_MAPPING_END_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -188,9 +225,10 @@ func (p *parser) mapping() *node {
|
|||
|
||||
type decoder struct {
|
||||
doc *node
|
||||
aliases map[string]bool
|
||||
aliases map[*node]bool
|
||||
mapType reflect.Type
|
||||
terrors []string
|
||||
strict bool
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -198,11 +236,13 @@ var (
|
|||
durationType = reflect.TypeOf(time.Duration(0))
|
||||
defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
|
||||
ifaceType = defaultMapType.Elem()
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
ptrTimeType = reflect.TypeOf(&time.Time{})
|
||||
)
|
||||
|
||||
func newDecoder() *decoder {
|
||||
d := &decoder{mapType: defaultMapType}
|
||||
d.aliases = make(map[string]bool)
|
||||
func newDecoder(strict bool) *decoder {
|
||||
d := &decoder{mapType: defaultMapType, strict: strict}
|
||||
d.aliases = make(map[*node]bool)
|
||||
return d
|
||||
}
|
||||
|
||||
|
@ -251,7 +291,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
|
|||
//
|
||||
// If n holds a null value, prepare returns before doing anything.
|
||||
func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
|
||||
if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
|
||||
if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
|
||||
return out, false, false
|
||||
}
|
||||
again := true
|
||||
|
@ -308,16 +348,13 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
|
||||
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
|
||||
an, ok := d.doc.anchors[n.value]
|
||||
if !ok {
|
||||
failf("unknown anchor '%s' referenced", n.value)
|
||||
}
|
||||
if d.aliases[n.value] {
|
||||
if d.aliases[n] {
|
||||
// TODO this could actually be allowed in some circumstances.
|
||||
failf("anchor '%s' value contains itself", n.value)
|
||||
}
|
||||
d.aliases[n.value] = true
|
||||
good = d.unmarshal(an, out)
|
||||
delete(d.aliases, n.value)
|
||||
d.aliases[n] = true
|
||||
good = d.unmarshal(n.alias, out)
|
||||
delete(d.aliases, n)
|
||||
return good
|
||||
}
|
||||
|
||||
|
@ -329,7 +366,7 @@ func resetMap(out reflect.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||
func (d *decoder) scalar(n *node, out reflect.Value) bool {
|
||||
var tag string
|
||||
var resolved interface{}
|
||||
if n.tag == "" && !n.implicit {
|
||||
|
@ -353,9 +390,26 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
return true
|
||||
}
|
||||
if s, ok := resolved.(string); ok && out.CanAddr() {
|
||||
if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
|
||||
err := u.UnmarshalText([]byte(s))
|
||||
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
||||
// We've resolved to exactly the type we want, so use that.
|
||||
out.Set(resolvedv)
|
||||
return true
|
||||
}
|
||||
// Perhaps we can use the value as a TextUnmarshaler to
|
||||
// set its value.
|
||||
if out.CanAddr() {
|
||||
u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
|
||||
if ok {
|
||||
var text []byte
|
||||
if tag == yaml_BINARY_TAG {
|
||||
text = []byte(resolved.(string))
|
||||
} else {
|
||||
// We let any value be unmarshaled into TextUnmarshaler.
|
||||
// That might be more lax than we'd like, but the
|
||||
// TextUnmarshaler itself should bowl out any dubious values.
|
||||
text = []byte(n.value)
|
||||
}
|
||||
err := u.UnmarshalText(text)
|
||||
if err != nil {
|
||||
fail(err)
|
||||
}
|
||||
|
@ -366,46 +420,54 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
case reflect.String:
|
||||
if tag == yaml_BINARY_TAG {
|
||||
out.SetString(resolved.(string))
|
||||
good = true
|
||||
} else if resolved != nil {
|
||||
return true
|
||||
}
|
||||
if resolved != nil {
|
||||
out.SetString(n.value)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case reflect.Interface:
|
||||
if resolved == nil {
|
||||
out.Set(reflect.Zero(out.Type()))
|
||||
} else if tag == yaml_TIMESTAMP_TAG {
|
||||
// It looks like a timestamp but for backward compatibility
|
||||
// reasons we set it as a string, so that code that unmarshals
|
||||
// timestamp-like values into interface{} will continue to
|
||||
// see a string and not a time.Time.
|
||||
// TODO(v3) Drop this.
|
||||
out.Set(reflect.ValueOf(n.value))
|
||||
} else {
|
||||
out.Set(reflect.ValueOf(resolved))
|
||||
}
|
||||
good = true
|
||||
return true
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch resolved := resolved.(type) {
|
||||
case int:
|
||||
if !out.OverflowInt(int64(resolved)) {
|
||||
out.SetInt(int64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case int64:
|
||||
if !out.OverflowInt(resolved) {
|
||||
out.SetInt(resolved)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case uint64:
|
||||
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
||||
out.SetInt(int64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case float64:
|
||||
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
||||
out.SetInt(int64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case string:
|
||||
if out.Type() == durationType {
|
||||
d, err := time.ParseDuration(resolved)
|
||||
if err == nil {
|
||||
out.SetInt(int64(d))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,44 +476,49 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
case int:
|
||||
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case int64:
|
||||
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case uint64:
|
||||
if !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case float64:
|
||||
if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
case reflect.Bool:
|
||||
switch resolved := resolved.(type) {
|
||||
case bool:
|
||||
out.SetBool(resolved)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch resolved := resolved.(type) {
|
||||
case int:
|
||||
out.SetFloat(float64(resolved))
|
||||
good = true
|
||||
return true
|
||||
case int64:
|
||||
out.SetFloat(float64(resolved))
|
||||
good = true
|
||||
return true
|
||||
case uint64:
|
||||
out.SetFloat(float64(resolved))
|
||||
good = true
|
||||
return true
|
||||
case float64:
|
||||
out.SetFloat(resolved)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case reflect.Struct:
|
||||
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
||||
out.Set(resolvedv)
|
||||
return true
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if out.Type().Elem() == reflect.TypeOf(resolved) {
|
||||
|
@ -459,13 +526,11 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
elem := reflect.New(out.Type().Elem())
|
||||
elem.Elem().Set(reflect.ValueOf(resolved))
|
||||
out.Set(elem)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !good {
|
||||
d.terror(n, tag, out)
|
||||
}
|
||||
return good
|
||||
return false
|
||||
}
|
||||
|
||||
func settableValueOf(i interface{}) reflect.Value {
|
||||
|
@ -482,6 +547,10 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
|||
switch out.Kind() {
|
||||
case reflect.Slice:
|
||||
out.Set(reflect.MakeSlice(out.Type(), l, l))
|
||||
case reflect.Array:
|
||||
if l != out.Len() {
|
||||
failf("invalid array: want %d elements but got %d", out.Len(), l)
|
||||
}
|
||||
case reflect.Interface:
|
||||
// No type hints. Will have to use a generic sequence.
|
||||
iface = out
|
||||
|
@ -500,7 +569,9 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
|||
j++
|
||||
}
|
||||
}
|
||||
if out.Kind() != reflect.Array {
|
||||
out.Set(out.Slice(0, j))
|
||||
}
|
||||
if iface.IsValid() {
|
||||
iface.Set(out)
|
||||
}
|
||||
|
@ -561,7 +632,7 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
e := reflect.New(et).Elem()
|
||||
if d.unmarshal(n.children[i+1], e) {
|
||||
out.SetMapIndex(k, e)
|
||||
d.setMapIndex(n.children[i+1], out, k, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -569,6 +640,14 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
|||
return true
|
||||
}
|
||||
|
||||
func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
|
||||
if d.strict && out.MapIndex(k) != zeroValue {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
|
||||
return
|
||||
}
|
||||
out.SetMapIndex(k, v)
|
||||
}
|
||||
|
||||
func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
|
||||
outt := out.Type()
|
||||
if outt.Elem() != mapItemType {
|
||||
|
@ -616,6 +695,10 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
|||
elemType = inlineMap.Type().Elem()
|
||||
}
|
||||
|
||||
var doneFields []bool
|
||||
if d.strict {
|
||||
doneFields = make([]bool, len(sinfo.FieldsList))
|
||||
}
|
||||
for i := 0; i < l; i += 2 {
|
||||
ni := n.children[i]
|
||||
if isMerge(ni) {
|
||||
|
@ -626,6 +709,13 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
|||
continue
|
||||
}
|
||||
if info, ok := sinfo.FieldsMap[name.String()]; ok {
|
||||
if d.strict {
|
||||
if doneFields[info.Id] {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
|
||||
continue
|
||||
}
|
||||
doneFields[info.Id] = true
|
||||
}
|
||||
var field reflect.Value
|
||||
if info.Inline == nil {
|
||||
field = out.Field(info.Num)
|
||||
|
@ -639,7 +729,9 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
value := reflect.New(elemType).Elem()
|
||||
d.unmarshal(n.children[i+1], value)
|
||||
inlineMap.SetMapIndex(name, value)
|
||||
d.setMapIndex(n.children[i+1], inlineMap, name, value)
|
||||
} else if d.strict {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
14
vendor/gopkg.in/yaml.v2/emitterc.go
generated
vendored
14
vendor/gopkg.in/yaml.v2/emitterc.go
generated
vendored
|
@ -2,6 +2,7 @@ package yaml
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Flush the buffer if needed.
|
||||
|
@ -664,9 +665,8 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
|
|||
return yaml_emitter_emit_mapping_start(emitter, event)
|
||||
default:
|
||||
return yaml_emitter_set_emitter_error(emitter,
|
||||
"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
|
||||
fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Expect ALIAS.
|
||||
|
@ -843,7 +843,7 @@ func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event
|
|||
return true
|
||||
}
|
||||
|
||||
// Write an achor.
|
||||
// Write an anchor.
|
||||
func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
|
||||
if emitter.anchor_data.anchor == nil {
|
||||
return true
|
||||
|
@ -995,7 +995,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
break_space = false
|
||||
space_break = false
|
||||
|
||||
preceeded_by_whitespace = false
|
||||
preceded_by_whitespace = false
|
||||
followed_by_whitespace = false
|
||||
previous_space = false
|
||||
previous_break = false
|
||||
|
@ -1017,7 +1017,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
flow_indicators = true
|
||||
}
|
||||
|
||||
preceeded_by_whitespace = true
|
||||
preceded_by_whitespace = true
|
||||
for i, w := 0, 0; i < len(value); i += w {
|
||||
w = width(value[i])
|
||||
followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
|
||||
|
@ -1048,7 +1048,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
block_indicators = true
|
||||
}
|
||||
case '#':
|
||||
if preceeded_by_whitespace {
|
||||
if preceded_by_whitespace {
|
||||
flow_indicators = true
|
||||
block_indicators = true
|
||||
}
|
||||
|
@ -1089,7 +1089,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
}
|
||||
|
||||
// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
|
||||
preceeded_by_whitespace = is_blankz(value, i)
|
||||
preceded_by_whitespace = is_blankz(value, i)
|
||||
}
|
||||
|
||||
emitter.scalar_data.multiline = line_breaks
|
||||
|
|
132
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
132
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
|
@ -3,12 +3,14 @@ package yaml
|
|||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type encoder struct {
|
||||
|
@ -16,25 +18,39 @@ type encoder struct {
|
|||
event yaml_event_t
|
||||
out []byte
|
||||
flow bool
|
||||
// doneInit holds whether the initial stream_start_event has been
|
||||
// emitted.
|
||||
doneInit bool
|
||||
}
|
||||
|
||||
func newEncoder() (e *encoder) {
|
||||
e = &encoder{}
|
||||
e.must(yaml_emitter_initialize(&e.emitter))
|
||||
func newEncoder() *encoder {
|
||||
e := &encoder{}
|
||||
yaml_emitter_initialize(&e.emitter)
|
||||
yaml_emitter_set_output_string(&e.emitter, &e.out)
|
||||
yaml_emitter_set_unicode(&e.emitter, true)
|
||||
e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
|
||||
e.emit()
|
||||
e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
|
||||
e.emit()
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *encoder) finish() {
|
||||
e.must(yaml_document_end_event_initialize(&e.event, true))
|
||||
func newEncoderWithWriter(w io.Writer) *encoder {
|
||||
e := &encoder{}
|
||||
yaml_emitter_initialize(&e.emitter)
|
||||
yaml_emitter_set_output_writer(&e.emitter, w)
|
||||
yaml_emitter_set_unicode(&e.emitter, true)
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *encoder) init() {
|
||||
if e.doneInit {
|
||||
return
|
||||
}
|
||||
yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
|
||||
e.emit()
|
||||
e.doneInit = true
|
||||
}
|
||||
|
||||
func (e *encoder) finish() {
|
||||
e.emitter.open_ended = false
|
||||
e.must(yaml_stream_end_event_initialize(&e.event))
|
||||
yaml_stream_end_event_initialize(&e.event)
|
||||
e.emit()
|
||||
}
|
||||
|
||||
|
@ -44,9 +60,7 @@ func (e *encoder) destroy() {
|
|||
|
||||
func (e *encoder) emit() {
|
||||
// This will internally delete the e.event value.
|
||||
if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
|
||||
e.must(false)
|
||||
}
|
||||
e.must(yaml_emitter_emit(&e.emitter, &e.event))
|
||||
}
|
||||
|
||||
func (e *encoder) must(ok bool) {
|
||||
|
@ -59,13 +73,28 @@ func (e *encoder) must(ok bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func (e *encoder) marshalDoc(tag string, in reflect.Value) {
|
||||
e.init()
|
||||
yaml_document_start_event_initialize(&e.event, nil, nil, true)
|
||||
e.emit()
|
||||
e.marshal(tag, in)
|
||||
yaml_document_end_event_initialize(&e.event, true)
|
||||
e.emit()
|
||||
}
|
||||
|
||||
func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||
if !in.IsValid() {
|
||||
if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
|
||||
e.nilv()
|
||||
return
|
||||
}
|
||||
iface := in.Interface()
|
||||
if m, ok := iface.(Marshaler); ok {
|
||||
switch m := iface.(type) {
|
||||
case time.Time, *time.Time:
|
||||
// Although time.Time implements TextMarshaler,
|
||||
// we don't want to treat it as a string for YAML
|
||||
// purposes because YAML has special support for
|
||||
// timestamps.
|
||||
case Marshaler:
|
||||
v, err := m.MarshalYAML()
|
||||
if err != nil {
|
||||
fail(err)
|
||||
|
@ -75,31 +104,34 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
|
|||
return
|
||||
}
|
||||
in = reflect.ValueOf(v)
|
||||
} else if m, ok := iface.(encoding.TextMarshaler); ok {
|
||||
case encoding.TextMarshaler:
|
||||
text, err := m.MarshalText()
|
||||
if err != nil {
|
||||
fail(err)
|
||||
}
|
||||
in = reflect.ValueOf(string(text))
|
||||
case nil:
|
||||
e.nilv()
|
||||
return
|
||||
}
|
||||
switch in.Kind() {
|
||||
case reflect.Interface:
|
||||
if in.IsNil() {
|
||||
e.nilv()
|
||||
} else {
|
||||
e.marshal(tag, in.Elem())
|
||||
}
|
||||
case reflect.Map:
|
||||
e.mapv(tag, in)
|
||||
case reflect.Ptr:
|
||||
if in.IsNil() {
|
||||
e.nilv()
|
||||
if in.Type() == ptrTimeType {
|
||||
e.timev(tag, in.Elem())
|
||||
} else {
|
||||
e.marshal(tag, in.Elem())
|
||||
}
|
||||
case reflect.Struct:
|
||||
if in.Type() == timeType {
|
||||
e.timev(tag, in)
|
||||
} else {
|
||||
e.structv(tag, in)
|
||||
case reflect.Slice:
|
||||
}
|
||||
case reflect.Slice, reflect.Array:
|
||||
if in.Type().Elem() == mapItemType {
|
||||
e.itemsv(tag, in)
|
||||
} else {
|
||||
|
@ -191,10 +223,10 @@ func (e *encoder) mappingv(tag string, f func()) {
|
|||
e.flow = false
|
||||
style = yaml_FLOW_MAPPING_STYLE
|
||||
}
|
||||
e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
|
||||
yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
|
||||
e.emit()
|
||||
f()
|
||||
e.must(yaml_mapping_end_event_initialize(&e.event))
|
||||
yaml_mapping_end_event_initialize(&e.event)
|
||||
e.emit()
|
||||
}
|
||||
|
||||
|
@ -240,23 +272,36 @@ var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0
|
|||
func (e *encoder) stringv(tag string, in reflect.Value) {
|
||||
var style yaml_scalar_style_t
|
||||
s := in.String()
|
||||
rtag, rs := resolve("", s)
|
||||
if rtag == yaml_BINARY_TAG {
|
||||
if tag == "" || tag == yaml_STR_TAG {
|
||||
tag = rtag
|
||||
s = rs.(string)
|
||||
} else if tag == yaml_BINARY_TAG {
|
||||
canUsePlain := true
|
||||
switch {
|
||||
case !utf8.ValidString(s):
|
||||
if tag == yaml_BINARY_TAG {
|
||||
failf("explicitly tagged !!binary data must be base64-encoded")
|
||||
} else {
|
||||
}
|
||||
if tag != "" {
|
||||
failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
|
||||
}
|
||||
// It can't be encoded directly as YAML so use a binary tag
|
||||
// and encode it as base64.
|
||||
tag = yaml_BINARY_TAG
|
||||
s = encodeBase64(s)
|
||||
case tag == "":
|
||||
// Check to see if it would resolve to a specific
|
||||
// tag when encoded unquoted. If it doesn't,
|
||||
// there's no need to quote it.
|
||||
rtag, _ := resolve("", s)
|
||||
canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
|
||||
}
|
||||
if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
|
||||
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
||||
} else if strings.Contains(s, "\n") {
|
||||
// Note: it's possible for user code to emit invalid YAML
|
||||
// if they explicitly specify a tag and a string containing
|
||||
// text that's incompatible with that tag.
|
||||
switch {
|
||||
case strings.Contains(s, "\n"):
|
||||
style = yaml_LITERAL_SCALAR_STYLE
|
||||
} else {
|
||||
case canUsePlain:
|
||||
style = yaml_PLAIN_SCALAR_STYLE
|
||||
default:
|
||||
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
||||
}
|
||||
e.emitScalar(s, "", tag, style)
|
||||
}
|
||||
|
@ -281,9 +326,20 @@ func (e *encoder) uintv(tag string, in reflect.Value) {
|
|||
e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
|
||||
}
|
||||
|
||||
func (e *encoder) timev(tag string, in reflect.Value) {
|
||||
t := in.Interface().(time.Time)
|
||||
s := t.Format(time.RFC3339Nano)
|
||||
e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
|
||||
}
|
||||
|
||||
func (e *encoder) floatv(tag string, in reflect.Value) {
|
||||
// FIXME: Handle 64 bits here.
|
||||
s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
|
||||
// Issue #352: When formatting, use the precision of the underlying value
|
||||
precision := 64
|
||||
if in.Kind() == reflect.Float32 {
|
||||
precision = 32
|
||||
}
|
||||
|
||||
s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
|
||||
switch s {
|
||||
case "+Inf":
|
||||
s = ".inf"
|
||||
|
|
1
vendor/gopkg.in/yaml.v2/parserc.go
generated
vendored
1
vendor/gopkg.in/yaml.v2/parserc.go
generated
vendored
|
@ -166,7 +166,6 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool
|
|||
default:
|
||||
panic("invalid parser state")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Parse the production:
|
||||
|
|
27
vendor/gopkg.in/yaml.v2/readerc.go
generated
vendored
27
vendor/gopkg.in/yaml.v2/readerc.go
generated
vendored
|
@ -93,9 +93,18 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
panic("read handler must be set")
|
||||
}
|
||||
|
||||
// [Go] This function was changed to guarantee the requested length size at EOF.
|
||||
// The fact we need to do this is pretty awful, but the description above implies
|
||||
// for that to be the case, and there are tests
|
||||
|
||||
// If the EOF flag is set and the raw buffer is empty, do nothing.
|
||||
if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
|
||||
return true
|
||||
// [Go] ACTUALLY! Read the documentation of this function above.
|
||||
// This is just broken. To return true, we need to have the
|
||||
// given length in the buffer. Not doing that means every single
|
||||
// check that calls this function to make sure the buffer has a
|
||||
// given length is Go) panicking; or C) accessing invalid memory.
|
||||
//return true
|
||||
}
|
||||
|
||||
// Return if the buffer contains enough characters.
|
||||
|
@ -247,7 +256,7 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
if parser.encoding == yaml_UTF16LE_ENCODING {
|
||||
low, high = 0, 1
|
||||
} else {
|
||||
high, low = 1, 0
|
||||
low, high = 1, 0
|
||||
}
|
||||
|
||||
// The UTF-16 encoding is not as simple as one might
|
||||
|
@ -357,23 +366,26 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
if value <= 0x7F {
|
||||
// 0000 0000-0000 007F . 0xxxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(value)
|
||||
buffer_len += 1
|
||||
} else if value <= 0x7FF {
|
||||
// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
|
||||
parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
|
||||
buffer_len += 2
|
||||
} else if value <= 0xFFFF {
|
||||
// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
|
||||
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
|
||||
parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
|
||||
buffer_len += 3
|
||||
} else {
|
||||
// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
|
||||
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
|
||||
parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
|
||||
parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
|
||||
buffer_len += 4
|
||||
}
|
||||
buffer_len += width
|
||||
|
||||
parser.unread++
|
||||
}
|
||||
|
@ -386,6 +398,15 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
break
|
||||
}
|
||||
}
|
||||
// [Go] Read the documentation of this function above. To return true,
|
||||
// we need to have the given length in the buffer. Not doing that means
|
||||
// every single check that calls this function to make sure the buffer
|
||||
// has a given length is Go) panicking; or C) accessing invalid memory.
|
||||
// This happens here due to the EOF above breaking early.
|
||||
for buffer_len < length {
|
||||
parser.buffer[buffer_len] = 0
|
||||
buffer_len++
|
||||
}
|
||||
parser.buffer = parser.buffer[:buffer_len]
|
||||
return true
|
||||
}
|
||||
|
|
83
vendor/gopkg.in/yaml.v2/resolve.go
generated
vendored
83
vendor/gopkg.in/yaml.v2/resolve.go
generated
vendored
|
@ -3,9 +3,10 @@ package yaml
|
|||
import (
|
||||
"encoding/base64"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
"time"
|
||||
)
|
||||
|
||||
type resolveMapItem struct {
|
||||
|
@ -74,12 +75,14 @@ func longTag(tag string) string {
|
|||
|
||||
func resolvableTag(tag string) bool {
|
||||
switch tag {
|
||||
case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
|
||||
case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
|
||||
|
||||
func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||
if !resolvableTag(tag) {
|
||||
return tag, in
|
||||
|
@ -89,6 +92,19 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
switch tag {
|
||||
case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
|
||||
return
|
||||
case yaml_FLOAT_TAG:
|
||||
if rtag == yaml_INT_TAG {
|
||||
switch v := out.(type) {
|
||||
case int64:
|
||||
rtag = yaml_FLOAT_TAG
|
||||
out = float64(v)
|
||||
return
|
||||
case int:
|
||||
rtag = yaml_FLOAT_TAG
|
||||
out = float64(v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
|
||||
}()
|
||||
|
@ -122,6 +138,15 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
|
||||
case 'D', 'S':
|
||||
// Int, float, or timestamp.
|
||||
// Only try values as a timestamp if the value is unquoted or there's an explicit
|
||||
// !!timestamp tag.
|
||||
if tag == "" || tag == yaml_TIMESTAMP_TAG {
|
||||
t, ok := parseTimestamp(in)
|
||||
if ok {
|
||||
return yaml_TIMESTAMP_TAG, t
|
||||
}
|
||||
}
|
||||
|
||||
plain := strings.Replace(in, "_", "", -1)
|
||||
intv, err := strconv.ParseInt(plain, 0, 64)
|
||||
if err == nil {
|
||||
|
@ -135,10 +160,12 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
if err == nil {
|
||||
return yaml_INT_TAG, uintv
|
||||
}
|
||||
if yamlStyleFloat.MatchString(plain) {
|
||||
floatv, err := strconv.ParseFloat(plain, 64)
|
||||
if err == nil {
|
||||
return yaml_FLOAT_TAG, floatv
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(plain, "0b") {
|
||||
intv, err := strconv.ParseInt(plain[2:], 2, 64)
|
||||
if err == nil {
|
||||
|
@ -153,28 +180,20 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
return yaml_INT_TAG, uintv
|
||||
}
|
||||
} else if strings.HasPrefix(plain, "-0b") {
|
||||
intv, err := strconv.ParseInt(plain[3:], 2, 64)
|
||||
intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
|
||||
if err == nil {
|
||||
if intv == int64(int(intv)) {
|
||||
return yaml_INT_TAG, -int(intv)
|
||||
if true || intv == int64(int(intv)) {
|
||||
return yaml_INT_TAG, int(intv)
|
||||
} else {
|
||||
return yaml_INT_TAG, -intv
|
||||
return yaml_INT_TAG, intv
|
||||
}
|
||||
}
|
||||
}
|
||||
// XXX Handle timestamps here.
|
||||
|
||||
default:
|
||||
panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
|
||||
}
|
||||
}
|
||||
if tag == yaml_BINARY_TAG {
|
||||
return yaml_BINARY_TAG, in
|
||||
}
|
||||
if utf8.ValidString(in) {
|
||||
return yaml_STR_TAG, in
|
||||
}
|
||||
return yaml_BINARY_TAG, encodeBase64(in)
|
||||
}
|
||||
|
||||
// encodeBase64 encodes s as base64 that is broken up into multiple lines
|
||||
|
@ -201,3 +220,39 @@ func encodeBase64(s string) string {
|
|||
}
|
||||
return string(out[:k])
|
||||
}
|
||||
|
||||
// This is a subset of the formats allowed by the regular expression
|
||||
// defined at http://yaml.org/type/timestamp.html.
|
||||
var allowedTimestampFormats = []string{
|
||||
"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
|
||||
"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
|
||||
"2006-1-2 15:4:5.999999999", // space separated with no time zone
|
||||
"2006-1-2", // date only
|
||||
// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
|
||||
// from the set of examples.
|
||||
}
|
||||
|
||||
// parseTimestamp parses s as a timestamp string and
|
||||
// returns the timestamp and reports whether it succeeded.
|
||||
// Timestamp formats are defined at http://yaml.org/type/timestamp.html
|
||||
func parseTimestamp(s string) (time.Time, bool) {
|
||||
// TODO write code to check all the formats supported by
|
||||
// http://yaml.org/type/timestamp.html instead of using time.Parse.
|
||||
|
||||
// Quick check: all date formats start with YYYY-.
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if c := s[i]; c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i != 4 || i == len(s) || s[i] != '-' {
|
||||
return time.Time{}, false
|
||||
}
|
||||
for _, format := range allowedTimestampFormats {
|
||||
if t, err := time.Parse(format, s); err == nil {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
|
42
vendor/gopkg.in/yaml.v2/scannerc.go
generated
vendored
42
vendor/gopkg.in/yaml.v2/scannerc.go
generated
vendored
|
@ -9,7 +9,7 @@ import (
|
|||
// ************
|
||||
//
|
||||
// The following notes assume that you are familiar with the YAML specification
|
||||
// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
|
||||
// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in
|
||||
// some cases we are less restrictive that it requires.
|
||||
//
|
||||
// The process of transforming a YAML stream into a sequence of events is
|
||||
|
@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
|
|||
if directive {
|
||||
context = "while parsing a %TAG directive"
|
||||
}
|
||||
return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
|
||||
return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
|
||||
}
|
||||
|
||||
func trace(args ...interface{}) func() {
|
||||
|
@ -871,12 +871,6 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
|
|||
|
||||
required := parser.flow_level == 0 && parser.indent == parser.mark.column
|
||||
|
||||
// A simple key is required only when it is the first token in the current
|
||||
// line. Therefore it is always allowed. But we add a check anyway.
|
||||
if required && !parser.simple_key_allowed {
|
||||
panic("should not happen")
|
||||
}
|
||||
|
||||
//
|
||||
// If the current position may start a simple key, save it.
|
||||
//
|
||||
|
@ -1546,7 +1540,7 @@ func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool
|
|||
// Unknown directive.
|
||||
} else {
|
||||
yaml_parser_set_scanner_error(parser, "while scanning a directive",
|
||||
start_mark, "found uknown directive name")
|
||||
start_mark, "found unknown directive name")
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -1944,7 +1938,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
|
|||
} else {
|
||||
// It's either the '!' tag or not really a tag handle. If it's a %TAG
|
||||
// directive, it's an error. If it's a tag token, it must be a part of URI.
|
||||
if directive && !(s[0] == '!' && s[1] == 0) {
|
||||
if directive && string(s) != "!" {
|
||||
yaml_parser_set_scanner_tag_error(parser, directive,
|
||||
start_mark, "did not find expected '!'")
|
||||
return false
|
||||
|
@ -1959,6 +1953,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
|
|||
func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
|
||||
//size_t length = head ? strlen((char *)head) : 0
|
||||
var s []byte
|
||||
hasTag := len(head) > 0
|
||||
|
||||
// Copy the head if needed.
|
||||
//
|
||||
|
@ -2000,10 +1995,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
|
|||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||
return false
|
||||
}
|
||||
hasTag = true
|
||||
}
|
||||
|
||||
// Check if the tag is non-empty.
|
||||
if len(s) == 0 {
|
||||
if !hasTag {
|
||||
yaml_parser_set_scanner_tag_error(parser, directive,
|
||||
start_mark, "did not find expected tag URI")
|
||||
return false
|
||||
|
@ -2474,6 +2469,10 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
|
|||
}
|
||||
}
|
||||
|
||||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if we are at the end of the scalar.
|
||||
if single {
|
||||
if parser.buffer[parser.buffer_pos] == '\'' {
|
||||
|
@ -2486,10 +2485,6 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
|
|||
}
|
||||
|
||||
// Consume blank characters.
|
||||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
|
||||
if is_blank(parser.buffer, parser.buffer_pos) {
|
||||
// Consume a space or a tab character.
|
||||
|
@ -2591,19 +2586,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
|
|||
// Consume non-blank characters.
|
||||
for !is_blankz(parser.buffer, parser.buffer_pos) {
|
||||
|
||||
// Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
|
||||
if parser.flow_level > 0 &&
|
||||
parser.buffer[parser.buffer_pos] == ':' &&
|
||||
!is_blankz(parser.buffer, parser.buffer_pos+1) {
|
||||
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
|
||||
start_mark, "found unexpected ':'")
|
||||
return false
|
||||
}
|
||||
|
||||
// Check for indicators that may end a plain scalar.
|
||||
if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
|
||||
(parser.flow_level > 0 &&
|
||||
(parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
|
||||
(parser.buffer[parser.buffer_pos] == ',' ||
|
||||
parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
|
||||
parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
|
||||
parser.buffer[parser.buffer_pos] == '}')) {
|
||||
|
@ -2655,10 +2641,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
|
|||
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
|
||||
if is_blank(parser.buffer, parser.buffer_pos) {
|
||||
|
||||
// Check for tab character that abuse indentation.
|
||||
// Check for tab characters that abuse indentation.
|
||||
if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
|
||||
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
|
||||
start_mark, "found a tab character that violate indentation")
|
||||
start_mark, "found a tab character that violates indentation")
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
9
vendor/gopkg.in/yaml.v2/sorter.go
generated
vendored
9
vendor/gopkg.in/yaml.v2/sorter.go
generated
vendored
|
@ -51,6 +51,15 @@ func (l keyList) Less(i, j int) bool {
|
|||
}
|
||||
var ai, bi int
|
||||
var an, bn int64
|
||||
if ar[i] == '0' || br[i] == '0' {
|
||||
for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
|
||||
if ar[j] != '0' {
|
||||
an = 1
|
||||
bn = 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
|
||||
an = an*10 + int64(ar[ai]-'0')
|
||||
}
|
||||
|
|
63
vendor/gopkg.in/yaml.v2/writerc.go
generated
vendored
63
vendor/gopkg.in/yaml.v2/writerc.go
generated
vendored
|
@ -18,72 +18,9 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// If the output encoding is UTF-8, we don't need to recode the buffer.
|
||||
if emitter.encoding == yaml_UTF8_ENCODING {
|
||||
if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
|
||||
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
|
||||
}
|
||||
emitter.buffer_pos = 0
|
||||
return true
|
||||
}
|
||||
|
||||
// Recode the buffer into the raw buffer.
|
||||
var low, high int
|
||||
if emitter.encoding == yaml_UTF16LE_ENCODING {
|
||||
low, high = 0, 1
|
||||
} else {
|
||||
high, low = 1, 0
|
||||
}
|
||||
|
||||
pos := 0
|
||||
for pos < emitter.buffer_pos {
|
||||
// See the "reader.c" code for more details on UTF-8 encoding. Note
|
||||
// that we assume that the buffer contains a valid UTF-8 sequence.
|
||||
|
||||
// Read the next UTF-8 character.
|
||||
octet := emitter.buffer[pos]
|
||||
|
||||
var w int
|
||||
var value rune
|
||||
switch {
|
||||
case octet&0x80 == 0x00:
|
||||
w, value = 1, rune(octet&0x7F)
|
||||
case octet&0xE0 == 0xC0:
|
||||
w, value = 2, rune(octet&0x1F)
|
||||
case octet&0xF0 == 0xE0:
|
||||
w, value = 3, rune(octet&0x0F)
|
||||
case octet&0xF8 == 0xF0:
|
||||
w, value = 4, rune(octet&0x07)
|
||||
}
|
||||
for k := 1; k < w; k++ {
|
||||
octet = emitter.buffer[pos+k]
|
||||
value = (value << 6) + (rune(octet) & 0x3F)
|
||||
}
|
||||
pos += w
|
||||
|
||||
// Write the character.
|
||||
if value < 0x10000 {
|
||||
var b [2]byte
|
||||
b[high] = byte(value >> 8)
|
||||
b[low] = byte(value & 0xFF)
|
||||
emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
|
||||
} else {
|
||||
// Write the character using a surrogate pair (check "reader.c").
|
||||
var b [4]byte
|
||||
value -= 0x10000
|
||||
b[high] = byte(0xD8 + (value >> 18))
|
||||
b[low] = byte((value >> 10) & 0xFF)
|
||||
b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
|
||||
b[low+2] = byte(value & 0xFF)
|
||||
emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
|
||||
}
|
||||
}
|
||||
|
||||
// Write the raw buffer.
|
||||
if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
|
||||
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
|
||||
}
|
||||
emitter.buffer_pos = 0
|
||||
emitter.raw_buffer = emitter.raw_buffer[:0]
|
||||
return true
|
||||
}
|
||||
|
|
138
vendor/gopkg.in/yaml.v2/yaml.go
generated
vendored
138
vendor/gopkg.in/yaml.v2/yaml.go
generated
vendored
|
@ -9,6 +9,7 @@ package yaml
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -77,8 +78,65 @@ type Marshaler interface {
|
|||
// supported tag options.
|
||||
//
|
||||
func Unmarshal(in []byte, out interface{}) (err error) {
|
||||
return unmarshal(in, out, false)
|
||||
}
|
||||
|
||||
// UnmarshalStrict is like Unmarshal except that any fields that are found
|
||||
// in the data that do not have corresponding struct members, or mapping
|
||||
// keys that are duplicates, will result in
|
||||
// an error.
|
||||
func UnmarshalStrict(in []byte, out interface{}) (err error) {
|
||||
return unmarshal(in, out, true)
|
||||
}
|
||||
|
||||
// A Decorder reads and decodes YAML values from an input stream.
|
||||
type Decoder struct {
|
||||
strict bool
|
||||
parser *parser
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder that reads from r.
|
||||
//
|
||||
// The decoder introduces its own buffering and may read
|
||||
// data from r beyond the YAML values requested.
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
return &Decoder{
|
||||
parser: newParserFromReader(r),
|
||||
}
|
||||
}
|
||||
|
||||
// SetStrict sets whether strict decoding behaviour is enabled when
|
||||
// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
|
||||
func (dec *Decoder) SetStrict(strict bool) {
|
||||
dec.strict = strict
|
||||
}
|
||||
|
||||
// Decode reads the next YAML-encoded value from its input
|
||||
// and stores it in the value pointed to by v.
|
||||
//
|
||||
// See the documentation for Unmarshal for details about the
|
||||
// conversion of YAML into a Go value.
|
||||
func (dec *Decoder) Decode(v interface{}) (err error) {
|
||||
d := newDecoder(dec.strict)
|
||||
defer handleErr(&err)
|
||||
d := newDecoder()
|
||||
node := dec.parser.parse()
|
||||
if node == nil {
|
||||
return io.EOF
|
||||
}
|
||||
out := reflect.ValueOf(v)
|
||||
if out.Kind() == reflect.Ptr && !out.IsNil() {
|
||||
out = out.Elem()
|
||||
}
|
||||
d.unmarshal(node, out)
|
||||
if len(d.terrors) > 0 {
|
||||
return &TypeError{d.terrors}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshal(in []byte, out interface{}, strict bool) (err error) {
|
||||
defer handleErr(&err)
|
||||
d := newDecoder(strict)
|
||||
p := newParser(in)
|
||||
defer p.destroy()
|
||||
node := p.parse()
|
||||
|
@ -99,8 +157,8 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||
// of the generated document will reflect the structure of the value itself.
|
||||
// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
|
||||
//
|
||||
// Struct fields are only unmarshalled if they are exported (have an upper case
|
||||
// first letter), and are unmarshalled using the field name lowercased as the
|
||||
// Struct fields are only marshalled if they are exported (have an upper case
|
||||
// first letter), and are marshalled using the field name lowercased as the
|
||||
// default key. Custom keys may be defined via the "yaml" name in the field
|
||||
// tag: the content preceding the first comma is used as the key, and the
|
||||
// following comma-separated options are used to tweak the marshalling process.
|
||||
|
@ -114,7 +172,10 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||
//
|
||||
// omitempty Only include the field if it's not set to the zero
|
||||
// value for the type or to empty slices or maps.
|
||||
// Does not apply to zero valued structs.
|
||||
// Zero valued structs will be omitted if all their public
|
||||
// fields are zero, unless they implement an IsZero
|
||||
// method (see the IsZeroer interface type), in which
|
||||
// case the field will be included if that method returns true.
|
||||
//
|
||||
// flow Marshal using a flow style (useful for structs,
|
||||
// sequences and maps).
|
||||
|
@ -129,7 +190,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||
// For example:
|
||||
//
|
||||
// type T struct {
|
||||
// F int "a,omitempty"
|
||||
// F int `yaml:"a,omitempty"`
|
||||
// B int
|
||||
// }
|
||||
// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
|
||||
|
@ -139,12 +200,47 @@ func Marshal(in interface{}) (out []byte, err error) {
|
|||
defer handleErr(&err)
|
||||
e := newEncoder()
|
||||
defer e.destroy()
|
||||
e.marshal("", reflect.ValueOf(in))
|
||||
e.marshalDoc("", reflect.ValueOf(in))
|
||||
e.finish()
|
||||
out = e.out
|
||||
return
|
||||
}
|
||||
|
||||
// An Encoder writes YAML values to an output stream.
|
||||
type Encoder struct {
|
||||
encoder *encoder
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
// The Encoder should be closed after use to flush all data
|
||||
// to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{
|
||||
encoder: newEncoderWithWriter(w),
|
||||
}
|
||||
}
|
||||
|
||||
// Encode writes the YAML encoding of v to the stream.
|
||||
// If multiple items are encoded to the stream, the
|
||||
// second and subsequent document will be preceded
|
||||
// with a "---" document separator, but the first will not.
|
||||
//
|
||||
// See the documentation for Marshal for details about the conversion of Go
|
||||
// values to YAML.
|
||||
func (e *Encoder) Encode(v interface{}) (err error) {
|
||||
defer handleErr(&err)
|
||||
e.encoder.marshalDoc("", reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the encoder by writing any remaining data.
|
||||
// It does not write a stream terminating string "...".
|
||||
func (e *Encoder) Close() (err error) {
|
||||
defer handleErr(&err)
|
||||
e.encoder.finish()
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleErr(err *error) {
|
||||
if v := recover(); v != nil {
|
||||
if e, ok := v.(yamlError); ok {
|
||||
|
@ -200,6 +296,9 @@ type fieldInfo struct {
|
|||
Num int
|
||||
OmitEmpty bool
|
||||
Flow bool
|
||||
// Id holds the unique field identifier, so we can cheaply
|
||||
// check for field duplicates without maintaining an extra map.
|
||||
Id int
|
||||
|
||||
// Inline holds the field index if the field is part of an inlined struct.
|
||||
Inline []int
|
||||
|
@ -222,7 +321,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
inlineMap := -1
|
||||
for i := 0; i != n; i++ {
|
||||
field := st.Field(i)
|
||||
if field.PkgPath != "" {
|
||||
if field.PkgPath != "" && !field.Anonymous {
|
||||
continue // Private field
|
||||
}
|
||||
|
||||
|
@ -279,6 +378,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
} else {
|
||||
finfo.Inline = append([]int{i}, finfo.Inline...)
|
||||
}
|
||||
finfo.Id = len(fieldsList)
|
||||
fieldsMap[finfo.Key] = finfo
|
||||
fieldsList = append(fieldsList, finfo)
|
||||
}
|
||||
|
@ -300,11 +400,16 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
return nil, errors.New(msg)
|
||||
}
|
||||
|
||||
info.Id = len(fieldsList)
|
||||
fieldsList = append(fieldsList, info)
|
||||
fieldsMap[info.Key] = info
|
||||
}
|
||||
|
||||
sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
|
||||
sinfo = &structInfo{
|
||||
FieldsMap: fieldsMap,
|
||||
FieldsList: fieldsList,
|
||||
InlineMap: inlineMap,
|
||||
}
|
||||
|
||||
fieldMapMutex.Lock()
|
||||
structMap[st] = sinfo
|
||||
|
@ -312,8 +417,23 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
return sinfo, nil
|
||||
}
|
||||
|
||||
// IsZeroer is used to check whether an object is zero to
|
||||
// determine whether it should be omitted when marshaling
|
||||
// with the omitempty flag. One notable implementation
|
||||
// is time.Time.
|
||||
type IsZeroer interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func isZero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
kind := v.Kind()
|
||||
if z, ok := v.Interface().(IsZeroer); ok {
|
||||
if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
|
||||
return true
|
||||
}
|
||||
return z.IsZero()
|
||||
}
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
return len(v.String()) == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
|
|
28
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
28
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
|
@ -239,6 +240,27 @@ const (
|
|||
yaml_MAPPING_END_EVENT // A MAPPING-END event.
|
||||
)
|
||||
|
||||
var eventStrings = []string{
|
||||
yaml_NO_EVENT: "none",
|
||||
yaml_STREAM_START_EVENT: "stream start",
|
||||
yaml_STREAM_END_EVENT: "stream end",
|
||||
yaml_DOCUMENT_START_EVENT: "document start",
|
||||
yaml_DOCUMENT_END_EVENT: "document end",
|
||||
yaml_ALIAS_EVENT: "alias",
|
||||
yaml_SCALAR_EVENT: "scalar",
|
||||
yaml_SEQUENCE_START_EVENT: "sequence start",
|
||||
yaml_SEQUENCE_END_EVENT: "sequence end",
|
||||
yaml_MAPPING_START_EVENT: "mapping start",
|
||||
yaml_MAPPING_END_EVENT: "mapping end",
|
||||
}
|
||||
|
||||
func (e yaml_event_type_t) String() string {
|
||||
if e < 0 || int(e) >= len(eventStrings) {
|
||||
return fmt.Sprintf("unknown event %d", e)
|
||||
}
|
||||
return eventStrings[e]
|
||||
}
|
||||
|
||||
// The event structure.
|
||||
type yaml_event_t struct {
|
||||
|
||||
|
@ -508,7 +530,7 @@ type yaml_parser_t struct {
|
|||
|
||||
problem string // Error description.
|
||||
|
||||
// The byte about which the problem occured.
|
||||
// The byte about which the problem occurred.
|
||||
problem_offset int
|
||||
problem_value int
|
||||
problem_mark yaml_mark_t
|
||||
|
@ -521,7 +543,7 @@ type yaml_parser_t struct {
|
|||
|
||||
read_handler yaml_read_handler_t // Read handler.
|
||||
|
||||
input_file io.Reader // File input data.
|
||||
input_reader io.Reader // File input data.
|
||||
input []byte // String input data.
|
||||
input_pos int
|
||||
|
||||
|
@ -632,7 +654,7 @@ type yaml_emitter_t struct {
|
|||
write_handler yaml_write_handler_t // Write handler.
|
||||
|
||||
output_buffer *[]byte // String output data.
|
||||
output_file io.Writer // File output data.
|
||||
output_writer io.Writer // File output data.
|
||||
|
||||
buffer []byte // The working buffer.
|
||||
buffer_pos int // The current position of the buffer.
|
||||
|
|
Loading…
Reference in a new issue