mirror of
https://github.com/Luzifer/vault-unseal.git
synced 2024-12-22 13:51:20 +00:00
Remove import comment, migrate to dep for vendoring
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
369b8501ca
commit
4f9b5d79c6
73 changed files with 4579 additions and 719 deletions
20
Godeps/Godeps.json
generated
20
Godeps/Godeps.json
generated
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Jimdo/vault-unseal",
|
|
||||||
"GoVersion": "go1.6",
|
|
||||||
"GodepVersion": "v74",
|
|
||||||
"Deps": [
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Luzifer/rconfig",
|
|
||||||
"Comment": "v1.1.0",
|
|
||||||
"Rev": "c27bd3a64b5b19556914d9fec69922cf3852d585"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/spf13/pflag",
|
|
||||||
"Rev": "b084184666e02084b8ccb9b704bf0d79c466eb1d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "gopkg.in/yaml.v2",
|
|
||||||
"Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
5
Godeps/Readme
generated
5
Godeps/Readme
generated
|
@ -1,5 +0,0 @@
|
||||||
This directory tree is generated automatically by godep.
|
|
||||||
|
|
||||||
Please do not edit.
|
|
||||||
|
|
||||||
See https://github.com/tools/godep for more information.
|
|
42
Gopkg.lock
generated
Normal file
42
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/Luzifer/rconfig"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "7aef1d393c1e2d0758901853b59981c7adc67c7e"
|
||||||
|
version = "v1.2.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/spf13/pflag"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||||
|
version = "v1.0.1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/net"
|
||||||
|
packages = [
|
||||||
|
"context",
|
||||||
|
"context/ctxhttp"
|
||||||
|
]
|
||||||
|
revision = "a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "v2"
|
||||||
|
name = "gopkg.in/validator.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "135c24b11c19e52befcae2ec3fca5d9b78c4e98e"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "gopkg.in/yaml.v2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||||
|
version = "v2.2.1"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "153f24f6adacf967b28337b0e5c383d777ec3f60491baa010492753c0cfc2664"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
38
Gopkg.toml
Normal file
38
Gopkg.toml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
#
|
||||||
|
# [prune]
|
||||||
|
# non-go = false
|
||||||
|
# go-tests = true
|
||||||
|
# unused-packages = true
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/Luzifer/rconfig"
|
||||||
|
version = "1.2.0"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
branch = "master"
|
||||||
|
name = "golang.org/x/net"
|
||||||
|
|
||||||
|
[prune]
|
||||||
|
go-tests = true
|
||||||
|
unused-packages = true
|
2
main.go
2
main.go
|
@ -1,4 +1,4 @@
|
||||||
package main // import "github.com/Jimdo/vault-unseal"
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
4
vendor/github.com/Luzifer/rconfig/.travis.yml
generated
vendored
4
vendor/github.com/Luzifer/rconfig/.travis.yml
generated
vendored
|
@ -1,8 +1,8 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.4
|
- 1.6
|
||||||
- 1.5
|
- 1.7
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
script: go test -v -race -cover ./...
|
script: go test -v -race -cover ./...
|
||||||
|
|
4
vendor/github.com/Luzifer/rconfig/History.md
generated
vendored
4
vendor/github.com/Luzifer/rconfig/History.md
generated
vendored
|
@ -1,3 +1,7 @@
|
||||||
|
# 1.2.0 / 2017-06-19
|
||||||
|
|
||||||
|
* Add ParseAndValidate method
|
||||||
|
|
||||||
# 1.1.0 / 2016-06-28
|
# 1.1.0 / 2016-06-28
|
||||||
|
|
||||||
* Support time.Duration config parameters
|
* Support time.Duration config parameters
|
||||||
|
|
47
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
47
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
|
@ -29,34 +29,31 @@ go test -v -race -cover github.com/Luzifer/rconfig
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
As a first step define a struct holding your configuration:
|
A very simple usecase is to just configure a struct inside the vars section of your `main.go` and to parse the commandline flags from the `main()` function:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type config struct {
|
package main
|
||||||
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:
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Luzifer/rconfig"
|
||||||
|
)
|
||||||
|
|
||||||
```go
|
var (
|
||||||
var cfg config
|
cfg = struct {
|
||||||
func init() {
|
Username string `default:"unknown" flag:"user" description:"Your name"`
|
||||||
cfg = config{}
|
Details struct {
|
||||||
rconfig.Parse(&cfg)
|
Age int `default:"25" flag:"age" env:"age" description:"Your age"`
|
||||||
}
|
}
|
||||||
```
|
}{}
|
||||||
|
)
|
||||||
|
|
||||||
You're ready to access your configuration:
|
|
||||||
|
|
||||||
```go
|
|
||||||
func main() {
|
func main() {
|
||||||
|
rconfig.Parse(&cfg)
|
||||||
|
|
||||||
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
||||||
cfg.Username,
|
cfg.Username,
|
||||||
cfg.Details.Age)
|
cfg.Details.Age)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -72,18 +69,14 @@ The order of the directives (lower number = higher precedence):
|
||||||
1. `default` tag in the struct
|
1. `default` tag in the struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type config struct {
|
var cfg = struct {
|
||||||
Username string `vardefault:"username" flag:"username" description:"Your username"`
|
Username string `vardefault:"username" flag:"username" description:"Your username"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfg = config{}
|
func main() {
|
||||||
|
|
||||||
func init() {
|
|
||||||
rconfig.SetVariableDefaults(rconfig.VarDefaultsFromYAMLFile("~/.myapp.yml"))
|
rconfig.SetVariableDefaults(rconfig.VarDefaultsFromYAMLFile("~/.myapp.yml"))
|
||||||
rconfig.Parse(&cfg)
|
rconfig.Parse(&cfg)
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Printf("Username = %s", cfg.Username)
|
fmt.Printf("Username = %s", cfg.Username)
|
||||||
// Output: Username = luzifer
|
// Output: Username = luzifer
|
||||||
}
|
}
|
||||||
|
|
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"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
validator "gopkg.in/validator.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -45,6 +46,15 @@ func Parse(config interface{}) error {
|
||||||
return parse(config, nil)
|
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.
|
// Args returns the non-flag command-line arguments.
|
||||||
func Args() []string {
|
func Args() []string {
|
||||||
return fs.Args()
|
return fs.Args()
|
||||||
|
@ -65,6 +75,14 @@ func SetVariableDefaults(defaults map[string]string) {
|
||||||
variableDefaults = defaults
|
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 {
|
func parse(in interface{}, args []string) error {
|
||||||
if args == nil {
|
if args == nil {
|
||||||
args = os.Args
|
args = os.Args
|
||||||
|
|
2
vendor/github.com/spf13/pflag/.gitignore
generated
vendored
Normal file
2
vendor/github.com/spf13/pflag/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.idea/*
|
||||||
|
|
20
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
20
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
|
@ -3,15 +3,19 @@ sudo: false
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.3
|
- 1.7.3
|
||||||
- 1.4
|
- 1.8.1
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- go get github.com/golang/lint/golint
|
- go get github.com/golang/lint/golint
|
||||||
- export PATH=$GOPATH/bin:$PATH
|
- export PATH=$GOPATH/bin:$PATH
|
||||||
- go install ./...
|
- go install ./...
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- verify/all.sh
|
- verify/all.sh -v
|
||||||
- go test ./...
|
- go test ./...
|
||||||
|
|
52
vendor/github.com/spf13/pflag/README.md
generated
vendored
52
vendor/github.com/spf13/pflag/README.md
generated
vendored
|
@ -1,4 +1,6 @@
|
||||||
[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)
|
[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/pflag)](https://goreportcard.com/report/github.com/spf13/pflag)
|
||||||
|
[![GoDoc](https://godoc.org/github.com/spf13/pflag?status.svg)](https://godoc.org/github.com/spf13/pflag)
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
|
@ -85,7 +87,7 @@ fmt.Println("flagvar has value ", flagvar)
|
||||||
```
|
```
|
||||||
|
|
||||||
There are helpers function to get values later if you have the FlagSet but
|
There are helpers function to get values later if you have the FlagSet but
|
||||||
it was difficult to keep up with all of the the flag pointers in your code.
|
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
|
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
|
can use GetInt() to get the int value. But notice that 'flagname' must exist
|
||||||
and it must be an int. GetString("flagname") will fail.
|
and it must be an int. GetString("flagname") will fail.
|
||||||
|
@ -106,9 +108,9 @@ that give one-letter shorthands for flags. You can use these by appending
|
||||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||||
var flagvar bool
|
var flagvar bool
|
||||||
func init() {
|
func init() {
|
||||||
flag.BoolVarP("boolname", "b", true, "help message")
|
flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
|
||||||
}
|
}
|
||||||
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
flag.VarP(&flagVal, "varname", "v", "help message")
|
||||||
```
|
```
|
||||||
|
|
||||||
Shorthand letters can be used with single dashes on the command line.
|
Shorthand letters can be used with single dashes on the command line.
|
||||||
|
@ -244,13 +246,51 @@ It is possible to mark a flag as hidden, meaning it will still function as norma
|
||||||
flags.MarkHidden("secretFlag")
|
flags.MarkHidden("secretFlag")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Disable sorting of flags
|
||||||
|
`pflag` allows you to disable sorting of flags for help and usage message.
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```go
|
||||||
|
flags.BoolP("verbose", "v", false, "verbose output")
|
||||||
|
flags.String("coolflag", "yeaah", "it's really cool flag")
|
||||||
|
flags.Int("usefulflag", 777, "sometimes it's very useful")
|
||||||
|
flags.SortFlags = false
|
||||||
|
flags.PrintDefaults()
|
||||||
|
```
|
||||||
|
**Output**:
|
||||||
|
```
|
||||||
|
-v, --verbose verbose output
|
||||||
|
--coolflag string it's really cool flag (default "yeaah")
|
||||||
|
--usefulflag int sometimes it's very useful (default 777)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 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
|
## More info
|
||||||
|
|
||||||
You can see the full reference documentation of the pflag package
|
You can see the full reference documentation of the pflag package
|
||||||
[at godoc.org][3], or through go's standard documentation system by
|
[at godoc.org][3], or through go's standard documentation system by
|
||||||
running `godoc -http=:6060` and browsing to
|
running `godoc -http=:6060` and browsing to
|
||||||
[http://localhost:6060/pkg/github.com/ogier/pflag][2] after
|
[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
|
||||||
installation.
|
installation.
|
||||||
|
|
||||||
[2]: http://localhost:6060/pkg/github.com/ogier/pflag
|
[2]: http://localhost:6060/pkg/github.com/spf13/pflag
|
||||||
[3]: http://godoc.org/github.com/ogier/pflag
|
[3]: http://godoc.org/github.com/spf13/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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// optional interface to indicate boolean flags that can be
|
// optional interface to indicate boolean flags that can be
|
||||||
// supplied without "=value" text
|
// supplied without "=value" text
|
||||||
|
@ -30,7 +27,7 @@ func (b *boolValue) Type() string {
|
||||||
return "bool"
|
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 }
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- count Value
|
// -- count Value
|
||||||
type countValue int
|
type countValue int
|
||||||
|
@ -14,13 +11,13 @@ func newCountValue(val int, p *int) *countValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *countValue) Set(s string) error {
|
func (i *countValue) Set(s string) error {
|
||||||
v, err := strconv.ParseInt(s, 0, 64)
|
// "+1" means that no specific value was passed, so increment
|
||||||
// -1 means that no specific value was passed, so increment
|
if s == "+1" {
|
||||||
if v == -1 {
|
|
||||||
*i = countValue(*i + 1)
|
*i = countValue(*i + 1)
|
||||||
} else {
|
return nil
|
||||||
*i = countValue(v)
|
|
||||||
}
|
}
|
||||||
|
v, err := strconv.ParseInt(s, 0, 0)
|
||||||
|
*i = countValue(v)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +25,7 @@ func (i *countValue) Type() string {
|
||||||
return "count"
|
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) {
|
func countConv(sval string) (interface{}, error) {
|
||||||
i, err := strconv.Atoi(sval)
|
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.
|
// CountVarP is like CountVar only take a shorthand for the flag name.
|
||||||
func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
|
func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
|
||||||
flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
|
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
|
// 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
|
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 {
|
func Count(name string, usage string) *int {
|
||||||
return CommandLine.CountP(name, "", usage)
|
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)
|
||||||
|
}
|
619
vendor/github.com/spf13/pflag/flag.go
generated
vendored
619
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
|
pflag under the name "flag" then all code should continue to function
|
||||||
with no changes.
|
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.
|
there is one more field "Shorthand" that you will need to set.
|
||||||
Most code never instantiates this struct directly, and instead uses
|
Most code never instantiates this struct directly, and instead uses
|
||||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||||
|
@ -101,6 +101,7 @@ package pflag
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
goflag "flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -123,6 +124,12 @@ const (
|
||||||
PanicOnError
|
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
|
// NormalizedName is a flag name that has been normalized according to rules
|
||||||
// for the FlagSet (e.g. making '-' and '_' equivalent).
|
// for the FlagSet (e.g. making '-' and '_' equivalent).
|
||||||
type NormalizedName string
|
type NormalizedName string
|
||||||
|
@ -134,18 +141,30 @@ type FlagSet struct {
|
||||||
// a custom error handler.
|
// a custom error handler.
|
||||||
Usage func()
|
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
|
name string
|
||||||
parsed bool
|
parsed bool
|
||||||
actual map[NormalizedName]*Flag
|
actual map[NormalizedName]*Flag
|
||||||
|
orderedActual []*Flag
|
||||||
|
sortedActual []*Flag
|
||||||
formal map[NormalizedName]*Flag
|
formal map[NormalizedName]*Flag
|
||||||
|
orderedFormal []*Flag
|
||||||
|
sortedFormal []*Flag
|
||||||
shorthands map[byte]*Flag
|
shorthands map[byte]*Flag
|
||||||
args []string // arguments after flags
|
args []string // arguments after flags
|
||||||
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
|
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
|
errorHandling ErrorHandling
|
||||||
output io.Writer // nil means stderr; use out() accessor
|
output io.Writer // nil means stderr; use out() accessor
|
||||||
interspersed bool // allow interspersed option/non-option args
|
interspersed bool // allow interspersed option/non-option args
|
||||||
normalizeNameFunc func(f *FlagSet, name string) NormalizedName
|
normalizeNameFunc func(f *FlagSet, name string) NormalizedName
|
||||||
|
|
||||||
|
addedGoFlagSets []*goflag.FlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Flag represents the state of a flag.
|
// A Flag represents the state of a flag.
|
||||||
|
@ -156,7 +175,7 @@ type Flag struct {
|
||||||
Value Value // value as set
|
Value Value // value as set
|
||||||
DefValue string // default value (as text); for usage message
|
DefValue string // default value (as text); for usage message
|
||||||
Changed bool // If the user set the value (or if left to default)
|
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
|
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
|
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
|
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.
|
// "--getUrl" which may also be translated to "geturl" and everything will work.
|
||||||
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
|
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
|
||||||
f.normalizeNameFunc = n
|
f.normalizeNameFunc = n
|
||||||
for k, v := range f.formal {
|
f.sortedFormal = f.sortedFormal[:0]
|
||||||
delete(f.formal, k)
|
for fname, flag := range f.formal {
|
||||||
nname := f.normalizeFlagName(string(k))
|
nname := f.normalizeFlagName(flag.Name)
|
||||||
f.formal[nname] = v
|
if fname == nname {
|
||||||
v.Name = string(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,35 +256,78 @@ func (f *FlagSet) SetOutput(output io.Writer) {
|
||||||
f.output = output
|
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.
|
// It visits all flags, even those not set.
|
||||||
func (f *FlagSet) VisitAll(fn func(*Flag)) {
|
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)
|
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 {
|
func (f *FlagSet) HasFlags() bool {
|
||||||
return len(f.formal) > 0
|
return len(f.formal) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// VisitAll visits the command-line flags in lexicographical order, calling
|
// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
|
||||||
// fn for each. It visits all flags, even those not set.
|
// that are not hidden.
|
||||||
|
func (f *FlagSet) HasAvailableFlags() bool {
|
||||||
|
for _, flag := range f.formal {
|
||||||
|
if !flag.Hidden {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)) {
|
func VisitAll(fn func(*Flag)) {
|
||||||
CommandLine.VisitAll(fn)
|
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.
|
// It visits only those flags that have been set.
|
||||||
func (f *FlagSet) Visit(fn func(*Flag)) {
|
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)
|
fn(flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visit visits the command-line flags in lexicographical order, calling fn
|
// Visit visits the command-line flags in lexicographical order or
|
||||||
// for each. It visits only those flags that have been set.
|
// 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)) {
|
func Visit(fn func(*Flag)) {
|
||||||
CommandLine.Visit(fn)
|
CommandLine.Visit(fn)
|
||||||
}
|
}
|
||||||
|
@ -267,6 +337,22 @@ func (f *FlagSet) Lookup(name string) *Flag {
|
||||||
return f.lookup(f.normalizeFlagName(name))
|
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.
|
// lookup returns the Flag structure of the named flag, returning nil if none exists.
|
||||||
func (f *FlagSet) lookup(name NormalizedName) *Flag {
|
func (f *FlagSet) lookup(name NormalizedName) *Flag {
|
||||||
return f.formal[name]
|
return f.formal[name]
|
||||||
|
@ -308,10 +394,11 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
|
||||||
if flag == nil {
|
if flag == nil {
|
||||||
return fmt.Errorf("flag %q does not exist", name)
|
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)
|
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||||
}
|
}
|
||||||
flag.Deprecated = usageMessage
|
flag.Deprecated = usageMessage
|
||||||
|
flag.Hidden = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +410,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
|
||||||
if flag == nil {
|
if flag == nil {
|
||||||
return fmt.Errorf("flag %q does not exist", name)
|
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)
|
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||||
}
|
}
|
||||||
flag.ShorthandDeprecated = usageMessage
|
flag.ShorthandDeprecated = usageMessage
|
||||||
|
@ -347,6 +434,12 @@ func Lookup(name string) *Flag {
|
||||||
return CommandLine.Lookup(name)
|
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.
|
// Set sets the value of the named flag.
|
||||||
func (f *FlagSet) Set(name, value string) error {
|
func (f *FlagSet) Set(name, value string) error {
|
||||||
normalName := f.normalizeFlagName(name)
|
normalName := f.normalizeFlagName(name)
|
||||||
|
@ -354,17 +447,30 @@ func (f *FlagSet) Set(name, value string) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("no such flag -%v", name)
|
return fmt.Errorf("no such flag -%v", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := flag.Value.Set(value)
|
err := flag.Value.Set(value)
|
||||||
if err != nil {
|
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 f.actual == nil {
|
|
||||||
f.actual = make(map[NormalizedName]*Flag)
|
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
|
||||||
}
|
}
|
||||||
f.actual[normalName] = flag
|
|
||||||
flag.Changed = true
|
if flag.Deprecated != "" {
|
||||||
if len(flag.Deprecated) > 0 {
|
fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -405,45 +511,232 @@ func Set(name, value string) error {
|
||||||
// otherwise, the default values of all defined flags in the set.
|
// otherwise, the default values of all defined flags in the set.
|
||||||
func (f *FlagSet) PrintDefaults() {
|
func (f *FlagSet) PrintDefaults() {
|
||||||
usages := f.FlagUsages()
|
usages := f.FlagUsages()
|
||||||
fmt.Fprintf(f.out(), "%s", usages)
|
fmt.Fprint(f.out(), usages)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlagUsages Returns a string containing the usage information for all flags in
|
// defaultIsZeroValue returns true if the default value for this flag represents
|
||||||
// the FlagSet
|
// a zero value.
|
||||||
func (f *FlagSet) FlagUsages() string {
|
func (f *Flag) defaultIsZeroValue() bool {
|
||||||
x := new(bytes.Buffer)
|
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>":
|
||||||
|
return true
|
||||||
|
case "":
|
||||||
|
return true
|
||||||
|
case "0":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnquoteUsage extracts a back-quoted name from the usage
|
||||||
|
// string for a flag and returns it and the un-quoted usage.
|
||||||
|
// Given "a `name` to show" it returns ("name", "a name to show").
|
||||||
|
// If there are no back quotes, the name is an educated guess of the
|
||||||
|
// type of the flag's value, or the empty string if the flag is boolean.
|
||||||
|
func UnquoteUsage(flag *Flag) (name string, usage string) {
|
||||||
|
// Look for a back-quoted name, but avoid the strings package.
|
||||||
|
usage = flag.Usage
|
||||||
|
for i := 0; i < len(usage); i++ {
|
||||||
|
if usage[i] == '`' {
|
||||||
|
for j := i + 1; j < len(usage); j++ {
|
||||||
|
if usage[j] == '`' {
|
||||||
|
name = usage[i+1 : j]
|
||||||
|
usage = usage[:i] + name + usage[j+1:]
|
||||||
|
return name, usage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break // Only one back quote; use type name.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name = flag.Value.Type()
|
||||||
|
switch name {
|
||||||
|
case "bool":
|
||||||
|
name = ""
|
||||||
|
case "float64":
|
||||||
|
name = "float"
|
||||||
|
case "int64":
|
||||||
|
name = "int"
|
||||||
|
case "uint64":
|
||||||
|
name = "uint"
|
||||||
|
case "stringSlice":
|
||||||
|
name = "strings"
|
||||||
|
case "intSlice":
|
||||||
|
name = "ints"
|
||||||
|
case "uintSlice":
|
||||||
|
name = "uints"
|
||||||
|
case "boolSlice":
|
||||||
|
name = "bools"
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
f.VisitAll(func(flag *Flag) {
|
||||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
if flag.Hidden {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
format := ""
|
|
||||||
if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
|
line := ""
|
||||||
format = " -%s, --%s"
|
if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
|
||||||
|
line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
|
||||||
} else {
|
} else {
|
||||||
format = " %s --%s"
|
line = fmt.Sprintf(" --%s", flag.Name)
|
||||||
}
|
}
|
||||||
if len(flag.NoOptDefVal) > 0 {
|
|
||||||
format = format + "["
|
varname, usage := UnquoteUsage(flag)
|
||||||
|
if varname != "" {
|
||||||
|
line += " " + varname
|
||||||
}
|
}
|
||||||
if flag.Value.Type() == "string" {
|
if flag.NoOptDefVal != "" {
|
||||||
// put quotes on the value
|
switch flag.Value.Type() {
|
||||||
format = format + "=%q"
|
case "string":
|
||||||
} else {
|
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
|
||||||
format = format + "=%s"
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(flag.NoOptDefVal) > 0 {
|
|
||||||
format = format + "]"
|
// This special character will be replaced with spacing once the
|
||||||
|
// correct alignment is calculated
|
||||||
|
line += "\x00"
|
||||||
|
if len(line) > maxlen {
|
||||||
|
maxlen = len(line)
|
||||||
}
|
}
|
||||||
format = format + ": %s\n"
|
|
||||||
shorthand := flag.Shorthand
|
line += usage
|
||||||
if len(flag.ShorthandDeprecated) > 0 {
|
if !flag.defaultIsZeroValue() {
|
||||||
shorthand = ""
|
if flag.Value.Type() == "string" {
|
||||||
|
line += fmt.Sprintf(" (default %q)", flag.DefValue)
|
||||||
|
} else {
|
||||||
|
line += fmt.Sprintf(" (default %s)", flag.DefValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
|
if len(flag.Deprecated) != 0 {
|
||||||
|
line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = append(lines, line)
|
||||||
})
|
})
|
||||||
|
|
||||||
return x.String()
|
for _, line := range lines {
|
||||||
|
sidx := strings.Index(line, "\x00")
|
||||||
|
spacing := strings.Repeat(" ", maxlen-sidx)
|
||||||
|
// 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 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.
|
// PrintDefaults prints to standard error the default values of all defined command-line flags.
|
||||||
|
@ -463,6 +756,8 @@ func defaultUsage(f *FlagSet) {
|
||||||
|
|
||||||
// Usage prints to standard error a usage message documenting all defined command-line flags.
|
// Usage prints to standard error a usage message documenting all defined command-line flags.
|
||||||
// The function is a variable that may be changed to point to a custom function.
|
// The function is a variable that may be changed to point to a custom function.
|
||||||
|
// By default it prints a simple header and calls PrintDefaults; for details about the
|
||||||
|
// format of the output and how to control it, see the documentation for PrintDefaults.
|
||||||
var Usage = func() {
|
var Usage = func() {
|
||||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||||
PrintDefaults()
|
PrintDefaults()
|
||||||
|
@ -527,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.
|
// 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) {
|
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
|
// AddFlag will add the flag to the FlagSet
|
||||||
func (f *FlagSet) AddFlag(flag *Flag) {
|
func (f *FlagSet) AddFlag(flag *Flag) {
|
||||||
// Call normalizeFlagName function only once
|
|
||||||
normalizedFlagName := f.normalizeFlagName(flag.Name)
|
normalizedFlagName := f.normalizeFlagName(flag.Name)
|
||||||
|
|
||||||
_, alreadythere := f.formal[normalizedFlagName]
|
_, alreadyThere := f.formal[normalizedFlagName]
|
||||||
if alreadythere {
|
if alreadyThere {
|
||||||
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
|
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
|
||||||
fmt.Fprintln(f.out(), msg)
|
fmt.Fprintln(f.out(), msg)
|
||||||
panic(msg) // Happens only if flags are declared with identical names
|
panic(msg) // Happens only if flags are declared with identical names
|
||||||
|
@ -547,28 +841,31 @@ func (f *FlagSet) AddFlag(flag *Flag) {
|
||||||
|
|
||||||
flag.Name = string(normalizedFlagName)
|
flag.Name = string(normalizedFlagName)
|
||||||
f.formal[normalizedFlagName] = flag
|
f.formal[normalizedFlagName] = flag
|
||||||
|
f.orderedFormal = append(f.orderedFormal, flag)
|
||||||
|
|
||||||
if len(flag.Shorthand) == 0 {
|
if flag.Shorthand == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(flag.Shorthand) > 1 {
|
if len(flag.Shorthand) > 1 {
|
||||||
fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
|
msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
|
||||||
panic("shorthand is more than one character")
|
fmt.Fprintf(f.out(), msg)
|
||||||
|
panic(msg)
|
||||||
}
|
}
|
||||||
if f.shorthands == nil {
|
if f.shorthands == nil {
|
||||||
f.shorthands = make(map[byte]*Flag)
|
f.shorthands = make(map[byte]*Flag)
|
||||||
}
|
}
|
||||||
c := flag.Shorthand[0]
|
c := flag.Shorthand[0]
|
||||||
old, alreadythere := f.shorthands[c]
|
used, alreadyThere := f.shorthands[c]
|
||||||
if alreadythere {
|
if alreadyThere {
|
||||||
fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
|
msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
|
||||||
panic("shorthand redefinition")
|
fmt.Fprintf(f.out(), msg)
|
||||||
|
panic(msg)
|
||||||
}
|
}
|
||||||
f.shorthands[c] = flag
|
f.shorthands[c] = flag
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
|
// 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) {
|
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
|
||||||
if newSet == nil {
|
if newSet == nil {
|
||||||
return
|
return
|
||||||
|
@ -599,8 +896,10 @@ func VarP(value Value, name, shorthand, usage string) {
|
||||||
// returns the error.
|
// returns the error.
|
||||||
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
||||||
err := fmt.Errorf(format, a...)
|
err := fmt.Errorf(format, a...)
|
||||||
fmt.Fprintln(f.out(), err)
|
if f.errorHandling != ContinueOnError {
|
||||||
f.usage()
|
fmt.Fprintln(f.out(), err)
|
||||||
|
f.usage()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,57 +915,61 @@ func (f *FlagSet) usage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
|
//--unknown (args will be empty)
|
||||||
if err := flag.Value.Set(value); err != nil {
|
//--unknown --next-flag ... (args will be --next-flag ...)
|
||||||
return f.failf("invalid argument %q for %s: %v", value, origArg, err)
|
//--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 {
|
first := args[0]
|
||||||
f.actual = make(map[NormalizedName]*Flag)
|
if first[0] == '-' {
|
||||||
|
//--unknown --next-flag ...
|
||||||
|
return args
|
||||||
}
|
}
|
||||||
f.actual[f.normalizeFlagName(flag.Name)] = flag
|
|
||||||
flag.Changed = true
|
//--unknown arg ... (args will be arg ...)
|
||||||
if len(flag.Deprecated) > 0 {
|
return args[1:]
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsShorthand(arg, shorthand string) bool {
|
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
|
||||||
// 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) {
|
|
||||||
a = args
|
a = args
|
||||||
name := s[2:]
|
name := s[2:]
|
||||||
if len(name) == 0 || name[0] == '-' || name[0] == '=' {
|
if len(name) == 0 || name[0] == '-' || name[0] == '=' {
|
||||||
err = f.failf("bad flag syntax: %s", s)
|
err = f.failf("bad flag syntax: %s", s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
split := strings.SplitN(name, "=", 2)
|
split := strings.SplitN(name, "=", 2)
|
||||||
name = split[0]
|
name = split[0]
|
||||||
flag, alreadythere := f.formal[f.normalizeFlagName(name)]
|
flag, exists := f.formal[f.normalizeFlagName(name)]
|
||||||
if !alreadythere {
|
|
||||||
if name == "help" { // special case for nice help message.
|
if !exists {
|
||||||
|
switch {
|
||||||
|
case name == "help":
|
||||||
f.usage()
|
f.usage()
|
||||||
return a, ErrHelp
|
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
|
||||||
}
|
}
|
||||||
err = f.failf("unknown flag: --%s", name)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var value string
|
var value string
|
||||||
if len(split) == 2 {
|
if len(split) == 2 {
|
||||||
// '--flag=arg'
|
// '--flag=arg'
|
||||||
value = split[1]
|
value = split[1]
|
||||||
} else if len(flag.NoOptDefVal) > 0 {
|
} else if flag.NoOptDefVal != "" {
|
||||||
// '--flag' (arg was optional)
|
// '--flag' (arg was optional)
|
||||||
value = flag.NoOptDefVal
|
value = flag.NoOptDefVal
|
||||||
} else if len(a) > 0 {
|
} else if len(a) > 0 {
|
||||||
|
@ -678,52 +981,86 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
|
||||||
err = f.failf("flag needs an argument: %s", s)
|
err = f.failf("flag needs an argument: %s", s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = f.setFlag(flag, value, s)
|
|
||||||
|
err = fn(flag, value)
|
||||||
|
if err != nil {
|
||||||
|
f.failf(err.Error())
|
||||||
|
}
|
||||||
return
|
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
|
outArgs = args
|
||||||
outShorts = shorthands[1:]
|
outShorts = shorthands[1:]
|
||||||
c := shorthands[0]
|
c := shorthands[0]
|
||||||
|
|
||||||
flag, alreadythere := f.shorthands[c]
|
flag, exists := f.shorthands[c]
|
||||||
if !alreadythere {
|
if !exists {
|
||||||
if c == 'h' { // special case for nice help message.
|
switch {
|
||||||
|
case c == 'h':
|
||||||
f.usage()
|
f.usage()
|
||||||
err = ErrHelp
|
err = ErrHelp
|
||||||
return
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
outArgs = stripUnknownFlagValue(outArgs)
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
//TODO continue on error
|
|
||||||
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var value string
|
var value string
|
||||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||||
|
// '-f=arg'
|
||||||
value = shorthands[2:]
|
value = shorthands[2:]
|
||||||
outShorts = ""
|
outShorts = ""
|
||||||
} else if len(flag.NoOptDefVal) > 0 {
|
} else if flag.NoOptDefVal != "" {
|
||||||
|
// '-f' (arg was optional)
|
||||||
value = flag.NoOptDefVal
|
value = flag.NoOptDefVal
|
||||||
} else if len(shorthands) > 1 {
|
} else if len(shorthands) > 1 {
|
||||||
|
// '-farg'
|
||||||
value = shorthands[1:]
|
value = shorthands[1:]
|
||||||
outShorts = ""
|
outShorts = ""
|
||||||
} else if len(args) > 0 {
|
} else if len(args) > 0 {
|
||||||
|
// '-f arg'
|
||||||
value = args[0]
|
value = args[0]
|
||||||
outArgs = args[1:]
|
outArgs = args[1:]
|
||||||
} else {
|
} else {
|
||||||
|
// '-f' (arg was required)
|
||||||
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
|
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
|
||||||
return
|
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
|
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
|
a = args
|
||||||
shorthands := s[1:]
|
shorthands := s[1:]
|
||||||
|
|
||||||
|
// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
|
||||||
for len(shorthands) > 0 {
|
for len(shorthands) > 0 {
|
||||||
shorthands, a, err = f.parseSingleShortArg(shorthands, args)
|
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -732,7 +1069,7 @@ func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlagSet) parseArgs(args []string) (err error) {
|
func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
|
||||||
for len(args) > 0 {
|
for len(args) > 0 {
|
||||||
s := args[0]
|
s := args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
|
@ -752,9 +1089,9 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
||||||
f.args = append(f.args, args...)
|
f.args = append(f.args, args...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
args, err = f.parseLongArg(s, args)
|
args, err = f.parseLongArg(s, args, fn)
|
||||||
} else {
|
} else {
|
||||||
args, err = f.parseShortArg(s, args)
|
args, err = f.parseShortArg(s, args, fn)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -768,9 +1105,50 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
||||||
// are defined and before flags are accessed by the program.
|
// are defined and before flags are accessed by the program.
|
||||||
// The return value will be ErrHelp if -help was set but not defined.
|
// The return value will be ErrHelp if -help was set but not defined.
|
||||||
func (f *FlagSet) Parse(arguments []string) error {
|
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.parsed = true
|
||||||
f.args = make([]string, 0, len(arguments))
|
f.args = make([]string, 0, len(arguments))
|
||||||
err := f.parseArgs(arguments)
|
|
||||||
|
err := f.parseArgs(arguments, fn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch f.errorHandling {
|
switch f.errorHandling {
|
||||||
case ContinueOnError:
|
case ContinueOnError:
|
||||||
|
@ -796,6 +1174,14 @@ func Parse() {
|
||||||
CommandLine.Parse(os.Args[1:])
|
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.
|
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||||
func SetInterspersed(interspersed bool) {
|
func SetInterspersed(interspersed bool) {
|
||||||
CommandLine.SetInterspersed(interspersed)
|
CommandLine.SetInterspersed(interspersed)
|
||||||
|
@ -806,17 +1192,18 @@ func Parsed() bool {
|
||||||
return CommandLine.Parsed()
|
return CommandLine.Parsed()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default set of command-line flags, parsed from os.Args.
|
// CommandLine is the default set of command-line flags, parsed from os.Args.
|
||||||
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
|
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
|
||||||
|
|
||||||
// NewFlagSet returns a new, empty flag set with the specified name and
|
// NewFlagSet returns a new, empty flag set with the specified name,
|
||||||
// error handling property.
|
// error handling property and SortFlags set to true.
|
||||||
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
|
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
|
||||||
f := &FlagSet{
|
f := &FlagSet{
|
||||||
name: name,
|
name: name,
|
||||||
errorHandling: errorHandling,
|
errorHandling: errorHandling,
|
||||||
argsLenAtDash: -1,
|
argsLenAtDash: -1,
|
||||||
interspersed: true,
|
interspersed: true,
|
||||||
|
SortFlags: true,
|
||||||
}
|
}
|
||||||
return f
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- float32 Value
|
// -- float32 Value
|
||||||
type float32Value float32
|
type float32Value float32
|
||||||
|
@ -23,7 +20,7 @@ func (f *float32Value) Type() string {
|
||||||
return "float32"
|
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) {
|
func float32Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseFloat(sval, 32)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- float64 Value
|
// -- float64 Value
|
||||||
type float64Value float64
|
type float64Value float64
|
||||||
|
@ -23,7 +20,7 @@ func (f *float64Value) Type() string {
|
||||||
return "float64"
|
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) {
|
func float64Conv(sval string) (interface{}, error) {
|
||||||
return strconv.ParseFloat(sval, 64)
|
return strconv.ParseFloat(sval, 64)
|
||||||
|
|
14
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
14
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
|
@ -6,13 +6,10 @@ package pflag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
goflag "flag"
|
goflag "flag"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Print
|
|
||||||
|
|
||||||
// flagValueWrapper implements pflag.Value around a flag.Value. The main
|
// flagValueWrapper implements pflag.Value around a flag.Value. The main
|
||||||
// difference here is the addition of the Type method that returns a string
|
// 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
|
// name of the type. As this is generally unknown, we approximate that with
|
||||||
|
@ -61,6 +58,9 @@ func (v *flagValueWrapper) Type() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
|
// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
|
||||||
|
// If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei
|
||||||
|
// with both `-v` and `--v` in flags. If the golang flag was more than a single
|
||||||
|
// character (ex: `verbose`) it will only be accessible via `--verbose`
|
||||||
func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
|
func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
|
||||||
// Remember the default value as a string; it won't change.
|
// Remember the default value as a string; it won't change.
|
||||||
flag := &Flag{
|
flag := &Flag{
|
||||||
|
@ -71,6 +71,10 @@ func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
|
||||||
//DefValue: goflag.DefValue,
|
//DefValue: goflag.DefValue,
|
||||||
DefValue: goflag.Value.String(),
|
DefValue: goflag.Value.String(),
|
||||||
}
|
}
|
||||||
|
// Ex: if the golang flag was -v, allow both -v and --v to work
|
||||||
|
if len(flag.Name) == 1 {
|
||||||
|
flag.Shorthand = flag.Name
|
||||||
|
}
|
||||||
if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
|
if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
|
||||||
flag.NoOptDefVal = "true"
|
flag.NoOptDefVal = "true"
|
||||||
}
|
}
|
||||||
|
@ -94,4 +98,8 @@ func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
|
||||||
newSet.VisitAll(func(goflag *goflag.Flag) {
|
newSet.VisitAll(func(goflag *goflag.Flag) {
|
||||||
f.AddGoFlag(goflag)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int Value
|
// -- int Value
|
||||||
type intValue int
|
type intValue int
|
||||||
|
@ -23,7 +20,7 @@ func (i *intValue) Type() string {
|
||||||
return "int"
|
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) {
|
func intConv(sval string) (interface{}, error) {
|
||||||
return strconv.Atoi(sval)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int32 Value
|
// -- int32 Value
|
||||||
type int32Value int32
|
type int32Value int32
|
||||||
|
@ -23,7 +20,7 @@ func (i *int32Value) Type() string {
|
||||||
return "int32"
|
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) {
|
func int32Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseInt(sval, 0, 32)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int64 Value
|
// -- int64 Value
|
||||||
type int64Value int64
|
type int64Value int64
|
||||||
|
@ -23,7 +20,7 @@ func (i *int64Value) Type() string {
|
||||||
return "int64"
|
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) {
|
func int64Conv(sval string) (interface{}, error) {
|
||||||
return strconv.ParseInt(sval, 0, 64)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int8 Value
|
// -- int8 Value
|
||||||
type int8Value int8
|
type int8Value int8
|
||||||
|
@ -23,7 +20,7 @@ func (i *int8Value) Type() string {
|
||||||
return "int8"
|
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) {
|
func int8Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseInt(sval, 0, 8)
|
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"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = strings.TrimSpace
|
|
||||||
|
|
||||||
// -- net.IP value
|
// -- net.IP value
|
||||||
type ipValue net.IP
|
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"
|
return "ipNet"
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = strings.TrimSpace
|
|
||||||
|
|
||||||
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
|
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
|
||||||
*p = val
|
*p = val
|
||||||
return (*ipNetValue)(p)
|
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
|
package pflag
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// -- string Value
|
// -- string Value
|
||||||
type stringValue string
|
type stringValue string
|
||||||
|
|
||||||
|
@ -18,7 +16,7 @@ func (s *stringValue) Type() string {
|
||||||
return "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) {
|
func stringConv(sval string) (interface{}, error) {
|
||||||
return sval, nil
|
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)
|
||||||
|
}
|
60
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
60
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
|
@ -1,12 +1,11 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"bytes"
|
||||||
|
"encoding/csv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Fprint
|
|
||||||
|
|
||||||
// -- stringSlice Value
|
// -- stringSlice Value
|
||||||
type stringSliceValue struct {
|
type stringSliceValue struct {
|
||||||
value *[]string
|
value *[]string
|
||||||
|
@ -20,8 +19,31 @@ func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
|
||||||
return ssv
|
return ssv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readAsCSV(val string) ([]string, error) {
|
||||||
|
if val == "" {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
stringReader := strings.NewReader(val)
|
||||||
|
csvReader := csv.NewReader(stringReader)
|
||||||
|
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 {
|
func (s *stringSliceValue) Set(val string) error {
|
||||||
v := strings.Split(val, ",")
|
v, err := readAsCSV(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if !s.changed {
|
if !s.changed {
|
||||||
*s.value = v
|
*s.value = v
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,16 +57,18 @@ func (s *stringSliceValue) Type() string {
|
||||||
return "stringSlice"
|
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) {
|
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
|
// An empty string would cause a slice with one (empty) string
|
||||||
if len(sval) == 0 {
|
if len(sval) == 0 {
|
||||||
return []string{}, nil
|
return []string{}, nil
|
||||||
}
|
}
|
||||||
v := strings.Split(sval, ",")
|
return readAsCSV(sval)
|
||||||
return v, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStringSlice return the []string value of a flag with the given name
|
// GetStringSlice return the []string value of a flag with the given name
|
||||||
|
@ -58,6 +82,11 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
|
||||||
|
|
||||||
// StringSliceVar defines a string flag with specified name, default value, and usage string.
|
// 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.
|
// 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) {
|
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||||
f.VarP(newStringSliceValue(value, p), name, "", usage)
|
f.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
@ -69,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.
|
// 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.
|
// 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) {
|
func StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||||
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
|
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
@ -80,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.
|
// 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.
|
// 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 {
|
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
|
||||||
p := []string{}
|
p := []string{}
|
||||||
f.StringSliceVarP(&p, name, "", value, usage)
|
f.StringSliceVarP(&p, name, "", value, usage)
|
||||||
|
@ -95,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.
|
// 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.
|
// 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 {
|
func StringSlice(name string, value []string, usage string) *[]string {
|
||||||
return CommandLine.StringSliceP(name, "", value, usage)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint Value
|
// -- uint Value
|
||||||
type uintValue uint
|
type uintValue uint
|
||||||
|
@ -23,7 +20,7 @@ func (i *uintValue) Type() string {
|
||||||
return "uint"
|
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) {
|
func uintConv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseUint(sval, 0, 0)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint16 value
|
// -- uint16 value
|
||||||
type uint16Value uint16
|
type uint16Value uint16
|
||||||
|
@ -12,7 +9,7 @@ func newUint16Value(val uint16, p *uint16) *uint16Value {
|
||||||
*p = val
|
*p = val
|
||||||
return (*uint16Value)(p)
|
return (*uint16Value)(p)
|
||||||
}
|
}
|
||||||
func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) }
|
|
||||||
func (i *uint16Value) Set(s string) error {
|
func (i *uint16Value) Set(s string) error {
|
||||||
v, err := strconv.ParseUint(s, 0, 16)
|
v, err := strconv.ParseUint(s, 0, 16)
|
||||||
*i = uint16Value(v)
|
*i = uint16Value(v)
|
||||||
|
@ -23,6 +20,8 @@ func (i *uint16Value) Type() string {
|
||||||
return "uint16"
|
return "uint16"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
func uint16Conv(sval string) (interface{}, error) {
|
func uint16Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseUint(sval, 0, 16)
|
v, err := strconv.ParseUint(sval, 0, 16)
|
||||||
if err != nil {
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint16 value
|
// -- uint32 value
|
||||||
type uint32Value uint32
|
type uint32Value uint32
|
||||||
|
|
||||||
func newUint32Value(val uint32, p *uint32) *uint32Value {
|
func newUint32Value(val uint32, p *uint32) *uint32Value {
|
||||||
*p = val
|
*p = val
|
||||||
return (*uint32Value)(p)
|
return (*uint32Value)(p)
|
||||||
}
|
}
|
||||||
func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) }
|
|
||||||
func (i *uint32Value) Set(s string) error {
|
func (i *uint32Value) Set(s string) error {
|
||||||
v, err := strconv.ParseUint(s, 0, 32)
|
v, err := strconv.ParseUint(s, 0, 32)
|
||||||
*i = uint32Value(v)
|
*i = uint32Value(v)
|
||||||
|
@ -23,6 +20,8 @@ func (i *uint32Value) Type() string {
|
||||||
return "uint32"
|
return "uint32"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
func uint32Conv(sval string) (interface{}, error) {
|
func uint32Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseUint(sval, 0, 32)
|
v, err := strconv.ParseUint(sval, 0, 32)
|
||||||
if err != nil {
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint64 Value
|
// -- uint64 Value
|
||||||
type uint64Value uint64
|
type uint64Value uint64
|
||||||
|
@ -23,7 +20,7 @@ func (i *uint64Value) Type() string {
|
||||||
return "uint64"
|
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) {
|
func uint64Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseUint(sval, 0, 64)
|
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
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint8 Value
|
// -- uint8 Value
|
||||||
type uint8Value uint8
|
type uint8Value uint8
|
||||||
|
@ -23,7 +20,7 @@ func (i *uint8Value) Type() string {
|
||||||
return "uint8"
|
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) {
|
func uint8Conv(sval string) (interface{}, error) {
|
||||||
v, err := strconv.ParseUint(sval, 0, 8)
|
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)
|
||||||
|
}
|
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google 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,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
56
vendor/golang.org/x/net/context/context.go
generated
vendored
Normal file
56
vendor/golang.org/x/net/context/context.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package context defines the Context type, which carries deadlines,
|
||||||
|
// cancelation signals, and other request-scoped values across API boundaries
|
||||||
|
// and between processes.
|
||||||
|
// As of Go 1.7 this package is available in the standard library under the
|
||||||
|
// name context. https://golang.org/pkg/context.
|
||||||
|
//
|
||||||
|
// Incoming requests to a server should create a Context, and outgoing calls to
|
||||||
|
// servers should accept a Context. The chain of function calls between must
|
||||||
|
// propagate the Context, optionally replacing it with a modified copy created
|
||||||
|
// using WithDeadline, WithTimeout, WithCancel, or WithValue.
|
||||||
|
//
|
||||||
|
// Programs that use Contexts should follow these rules to keep interfaces
|
||||||
|
// consistent across packages and enable static analysis tools to check context
|
||||||
|
// propagation:
|
||||||
|
//
|
||||||
|
// Do not store Contexts inside a struct type; instead, pass a Context
|
||||||
|
// explicitly to each function that needs it. The Context should be the first
|
||||||
|
// parameter, typically named ctx:
|
||||||
|
//
|
||||||
|
// func DoSomething(ctx context.Context, arg Arg) error {
|
||||||
|
// // ... use ctx ...
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Do not pass a nil Context, even if a function permits it. Pass context.TODO
|
||||||
|
// if you are unsure about which Context to use.
|
||||||
|
//
|
||||||
|
// Use context Values only for request-scoped data that transits processes and
|
||||||
|
// APIs, not for passing optional parameters to functions.
|
||||||
|
//
|
||||||
|
// The same Context may be passed to functions running in different goroutines;
|
||||||
|
// Contexts are safe for simultaneous use by multiple goroutines.
|
||||||
|
//
|
||||||
|
// See http://blog.golang.org/context for example code for a server that uses
|
||||||
|
// Contexts.
|
||||||
|
package context // import "golang.org/x/net/context"
|
||||||
|
|
||||||
|
// Background returns a non-nil, empty Context. It is never canceled, has no
|
||||||
|
// values, and has no deadline. It is typically used by the main function,
|
||||||
|
// initialization, and tests, and as the top-level Context for incoming
|
||||||
|
// requests.
|
||||||
|
func Background() Context {
|
||||||
|
return background
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO returns a non-nil, empty Context. Code should use context.TODO when
|
||||||
|
// it's unclear which Context to use or it is not yet available (because the
|
||||||
|
// surrounding function has not yet been extended to accept a Context
|
||||||
|
// parameter). TODO is recognized by static analysis tools that determine
|
||||||
|
// whether Contexts are propagated correctly in a program.
|
||||||
|
func TODO() Context {
|
||||||
|
return todo
|
||||||
|
}
|
74
vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
Normal file
74
vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
|
||||||
|
package ctxhttp // import "golang.org/x/net/context/ctxhttp"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Do sends an HTTP request with the provided http.Client and returns
|
||||||
|
// an HTTP response.
|
||||||
|
//
|
||||||
|
// If the client is nil, http.DefaultClient is used.
|
||||||
|
//
|
||||||
|
// The provided ctx must be non-nil. If it is canceled or times out,
|
||||||
|
// ctx.Err() will be returned.
|
||||||
|
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
|
||||||
|
if client == nil {
|
||||||
|
client = http.DefaultClient
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req.WithContext(ctx))
|
||||||
|
// If we got an error, and the context has been canceled,
|
||||||
|
// the context's error is probably more useful.
|
||||||
|
if err != nil {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
err = ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get issues a GET request via the Do function.
|
||||||
|
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head issues a HEAD request via the Do function.
|
||||||
|
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("HEAD", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post issues a POST request via the Do function.
|
||||||
|
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("POST", url, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", bodyType)
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostForm issues a POST request via the Do function.
|
||||||
|
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
|
||||||
|
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||||
|
}
|
147
vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
generated
vendored
Normal file
147
vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.7
|
||||||
|
|
||||||
|
package ctxhttp // import "golang.org/x/net/context/ctxhttp"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func nop() {}
|
||||||
|
|
||||||
|
var (
|
||||||
|
testHookContextDoneBeforeHeaders = nop
|
||||||
|
testHookDoReturned = nop
|
||||||
|
testHookDidBodyClose = nop
|
||||||
|
)
|
||||||
|
|
||||||
|
// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
|
||||||
|
// If the client is nil, http.DefaultClient is used.
|
||||||
|
// If the context is canceled or times out, ctx.Err() will be returned.
|
||||||
|
func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
|
||||||
|
if client == nil {
|
||||||
|
client = http.DefaultClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(djd): Respect any existing value of req.Cancel.
|
||||||
|
cancel := make(chan struct{})
|
||||||
|
req.Cancel = cancel
|
||||||
|
|
||||||
|
type responseAndError struct {
|
||||||
|
resp *http.Response
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
result := make(chan responseAndError, 1)
|
||||||
|
|
||||||
|
// Make local copies of test hooks closed over by goroutines below.
|
||||||
|
// Prevents data races in tests.
|
||||||
|
testHookDoReturned := testHookDoReturned
|
||||||
|
testHookDidBodyClose := testHookDidBodyClose
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
testHookDoReturned()
|
||||||
|
result <- responseAndError{resp, err}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var resp *http.Response
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
testHookContextDoneBeforeHeaders()
|
||||||
|
close(cancel)
|
||||||
|
// Clean up after the goroutine calling client.Do:
|
||||||
|
go func() {
|
||||||
|
if r := <-result; r.resp != nil {
|
||||||
|
testHookDidBodyClose()
|
||||||
|
r.resp.Body.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil, ctx.Err()
|
||||||
|
case r := <-result:
|
||||||
|
var err error
|
||||||
|
resp, err = r.resp, r.err
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
close(cancel)
|
||||||
|
case <-c:
|
||||||
|
// The response's Body is closed.
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resp.Body = ¬ifyingReader{resp.Body, c}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get issues a GET request via the Do function.
|
||||||
|
func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head issues a HEAD request via the Do function.
|
||||||
|
func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("HEAD", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post issues a POST request via the Do function.
|
||||||
|
func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
|
||||||
|
req, err := http.NewRequest("POST", url, body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", bodyType)
|
||||||
|
return Do(ctx, client, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostForm issues a POST request via the Do function.
|
||||||
|
func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
|
||||||
|
return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// notifyingReader is an io.ReadCloser that closes the notify channel after
|
||||||
|
// Close is called or a Read fails on the underlying ReadCloser.
|
||||||
|
type notifyingReader struct {
|
||||||
|
io.ReadCloser
|
||||||
|
notify chan<- struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *notifyingReader) Read(p []byte) (int, error) {
|
||||||
|
n, err := r.ReadCloser.Read(p)
|
||||||
|
if err != nil && r.notify != nil {
|
||||||
|
close(r.notify)
|
||||||
|
r.notify = nil
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *notifyingReader) Close() error {
|
||||||
|
err := r.ReadCloser.Close()
|
||||||
|
if r.notify != nil {
|
||||||
|
close(r.notify)
|
||||||
|
r.notify = nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
72
vendor/golang.org/x/net/context/go17.go
generated
vendored
Normal file
72
vendor/golang.org/x/net/context/go17.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context" // standard library's context, as of Go 1.7
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
todo = context.TODO()
|
||||||
|
background = context.Background()
|
||||||
|
)
|
||||||
|
|
||||||
|
// Canceled is the error returned by Context.Err when the context is canceled.
|
||||||
|
var Canceled = context.Canceled
|
||||||
|
|
||||||
|
// DeadlineExceeded is the error returned by Context.Err when the context's
|
||||||
|
// deadline passes.
|
||||||
|
var DeadlineExceeded = context.DeadlineExceeded
|
||||||
|
|
||||||
|
// WithCancel returns a copy of parent with a new Done channel. The returned
|
||||||
|
// context's Done channel is closed when the returned cancel function is called
|
||||||
|
// or when the parent context's Done channel is closed, whichever happens first.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||||
|
ctx, f := context.WithCancel(parent)
|
||||||
|
return ctx, CancelFunc(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
||||||
|
// to be no later than d. If the parent's deadline is already earlier than d,
|
||||||
|
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
|
||||||
|
// context's Done channel is closed when the deadline expires, when the returned
|
||||||
|
// cancel function is called, or when the parent context's Done channel is
|
||||||
|
// closed, whichever happens first.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||||
|
ctx, f := context.WithDeadline(parent, deadline)
|
||||||
|
return ctx, CancelFunc(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete:
|
||||||
|
//
|
||||||
|
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||||
|
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||||
|
// return slowOperation(ctx)
|
||||||
|
// }
|
||||||
|
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
|
||||||
|
return WithDeadline(parent, time.Now().Add(timeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithValue returns a copy of parent in which the value associated with key is
|
||||||
|
// val.
|
||||||
|
//
|
||||||
|
// Use context Values only for request-scoped data that transits processes and
|
||||||
|
// APIs, not for passing optional parameters to functions.
|
||||||
|
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||||
|
return context.WithValue(parent, key, val)
|
||||||
|
}
|
20
vendor/golang.org/x/net/context/go19.go
generated
vendored
Normal file
20
vendor/golang.org/x/net/context/go19.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.9
|
||||||
|
|
||||||
|
package context
|
||||||
|
|
||||||
|
import "context" // standard library's context, as of Go 1.7
|
||||||
|
|
||||||
|
// A Context carries a deadline, a cancelation signal, and other values across
|
||||||
|
// API boundaries.
|
||||||
|
//
|
||||||
|
// Context's methods may be called by multiple goroutines simultaneously.
|
||||||
|
type Context = context.Context
|
||||||
|
|
||||||
|
// A CancelFunc tells an operation to abandon its work.
|
||||||
|
// A CancelFunc does not wait for the work to stop.
|
||||||
|
// After the first call, subsequent calls to a CancelFunc do nothing.
|
||||||
|
type CancelFunc = context.CancelFunc
|
300
vendor/golang.org/x/net/context/pre_go17.go
generated
vendored
Normal file
300
vendor/golang.org/x/net/context/pre_go17.go
generated
vendored
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.7
|
||||||
|
|
||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
||||||
|
// struct{}, since vars of this type must have distinct addresses.
|
||||||
|
type emptyCtx int
|
||||||
|
|
||||||
|
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*emptyCtx) Done() <-chan struct{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*emptyCtx) Err() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*emptyCtx) Value(key interface{}) interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *emptyCtx) String() string {
|
||||||
|
switch e {
|
||||||
|
case background:
|
||||||
|
return "context.Background"
|
||||||
|
case todo:
|
||||||
|
return "context.TODO"
|
||||||
|
}
|
||||||
|
return "unknown empty Context"
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
background = new(emptyCtx)
|
||||||
|
todo = new(emptyCtx)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Canceled is the error returned by Context.Err when the context is canceled.
|
||||||
|
var Canceled = errors.New("context canceled")
|
||||||
|
|
||||||
|
// DeadlineExceeded is the error returned by Context.Err when the context's
|
||||||
|
// deadline passes.
|
||||||
|
var DeadlineExceeded = errors.New("context deadline exceeded")
|
||||||
|
|
||||||
|
// WithCancel returns a copy of parent with a new Done channel. The returned
|
||||||
|
// context's Done channel is closed when the returned cancel function is called
|
||||||
|
// or when the parent context's Done channel is closed, whichever happens first.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||||
|
c := newCancelCtx(parent)
|
||||||
|
propagateCancel(parent, c)
|
||||||
|
return c, func() { c.cancel(true, Canceled) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// newCancelCtx returns an initialized cancelCtx.
|
||||||
|
func newCancelCtx(parent Context) *cancelCtx {
|
||||||
|
return &cancelCtx{
|
||||||
|
Context: parent,
|
||||||
|
done: make(chan struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// propagateCancel arranges for child to be canceled when parent is.
|
||||||
|
func propagateCancel(parent Context, child canceler) {
|
||||||
|
if parent.Done() == nil {
|
||||||
|
return // parent is never canceled
|
||||||
|
}
|
||||||
|
if p, ok := parentCancelCtx(parent); ok {
|
||||||
|
p.mu.Lock()
|
||||||
|
if p.err != nil {
|
||||||
|
// parent has already been canceled
|
||||||
|
child.cancel(false, p.err)
|
||||||
|
} else {
|
||||||
|
if p.children == nil {
|
||||||
|
p.children = make(map[canceler]bool)
|
||||||
|
}
|
||||||
|
p.children[child] = true
|
||||||
|
}
|
||||||
|
p.mu.Unlock()
|
||||||
|
} else {
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-parent.Done():
|
||||||
|
child.cancel(false, parent.Err())
|
||||||
|
case <-child.Done():
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parentCancelCtx follows a chain of parent references until it finds a
|
||||||
|
// *cancelCtx. This function understands how each of the concrete types in this
|
||||||
|
// package represents its parent.
|
||||||
|
func parentCancelCtx(parent Context) (*cancelCtx, bool) {
|
||||||
|
for {
|
||||||
|
switch c := parent.(type) {
|
||||||
|
case *cancelCtx:
|
||||||
|
return c, true
|
||||||
|
case *timerCtx:
|
||||||
|
return c.cancelCtx, true
|
||||||
|
case *valueCtx:
|
||||||
|
parent = c.Context
|
||||||
|
default:
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeChild removes a context from its parent.
|
||||||
|
func removeChild(parent Context, child canceler) {
|
||||||
|
p, ok := parentCancelCtx(parent)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.mu.Lock()
|
||||||
|
if p.children != nil {
|
||||||
|
delete(p.children, child)
|
||||||
|
}
|
||||||
|
p.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A canceler is a context type that can be canceled directly. The
|
||||||
|
// implementations are *cancelCtx and *timerCtx.
|
||||||
|
type canceler interface {
|
||||||
|
cancel(removeFromParent bool, err error)
|
||||||
|
Done() <-chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A cancelCtx can be canceled. When canceled, it also cancels any children
|
||||||
|
// that implement canceler.
|
||||||
|
type cancelCtx struct {
|
||||||
|
Context
|
||||||
|
|
||||||
|
done chan struct{} // closed by the first cancel call.
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
children map[canceler]bool // set to nil by the first cancel call
|
||||||
|
err error // set to non-nil by the first cancel call
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cancelCtx) Done() <-chan struct{} {
|
||||||
|
return c.done
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cancelCtx) Err() error {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
return c.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *cancelCtx) String() string {
|
||||||
|
return fmt.Sprintf("%v.WithCancel", c.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel closes c.done, cancels each of c's children, and, if
|
||||||
|
// removeFromParent is true, removes c from its parent's children.
|
||||||
|
func (c *cancelCtx) cancel(removeFromParent bool, err error) {
|
||||||
|
if err == nil {
|
||||||
|
panic("context: internal error: missing cancel error")
|
||||||
|
}
|
||||||
|
c.mu.Lock()
|
||||||
|
if c.err != nil {
|
||||||
|
c.mu.Unlock()
|
||||||
|
return // already canceled
|
||||||
|
}
|
||||||
|
c.err = err
|
||||||
|
close(c.done)
|
||||||
|
for child := range c.children {
|
||||||
|
// NOTE: acquiring the child's lock while holding parent's lock.
|
||||||
|
child.cancel(false, err)
|
||||||
|
}
|
||||||
|
c.children = nil
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
|
if removeFromParent {
|
||||||
|
removeChild(c.Context, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
||||||
|
// to be no later than d. If the parent's deadline is already earlier than d,
|
||||||
|
// WithDeadline(parent, d) is semantically equivalent to parent. The returned
|
||||||
|
// context's Done channel is closed when the deadline expires, when the returned
|
||||||
|
// cancel function is called, or when the parent context's Done channel is
|
||||||
|
// closed, whichever happens first.
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete.
|
||||||
|
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||||
|
if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
|
||||||
|
// The current deadline is already sooner than the new one.
|
||||||
|
return WithCancel(parent)
|
||||||
|
}
|
||||||
|
c := &timerCtx{
|
||||||
|
cancelCtx: newCancelCtx(parent),
|
||||||
|
deadline: deadline,
|
||||||
|
}
|
||||||
|
propagateCancel(parent, c)
|
||||||
|
d := deadline.Sub(time.Now())
|
||||||
|
if d <= 0 {
|
||||||
|
c.cancel(true, DeadlineExceeded) // deadline has already passed
|
||||||
|
return c, func() { c.cancel(true, Canceled) }
|
||||||
|
}
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
if c.err == nil {
|
||||||
|
c.timer = time.AfterFunc(d, func() {
|
||||||
|
c.cancel(true, DeadlineExceeded)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return c, func() { c.cancel(true, Canceled) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
|
||||||
|
// implement Done and Err. It implements cancel by stopping its timer then
|
||||||
|
// delegating to cancelCtx.cancel.
|
||||||
|
type timerCtx struct {
|
||||||
|
*cancelCtx
|
||||||
|
timer *time.Timer // Under cancelCtx.mu.
|
||||||
|
|
||||||
|
deadline time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
|
||||||
|
return c.deadline, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *timerCtx) String() string {
|
||||||
|
return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *timerCtx) cancel(removeFromParent bool, err error) {
|
||||||
|
c.cancelCtx.cancel(false, err)
|
||||||
|
if removeFromParent {
|
||||||
|
// Remove this timerCtx from its parent cancelCtx's children.
|
||||||
|
removeChild(c.cancelCtx.Context, c)
|
||||||
|
}
|
||||||
|
c.mu.Lock()
|
||||||
|
if c.timer != nil {
|
||||||
|
c.timer.Stop()
|
||||||
|
c.timer = nil
|
||||||
|
}
|
||||||
|
c.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
||||||
|
//
|
||||||
|
// Canceling this context releases resources associated with it, so code should
|
||||||
|
// call cancel as soon as the operations running in this Context complete:
|
||||||
|
//
|
||||||
|
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||||
|
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||||
|
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||||
|
// return slowOperation(ctx)
|
||||||
|
// }
|
||||||
|
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
|
||||||
|
return WithDeadline(parent, time.Now().Add(timeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithValue returns a copy of parent in which the value associated with key is
|
||||||
|
// val.
|
||||||
|
//
|
||||||
|
// Use context Values only for request-scoped data that transits processes and
|
||||||
|
// APIs, not for passing optional parameters to functions.
|
||||||
|
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||||
|
return &valueCtx{parent, key, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A valueCtx carries a key-value pair. It implements Value for that key and
|
||||||
|
// delegates all other calls to the embedded Context.
|
||||||
|
type valueCtx struct {
|
||||||
|
Context
|
||||||
|
key, val interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *valueCtx) String() string {
|
||||||
|
return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *valueCtx) Value(key interface{}) interface{} {
|
||||||
|
if c.key == key {
|
||||||
|
return c.val
|
||||||
|
}
|
||||||
|
return c.Context.Value(key)
|
||||||
|
}
|
109
vendor/golang.org/x/net/context/pre_go19.go
generated
vendored
Normal file
109
vendor/golang.org/x/net/context/pre_go19.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.9
|
||||||
|
|
||||||
|
package context
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// A Context carries a deadline, a cancelation signal, and other values across
|
||||||
|
// API boundaries.
|
||||||
|
//
|
||||||
|
// Context's methods may be called by multiple goroutines simultaneously.
|
||||||
|
type Context interface {
|
||||||
|
// Deadline returns the time when work done on behalf of this context
|
||||||
|
// should be canceled. Deadline returns ok==false when no deadline is
|
||||||
|
// set. Successive calls to Deadline return the same results.
|
||||||
|
Deadline() (deadline time.Time, ok bool)
|
||||||
|
|
||||||
|
// Done returns a channel that's closed when work done on behalf of this
|
||||||
|
// context should be canceled. Done may return nil if this context can
|
||||||
|
// never be canceled. Successive calls to Done return the same value.
|
||||||
|
//
|
||||||
|
// WithCancel arranges for Done to be closed when cancel is called;
|
||||||
|
// WithDeadline arranges for Done to be closed when the deadline
|
||||||
|
// expires; WithTimeout arranges for Done to be closed when the timeout
|
||||||
|
// elapses.
|
||||||
|
//
|
||||||
|
// Done is provided for use in select statements:
|
||||||
|
//
|
||||||
|
// // Stream generates values with DoSomething and sends them to out
|
||||||
|
// // until DoSomething returns an error or ctx.Done is closed.
|
||||||
|
// func Stream(ctx context.Context, out chan<- Value) error {
|
||||||
|
// for {
|
||||||
|
// v, err := DoSomething(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// select {
|
||||||
|
// case <-ctx.Done():
|
||||||
|
// return ctx.Err()
|
||||||
|
// case out <- v:
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// See http://blog.golang.org/pipelines for more examples of how to use
|
||||||
|
// a Done channel for cancelation.
|
||||||
|
Done() <-chan struct{}
|
||||||
|
|
||||||
|
// Err returns a non-nil error value after Done is closed. Err returns
|
||||||
|
// Canceled if the context was canceled or DeadlineExceeded if the
|
||||||
|
// context's deadline passed. No other values for Err are defined.
|
||||||
|
// After Done is closed, successive calls to Err return the same value.
|
||||||
|
Err() error
|
||||||
|
|
||||||
|
// Value returns the value associated with this context for key, or nil
|
||||||
|
// if no value is associated with key. Successive calls to Value with
|
||||||
|
// the same key returns the same result.
|
||||||
|
//
|
||||||
|
// Use context values only for request-scoped data that transits
|
||||||
|
// processes and API boundaries, not for passing optional parameters to
|
||||||
|
// functions.
|
||||||
|
//
|
||||||
|
// A key identifies a specific value in a Context. Functions that wish
|
||||||
|
// to store values in Context typically allocate a key in a global
|
||||||
|
// variable then use that key as the argument to context.WithValue and
|
||||||
|
// Context.Value. A key can be any type that supports equality;
|
||||||
|
// packages should define keys as an unexported type to avoid
|
||||||
|
// collisions.
|
||||||
|
//
|
||||||
|
// Packages that define a Context key should provide type-safe accessors
|
||||||
|
// for the values stores using that key:
|
||||||
|
//
|
||||||
|
// // Package user defines a User type that's stored in Contexts.
|
||||||
|
// package user
|
||||||
|
//
|
||||||
|
// import "golang.org/x/net/context"
|
||||||
|
//
|
||||||
|
// // User is the type of value stored in the Contexts.
|
||||||
|
// type User struct {...}
|
||||||
|
//
|
||||||
|
// // key is an unexported type for keys defined in this package.
|
||||||
|
// // This prevents collisions with keys defined in other packages.
|
||||||
|
// type key int
|
||||||
|
//
|
||||||
|
// // userKey is the key for user.User values in Contexts. It is
|
||||||
|
// // unexported; clients use user.NewContext and user.FromContext
|
||||||
|
// // instead of using this key directly.
|
||||||
|
// var userKey key = 0
|
||||||
|
//
|
||||||
|
// // NewContext returns a new Context that carries value u.
|
||||||
|
// func NewContext(ctx context.Context, u *User) context.Context {
|
||||||
|
// return context.WithValue(ctx, userKey, u)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // FromContext returns the User value stored in ctx, if any.
|
||||||
|
// func FromContext(ctx context.Context) (*User, bool) {
|
||||||
|
// u, ok := ctx.Value(userKey).(*User)
|
||||||
|
// return u, ok
|
||||||
|
// }
|
||||||
|
Value(key interface{}) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A CancelFunc tells an operation to abandon its work.
|
||||||
|
// A CancelFunc does not wait for the work to stop.
|
||||||
|
// After the first call, subsequent calls to a CancelFunc do nothing.
|
||||||
|
type CancelFunc func()
|
23
vendor/gopkg.in/validator.v2/.gitignore
generated
vendored
Normal file
23
vendor/gopkg.in/validator.v2/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
10
vendor/gopkg.in/validator.v2/.travis.yml
generated
vendored
Normal file
10
vendor/gopkg.in/validator.v2/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.5
|
||||||
|
- 1.6
|
||||||
|
- 1.7
|
||||||
|
go_import_path: gopkg.in/validator.v2
|
||||||
|
script:
|
||||||
|
- go test -race -v -bench=.
|
||||||
|
notifications:
|
||||||
|
email: false
|
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.
|
188
vendor/gopkg.in/validator.v2/README.md
generated
vendored
Normal file
188
vendor/gopkg.in/validator.v2/README.md
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
Package validator
|
||||||
|
================
|
||||||
|
|
||||||
|
Package validator implements variable validations
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
Just use go get.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get gopkg.in/validator.v2
|
||||||
|
```
|
||||||
|
|
||||||
|
And then just import the package into your own code.
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"gopkg.in/validator.v2"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
Please see http://godoc.org/gopkg.in/validator.v2 for detailed usage docs.
|
||||||
|
A simple example would be.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type NewUserRequest struct {
|
||||||
|
Username string `validate:"min=3,max=40,regexp=^[a-zA-Z]*$"`
|
||||||
|
Name string `validate:"nonzero"`
|
||||||
|
Age int `validate:"min=21"`
|
||||||
|
Password string `validate:"min=8"`
|
||||||
|
}
|
||||||
|
|
||||||
|
nur := NewUserRequest{Username: "something", Age: 20}
|
||||||
|
if errs := validator.Validate(nur); errs != nil {
|
||||||
|
// values not valid, deal with errors here
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Builtin validators
|
||||||
|
|
||||||
|
Here is the list of validators buildin in the package. Validators buildin
|
||||||
|
will check the element pointed to if the value to check is a pointer.
|
||||||
|
The `nil` pointer is treated as a valid value by validators buildin other
|
||||||
|
than `nonzero`, so you should to use `nonzero` if you don't want to
|
||||||
|
accept a `nil` pointer.
|
||||||
|
|
||||||
|
```
|
||||||
|
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.) For structs, it
|
||||||
|
will not check to see if the struct itself has all zero
|
||||||
|
values, instead use a pointer or put nonzero on the struct's
|
||||||
|
keys that you care about. (Usage: nonzero)
|
||||||
|
|
||||||
|
regexp
|
||||||
|
Only valid for string types, it will validator that the
|
||||||
|
value matches the regular expression provided as parameter.
|
||||||
|
(Usage: regexp=^a.*b$)
|
||||||
|
```
|
||||||
|
|
||||||
|
Custom validators
|
||||||
|
|
||||||
|
It is possible to define custom validators by using SetValidationFunc.
|
||||||
|
First, one needs to create a validation function.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Very simple validator
|
||||||
|
func notZZ(v interface{}, param string) error {
|
||||||
|
st := reflect.ValueOf(v)
|
||||||
|
if st.Kind() != reflect.String {
|
||||||
|
return errors.New("notZZ only validates strings")
|
||||||
|
}
|
||||||
|
if st.String() == "ZZ" {
|
||||||
|
return errors.New("value cannot be ZZ")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then one needs to add it to the list of validators and give it a "tag"
|
||||||
|
name.
|
||||||
|
|
||||||
|
```go
|
||||||
|
validator.SetValidationFunc("notzz", notZZ)
|
||||||
|
```
|
||||||
|
|
||||||
|
Then it is possible to use the notzz validation tag. This will print
|
||||||
|
"Field A error: value cannot be ZZ"
|
||||||
|
|
||||||
|
```go
|
||||||
|
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])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also have multiple sets of validator rules with SetTag().
|
||||||
|
|
||||||
|
```go
|
||||||
|
type T struct {
|
||||||
|
A int `foo:"nonzero" bar:"min=10"`
|
||||||
|
}
|
||||||
|
t := T{5}
|
||||||
|
SetTag("foo")
|
||||||
|
validator.Validate(t) // valid as it's nonzero
|
||||||
|
SetTag("bar")
|
||||||
|
validator.Validate(t) // invalid as it's less than 10
|
||||||
|
```
|
||||||
|
|
||||||
|
SetTag is probably better used with multiple validators.
|
||||||
|
|
||||||
|
```go
|
||||||
|
fooValidator := validator.NewValidator()
|
||||||
|
fooValidator.SetTag("foo")
|
||||||
|
barValidator := validator.NewValidator()
|
||||||
|
barValidator.SetTag("bar")
|
||||||
|
fooValidator.Validate(t)
|
||||||
|
barValidator.Validate(t)
|
||||||
|
```
|
||||||
|
|
||||||
|
This keeps the default validator's tag clean. Again, please refer to
|
||||||
|
godocs for a lot of more examples and different uses.
|
||||||
|
|
||||||
|
Pull requests policy
|
||||||
|
====================
|
||||||
|
|
||||||
|
tl;dr. Contributions are welcome.
|
||||||
|
|
||||||
|
The repository is organized in version branches. Pull requests to, say, the
|
||||||
|
`v2` branch that break API compatibility will not be accepted. It is okay to
|
||||||
|
break the API in master, *not in the branches*.
|
||||||
|
|
||||||
|
As for validation functions, the preference is to keep the main code simple
|
||||||
|
and add most new functions to the validator-contrib repository.
|
||||||
|
|
||||||
|
https://github.com/go-validator/validator-contrib
|
||||||
|
|
||||||
|
For improvements and/or fixes to the builtin validation functions, please
|
||||||
|
make sure the behaviour will not break existing functionality in the branches.
|
||||||
|
If you see a case where the functionality of the builtin will change
|
||||||
|
significantly, please send a pull request against `master`. We can discuss then
|
||||||
|
whether the changes should be incorporated in the version branches as well.
|
||||||
|
|
||||||
|
License
|
||||||
|
=======
|
||||||
|
|
||||||
|
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.
|
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
|
||||||
|
}
|
12
vendor/gopkg.in/yaml.v2/.travis.yml
generated
vendored
Normal file
12
vendor/gopkg.in/yaml.v2/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.4
|
||||||
|
- 1.5
|
||||||
|
- 1.6
|
||||||
|
- 1.7
|
||||||
|
- 1.8
|
||||||
|
- 1.9
|
||||||
|
- tip
|
||||||
|
|
||||||
|
go_import_path: gopkg.in/yaml.v2
|
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
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
("LGPL3"), the copyright holders of this Library give you permission to
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
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.
|
|
||||||
|
|
||||||
Except as stated in this special exception, the provisions of LGPL3 will
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
continue to comply in full to this Library. If you modify this Library, you
|
the copyright owner that is granting the License.
|
||||||
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.
|
|
||||||
|
|
||||||
|
"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
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
Version 3, 29 June 2007
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
including but not limited to software source code, documentation
|
||||||
of this license document, but changing it is not allowed.
|
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
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
the terms and conditions of version 3 of the GNU General Public
|
Object form, made available under the License, as indicated by a
|
||||||
License, supplemented by the additional permissions listed below.
|
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
|
"Contribution" shall mean any work of authorship, including
|
||||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
the original version of the Work and any modifications or additions
|
||||||
General Public License.
|
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,
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
other than an Application or a Combined Work as defined below.
|
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
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
by the Library, but which is not otherwise based on the Library.
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
Defining a subclass of a class defined by the Library is deemed a mode
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
of using an interface provided by the Library.
|
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
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
Application with the Library. The particular version of the Library
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
with which the Combined Work was made is also called the "Linked
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
Version".
|
(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
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
Corresponding Source for the Combined Work, excluding any source code
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
for portions of the Combined Work that, considered in isolation, are
|
modifications, and in Source or Object form, provided that You
|
||||||
based on the Application, and not on the Linked Version.
|
meet the following conditions:
|
||||||
|
|
||||||
The "Corresponding Application Code" for a Combined Work means the
|
(a) You must give any other recipients of the Work or
|
||||||
object code and/or source code for the Application, including any data
|
Derivative Works a copy of this License; and
|
||||||
and utility programs needed for reproducing the Combined Work from the
|
|
||||||
Application, but excluding the System Libraries of the Combined Work.
|
|
||||||
|
|
||||||
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
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
without being bound by section 3 of the GNU GPL.
|
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
|
You may add Your own copyright statement to Your modifications and
|
||||||
facility refers to a function or data to be supplied by an Application
|
may provide additional or different license terms and conditions
|
||||||
that uses the facility (other than as an argument passed when the
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
facility is invoked), then you may convey a copy of the modified
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
version:
|
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
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
ensure that, in the event an Application does not supply the
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
function or data, the facility still operates, and performs
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
whatever part of its purpose remains meaningful, or
|
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
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
this License applicable to that copy.
|
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
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
a header file that is part of the Library. You may convey such object
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
code under terms of your choice, provided that, if the incorporated
|
unless required by applicable law (such as deliberate and grossly
|
||||||
material is not limited to numerical parameters, data structure
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
layouts and accessors, or small macros, inline functions and templates
|
liable to You for damages, including any direct, indirect, special,
|
||||||
(ten or fewer lines in length), you do both of the following:
|
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
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
Library is used in it and that the Library and its use are
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
covered by this License.
|
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
|
END OF TERMS AND CONDITIONS
|
||||||
document.
|
|
||||||
|
|
||||||
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,
|
To apply the Apache License to your work, attach the following
|
||||||
taken together, effectively do not restrict modification of the
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
portions of the Library contained in the Combined Work and reverse
|
replaced with your own identifying information. (Don't include
|
||||||
engineering for debugging such modifications, if you also do each of
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
the following:
|
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
|
Copyright {yyyy} {name of copyright owner}
|
||||||
the Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
document.
|
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
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
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.
|
|
||||||
|
|
||||||
d) Do one of the following:
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
0) Convey the Minimal Corresponding Source under the terms of this
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
License, and the Corresponding Application Code in a form
|
See the License for the specific language governing permissions and
|
||||||
suitable for, and under terms that permit, the user to
|
limitations under the License.
|
||||||
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.
|
|
||||||
|
|
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.
|
4
vendor/gopkg.in/yaml.v2/README.md
generated
vendored
4
vendor/gopkg.in/yaml.v2/README.md
generated
vendored
|
@ -42,7 +42,7 @@ The package API for yaml v2 will remain stable as described in [gopkg.in](https:
|
||||||
License
|
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.
|
The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
@ -65,6 +65,8 @@ b:
|
||||||
d: [3, 4]
|
d: [3, 4]
|
||||||
`
|
`
|
||||||
|
|
||||||
|
// Note: struct fields must be public in order for unmarshal to
|
||||||
|
// correctly populate the data.
|
||||||
type T struct {
|
type T struct {
|
||||||
A string
|
A string
|
||||||
B struct {
|
B struct {
|
||||||
|
|
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 (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
|
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
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// File read handler.
|
// Reader read handler.
|
||||||
func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
|
func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
|
||||||
return parser.input_file.Read(buffer)
|
return parser.input_reader.Read(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a string input.
|
// Set a string input.
|
||||||
|
@ -64,12 +63,12 @@ func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a file input.
|
// 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 {
|
if parser.read_handler != nil {
|
||||||
panic("must set the input source only once")
|
panic("must set the input source only once")
|
||||||
}
|
}
|
||||||
parser.read_handler = yaml_file_read_handler
|
parser.read_handler = yaml_reader_read_handler
|
||||||
parser.input_file = file
|
parser.input_reader = r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the source encoding.
|
// 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.
|
// 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{
|
*emitter = yaml_emitter_t{
|
||||||
buffer: make([]byte, output_buffer_size),
|
buffer: make([]byte, output_buffer_size),
|
||||||
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
||||||
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
||||||
events: make([]yaml_event_t, 0, initial_queue_size),
|
events: make([]yaml_event_t, 0, initial_queue_size),
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy an emitter object.
|
// Destroy an emitter object.
|
||||||
|
@ -102,9 +100,10 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// File write handler.
|
// yaml_writer_write_handler uses emitter.output_writer to write the
|
||||||
func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
// emitted text.
|
||||||
_, err := emitter.output_file.Write(buffer)
|
func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
||||||
|
_, err := emitter.output_writer.Write(buffer)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,12 +117,12 @@ func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]by
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a file output.
|
// 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 {
|
if emitter.write_handler != nil {
|
||||||
panic("must set the output target only once")
|
panic("must set the output target only once")
|
||||||
}
|
}
|
||||||
emitter.write_handler = yaml_file_write_handler
|
emitter.write_handler = yaml_writer_write_handler
|
||||||
emitter.output_file = file
|
emitter.output_writer = w
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the output encoding.
|
// 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.
|
// 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{
|
*event = yaml_event_t{
|
||||||
typ: yaml_STREAM_START_EVENT,
|
typ: yaml_STREAM_START_EVENT,
|
||||||
encoding: encoding,
|
encoding: encoding,
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create STREAM-END.
|
// 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{
|
*event = yaml_event_t{
|
||||||
typ: yaml_STREAM_END_EVENT,
|
typ: yaml_STREAM_END_EVENT,
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create DOCUMENT-START.
|
// Create DOCUMENT-START.
|
||||||
func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
|
func yaml_document_start_event_initialize(
|
||||||
tag_directives []yaml_tag_directive_t, implicit bool) bool {
|
event *yaml_event_t,
|
||||||
|
version_directive *yaml_version_directive_t,
|
||||||
|
tag_directives []yaml_tag_directive_t,
|
||||||
|
implicit bool,
|
||||||
|
) {
|
||||||
*event = yaml_event_t{
|
*event = yaml_event_t{
|
||||||
typ: yaml_DOCUMENT_START_EVENT,
|
typ: yaml_DOCUMENT_START_EVENT,
|
||||||
version_directive: version_directive,
|
version_directive: version_directive,
|
||||||
tag_directives: tag_directives,
|
tag_directives: tag_directives,
|
||||||
implicit: implicit,
|
implicit: implicit,
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create DOCUMENT-END.
|
// 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{
|
*event = yaml_event_t{
|
||||||
typ: yaml_DOCUMENT_END_EVENT,
|
typ: yaml_DOCUMENT_END_EVENT,
|
||||||
implicit: implicit,
|
implicit: implicit,
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///*
|
///*
|
||||||
|
@ -348,7 +347,7 @@ func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create MAPPING-START.
|
// 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{
|
*event = yaml_event_t{
|
||||||
typ: yaml_MAPPING_START_EVENT,
|
typ: yaml_MAPPING_START_EVENT,
|
||||||
anchor: anchor,
|
anchor: anchor,
|
||||||
|
@ -356,15 +355,13 @@ func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte
|
||||||
implicit: implicit,
|
implicit: implicit,
|
||||||
style: yaml_style_t(style),
|
style: yaml_style_t(style),
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create MAPPING-END.
|
// 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{
|
*event = yaml_event_t{
|
||||||
typ: yaml_MAPPING_END_EVENT,
|
typ: yaml_MAPPING_END_EVENT,
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy an event object.
|
// Destroy an event object.
|
||||||
|
@ -471,7 +468,7 @@ func yaml_event_delete(event *yaml_event_t) {
|
||||||
// } context
|
// } context
|
||||||
// tag_directive *yaml_tag_directive_t
|
// 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.
|
// assert(document) // Non-NULL document object is expected.
|
||||||
//
|
//
|
||||||
|
|
250
vendor/gopkg.in/yaml.v2/decode.go
generated
vendored
250
vendor/gopkg.in/yaml.v2/decode.go
generated
vendored
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding"
|
"encoding"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -22,19 +23,22 @@ type node struct {
|
||||||
kind int
|
kind int
|
||||||
line, column int
|
line, column int
|
||||||
tag string
|
tag string
|
||||||
value string
|
// For an alias node, alias holds the resolved alias.
|
||||||
implicit bool
|
alias *node
|
||||||
children []*node
|
value string
|
||||||
anchors map[string]*node
|
implicit bool
|
||||||
|
children []*node
|
||||||
|
anchors map[string]*node
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Parser, produces a node tree out of a libyaml event stream.
|
// Parser, produces a node tree out of a libyaml event stream.
|
||||||
|
|
||||||
type parser struct {
|
type parser struct {
|
||||||
parser yaml_parser_t
|
parser yaml_parser_t
|
||||||
event yaml_event_t
|
event yaml_event_t
|
||||||
doc *node
|
doc *node
|
||||||
|
doneInit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newParser(b []byte) *parser {
|
func newParser(b []byte) *parser {
|
||||||
|
@ -42,21 +46,30 @@ func newParser(b []byte) *parser {
|
||||||
if !yaml_parser_initialize(&p.parser) {
|
if !yaml_parser_initialize(&p.parser) {
|
||||||
panic("failed to initialize YAML emitter")
|
panic("failed to initialize YAML emitter")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
b = []byte{'\n'}
|
b = []byte{'\n'}
|
||||||
}
|
}
|
||||||
|
|
||||||
yaml_parser_set_input_string(&p.parser, b)
|
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
|
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() {
|
func (p *parser) destroy() {
|
||||||
if p.event.typ != yaml_NO_EVENT {
|
if p.event.typ != yaml_NO_EVENT {
|
||||||
yaml_event_delete(&p.event)
|
yaml_event_delete(&p.event)
|
||||||
|
@ -64,16 +77,35 @@ func (p *parser) destroy() {
|
||||||
yaml_parser_delete(&p.parser)
|
yaml_parser_delete(&p.parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) skip() {
|
// expect consumes an event from the event stream and
|
||||||
if p.event.typ != yaml_NO_EVENT {
|
// checks that it's of the expected type.
|
||||||
if p.event.typ == yaml_STREAM_END_EVENT {
|
func (p *parser) expect(e yaml_event_type_t) {
|
||||||
failf("attempted to go past the end of stream; corrupted value?")
|
if p.event.typ == yaml_NO_EVENT {
|
||||||
|
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||||
|
p.fail()
|
||||||
}
|
}
|
||||||
yaml_event_delete(&p.event)
|
}
|
||||||
|
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) {
|
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||||
p.fail()
|
p.fail()
|
||||||
}
|
}
|
||||||
|
return p.event.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) fail() {
|
func (p *parser) fail() {
|
||||||
|
@ -81,6 +113,10 @@ func (p *parser) fail() {
|
||||||
var line int
|
var line int
|
||||||
if p.parser.problem_mark.line != 0 {
|
if p.parser.problem_mark.line != 0 {
|
||||||
line = p.parser.problem_mark.line
|
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 {
|
} else if p.parser.context_mark.line != 0 {
|
||||||
line = p.parser.context_mark.line
|
line = p.parser.context_mark.line
|
||||||
}
|
}
|
||||||
|
@ -103,7 +139,8 @@ func (p *parser) anchor(n *node, anchor []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) parse() *node {
|
func (p *parser) parse() *node {
|
||||||
switch p.event.typ {
|
p.init()
|
||||||
|
switch p.peek() {
|
||||||
case yaml_SCALAR_EVENT:
|
case yaml_SCALAR_EVENT:
|
||||||
return p.scalar()
|
return p.scalar()
|
||||||
case yaml_ALIAS_EVENT:
|
case yaml_ALIAS_EVENT:
|
||||||
|
@ -118,9 +155,8 @@ func (p *parser) parse() *node {
|
||||||
// Happens when attempting to decode an empty buffer.
|
// Happens when attempting to decode an empty buffer.
|
||||||
return nil
|
return nil
|
||||||
default:
|
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 {
|
func (p *parser) node(kind int) *node {
|
||||||
|
@ -135,19 +171,20 @@ func (p *parser) document() *node {
|
||||||
n := p.node(documentNode)
|
n := p.node(documentNode)
|
||||||
n.anchors = make(map[string]*node)
|
n.anchors = make(map[string]*node)
|
||||||
p.doc = n
|
p.doc = n
|
||||||
p.skip()
|
p.expect(yaml_DOCUMENT_START_EVENT)
|
||||||
n.children = append(n.children, p.parse())
|
n.children = append(n.children, p.parse())
|
||||||
if p.event.typ != yaml_DOCUMENT_END_EVENT {
|
p.expect(yaml_DOCUMENT_END_EVENT)
|
||||||
panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
|
|
||||||
}
|
|
||||||
p.skip()
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) alias() *node {
|
func (p *parser) alias() *node {
|
||||||
n := p.node(aliasNode)
|
n := p.node(aliasNode)
|
||||||
n.value = string(p.event.anchor)
|
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
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,29 +194,29 @@ func (p *parser) scalar() *node {
|
||||||
n.tag = string(p.event.tag)
|
n.tag = string(p.event.tag)
|
||||||
n.implicit = p.event.implicit
|
n.implicit = p.event.implicit
|
||||||
p.anchor(n, p.event.anchor)
|
p.anchor(n, p.event.anchor)
|
||||||
p.skip()
|
p.expect(yaml_SCALAR_EVENT)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) sequence() *node {
|
func (p *parser) sequence() *node {
|
||||||
n := p.node(sequenceNode)
|
n := p.node(sequenceNode)
|
||||||
p.anchor(n, p.event.anchor)
|
p.anchor(n, p.event.anchor)
|
||||||
p.skip()
|
p.expect(yaml_SEQUENCE_START_EVENT)
|
||||||
for p.event.typ != yaml_SEQUENCE_END_EVENT {
|
for p.peek() != yaml_SEQUENCE_END_EVENT {
|
||||||
n.children = append(n.children, p.parse())
|
n.children = append(n.children, p.parse())
|
||||||
}
|
}
|
||||||
p.skip()
|
p.expect(yaml_SEQUENCE_END_EVENT)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) mapping() *node {
|
func (p *parser) mapping() *node {
|
||||||
n := p.node(mappingNode)
|
n := p.node(mappingNode)
|
||||||
p.anchor(n, p.event.anchor)
|
p.anchor(n, p.event.anchor)
|
||||||
p.skip()
|
p.expect(yaml_MAPPING_START_EVENT)
|
||||||
for p.event.typ != yaml_MAPPING_END_EVENT {
|
for p.peek() != yaml_MAPPING_END_EVENT {
|
||||||
n.children = append(n.children, p.parse(), p.parse())
|
n.children = append(n.children, p.parse(), p.parse())
|
||||||
}
|
}
|
||||||
p.skip()
|
p.expect(yaml_MAPPING_END_EVENT)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +225,10 @@ func (p *parser) mapping() *node {
|
||||||
|
|
||||||
type decoder struct {
|
type decoder struct {
|
||||||
doc *node
|
doc *node
|
||||||
aliases map[string]bool
|
aliases map[*node]bool
|
||||||
mapType reflect.Type
|
mapType reflect.Type
|
||||||
terrors []string
|
terrors []string
|
||||||
|
strict bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -198,11 +236,13 @@ var (
|
||||||
durationType = reflect.TypeOf(time.Duration(0))
|
durationType = reflect.TypeOf(time.Duration(0))
|
||||||
defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
|
defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
|
||||||
ifaceType = defaultMapType.Elem()
|
ifaceType = defaultMapType.Elem()
|
||||||
|
timeType = reflect.TypeOf(time.Time{})
|
||||||
|
ptrTimeType = reflect.TypeOf(&time.Time{})
|
||||||
)
|
)
|
||||||
|
|
||||||
func newDecoder() *decoder {
|
func newDecoder(strict bool) *decoder {
|
||||||
d := &decoder{mapType: defaultMapType}
|
d := &decoder{mapType: defaultMapType, strict: strict}
|
||||||
d.aliases = make(map[string]bool)
|
d.aliases = make(map[*node]bool)
|
||||||
return d
|
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.
|
// 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) {
|
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
|
return out, false, false
|
||||||
}
|
}
|
||||||
again := true
|
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) {
|
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
|
||||||
an, ok := d.doc.anchors[n.value]
|
if d.aliases[n] {
|
||||||
if !ok {
|
// TODO this could actually be allowed in some circumstances.
|
||||||
failf("unknown anchor '%s' referenced", n.value)
|
|
||||||
}
|
|
||||||
if d.aliases[n.value] {
|
|
||||||
failf("anchor '%s' value contains itself", n.value)
|
failf("anchor '%s' value contains itself", n.value)
|
||||||
}
|
}
|
||||||
d.aliases[n.value] = true
|
d.aliases[n] = true
|
||||||
good = d.unmarshal(an, out)
|
good = d.unmarshal(n.alias, out)
|
||||||
delete(d.aliases, n.value)
|
delete(d.aliases, n)
|
||||||
return good
|
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 tag string
|
||||||
var resolved interface{}
|
var resolved interface{}
|
||||||
if n.tag == "" && !n.implicit {
|
if n.tag == "" && !n.implicit {
|
||||||
|
@ -353,9 +390,26 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if s, ok := resolved.(string); ok && out.CanAddr() {
|
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
||||||
if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
|
// We've resolved to exactly the type we want, so use that.
|
||||||
err := u.UnmarshalText([]byte(s))
|
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 {
|
if err != nil {
|
||||||
fail(err)
|
fail(err)
|
||||||
}
|
}
|
||||||
|
@ -366,46 +420,54 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
if tag == yaml_BINARY_TAG {
|
if tag == yaml_BINARY_TAG {
|
||||||
out.SetString(resolved.(string))
|
out.SetString(resolved.(string))
|
||||||
good = true
|
return true
|
||||||
} else if resolved != nil {
|
}
|
||||||
|
if resolved != nil {
|
||||||
out.SetString(n.value)
|
out.SetString(n.value)
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
if resolved == nil {
|
if resolved == nil {
|
||||||
out.Set(reflect.Zero(out.Type()))
|
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 {
|
} else {
|
||||||
out.Set(reflect.ValueOf(resolved))
|
out.Set(reflect.ValueOf(resolved))
|
||||||
}
|
}
|
||||||
good = true
|
return true
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
switch resolved := resolved.(type) {
|
switch resolved := resolved.(type) {
|
||||||
case int:
|
case int:
|
||||||
if !out.OverflowInt(int64(resolved)) {
|
if !out.OverflowInt(int64(resolved)) {
|
||||||
out.SetInt(int64(resolved))
|
out.SetInt(int64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case int64:
|
case int64:
|
||||||
if !out.OverflowInt(resolved) {
|
if !out.OverflowInt(resolved) {
|
||||||
out.SetInt(resolved)
|
out.SetInt(resolved)
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case uint64:
|
case uint64:
|
||||||
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
||||||
out.SetInt(int64(resolved))
|
out.SetInt(int64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case float64:
|
case float64:
|
||||||
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
||||||
out.SetInt(int64(resolved))
|
out.SetInt(int64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case string:
|
case string:
|
||||||
if out.Type() == durationType {
|
if out.Type() == durationType {
|
||||||
d, err := time.ParseDuration(resolved)
|
d, err := time.ParseDuration(resolved)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
out.SetInt(int64(d))
|
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:
|
case int:
|
||||||
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
||||||
out.SetUint(uint64(resolved))
|
out.SetUint(uint64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case int64:
|
case int64:
|
||||||
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
||||||
out.SetUint(uint64(resolved))
|
out.SetUint(uint64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case uint64:
|
case uint64:
|
||||||
if !out.OverflowUint(uint64(resolved)) {
|
if !out.OverflowUint(uint64(resolved)) {
|
||||||
out.SetUint(uint64(resolved))
|
out.SetUint(uint64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case float64:
|
case float64:
|
||||||
if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
|
if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
|
||||||
out.SetUint(uint64(resolved))
|
out.SetUint(uint64(resolved))
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
switch resolved := resolved.(type) {
|
switch resolved := resolved.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
out.SetBool(resolved)
|
out.SetBool(resolved)
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
switch resolved := resolved.(type) {
|
switch resolved := resolved.(type) {
|
||||||
case int:
|
case int:
|
||||||
out.SetFloat(float64(resolved))
|
out.SetFloat(float64(resolved))
|
||||||
good = true
|
return true
|
||||||
case int64:
|
case int64:
|
||||||
out.SetFloat(float64(resolved))
|
out.SetFloat(float64(resolved))
|
||||||
good = true
|
return true
|
||||||
case uint64:
|
case uint64:
|
||||||
out.SetFloat(float64(resolved))
|
out.SetFloat(float64(resolved))
|
||||||
good = true
|
return true
|
||||||
case float64:
|
case float64:
|
||||||
out.SetFloat(resolved)
|
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:
|
case reflect.Ptr:
|
||||||
if out.Type().Elem() == reflect.TypeOf(resolved) {
|
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 := reflect.New(out.Type().Elem())
|
||||||
elem.Elem().Set(reflect.ValueOf(resolved))
|
elem.Elem().Set(reflect.ValueOf(resolved))
|
||||||
out.Set(elem)
|
out.Set(elem)
|
||||||
good = true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !good {
|
d.terror(n, tag, out)
|
||||||
d.terror(n, tag, out)
|
return false
|
||||||
}
|
|
||||||
return good
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func settableValueOf(i interface{}) reflect.Value {
|
func settableValueOf(i interface{}) reflect.Value {
|
||||||
|
@ -482,6 +547,10 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
||||||
switch out.Kind() {
|
switch out.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
out.Set(reflect.MakeSlice(out.Type(), l, l))
|
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:
|
case reflect.Interface:
|
||||||
// No type hints. Will have to use a generic sequence.
|
// No type hints. Will have to use a generic sequence.
|
||||||
iface = out
|
iface = out
|
||||||
|
@ -500,7 +569,9 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.Set(out.Slice(0, j))
|
if out.Kind() != reflect.Array {
|
||||||
|
out.Set(out.Slice(0, j))
|
||||||
|
}
|
||||||
if iface.IsValid() {
|
if iface.IsValid() {
|
||||||
iface.Set(out)
|
iface.Set(out)
|
||||||
}
|
}
|
||||||
|
@ -561,7 +632,7 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
||||||
}
|
}
|
||||||
e := reflect.New(et).Elem()
|
e := reflect.New(et).Elem()
|
||||||
if d.unmarshal(n.children[i+1], e) {
|
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
|
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) {
|
func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
|
||||||
outt := out.Type()
|
outt := out.Type()
|
||||||
if outt.Elem() != mapItemType {
|
if outt.Elem() != mapItemType {
|
||||||
|
@ -616,6 +695,10 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
||||||
elemType = inlineMap.Type().Elem()
|
elemType = inlineMap.Type().Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var doneFields []bool
|
||||||
|
if d.strict {
|
||||||
|
doneFields = make([]bool, len(sinfo.FieldsList))
|
||||||
|
}
|
||||||
for i := 0; i < l; i += 2 {
|
for i := 0; i < l; i += 2 {
|
||||||
ni := n.children[i]
|
ni := n.children[i]
|
||||||
if isMerge(ni) {
|
if isMerge(ni) {
|
||||||
|
@ -626,6 +709,13 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if info, ok := sinfo.FieldsMap[name.String()]; ok {
|
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
|
var field reflect.Value
|
||||||
if info.Inline == nil {
|
if info.Inline == nil {
|
||||||
field = out.Field(info.Num)
|
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()
|
value := reflect.New(elemType).Elem()
|
||||||
d.unmarshal(n.children[i+1], value)
|
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
|
return true
|
||||||
|
|
20
vendor/gopkg.in/yaml.v2/emitterc.go
generated
vendored
20
vendor/gopkg.in/yaml.v2/emitterc.go
generated
vendored
|
@ -2,6 +2,7 @@ package yaml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Flush the buffer if needed.
|
// 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)
|
return yaml_emitter_emit_mapping_start(emitter, event)
|
||||||
default:
|
default:
|
||||||
return yaml_emitter_set_emitter_error(emitter,
|
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.
|
// Expect ALIAS.
|
||||||
|
@ -843,7 +843,7 @@ func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write an achor.
|
// Write an anchor.
|
||||||
func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
|
func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
|
||||||
if emitter.anchor_data.anchor == nil {
|
if emitter.anchor_data.anchor == nil {
|
||||||
return true
|
return true
|
||||||
|
@ -995,10 +995,10 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
||||||
break_space = false
|
break_space = false
|
||||||
space_break = false
|
space_break = false
|
||||||
|
|
||||||
preceeded_by_whitespace = false
|
preceded_by_whitespace = false
|
||||||
followed_by_whitespace = false
|
followed_by_whitespace = false
|
||||||
previous_space = false
|
previous_space = false
|
||||||
previous_break = false
|
previous_break = false
|
||||||
)
|
)
|
||||||
|
|
||||||
emitter.scalar_data.value = value
|
emitter.scalar_data.value = value
|
||||||
|
@ -1017,7 +1017,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
||||||
flow_indicators = true
|
flow_indicators = true
|
||||||
}
|
}
|
||||||
|
|
||||||
preceeded_by_whitespace = true
|
preceded_by_whitespace = true
|
||||||
for i, w := 0, 0; i < len(value); i += w {
|
for i, w := 0, 0; i < len(value); i += w {
|
||||||
w = width(value[i])
|
w = width(value[i])
|
||||||
followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
|
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
|
block_indicators = true
|
||||||
}
|
}
|
||||||
case '#':
|
case '#':
|
||||||
if preceeded_by_whitespace {
|
if preceded_by_whitespace {
|
||||||
flow_indicators = true
|
flow_indicators = true
|
||||||
block_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.
|
// [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
|
emitter.scalar_data.multiline = line_breaks
|
||||||
|
|
136
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
136
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
|
@ -3,12 +3,14 @@ package yaml
|
||||||
import (
|
import (
|
||||||
"encoding"
|
"encoding"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
type encoder struct {
|
type encoder struct {
|
||||||
|
@ -16,25 +18,39 @@ type encoder struct {
|
||||||
event yaml_event_t
|
event yaml_event_t
|
||||||
out []byte
|
out []byte
|
||||||
flow bool
|
flow bool
|
||||||
|
// doneInit holds whether the initial stream_start_event has been
|
||||||
|
// emitted.
|
||||||
|
doneInit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newEncoder() (e *encoder) {
|
func newEncoder() *encoder {
|
||||||
e = &encoder{}
|
e := &encoder{}
|
||||||
e.must(yaml_emitter_initialize(&e.emitter))
|
yaml_emitter_initialize(&e.emitter)
|
||||||
yaml_emitter_set_output_string(&e.emitter, &e.out)
|
yaml_emitter_set_output_string(&e.emitter, &e.out)
|
||||||
yaml_emitter_set_unicode(&e.emitter, true)
|
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
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) finish() {
|
func newEncoderWithWriter(w io.Writer) *encoder {
|
||||||
e.must(yaml_document_end_event_initialize(&e.event, true))
|
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.emit()
|
||||||
|
e.doneInit = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encoder) finish() {
|
||||||
e.emitter.open_ended = false
|
e.emitter.open_ended = false
|
||||||
e.must(yaml_stream_end_event_initialize(&e.event))
|
yaml_stream_end_event_initialize(&e.event)
|
||||||
e.emit()
|
e.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,9 +60,7 @@ func (e *encoder) destroy() {
|
||||||
|
|
||||||
func (e *encoder) emit() {
|
func (e *encoder) emit() {
|
||||||
// This will internally delete the e.event value.
|
// 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(yaml_emitter_emit(&e.emitter, &e.event))
|
||||||
e.must(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encoder) must(ok bool) {
|
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) {
|
func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||||
if !in.IsValid() {
|
if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
|
||||||
e.nilv()
|
e.nilv()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
iface := in.Interface()
|
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()
|
v, err := m.MarshalYAML()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err)
|
fail(err)
|
||||||
|
@ -75,31 +104,34 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
in = reflect.ValueOf(v)
|
in = reflect.ValueOf(v)
|
||||||
} else if m, ok := iface.(encoding.TextMarshaler); ok {
|
case encoding.TextMarshaler:
|
||||||
text, err := m.MarshalText()
|
text, err := m.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err)
|
fail(err)
|
||||||
}
|
}
|
||||||
in = reflect.ValueOf(string(text))
|
in = reflect.ValueOf(string(text))
|
||||||
|
case nil:
|
||||||
|
e.nilv()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
switch in.Kind() {
|
switch in.Kind() {
|
||||||
case reflect.Interface:
|
case reflect.Interface:
|
||||||
if in.IsNil() {
|
e.marshal(tag, in.Elem())
|
||||||
e.nilv()
|
|
||||||
} else {
|
|
||||||
e.marshal(tag, in.Elem())
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
e.mapv(tag, in)
|
e.mapv(tag, in)
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if in.IsNil() {
|
if in.Type() == ptrTimeType {
|
||||||
e.nilv()
|
e.timev(tag, in.Elem())
|
||||||
} else {
|
} else {
|
||||||
e.marshal(tag, in.Elem())
|
e.marshal(tag, in.Elem())
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
e.structv(tag, in)
|
if in.Type() == timeType {
|
||||||
case reflect.Slice:
|
e.timev(tag, in)
|
||||||
|
} else {
|
||||||
|
e.structv(tag, in)
|
||||||
|
}
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
if in.Type().Elem() == mapItemType {
|
if in.Type().Elem() == mapItemType {
|
||||||
e.itemsv(tag, in)
|
e.itemsv(tag, in)
|
||||||
} else {
|
} else {
|
||||||
|
@ -191,10 +223,10 @@ func (e *encoder) mappingv(tag string, f func()) {
|
||||||
e.flow = false
|
e.flow = false
|
||||||
style = yaml_FLOW_MAPPING_STYLE
|
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()
|
e.emit()
|
||||||
f()
|
f()
|
||||||
e.must(yaml_mapping_end_event_initialize(&e.event))
|
yaml_mapping_end_event_initialize(&e.event)
|
||||||
e.emit()
|
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) {
|
func (e *encoder) stringv(tag string, in reflect.Value) {
|
||||||
var style yaml_scalar_style_t
|
var style yaml_scalar_style_t
|
||||||
s := in.String()
|
s := in.String()
|
||||||
rtag, rs := resolve("", s)
|
canUsePlain := true
|
||||||
if rtag == yaml_BINARY_TAG {
|
switch {
|
||||||
if tag == "" || tag == yaml_STR_TAG {
|
case !utf8.ValidString(s):
|
||||||
tag = rtag
|
if tag == yaml_BINARY_TAG {
|
||||||
s = rs.(string)
|
|
||||||
} else if tag == yaml_BINARY_TAG {
|
|
||||||
failf("explicitly tagged !!binary data must be base64-encoded")
|
failf("explicitly tagged !!binary data must be base64-encoded")
|
||||||
} else {
|
}
|
||||||
|
if tag != "" {
|
||||||
failf("cannot marshal invalid UTF-8 data as %s", shortTag(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)) {
|
// Note: it's possible for user code to emit invalid YAML
|
||||||
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
// if they explicitly specify a tag and a string containing
|
||||||
} else if strings.Contains(s, "\n") {
|
// text that's incompatible with that tag.
|
||||||
|
switch {
|
||||||
|
case strings.Contains(s, "\n"):
|
||||||
style = yaml_LITERAL_SCALAR_STYLE
|
style = yaml_LITERAL_SCALAR_STYLE
|
||||||
} else {
|
case canUsePlain:
|
||||||
style = yaml_PLAIN_SCALAR_STYLE
|
style = yaml_PLAIN_SCALAR_STYLE
|
||||||
|
default:
|
||||||
|
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
||||||
}
|
}
|
||||||
e.emitScalar(s, "", tag, 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)
|
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) {
|
func (e *encoder) floatv(tag string, in reflect.Value) {
|
||||||
// FIXME: Handle 64 bits here.
|
// Issue #352: When formatting, use the precision of the underlying value
|
||||||
s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
|
precision := 64
|
||||||
|
if in.Kind() == reflect.Float32 {
|
||||||
|
precision = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
|
||||||
switch s {
|
switch s {
|
||||||
case "+Inf":
|
case "+Inf":
|
||||||
s = ".inf"
|
s = ".inf"
|
||||||
|
|
5
vendor/gopkg.in/yaml.v2/go.mod
generated
vendored
Normal file
5
vendor/gopkg.in/yaml.v2/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
require (
|
||||||
|
"gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
|
||||||
|
)
|
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:
|
default:
|
||||||
panic("invalid parser state")
|
panic("invalid parser state")
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the production:
|
// 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")
|
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 the EOF flag is set and the raw buffer is empty, do nothing.
|
||||||
if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
|
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.
|
// 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 {
|
if parser.encoding == yaml_UTF16LE_ENCODING {
|
||||||
low, high = 0, 1
|
low, high = 0, 1
|
||||||
} else {
|
} else {
|
||||||
high, low = 1, 0
|
low, high = 1, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// The UTF-16 encoding is not as simple as one might
|
// 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 {
|
if value <= 0x7F {
|
||||||
// 0000 0000-0000 007F . 0xxxxxxx
|
// 0000 0000-0000 007F . 0xxxxxxx
|
||||||
parser.buffer[buffer_len+0] = byte(value)
|
parser.buffer[buffer_len+0] = byte(value)
|
||||||
|
buffer_len += 1
|
||||||
} else if value <= 0x7FF {
|
} else if value <= 0x7FF {
|
||||||
// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
|
// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
|
||||||
parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
|
parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
|
||||||
parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
|
parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
|
||||||
|
buffer_len += 2
|
||||||
} else if value <= 0xFFFF {
|
} else if value <= 0xFFFF {
|
||||||
// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
|
// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
|
parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
|
||||||
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
|
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
|
||||||
parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
|
parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
|
||||||
|
buffer_len += 3
|
||||||
} else {
|
} else {
|
||||||
// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
|
parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
|
||||||
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
|
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
|
||||||
parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
|
parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
|
||||||
parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
|
parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
|
||||||
|
buffer_len += 4
|
||||||
}
|
}
|
||||||
buffer_len += width
|
|
||||||
|
|
||||||
parser.unread++
|
parser.unread++
|
||||||
}
|
}
|
||||||
|
@ -386,6 +398,15 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
||||||
break
|
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]
|
parser.buffer = parser.buffer[:buffer_len]
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
91
vendor/gopkg.in/yaml.v2/resolve.go
generated
vendored
91
vendor/gopkg.in/yaml.v2/resolve.go
generated
vendored
|
@ -3,9 +3,10 @@ package yaml
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"math"
|
"math"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type resolveMapItem struct {
|
type resolveMapItem struct {
|
||||||
|
@ -74,12 +75,14 @@ func longTag(tag string) string {
|
||||||
|
|
||||||
func resolvableTag(tag string) bool {
|
func resolvableTag(tag string) bool {
|
||||||
switch tag {
|
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 true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
|
||||||
|
|
||||||
func resolve(tag string, in string) (rtag string, out interface{}) {
|
func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||||
if !resolvableTag(tag) {
|
if !resolvableTag(tag) {
|
||||||
return tag, in
|
return tag, in
|
||||||
|
@ -89,6 +92,19 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||||
switch tag {
|
switch tag {
|
||||||
case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
|
case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
|
||||||
return
|
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))
|
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':
|
case 'D', 'S':
|
||||||
// Int, float, or timestamp.
|
// 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)
|
plain := strings.Replace(in, "_", "", -1)
|
||||||
intv, err := strconv.ParseInt(plain, 0, 64)
|
intv, err := strconv.ParseInt(plain, 0, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -135,9 +160,11 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return yaml_INT_TAG, uintv
|
return yaml_INT_TAG, uintv
|
||||||
}
|
}
|
||||||
floatv, err := strconv.ParseFloat(plain, 64)
|
if yamlStyleFloat.MatchString(plain) {
|
||||||
if err == nil {
|
floatv, err := strconv.ParseFloat(plain, 64)
|
||||||
return yaml_FLOAT_TAG, floatv
|
if err == nil {
|
||||||
|
return yaml_FLOAT_TAG, floatv
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(plain, "0b") {
|
if strings.HasPrefix(plain, "0b") {
|
||||||
intv, err := strconv.ParseInt(plain[2:], 2, 64)
|
intv, err := strconv.ParseInt(plain[2:], 2, 64)
|
||||||
|
@ -153,28 +180,20 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||||
return yaml_INT_TAG, uintv
|
return yaml_INT_TAG, uintv
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(plain, "-0b") {
|
} 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 err == nil {
|
||||||
if intv == int64(int(intv)) {
|
if true || intv == int64(int(intv)) {
|
||||||
return yaml_INT_TAG, -int(intv)
|
return yaml_INT_TAG, int(intv)
|
||||||
} else {
|
} else {
|
||||||
return yaml_INT_TAG, -intv
|
return yaml_INT_TAG, intv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX Handle timestamps here.
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
|
panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tag == yaml_BINARY_TAG {
|
return yaml_STR_TAG, in
|
||||||
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
|
// 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])
|
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
|
// 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.
|
// some cases we are less restrictive that it requires.
|
||||||
//
|
//
|
||||||
// The process of transforming a YAML stream into a sequence of events is
|
// 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 {
|
if directive {
|
||||||
context = "while parsing a %TAG 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() {
|
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
|
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.
|
// 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.
|
// Unknown directive.
|
||||||
} else {
|
} else {
|
||||||
yaml_parser_set_scanner_error(parser, "while scanning a directive",
|
yaml_parser_set_scanner_error(parser, "while scanning a directive",
|
||||||
start_mark, "found uknown directive name")
|
start_mark, "found unknown directive name")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1944,7 +1938,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
|
||||||
} else {
|
} else {
|
||||||
// It's either the '!' tag or not really a tag handle. If it's a %TAG
|
// 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.
|
// 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,
|
yaml_parser_set_scanner_tag_error(parser, directive,
|
||||||
start_mark, "did not find expected '!'")
|
start_mark, "did not find expected '!'")
|
||||||
return false
|
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 {
|
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
|
//size_t length = head ? strlen((char *)head) : 0
|
||||||
var s []byte
|
var s []byte
|
||||||
|
hasTag := len(head) > 0
|
||||||
|
|
||||||
// Copy the head if needed.
|
// 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) {
|
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
hasTag = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the tag is non-empty.
|
if !hasTag {
|
||||||
if len(s) == 0 {
|
|
||||||
yaml_parser_set_scanner_tag_error(parser, directive,
|
yaml_parser_set_scanner_tag_error(parser, directive,
|
||||||
start_mark, "did not find expected tag URI")
|
start_mark, "did not find expected tag URI")
|
||||||
return false
|
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.
|
// Check if we are at the end of the scalar.
|
||||||
if single {
|
if single {
|
||||||
if parser.buffer[parser.buffer_pos] == '\'' {
|
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.
|
// 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) {
|
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
|
||||||
if is_blank(parser.buffer, parser.buffer_pos) {
|
if is_blank(parser.buffer, parser.buffer_pos) {
|
||||||
// Consume a space or a tab character.
|
// 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.
|
// Consume non-blank characters.
|
||||||
for !is_blankz(parser.buffer, parser.buffer_pos) {
|
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.
|
// Check for indicators that may end a plain scalar.
|
||||||
if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
|
if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
|
||||||
(parser.flow_level > 0 &&
|
(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] == ']' || 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) {
|
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
|
||||||
if is_blank(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) {
|
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",
|
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
|
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 ai, bi int
|
||||||
var an, bn int64
|
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++ {
|
for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
|
||||||
an = an*10 + int64(ar[ai]-'0')
|
an = an*10 + int64(ar[ai]-'0')
|
||||||
}
|
}
|
||||||
|
|
65
vendor/gopkg.in/yaml.v2/writerc.go
generated
vendored
65
vendor/gopkg.in/yaml.v2/writerc.go
generated
vendored
|
@ -18,72 +18,9 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the output encoding is UTF-8, we don't need to recode the buffer.
|
if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
|
||||||
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())
|
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
|
||||||
}
|
}
|
||||||
emitter.buffer_pos = 0
|
emitter.buffer_pos = 0
|
||||||
emitter.raw_buffer = emitter.raw_buffer[:0]
|
|
||||||
return true
|
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 (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -77,8 +78,65 @@ type Marshaler interface {
|
||||||
// supported tag options.
|
// supported tag options.
|
||||||
//
|
//
|
||||||
func Unmarshal(in []byte, out interface{}) (err error) {
|
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)
|
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)
|
p := newParser(in)
|
||||||
defer p.destroy()
|
defer p.destroy()
|
||||||
node := p.parse()
|
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.
|
// 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.
|
// 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
|
// Struct fields are only marshalled if they are exported (have an upper case
|
||||||
// first letter), and are unmarshalled using the field name lowercased as the
|
// 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
|
// 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
|
// 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.
|
// 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
|
// omitempty Only include the field if it's not set to the zero
|
||||||
// value for the type or to empty slices or maps.
|
// 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,
|
// flow Marshal using a flow style (useful for structs,
|
||||||
// sequences and maps).
|
// sequences and maps).
|
||||||
|
@ -129,7 +190,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
||||||
// For example:
|
// For example:
|
||||||
//
|
//
|
||||||
// type T struct {
|
// type T struct {
|
||||||
// F int "a,omitempty"
|
// F int `yaml:"a,omitempty"`
|
||||||
// B int
|
// B int
|
||||||
// }
|
// }
|
||||||
// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
|
// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
|
||||||
|
@ -139,12 +200,47 @@ func Marshal(in interface{}) (out []byte, err error) {
|
||||||
defer handleErr(&err)
|
defer handleErr(&err)
|
||||||
e := newEncoder()
|
e := newEncoder()
|
||||||
defer e.destroy()
|
defer e.destroy()
|
||||||
e.marshal("", reflect.ValueOf(in))
|
e.marshalDoc("", reflect.ValueOf(in))
|
||||||
e.finish()
|
e.finish()
|
||||||
out = e.out
|
out = e.out
|
||||||
return
|
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) {
|
func handleErr(err *error) {
|
||||||
if v := recover(); v != nil {
|
if v := recover(); v != nil {
|
||||||
if e, ok := v.(yamlError); ok {
|
if e, ok := v.(yamlError); ok {
|
||||||
|
@ -200,6 +296,9 @@ type fieldInfo struct {
|
||||||
Num int
|
Num int
|
||||||
OmitEmpty bool
|
OmitEmpty bool
|
||||||
Flow 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 holds the field index if the field is part of an inlined struct.
|
||||||
Inline []int
|
Inline []int
|
||||||
|
@ -222,7 +321,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||||
inlineMap := -1
|
inlineMap := -1
|
||||||
for i := 0; i != n; i++ {
|
for i := 0; i != n; i++ {
|
||||||
field := st.Field(i)
|
field := st.Field(i)
|
||||||
if field.PkgPath != "" {
|
if field.PkgPath != "" && !field.Anonymous {
|
||||||
continue // Private field
|
continue // Private field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +378,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||||
} else {
|
} else {
|
||||||
finfo.Inline = append([]int{i}, finfo.Inline...)
|
finfo.Inline = append([]int{i}, finfo.Inline...)
|
||||||
}
|
}
|
||||||
|
finfo.Id = len(fieldsList)
|
||||||
fieldsMap[finfo.Key] = finfo
|
fieldsMap[finfo.Key] = finfo
|
||||||
fieldsList = append(fieldsList, finfo)
|
fieldsList = append(fieldsList, finfo)
|
||||||
}
|
}
|
||||||
|
@ -300,11 +400,16 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||||
return nil, errors.New(msg)
|
return nil, errors.New(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.Id = len(fieldsList)
|
||||||
fieldsList = append(fieldsList, info)
|
fieldsList = append(fieldsList, info)
|
||||||
fieldsMap[info.Key] = info
|
fieldsMap[info.Key] = info
|
||||||
}
|
}
|
||||||
|
|
||||||
sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
|
sinfo = &structInfo{
|
||||||
|
FieldsMap: fieldsMap,
|
||||||
|
FieldsList: fieldsList,
|
||||||
|
InlineMap: inlineMap,
|
||||||
|
}
|
||||||
|
|
||||||
fieldMapMutex.Lock()
|
fieldMapMutex.Lock()
|
||||||
structMap[st] = sinfo
|
structMap[st] = sinfo
|
||||||
|
@ -312,8 +417,23 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
||||||
return sinfo, nil
|
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 {
|
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:
|
case reflect.String:
|
||||||
return len(v.String()) == 0
|
return len(v.String()) == 0
|
||||||
case reflect.Interface, reflect.Ptr:
|
case reflect.Interface, reflect.Ptr:
|
||||||
|
|
32
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
32
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
|
@ -1,6 +1,7 @@
|
||||||
package yaml
|
package yaml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -239,6 +240,27 @@ const (
|
||||||
yaml_MAPPING_END_EVENT // A MAPPING-END event.
|
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.
|
// The event structure.
|
||||||
type yaml_event_t struct {
|
type yaml_event_t struct {
|
||||||
|
|
||||||
|
@ -508,7 +530,7 @@ type yaml_parser_t struct {
|
||||||
|
|
||||||
problem string // Error description.
|
problem string // Error description.
|
||||||
|
|
||||||
// The byte about which the problem occured.
|
// The byte about which the problem occurred.
|
||||||
problem_offset int
|
problem_offset int
|
||||||
problem_value int
|
problem_value int
|
||||||
problem_mark yaml_mark_t
|
problem_mark yaml_mark_t
|
||||||
|
@ -521,9 +543,9 @@ type yaml_parser_t struct {
|
||||||
|
|
||||||
read_handler yaml_read_handler_t // Read handler.
|
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 []byte // String input data.
|
||||||
input_pos int
|
input_pos int
|
||||||
|
|
||||||
eof bool // EOF flag
|
eof bool // EOF flag
|
||||||
|
|
||||||
|
@ -632,7 +654,7 @@ type yaml_emitter_t struct {
|
||||||
write_handler yaml_write_handler_t // Write handler.
|
write_handler yaml_write_handler_t // Write handler.
|
||||||
|
|
||||||
output_buffer *[]byte // String output data.
|
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 []byte // The working buffer.
|
||||||
buffer_pos int // The current position of the buffer.
|
buffer_pos int // The current position of the buffer.
|
||||||
|
|
Loading…
Reference in a new issue