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 (
|
||||
"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
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- tip
|
||||
|
||||
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
|
||||
|
||||
* Support time.Duration config parameters
|
||||
|
|
39
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
39
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
|
@ -29,31 +29,28 @@ go test -v -race -cover github.com/Luzifer/rconfig
|
|||
|
||||
## 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
|
||||
type config struct {
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Luzifer/rconfig"
|
||||
)
|
||||
|
||||
var (
|
||||
cfg = struct {
|
||||
Username string `default:"unknown" flag:"user" description:"Your name"`
|
||||
Details struct {
|
||||
Age int `default:"25" flag:"age" env:"age" description:"Your age"`
|
||||
}
|
||||
}
|
||||
```
|
||||
}{}
|
||||
)
|
||||
|
||||
Next create an instance of that struct and let `rconfig` fill that config:
|
||||
|
||||
```go
|
||||
var cfg config
|
||||
func init() {
|
||||
cfg = config{}
|
||||
rconfig.Parse(&cfg)
|
||||
}
|
||||
```
|
||||
|
||||
You're ready to access your configuration:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
rconfig.Parse(&cfg)
|
||||
|
||||
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
||||
cfg.Username,
|
||||
cfg.Details.Age)
|
||||
|
@ -72,18 +69,14 @@ The order of the directives (lower number = higher precedence):
|
|||
1. `default` tag in the struct
|
||||
|
||||
```go
|
||||
type config struct {
|
||||
var cfg = struct {
|
||||
Username string `vardefault:"username" flag:"username" description:"Your username"`
|
||||
}
|
||||
|
||||
var cfg = config{}
|
||||
|
||||
func init() {
|
||||
func main() {
|
||||
rconfig.SetVariableDefaults(rconfig.VarDefaultsFromYAMLFile("~/.myapp.yml"))
|
||||
rconfig.Parse(&cfg)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Username = %s", cfg.Username)
|
||||
// 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"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
validator "gopkg.in/validator.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -45,6 +46,15 @@ func Parse(config interface{}) error {
|
|||
return parse(config, nil)
|
||||
}
|
||||
|
||||
// ParseAndValidate works exactly like Parse but implements an additional run of
|
||||
// the go-validator package on the configuration struct. Therefore additonal struct
|
||||
// tags are supported like described in the readme file of the go-validator package:
|
||||
//
|
||||
// https://github.com/go-validator/validator/tree/v2#usage
|
||||
func ParseAndValidate(config interface{}) error {
|
||||
return parseAndValidate(config, nil)
|
||||
}
|
||||
|
||||
// Args returns the non-flag command-line arguments.
|
||||
func Args() []string {
|
||||
return fs.Args()
|
||||
|
@ -65,6 +75,14 @@ func SetVariableDefaults(defaults map[string]string) {
|
|||
variableDefaults = defaults
|
||||
}
|
||||
|
||||
func parseAndValidate(in interface{}, args []string) error {
|
||||
if err := parse(in, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validator.Validate(in)
|
||||
}
|
||||
|
||||
func parse(in interface{}, args []string) error {
|
||||
if args == nil {
|
||||
args = os.Args
|
||||
|
|
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/*
|
||||
|
10
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
10
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
|
@ -3,15 +3,19 @@ sudo: false
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.7.3
|
||||
- 1.8.1
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
install:
|
||||
- go get github.com/golang/lint/golint
|
||||
- export PATH=$GOPATH/bin:$PATH
|
||||
- go install ./...
|
||||
|
||||
script:
|
||||
- verify/all.sh
|
||||
- verify/all.sh -v
|
||||
- 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)
|
||||
[![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
|
||||
|
||||
|
@ -85,7 +87,7 @@ fmt.Println("flagvar has value ", flagvar)
|
|||
```
|
||||
|
||||
There are helpers function to get values later if you have the FlagSet but
|
||||
it was difficult to keep up with all of the 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
|
||||
can use GetInt() to get the int value. But notice that 'flagname' must exist
|
||||
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 flagvar bool
|
||||
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.
|
||||
|
@ -244,13 +246,51 @@ It is possible to mark a flag as hidden, meaning it will still function as norma
|
|||
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
|
||||
|
||||
You can see the full reference documentation of the pflag package
|
||||
[at godoc.org][3], or through go's standard documentation system by
|
||||
running `godoc -http=:6060` and browsing to
|
||||
[http://localhost:6060/pkg/github.com/ogier/pflag][2] after
|
||||
[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
|
||||
installation.
|
||||
|
||||
[2]: http://localhost:6060/pkg/github.com/ogier/pflag
|
||||
[3]: http://godoc.org/github.com/ogier/pflag
|
||||
[2]: http://localhost:6060/pkg/github.com/spf13/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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// optional interface to indicate boolean flags that can be
|
||||
// supplied without "=value" text
|
||||
|
@ -30,7 +27,7 @@ func (b *boolValue) Type() string {
|
|||
return "bool"
|
||||
}
|
||||
|
||||
func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
|
||||
func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
|
|
147
vendor/github.com/spf13/pflag/bool_slice.go
generated
vendored
Normal file
147
vendor/github.com/spf13/pflag/bool_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- boolSlice Value
|
||||
type boolSliceValue struct {
|
||||
value *[]bool
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue {
|
||||
bsv := new(boolSliceValue)
|
||||
bsv.value = p
|
||||
*bsv.value = val
|
||||
return bsv
|
||||
}
|
||||
|
||||
// Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.
|
||||
// If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.
|
||||
func (s *boolSliceValue) Set(val string) error {
|
||||
|
||||
// remove all quote characters
|
||||
rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
|
||||
|
||||
// read flag arguments with CSV parser
|
||||
boolStrSlice, err := readAsCSV(rmQuote.Replace(val))
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse boolean values into slice
|
||||
out := make([]bool, 0, len(boolStrSlice))
|
||||
for _, boolStr := range boolStrSlice {
|
||||
b, err := strconv.ParseBool(strings.TrimSpace(boolStr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out = append(out, b)
|
||||
}
|
||||
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
|
||||
s.changed = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a string that uniquely represents this flag's type.
|
||||
func (s *boolSliceValue) Type() string {
|
||||
return "boolSlice"
|
||||
}
|
||||
|
||||
// String defines a "native" format for this boolean slice flag value.
|
||||
func (s *boolSliceValue) String() string {
|
||||
|
||||
boolStrSlice := make([]string, len(*s.value))
|
||||
for i, b := range *s.value {
|
||||
boolStrSlice[i] = strconv.FormatBool(b)
|
||||
}
|
||||
|
||||
out, _ := writeAsCSV(boolStrSlice)
|
||||
|
||||
return "[" + out + "]"
|
||||
}
|
||||
|
||||
func boolSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []bool{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]bool, len(ss))
|
||||
for i, t := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.ParseBool(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetBoolSlice returns the []bool value of a flag with the given name.
|
||||
func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {
|
||||
val, err := f.getFlagType(name, "boolSlice", boolSliceConv)
|
||||
if err != nil {
|
||||
return []bool{}, err
|
||||
}
|
||||
return val.([]bool), nil
|
||||
}
|
||||
|
||||
// BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []bool variable in which to store the value of the flag.
|
||||
func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
|
||||
f.VarP(newBoolSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
|
||||
f.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BoolSliceVar defines a []bool flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []bool variable in which to store the value of the flag.
|
||||
func BoolSliceVar(p *[]bool, name string, value []bool, usage string) {
|
||||
CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {
|
||||
CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BoolSlice defines a []bool flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []bool variable that stores the value of the flag.
|
||||
func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {
|
||||
p := []bool{}
|
||||
f.BoolSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
|
||||
p := []bool{}
|
||||
f.BoolSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// BoolSlice defines a []bool flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []bool variable that stores the value of the flag.
|
||||
func BoolSlice(name string, value []bool, usage string) *[]bool {
|
||||
return CommandLine.BoolSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {
|
||||
return CommandLine.BoolSliceP(name, shorthand, value, usage)
|
||||
}
|
105
vendor/github.com/spf13/pflag/bytes.go
generated
vendored
Normal file
105
vendor/github.com/spf13/pflag/bytes.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded
|
||||
type bytesHexValue []byte
|
||||
|
||||
func (bytesHex bytesHexValue) String() string {
|
||||
return fmt.Sprintf("%X", []byte(bytesHex))
|
||||
}
|
||||
|
||||
func (bytesHex *bytesHexValue) Set(value string) error {
|
||||
bin, err := hex.DecodeString(strings.TrimSpace(value))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*bytesHex = bin
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*bytesHexValue) Type() string {
|
||||
return "bytesHex"
|
||||
}
|
||||
|
||||
func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {
|
||||
*p = val
|
||||
return (*bytesHexValue)(p)
|
||||
}
|
||||
|
||||
func bytesHexConv(sval string) (interface{}, error) {
|
||||
|
||||
bin, err := hex.DecodeString(sval)
|
||||
|
||||
if err == nil {
|
||||
return bin, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
|
||||
}
|
||||
|
||||
// GetBytesHex return the []byte value of a flag with the given name
|
||||
func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
|
||||
val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
|
||||
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
return val.([]byte), nil
|
||||
}
|
||||
|
||||
// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
|
||||
// The argument p points to an []byte variable in which to store the value of the flag.
|
||||
func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
|
||||
f.VarP(newBytesHexValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
|
||||
f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
|
||||
// The argument p points to an []byte variable in which to store the value of the flag.
|
||||
func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
|
||||
CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
|
||||
CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// BytesHex defines an []byte flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an []byte variable that stores the value of the flag.
|
||||
func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
|
||||
p := new([]byte)
|
||||
f.BytesHexVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
|
||||
p := new([]byte)
|
||||
f.BytesHexVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// BytesHex defines an []byte flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an []byte variable that stores the value of the flag.
|
||||
func BytesHex(name string, value []byte, usage string) *[]byte {
|
||||
return CommandLine.BytesHexP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
|
||||
return CommandLine.BytesHexP(name, shorthand, value, usage)
|
||||
}
|
23
vendor/github.com/spf13/pflag/count.go
generated
vendored
23
vendor/github.com/spf13/pflag/count.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- count Value
|
||||
type countValue int
|
||||
|
@ -14,13 +11,13 @@ func newCountValue(val int, p *int) *countValue {
|
|||
}
|
||||
|
||||
func (i *countValue) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 64)
|
||||
// -1 means that no specific value was passed, so increment
|
||||
if v == -1 {
|
||||
// "+1" means that no specific value was passed, so increment
|
||||
if s == "+1" {
|
||||
*i = countValue(*i + 1)
|
||||
} else {
|
||||
*i = countValue(v)
|
||||
return nil
|
||||
}
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
*i = countValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -28,7 +25,7 @@ func (i *countValue) Type() string {
|
|||
return "count"
|
||||
}
|
||||
|
||||
func (i *countValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *countValue) String() string { return strconv.Itoa(int(*i)) }
|
||||
|
||||
func countConv(sval string) (interface{}, error) {
|
||||
i, err := strconv.Atoi(sval)
|
||||
|
@ -57,7 +54,7 @@ func (f *FlagSet) CountVar(p *int, name string, usage string) {
|
|||
// CountVarP is like CountVar only take a shorthand for the flag name.
|
||||
func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
|
||||
flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
|
||||
flag.NoOptDefVal = "-1"
|
||||
flag.NoOptDefVal = "+1"
|
||||
}
|
||||
|
||||
// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
|
||||
|
@ -86,7 +83,9 @@ func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
|
|||
return p
|
||||
}
|
||||
|
||||
// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
|
||||
// Count defines a count flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int variable that stores the value of the flag.
|
||||
// A count flag will add 1 to its value evey time it is found on the command line
|
||||
func Count(name string, usage string) *int {
|
||||
return CommandLine.CountP(name, "", usage)
|
||||
}
|
||||
|
|
128
vendor/github.com/spf13/pflag/duration_slice.go
generated
vendored
Normal file
128
vendor/github.com/spf13/pflag/duration_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// -- durationSlice Value
|
||||
type durationSliceValue struct {
|
||||
value *[]time.Duration
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {
|
||||
dsv := new(durationSliceValue)
|
||||
dsv.value = p
|
||||
*dsv.value = val
|
||||
return dsv
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]time.Duration, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = time.ParseDuration(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) Type() string {
|
||||
return "durationSlice"
|
||||
}
|
||||
|
||||
func (s *durationSliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%s", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func durationSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []time.Duration{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]time.Duration, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = time.ParseDuration(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetDurationSlice returns the []time.Duration value of a flag with the given name
|
||||
func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {
|
||||
val, err := f.getFlagType(name, "durationSlice", durationSliceConv)
|
||||
if err != nil {
|
||||
return []time.Duration{}, err
|
||||
}
|
||||
return val.([]time.Duration), nil
|
||||
}
|
||||
|
||||
// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []time.Duration variable in which to store the value of the flag.
|
||||
func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
|
||||
f.VarP(newDurationSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
|
||||
f.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a duration[] variable in which to store the value of the flag.
|
||||
func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
|
||||
CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
|
||||
CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []time.Duration variable that stores the value of the flag.
|
||||
func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
|
||||
p := []time.Duration{}
|
||||
f.DurationSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
|
||||
p := []time.Duration{}
|
||||
f.DurationSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []time.Duration variable that stores the value of the flag.
|
||||
func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
|
||||
return CommandLine.DurationSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
|
||||
return CommandLine.DurationSliceP(name, shorthand, value, usage)
|
||||
}
|
595
vendor/github.com/spf13/pflag/flag.go
generated
vendored
595
vendor/github.com/spf13/pflag/flag.go
generated
vendored
|
@ -16,9 +16,9 @@ pflag is a drop-in replacement of Go's native flag package. If you import
|
|||
pflag under the name "flag" then all code should continue to function
|
||||
with no changes.
|
||||
|
||||
import flag "github.com/ogier/pflag"
|
||||
import flag "github.com/spf13/pflag"
|
||||
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
there is one more field "Shorthand" that you will need to set.
|
||||
Most code never instantiates this struct directly, and instead uses
|
||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||
|
@ -101,6 +101,7 @@ package pflag
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
@ -123,6 +124,12 @@ const (
|
|||
PanicOnError
|
||||
)
|
||||
|
||||
// ParseErrorsWhitelist defines the parsing errors that can be ignored
|
||||
type ParseErrorsWhitelist struct {
|
||||
// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
|
||||
UnknownFlags bool
|
||||
}
|
||||
|
||||
// NormalizedName is a flag name that has been normalized according to rules
|
||||
// for the FlagSet (e.g. making '-' and '_' equivalent).
|
||||
type NormalizedName string
|
||||
|
@ -134,18 +141,30 @@ type FlagSet struct {
|
|||
// a custom error handler.
|
||||
Usage func()
|
||||
|
||||
// SortFlags is used to indicate, if user wants to have sorted flags in
|
||||
// help/usage messages.
|
||||
SortFlags bool
|
||||
|
||||
// ParseErrorsWhitelist is used to configure a whitelist of errors
|
||||
ParseErrorsWhitelist ParseErrorsWhitelist
|
||||
|
||||
name string
|
||||
parsed bool
|
||||
actual map[NormalizedName]*Flag
|
||||
orderedActual []*Flag
|
||||
sortedActual []*Flag
|
||||
formal map[NormalizedName]*Flag
|
||||
orderedFormal []*Flag
|
||||
sortedFormal []*Flag
|
||||
shorthands map[byte]*Flag
|
||||
args []string // arguments after flags
|
||||
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
|
||||
exitOnError bool // does the program exit if there's an error?
|
||||
errorHandling ErrorHandling
|
||||
output io.Writer // nil means stderr; use out() accessor
|
||||
interspersed bool // allow interspersed option/non-option args
|
||||
normalizeNameFunc func(f *FlagSet, name string) NormalizedName
|
||||
|
||||
addedGoFlagSets []*goflag.FlagSet
|
||||
}
|
||||
|
||||
// A Flag represents the state of a flag.
|
||||
|
@ -156,7 +175,7 @@ type Flag struct {
|
|||
Value Value // value as set
|
||||
DefValue string // default value (as text); for usage message
|
||||
Changed bool // If the user set the value (or if left to default)
|
||||
NoOptDefVal string //default value (as text); if the flag is on the command line without any options
|
||||
NoOptDefVal string // default value (as text); if the flag is on the command line without any options
|
||||
Deprecated string // If this flag is deprecated, this string is the new or now thing to use
|
||||
Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
|
||||
ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
|
||||
|
@ -194,11 +213,19 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
|
|||
// "--getUrl" which may also be translated to "geturl" and everything will work.
|
||||
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
|
||||
f.normalizeNameFunc = n
|
||||
for k, v := range f.formal {
|
||||
delete(f.formal, k)
|
||||
nname := f.normalizeFlagName(string(k))
|
||||
f.formal[nname] = v
|
||||
v.Name = string(nname)
|
||||
f.sortedFormal = f.sortedFormal[:0]
|
||||
for fname, flag := range f.formal {
|
||||
nname := f.normalizeFlagName(flag.Name)
|
||||
if fname == nname {
|
||||
continue
|
||||
}
|
||||
flag.Name = string(nname)
|
||||
delete(f.formal, fname)
|
||||
f.formal[nname] = flag
|
||||
if _, set := f.actual[fname]; set {
|
||||
delete(f.actual, fname)
|
||||
f.actual[nname] = flag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,35 +256,78 @@ func (f *FlagSet) SetOutput(output io.Writer) {
|
|||
f.output = output
|
||||
}
|
||||
|
||||
// VisitAll visits the flags in lexicographical order, calling fn for each.
|
||||
// VisitAll visits the flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits all flags, even those not set.
|
||||
func (f *FlagSet) VisitAll(fn func(*Flag)) {
|
||||
for _, flag := range sortFlags(f.formal) {
|
||||
if len(f.formal) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var flags []*Flag
|
||||
if f.SortFlags {
|
||||
if len(f.formal) != len(f.sortedFormal) {
|
||||
f.sortedFormal = sortFlags(f.formal)
|
||||
}
|
||||
flags = f.sortedFormal
|
||||
} else {
|
||||
flags = f.orderedFormal
|
||||
}
|
||||
|
||||
for _, flag := range flags {
|
||||
fn(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
|
||||
// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
|
||||
func (f *FlagSet) HasFlags() bool {
|
||||
return len(f.formal) > 0
|
||||
}
|
||||
|
||||
// VisitAll visits the command-line flags in lexicographical order, calling
|
||||
// fn for each. It visits all flags, even those not set.
|
||||
// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
|
||||
// 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)) {
|
||||
CommandLine.VisitAll(fn)
|
||||
}
|
||||
|
||||
// Visit visits the flags in lexicographical order, calling fn for each.
|
||||
// Visit visits the flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits only those flags that have been set.
|
||||
func (f *FlagSet) Visit(fn func(*Flag)) {
|
||||
for _, flag := range sortFlags(f.actual) {
|
||||
if len(f.actual) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var flags []*Flag
|
||||
if f.SortFlags {
|
||||
if len(f.actual) != len(f.sortedActual) {
|
||||
f.sortedActual = sortFlags(f.actual)
|
||||
}
|
||||
flags = f.sortedActual
|
||||
} else {
|
||||
flags = f.orderedActual
|
||||
}
|
||||
|
||||
for _, flag := range flags {
|
||||
fn(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// Visit visits the command-line flags in lexicographical order, calling fn
|
||||
// for each. It visits only those flags that have been set.
|
||||
// Visit visits the command-line flags in lexicographical order or
|
||||
// in primordial order if f.SortFlags is false, calling fn for each.
|
||||
// It visits only those flags that have been set.
|
||||
func Visit(fn func(*Flag)) {
|
||||
CommandLine.Visit(fn)
|
||||
}
|
||||
|
@ -267,6 +337,22 @@ func (f *FlagSet) Lookup(name string) *Flag {
|
|||
return f.lookup(f.normalizeFlagName(name))
|
||||
}
|
||||
|
||||
// ShorthandLookup returns the Flag structure of the short handed flag,
|
||||
// returning nil if none exists.
|
||||
// It panics, if len(name) > 1.
|
||||
func (f *FlagSet) ShorthandLookup(name string) *Flag {
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
if len(name) > 1 {
|
||||
msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
|
||||
fmt.Fprintf(f.out(), msg)
|
||||
panic(msg)
|
||||
}
|
||||
c := name[0]
|
||||
return f.shorthands[c]
|
||||
}
|
||||
|
||||
// lookup returns the Flag structure of the named flag, returning nil if none exists.
|
||||
func (f *FlagSet) lookup(name NormalizedName) *Flag {
|
||||
return f.formal[name]
|
||||
|
@ -308,10 +394,11 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
|
|||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
if len(usageMessage) == 0 {
|
||||
if usageMessage == "" {
|
||||
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||
}
|
||||
flag.Deprecated = usageMessage
|
||||
flag.Hidden = true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -323,7 +410,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
|
|||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
if len(usageMessage) == 0 {
|
||||
if usageMessage == "" {
|
||||
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||
}
|
||||
flag.ShorthandDeprecated = usageMessage
|
||||
|
@ -347,6 +434,12 @@ func Lookup(name string) *Flag {
|
|||
return CommandLine.Lookup(name)
|
||||
}
|
||||
|
||||
// ShorthandLookup returns the Flag structure of the short handed flag,
|
||||
// returning nil if none exists.
|
||||
func ShorthandLookup(name string) *Flag {
|
||||
return CommandLine.ShorthandLookup(name)
|
||||
}
|
||||
|
||||
// Set sets the value of the named flag.
|
||||
func (f *FlagSet) Set(name, value string) error {
|
||||
normalName := f.normalizeFlagName(name)
|
||||
|
@ -354,17 +447,30 @@ func (f *FlagSet) Set(name, value string) error {
|
|||
if !ok {
|
||||
return fmt.Errorf("no such flag -%v", name)
|
||||
}
|
||||
|
||||
err := flag.Value.Set(value)
|
||||
if err != nil {
|
||||
return err
|
||||
var flagName string
|
||||
if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
|
||||
flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
|
||||
} else {
|
||||
flagName = fmt.Sprintf("--%s", flag.Name)
|
||||
}
|
||||
return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
|
||||
}
|
||||
|
||||
if !flag.Changed {
|
||||
if f.actual == nil {
|
||||
f.actual = make(map[NormalizedName]*Flag)
|
||||
}
|
||||
f.actual[normalName] = flag
|
||||
f.orderedActual = append(f.orderedActual, flag)
|
||||
|
||||
flag.Changed = true
|
||||
if len(flag.Deprecated) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
|
||||
if flag.Deprecated != "" {
|
||||
fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -405,45 +511,232 @@ func Set(name, value string) error {
|
|||
// otherwise, the default values of all defined flags in the set.
|
||||
func (f *FlagSet) PrintDefaults() {
|
||||
usages := f.FlagUsages()
|
||||
fmt.Fprintf(f.out(), "%s", usages)
|
||||
fmt.Fprint(f.out(), usages)
|
||||
}
|
||||
|
||||
// FlagUsages Returns a string containing the usage information for all flags in
|
||||
// the FlagSet
|
||||
func (f *FlagSet) FlagUsages() string {
|
||||
x := new(bytes.Buffer)
|
||||
// defaultIsZeroValue returns true if the default value for this flag represents
|
||||
// a zero value.
|
||||
func (f *Flag) defaultIsZeroValue() bool {
|
||||
switch f.Value.(type) {
|
||||
case boolFlag:
|
||||
return f.DefValue == "false"
|
||||
case *durationValue:
|
||||
// Beginning in Go 1.7, duration zero values are "0s"
|
||||
return f.DefValue == "0" || f.DefValue == "0s"
|
||||
case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
|
||||
return f.DefValue == "0"
|
||||
case *stringValue:
|
||||
return f.DefValue == ""
|
||||
case *ipValue, *ipMaskValue, *ipNetValue:
|
||||
return f.DefValue == "<nil>"
|
||||
case *intSliceValue, *stringSliceValue, *stringArrayValue:
|
||||
return f.DefValue == "[]"
|
||||
default:
|
||||
switch f.Value.String() {
|
||||
case "false":
|
||||
return true
|
||||
case "<nil>":
|
||||
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) {
|
||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||
if flag.Hidden {
|
||||
return
|
||||
}
|
||||
format := ""
|
||||
if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
|
||||
format = " -%s, --%s"
|
||||
|
||||
line := ""
|
||||
if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
|
||||
line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
|
||||
} 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.NoOptDefVal != "" {
|
||||
switch flag.Value.Type() {
|
||||
case "string":
|
||||
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
|
||||
case "bool":
|
||||
if flag.NoOptDefVal != "true" {
|
||||
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||
}
|
||||
case "count":
|
||||
if flag.NoOptDefVal != "+1" {
|
||||
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||
}
|
||||
default:
|
||||
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||
}
|
||||
}
|
||||
|
||||
// This special character will be replaced with spacing once the
|
||||
// correct alignment is calculated
|
||||
line += "\x00"
|
||||
if len(line) > maxlen {
|
||||
maxlen = len(line)
|
||||
}
|
||||
|
||||
line += usage
|
||||
if !flag.defaultIsZeroValue() {
|
||||
if flag.Value.Type() == "string" {
|
||||
// put quotes on the value
|
||||
format = format + "=%q"
|
||||
line += fmt.Sprintf(" (default %q)", flag.DefValue)
|
||||
} else {
|
||||
format = format + "=%s"
|
||||
line += fmt.Sprintf(" (default %s)", flag.DefValue)
|
||||
}
|
||||
if len(flag.NoOptDefVal) > 0 {
|
||||
format = format + "]"
|
||||
}
|
||||
format = format + ": %s\n"
|
||||
shorthand := flag.Shorthand
|
||||
if len(flag.ShorthandDeprecated) > 0 {
|
||||
shorthand = ""
|
||||
if len(flag.Deprecated) != 0 {
|
||||
line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
|
||||
}
|
||||
fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
|
||||
|
||||
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.
|
||||
|
@ -463,6 +756,8 @@ func defaultUsage(f *FlagSet) {
|
|||
|
||||
// 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.
|
||||
// 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() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
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.
|
||||
func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
|
||||
_ = f.VarPF(value, name, shorthand, usage)
|
||||
f.VarPF(value, name, shorthand, usage)
|
||||
}
|
||||
|
||||
// AddFlag will add the flag to the FlagSet
|
||||
func (f *FlagSet) AddFlag(flag *Flag) {
|
||||
// Call normalizeFlagName function only once
|
||||
normalizedFlagName := f.normalizeFlagName(flag.Name)
|
||||
|
||||
_, alreadythere := f.formal[normalizedFlagName]
|
||||
if alreadythere {
|
||||
_, alreadyThere := f.formal[normalizedFlagName]
|
||||
if alreadyThere {
|
||||
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
|
||||
fmt.Fprintln(f.out(), msg)
|
||||
panic(msg) // Happens only if flags are declared with identical names
|
||||
|
@ -547,28 +841,31 @@ func (f *FlagSet) AddFlag(flag *Flag) {
|
|||
|
||||
flag.Name = string(normalizedFlagName)
|
||||
f.formal[normalizedFlagName] = flag
|
||||
f.orderedFormal = append(f.orderedFormal, flag)
|
||||
|
||||
if len(flag.Shorthand) == 0 {
|
||||
if flag.Shorthand == "" {
|
||||
return
|
||||
}
|
||||
if len(flag.Shorthand) > 1 {
|
||||
fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
|
||||
panic("shorthand is more than one character")
|
||||
msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
|
||||
fmt.Fprintf(f.out(), msg)
|
||||
panic(msg)
|
||||
}
|
||||
if f.shorthands == nil {
|
||||
f.shorthands = make(map[byte]*Flag)
|
||||
}
|
||||
c := flag.Shorthand[0]
|
||||
old, alreadythere := f.shorthands[c]
|
||||
if alreadythere {
|
||||
fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
|
||||
panic("shorthand redefinition")
|
||||
used, alreadyThere := f.shorthands[c]
|
||||
if alreadyThere {
|
||||
msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
|
||||
fmt.Fprintf(f.out(), msg)
|
||||
panic(msg)
|
||||
}
|
||||
f.shorthands[c] = flag
|
||||
}
|
||||
|
||||
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
|
||||
// the flag from newSet will be ignored
|
||||
// the flag from newSet will be ignored.
|
||||
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
|
||||
if newSet == nil {
|
||||
return
|
||||
|
@ -599,8 +896,10 @@ func VarP(value Value, name, shorthand, usage string) {
|
|||
// returns the error.
|
||||
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
||||
err := fmt.Errorf(format, a...)
|
||||
if f.errorHandling != ContinueOnError {
|
||||
fmt.Fprintln(f.out(), err)
|
||||
f.usage()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -616,57 +915,61 @@ func (f *FlagSet) usage() {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
|
||||
if err := flag.Value.Set(value); err != nil {
|
||||
return f.failf("invalid argument %q for %s: %v", value, origArg, err)
|
||||
//--unknown (args will be empty)
|
||||
//--unknown --next-flag ... (args will be --next-flag ...)
|
||||
//--unknown arg ... (args will be arg ...)
|
||||
func stripUnknownFlagValue(args []string) []string {
|
||||
if len(args) == 0 {
|
||||
//--unknown
|
||||
return args
|
||||
}
|
||||
// mark as visited for Visit()
|
||||
if f.actual == nil {
|
||||
f.actual = make(map[NormalizedName]*Flag)
|
||||
|
||||
first := args[0]
|
||||
if first[0] == '-' {
|
||||
//--unknown --next-flag ...
|
||||
return args
|
||||
}
|
||||
f.actual[f.normalizeFlagName(flag.Name)] = flag
|
||||
flag.Changed = true
|
||||
if len(flag.Deprecated) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
|
||||
fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
|
||||
}
|
||||
return nil
|
||||
|
||||
//--unknown arg ... (args will be arg ...)
|
||||
return args[1:]
|
||||
}
|
||||
|
||||
func containsShorthand(arg, shorthand string) bool {
|
||||
// filter out flags --<flag_name>
|
||||
if strings.HasPrefix(arg, "-") {
|
||||
return false
|
||||
}
|
||||
arg = strings.SplitN(arg, "=", 2)[0]
|
||||
return strings.Contains(arg, shorthand)
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
|
||||
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
|
||||
a = args
|
||||
name := s[2:]
|
||||
if len(name) == 0 || name[0] == '-' || name[0] == '=' {
|
||||
err = f.failf("bad flag syntax: %s", s)
|
||||
return
|
||||
}
|
||||
|
||||
split := strings.SplitN(name, "=", 2)
|
||||
name = split[0]
|
||||
flag, alreadythere := f.formal[f.normalizeFlagName(name)]
|
||||
if !alreadythere {
|
||||
if name == "help" { // special case for nice help message.
|
||||
flag, exists := f.formal[f.normalizeFlagName(name)]
|
||||
|
||||
if !exists {
|
||||
switch {
|
||||
case name == "help":
|
||||
f.usage()
|
||||
return a, ErrHelp
|
||||
case f.ParseErrorsWhitelist.UnknownFlags:
|
||||
// --unknown=unknownval arg ...
|
||||
// we do not want to lose arg in this case
|
||||
if len(split) >= 2 {
|
||||
return a, nil
|
||||
}
|
||||
|
||||
return stripUnknownFlagValue(a), nil
|
||||
default:
|
||||
err = f.failf("unknown flag: --%s", name)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var value string
|
||||
if len(split) == 2 {
|
||||
// '--flag=arg'
|
||||
value = split[1]
|
||||
} else if len(flag.NoOptDefVal) > 0 {
|
||||
} else if flag.NoOptDefVal != "" {
|
||||
// '--flag' (arg was optional)
|
||||
value = flag.NoOptDefVal
|
||||
} else if len(a) > 0 {
|
||||
|
@ -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)
|
||||
return
|
||||
}
|
||||
err = f.setFlag(flag, value, s)
|
||||
|
||||
err = fn(flag, value)
|
||||
if err != nil {
|
||||
f.failf(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
|
||||
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
|
||||
if strings.HasPrefix(shorthands, "test.") {
|
||||
return
|
||||
}
|
||||
|
||||
outArgs = args
|
||||
outShorts = shorthands[1:]
|
||||
c := shorthands[0]
|
||||
|
||||
flag, alreadythere := f.shorthands[c]
|
||||
if !alreadythere {
|
||||
if c == 'h' { // special case for nice help message.
|
||||
flag, exists := f.shorthands[c]
|
||||
if !exists {
|
||||
switch {
|
||||
case c == 'h':
|
||||
f.usage()
|
||||
err = ErrHelp
|
||||
return
|
||||
case f.ParseErrorsWhitelist.UnknownFlags:
|
||||
// '-f=arg arg ...'
|
||||
// we do not want to lose arg in this case
|
||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||
outShorts = ""
|
||||
return
|
||||
}
|
||||
//TODO continue on error
|
||||
|
||||
outArgs = stripUnknownFlagValue(outArgs)
|
||||
return
|
||||
default:
|
||||
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var value string
|
||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||
// '-f=arg'
|
||||
value = shorthands[2:]
|
||||
outShorts = ""
|
||||
} else if len(flag.NoOptDefVal) > 0 {
|
||||
} else if flag.NoOptDefVal != "" {
|
||||
// '-f' (arg was optional)
|
||||
value = flag.NoOptDefVal
|
||||
} else if len(shorthands) > 1 {
|
||||
// '-farg'
|
||||
value = shorthands[1:]
|
||||
outShorts = ""
|
||||
} else if len(args) > 0 {
|
||||
// '-f arg'
|
||||
value = args[0]
|
||||
outArgs = args[1:]
|
||||
} else {
|
||||
// '-f' (arg was required)
|
||||
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
|
||||
return
|
||||
}
|
||||
err = f.setFlag(flag, value, shorthands)
|
||||
|
||||
if flag.ShorthandDeprecated != "" {
|
||||
fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
|
||||
}
|
||||
|
||||
err = fn(flag, value)
|
||||
if err != nil {
|
||||
f.failf(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) {
|
||||
func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
|
||||
a = args
|
||||
shorthands := s[1:]
|
||||
|
||||
// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
|
||||
for len(shorthands) > 0 {
|
||||
shorthands, a, err = f.parseSingleShortArg(shorthands, args)
|
||||
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -732,7 +1069,7 @@ func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error)
|
|||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseArgs(args []string) (err error) {
|
||||
func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
|
||||
for len(args) > 0 {
|
||||
s := args[0]
|
||||
args = args[1:]
|
||||
|
@ -752,9 +1089,9 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
|||
f.args = append(f.args, args...)
|
||||
break
|
||||
}
|
||||
args, err = f.parseLongArg(s, args)
|
||||
args, err = f.parseLongArg(s, args, fn)
|
||||
} else {
|
||||
args, err = f.parseShortArg(s, args)
|
||||
args, err = f.parseShortArg(s, args, fn)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -768,9 +1105,50 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
|||
// are defined and before flags are accessed by the program.
|
||||
// The return value will be ErrHelp if -help was set but not defined.
|
||||
func (f *FlagSet) Parse(arguments []string) error {
|
||||
if f.addedGoFlagSets != nil {
|
||||
for _, goFlagSet := range f.addedGoFlagSets {
|
||||
goFlagSet.Parse(nil)
|
||||
}
|
||||
}
|
||||
f.parsed = true
|
||||
|
||||
if len(arguments) < 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.args = make([]string, 0, len(arguments))
|
||||
|
||||
set := func(flag *Flag, value string) error {
|
||||
return f.Set(flag.Name, value)
|
||||
}
|
||||
|
||||
err := f.parseArgs(arguments, set)
|
||||
if err != nil {
|
||||
switch f.errorHandling {
|
||||
case ContinueOnError:
|
||||
return err
|
||||
case ExitOnError:
|
||||
fmt.Println(err)
|
||||
os.Exit(2)
|
||||
case PanicOnError:
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type parseFunc func(flag *Flag, value string) error
|
||||
|
||||
// ParseAll parses flag definitions from the argument list, which should not
|
||||
// include the command name. The arguments for fn are flag and value. Must be
|
||||
// called after all flags in the FlagSet are defined and before flags are
|
||||
// accessed by the program. The return value will be ErrHelp if -help was set
|
||||
// but not defined.
|
||||
func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
|
||||
f.parsed = true
|
||||
f.args = make([]string, 0, len(arguments))
|
||||
err := f.parseArgs(arguments)
|
||||
|
||||
err := f.parseArgs(arguments, fn)
|
||||
if err != nil {
|
||||
switch f.errorHandling {
|
||||
case ContinueOnError:
|
||||
|
@ -796,6 +1174,14 @@ func Parse() {
|
|||
CommandLine.Parse(os.Args[1:])
|
||||
}
|
||||
|
||||
// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
|
||||
// The arguments for fn are flag and value. Must be called after all flags are
|
||||
// defined and before flags are accessed by the program.
|
||||
func ParseAll(fn func(flag *Flag, value string) error) {
|
||||
// Ignore errors; CommandLine is set for ExitOnError.
|
||||
CommandLine.ParseAll(os.Args[1:], fn)
|
||||
}
|
||||
|
||||
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||
func SetInterspersed(interspersed bool) {
|
||||
CommandLine.SetInterspersed(interspersed)
|
||||
|
@ -806,17 +1192,18 @@ func Parsed() bool {
|
|||
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)
|
||||
|
||||
// NewFlagSet returns a new, empty flag set with the specified name and
|
||||
// error handling property.
|
||||
// NewFlagSet returns a new, empty flag set with the specified name,
|
||||
// error handling property and SortFlags set to true.
|
||||
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
|
||||
f := &FlagSet{
|
||||
name: name,
|
||||
errorHandling: errorHandling,
|
||||
argsLenAtDash: -1,
|
||||
interspersed: true,
|
||||
SortFlags: true,
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
|
7
vendor/github.com/spf13/pflag/float32.go
generated
vendored
7
vendor/github.com/spf13/pflag/float32.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- float32 Value
|
||||
type float32Value float32
|
||||
|
@ -23,7 +20,7 @@ func (f *float32Value) Type() string {
|
|||
return "float32"
|
||||
}
|
||||
|
||||
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
|
||||
func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) }
|
||||
|
||||
func float32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseFloat(sval, 32)
|
||||
|
|
7
vendor/github.com/spf13/pflag/float64.go
generated
vendored
7
vendor/github.com/spf13/pflag/float64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- float64 Value
|
||||
type float64Value float64
|
||||
|
@ -23,7 +20,7 @@ func (f *float64Value) Type() string {
|
|||
return "float64"
|
||||
}
|
||||
|
||||
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
|
||||
func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
|
||||
|
||||
func float64Conv(sval string) (interface{}, error) {
|
||||
return strconv.ParseFloat(sval, 64)
|
||||
|
|
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 (
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = fmt.Print
|
||||
|
||||
// flagValueWrapper implements pflag.Value around a flag.Value. The main
|
||||
// difference here is the addition of the Type method that returns a string
|
||||
// name of the type. As this is generally unknown, we approximate that with
|
||||
|
@ -61,6 +58,9 @@ func (v *flagValueWrapper) Type() string {
|
|||
}
|
||||
|
||||
// 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 {
|
||||
// Remember the default value as a string; it won't change.
|
||||
flag := &Flag{
|
||||
|
@ -71,6 +71,10 @@ func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
|
|||
//DefValue: goflag.DefValue,
|
||||
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() {
|
||||
flag.NoOptDefVal = "true"
|
||||
}
|
||||
|
@ -94,4 +98,8 @@ func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
|
|||
newSet.VisitAll(func(goflag *goflag.Flag) {
|
||||
f.AddGoFlag(goflag)
|
||||
})
|
||||
if f.addedGoFlagSets == nil {
|
||||
f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
|
||||
}
|
||||
f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
|
||||
}
|
||||
|
|
7
vendor/github.com/spf13/pflag/int.go
generated
vendored
7
vendor/github.com/spf13/pflag/int.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int Value
|
||||
type intValue int
|
||||
|
@ -23,7 +20,7 @@ func (i *intValue) Type() string {
|
|||
return "int"
|
||||
}
|
||||
|
||||
func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
|
||||
|
||||
func intConv(sval string) (interface{}, error) {
|
||||
return strconv.Atoi(sval)
|
||||
|
|
88
vendor/github.com/spf13/pflag/int16.go
generated
vendored
Normal file
88
vendor/github.com/spf13/pflag/int16.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
package pflag
|
||||
|
||||
import "strconv"
|
||||
|
||||
// -- int16 Value
|
||||
type int16Value int16
|
||||
|
||||
func newInt16Value(val int16, p *int16) *int16Value {
|
||||
*p = val
|
||||
return (*int16Value)(p)
|
||||
}
|
||||
|
||||
func (i *int16Value) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 16)
|
||||
*i = int16Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *int16Value) Type() string {
|
||||
return "int16"
|
||||
}
|
||||
|
||||
func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int16Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int16(v), nil
|
||||
}
|
||||
|
||||
// GetInt16 returns the int16 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt16(name string) (int16, error) {
|
||||
val, err := f.getFlagType(name, "int16", int16Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int16), nil
|
||||
}
|
||||
|
||||
// Int16Var defines an int16 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int16 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {
|
||||
f.VarP(newInt16Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
|
||||
f.VarP(newInt16Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int16Var defines an int16 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int16 variable in which to store the value of the flag.
|
||||
func Int16Var(p *int16, name string, value int16, usage string) {
|
||||
CommandLine.VarP(newInt16Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
|
||||
CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int16 defines an int16 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int16 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int16(name string, value int16, usage string) *int16 {
|
||||
p := new(int16)
|
||||
f.Int16VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {
|
||||
p := new(int16)
|
||||
f.Int16VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int16 defines an int16 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int16 variable that stores the value of the flag.
|
||||
func Int16(name string, value int16, usage string) *int16 {
|
||||
return CommandLine.Int16P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int16P(name, shorthand string, value int16, usage string) *int16 {
|
||||
return CommandLine.Int16P(name, shorthand, value, usage)
|
||||
}
|
7
vendor/github.com/spf13/pflag/int32.go
generated
vendored
7
vendor/github.com/spf13/pflag/int32.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int32 Value
|
||||
type int32Value int32
|
||||
|
@ -23,7 +20,7 @@ func (i *int32Value) Type() string {
|
|||
return "int32"
|
||||
}
|
||||
|
||||
func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 32)
|
||||
|
|
7
vendor/github.com/spf13/pflag/int64.go
generated
vendored
7
vendor/github.com/spf13/pflag/int64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int64 Value
|
||||
type int64Value int64
|
||||
|
@ -23,7 +20,7 @@ func (i *int64Value) Type() string {
|
|||
return "int64"
|
||||
}
|
||||
|
||||
func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int64Conv(sval string) (interface{}, error) {
|
||||
return strconv.ParseInt(sval, 0, 64)
|
||||
|
|
7
vendor/github.com/spf13/pflag/int8.go
generated
vendored
7
vendor/github.com/spf13/pflag/int8.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- int8 Value
|
||||
type int8Value int8
|
||||
|
@ -23,7 +20,7 @@ func (i *int8Value) Type() string {
|
|||
return "int8"
|
||||
}
|
||||
|
||||
func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||
|
||||
func int8Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 8)
|
||||
|
|
2
vendor/github.com/spf13/pflag/ip.go
generated
vendored
2
vendor/github.com/spf13/pflag/ip.go
generated
vendored
|
@ -6,8 +6,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var _ = strings.TrimSpace
|
||||
|
||||
// -- net.IP value
|
||||
type ipValue net.IP
|
||||
|
||||
|
|
148
vendor/github.com/spf13/pflag/ip_slice.go
generated
vendored
Normal file
148
vendor/github.com/spf13/pflag/ip_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- ipSlice Value
|
||||
type ipSliceValue struct {
|
||||
value *[]net.IP
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue {
|
||||
ipsv := new(ipSliceValue)
|
||||
ipsv.value = p
|
||||
*ipsv.value = val
|
||||
return ipsv
|
||||
}
|
||||
|
||||
// Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag.
|
||||
// If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended.
|
||||
func (s *ipSliceValue) Set(val string) error {
|
||||
|
||||
// remove all quote characters
|
||||
rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "")
|
||||
|
||||
// read flag arguments with CSV parser
|
||||
ipStrSlice, err := readAsCSV(rmQuote.Replace(val))
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// parse ip values into slice
|
||||
out := make([]net.IP, 0, len(ipStrSlice))
|
||||
for _, ipStr := range ipStrSlice {
|
||||
ip := net.ParseIP(strings.TrimSpace(ipStr))
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid string being converted to IP address: %s", ipStr)
|
||||
}
|
||||
out = append(out, ip)
|
||||
}
|
||||
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
|
||||
s.changed = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type returns a string that uniquely represents this flag's type.
|
||||
func (s *ipSliceValue) Type() string {
|
||||
return "ipSlice"
|
||||
}
|
||||
|
||||
// String defines a "native" format for this net.IP slice flag value.
|
||||
func (s *ipSliceValue) String() string {
|
||||
|
||||
ipStrSlice := make([]string, len(*s.value))
|
||||
for i, ip := range *s.value {
|
||||
ipStrSlice[i] = ip.String()
|
||||
}
|
||||
|
||||
out, _ := writeAsCSV(ipStrSlice)
|
||||
|
||||
return "[" + out + "]"
|
||||
}
|
||||
|
||||
func ipSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Emtpy string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []net.IP{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]net.IP, len(ss))
|
||||
for i, sval := range ss {
|
||||
ip := net.ParseIP(strings.TrimSpace(sval))
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
|
||||
}
|
||||
out[i] = ip
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetIPSlice returns the []net.IP value of a flag with the given name
|
||||
func (f *FlagSet) GetIPSlice(name string) ([]net.IP, error) {
|
||||
val, err := f.getFlagType(name, "ipSlice", ipSliceConv)
|
||||
if err != nil {
|
||||
return []net.IP{}, err
|
||||
}
|
||||
return val.([]net.IP), nil
|
||||
}
|
||||
|
||||
// IPSliceVar defines a ipSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []net.IP variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
|
||||
f.VarP(newIPSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
|
||||
f.VarP(newIPSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPSliceVar defines a []net.IP flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []net.IP variable in which to store the value of the flag.
|
||||
func IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {
|
||||
CommandLine.VarP(newIPSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {
|
||||
CommandLine.VarP(newIPSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []net.IP variable that stores the value of that flag.
|
||||
func (f *FlagSet) IPSlice(name string, value []net.IP, usage string) *[]net.IP {
|
||||
p := []net.IP{}
|
||||
f.IPSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
|
||||
p := []net.IP{}
|
||||
f.IPSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IPSlice defines a []net.IP flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []net.IP variable that stores the value of the flag.
|
||||
func IPSlice(name string, value []net.IP, usage string) *[]net.IP {
|
||||
return CommandLine.IPSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {
|
||||
return CommandLine.IPSliceP(name, shorthand, value, usage)
|
||||
}
|
2
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
2
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
|
@ -27,8 +27,6 @@ func (*ipNetValue) Type() string {
|
|||
return "ipNet"
|
||||
}
|
||||
|
||||
var _ = strings.TrimSpace
|
||||
|
||||
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
|
||||
*p = val
|
||||
return (*ipNetValue)(p)
|
||||
|
|
4
vendor/github.com/spf13/pflag/string.go
generated
vendored
4
vendor/github.com/spf13/pflag/string.go
generated
vendored
|
@ -1,7 +1,5 @@
|
|||
package pflag
|
||||
|
||||
import "fmt"
|
||||
|
||||
// -- string Value
|
||||
type stringValue string
|
||||
|
||||
|
@ -18,7 +16,7 @@ func (s *stringValue) Type() string {
|
|||
return "string"
|
||||
}
|
||||
|
||||
func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
|
||||
func (s *stringValue) String() string { return string(*s) }
|
||||
|
||||
func stringConv(sval string) (interface{}, error) {
|
||||
return sval, nil
|
||||
|
|
103
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
Normal file
103
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package pflag
|
||||
|
||||
// -- stringArray Value
|
||||
type stringArrayValue struct {
|
||||
value *[]string
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newStringArrayValue(val []string, p *[]string) *stringArrayValue {
|
||||
ssv := new(stringArrayValue)
|
||||
ssv.value = p
|
||||
*ssv.value = val
|
||||
return ssv
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Set(val string) error {
|
||||
if !s.changed {
|
||||
*s.value = []string{val}
|
||||
s.changed = true
|
||||
} else {
|
||||
*s.value = append(*s.value, val)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) Type() string {
|
||||
return "stringArray"
|
||||
}
|
||||
|
||||
func (s *stringArrayValue) String() string {
|
||||
str, _ := writeAsCSV(*s.value)
|
||||
return "[" + str + "]"
|
||||
}
|
||||
|
||||
func stringArrayConv(sval string) (interface{}, error) {
|
||||
sval = sval[1 : len(sval)-1]
|
||||
// An empty string would cause a array with one (empty) string
|
||||
if len(sval) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
return readAsCSV(sval)
|
||||
}
|
||||
|
||||
// GetStringArray return the []string value of a flag with the given name
|
||||
func (f *FlagSet) GetStringArray(name string) ([]string, error) {
|
||||
val, err := f.getFlagType(name, "stringArray", stringArrayConv)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return val.([]string), nil
|
||||
}
|
||||
|
||||
// StringArrayVar defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []string variable in which to store the values of the multiple flags.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
|
||||
f.VarP(newStringArrayValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||
f.VarP(newStringArrayValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringArrayVar defines a string flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func StringArrayVar(p *[]string, name string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringArray defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringArrayVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringArrayVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringArray defines a string flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
|
||||
func StringArray(name string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringArrayP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringArrayP(name, shorthand string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringArrayP(name, shorthand, value, usage)
|
||||
}
|
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = fmt.Fprint
|
||||
|
||||
// -- stringSlice Value
|
||||
type stringSliceValue struct {
|
||||
value *[]string
|
||||
|
@ -20,8 +19,31 @@ func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
|
|||
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 {
|
||||
v := strings.Split(val, ",")
|
||||
v, err := readAsCSV(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = v
|
||||
} else {
|
||||
|
@ -35,16 +57,18 @@ func (s *stringSliceValue) Type() string {
|
|||
return "stringSlice"
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) String() string { return "[" + strings.Join(*s.value, ",") + "]" }
|
||||
func (s *stringSliceValue) String() string {
|
||||
str, _ := writeAsCSV(*s.value)
|
||||
return "[" + str + "]"
|
||||
}
|
||||
|
||||
func stringSliceConv(sval string) (interface{}, error) {
|
||||
sval = strings.Trim(sval, "[]")
|
||||
sval = sval[1 : len(sval)-1]
|
||||
// An empty string would cause a slice with one (empty) string
|
||||
if len(sval) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
v := strings.Split(sval, ",")
|
||||
return v, nil
|
||||
return readAsCSV(sval)
|
||||
}
|
||||
|
||||
// GetStringSlice return the []string value of a flag with the given name
|
||||
|
@ -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.
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
f.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
@ -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.
|
||||
// The argument p points to a []string variable in which to store the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
@ -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.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringSliceVarP(&p, name, "", value, usage)
|
||||
|
@ -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.
|
||||
// The return value is the address of a []string variable that stores the value of the flag.
|
||||
// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
|
||||
// For example:
|
||||
// --ss="v1,v2" -ss="v3"
|
||||
// will result in
|
||||
// []string{"v1", "v2", "v3"}
|
||||
func StringSlice(name string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringSliceP(name, "", value, usage)
|
||||
}
|
||||
|
|
7
vendor/github.com/spf13/pflag/uint.go
generated
vendored
7
vendor/github.com/spf13/pflag/uint.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint Value
|
||||
type uintValue uint
|
||||
|
@ -23,7 +20,7 @@ func (i *uintValue) Type() string {
|
|||
return "uint"
|
||||
}
|
||||
|
||||
func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uintConv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 0)
|
||||
|
|
9
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
9
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint16 value
|
||||
type uint16Value uint16
|
||||
|
@ -12,7 +9,7 @@ func newUint16Value(val uint16, p *uint16) *uint16Value {
|
|||
*p = val
|
||||
return (*uint16Value)(p)
|
||||
}
|
||||
func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) }
|
||||
|
||||
func (i *uint16Value) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 16)
|
||||
*i = uint16Value(v)
|
||||
|
@ -23,6 +20,8 @@ func (i *uint16Value) Type() string {
|
|||
return "uint16"
|
||||
}
|
||||
|
||||
func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint16Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 16)
|
||||
if err != nil {
|
||||
|
|
11
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
11
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
|
@ -1,18 +1,15 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint16 value
|
||||
// -- uint32 value
|
||||
type uint32Value uint32
|
||||
|
||||
func newUint32Value(val uint32, p *uint32) *uint32Value {
|
||||
*p = val
|
||||
return (*uint32Value)(p)
|
||||
}
|
||||
func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) }
|
||||
|
||||
func (i *uint32Value) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 32)
|
||||
*i = uint32Value(v)
|
||||
|
@ -23,6 +20,8 @@ func (i *uint32Value) Type() string {
|
|||
return "uint32"
|
||||
}
|
||||
|
||||
func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 32)
|
||||
if err != nil {
|
||||
|
|
7
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
7
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint64 Value
|
||||
type uint64Value uint64
|
||||
|
@ -23,7 +20,7 @@ func (i *uint64Value) Type() string {
|
|||
return "uint64"
|
||||
}
|
||||
|
||||
func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint64Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 64)
|
||||
|
|
7
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
7
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
|
@ -1,9 +1,6 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// -- uint8 Value
|
||||
type uint8Value uint8
|
||||
|
@ -23,7 +20,7 @@ func (i *uint8Value) Type() string {
|
|||
return "uint8"
|
||||
}
|
||||
|
||||
func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||
|
||||
func uint8Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 8)
|
||||
|
|
126
vendor/github.com/spf13/pflag/uint_slice.go
generated
vendored
Normal file
126
vendor/github.com/spf13/pflag/uint_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- uintSlice Value
|
||||
type uintSliceValue struct {
|
||||
value *[]uint
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newUintSliceValue(val []uint, p *[]uint) *uintSliceValue {
|
||||
uisv := new(uintSliceValue)
|
||||
uisv.value = p
|
||||
*uisv.value = val
|
||||
return uisv
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]uint, len(ss))
|
||||
for i, d := range ss {
|
||||
u, err := strconv.ParseUint(d, 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out[i] = uint(u)
|
||||
}
|
||||
if !s.changed {
|
||||
*s.value = out
|
||||
} else {
|
||||
*s.value = append(*s.value, out...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) Type() string {
|
||||
return "uintSlice"
|
||||
}
|
||||
|
||||
func (s *uintSliceValue) String() string {
|
||||
out := make([]string, len(*s.value))
|
||||
for i, d := range *s.value {
|
||||
out[i] = fmt.Sprintf("%d", d)
|
||||
}
|
||||
return "[" + strings.Join(out, ",") + "]"
|
||||
}
|
||||
|
||||
func uintSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []uint{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]uint, len(ss))
|
||||
for i, d := range ss {
|
||||
u, err := strconv.ParseUint(d, 10, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = uint(u)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetUintSlice returns the []uint value of a flag with the given name.
|
||||
func (f *FlagSet) GetUintSlice(name string) ([]uint, error) {
|
||||
val, err := f.getFlagType(name, "uintSlice", uintSliceConv)
|
||||
if err != nil {
|
||||
return []uint{}, err
|
||||
}
|
||||
return val.([]uint), nil
|
||||
}
|
||||
|
||||
// UintSliceVar defines a uintSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []uint variable in which to store the value of the flag.
|
||||
func (f *FlagSet) UintSliceVar(p *[]uint, name string, value []uint, usage string) {
|
||||
f.VarP(newUintSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// UintSliceVarP is like UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
|
||||
f.VarP(newUintSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// UintSliceVar defines a uint[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint[] variable in which to store the value of the flag.
|
||||
func UintSliceVar(p *[]uint, name string, value []uint, usage string) {
|
||||
CommandLine.VarP(newUintSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// UintSliceVarP is like the UintSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {
|
||||
CommandLine.VarP(newUintSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// UintSlice defines a []uint flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []uint variable that stores the value of the flag.
|
||||
func (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint {
|
||||
p := []uint{}
|
||||
f.UintSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
|
||||
p := []uint{}
|
||||
f.UintSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// UintSlice defines a []uint flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []uint variable that stores the value of the flag.
|
||||
func UintSlice(name string, value []uint, usage string) *[]uint {
|
||||
return CommandLine.UintSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {
|
||||
return CommandLine.UintSliceP(name, shorthand, value, usage)
|
||||
}
|
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
|
||||
("LGPL3"), the copyright holders of this Library give you permission to
|
||||
convey to a third party a Combined Work that links statically or dynamically
|
||||
to this Library without providing any Minimal Corresponding Source or
|
||||
Minimal Application Code as set out in 4d or providing the installation
|
||||
information set out in section 4e, provided that you comply with the other
|
||||
provisions of LGPL3 and provided that you meet, for the Application the
|
||||
terms and conditions of the license(s) which apply to the Application.
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
Except as stated in this special exception, the provisions of LGPL3 will
|
||||
continue to comply in full to this Library. If you modify this Library, you
|
||||
may apply this exception to your version of this Library, but you are not
|
||||
obliged to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version. This exception does not (and cannot) modify any
|
||||
license terms which apply to the Application, with which you must still
|
||||
comply.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
0. Additional Definitions.
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
4. Combined Works.
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
13
vendor/gopkg.in/yaml.v2/NOTICE
generated
vendored
Normal file
13
vendor/gopkg.in/yaml.v2/NOTICE
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright 2011-2016 Canonical Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
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
|
||||
-------
|
||||
|
||||
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
|
||||
|
@ -65,6 +65,8 @@ b:
|
|||
d: [3, 4]
|
||||
`
|
||||
|
||||
// Note: struct fields must be public in order for unmarshal to
|
||||
// correctly populate the data.
|
||||
type T struct {
|
||||
A string
|
||||
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 (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
|
||||
|
@ -48,9 +47,9 @@ func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err
|
|||
return n, nil
|
||||
}
|
||||
|
||||
// File read handler.
|
||||
func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
|
||||
return parser.input_file.Read(buffer)
|
||||
// Reader read handler.
|
||||
func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
|
||||
return parser.input_reader.Read(buffer)
|
||||
}
|
||||
|
||||
// Set a string input.
|
||||
|
@ -64,12 +63,12 @@ func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
|
|||
}
|
||||
|
||||
// Set a file input.
|
||||
func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
|
||||
func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
|
||||
if parser.read_handler != nil {
|
||||
panic("must set the input source only once")
|
||||
}
|
||||
parser.read_handler = yaml_file_read_handler
|
||||
parser.input_file = file
|
||||
parser.read_handler = yaml_reader_read_handler
|
||||
parser.input_reader = r
|
||||
}
|
||||
|
||||
// Set the source encoding.
|
||||
|
@ -81,14 +80,13 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
|
|||
}
|
||||
|
||||
// Create a new emitter object.
|
||||
func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
|
||||
func yaml_emitter_initialize(emitter *yaml_emitter_t) {
|
||||
*emitter = yaml_emitter_t{
|
||||
buffer: make([]byte, output_buffer_size),
|
||||
raw_buffer: make([]byte, 0, output_raw_buffer_size),
|
||||
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
|
||||
events: make([]yaml_event_t, 0, initial_queue_size),
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Destroy an emitter object.
|
||||
|
@ -102,9 +100,10 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// File write handler.
|
||||
func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
||||
_, err := emitter.output_file.Write(buffer)
|
||||
// yaml_writer_write_handler uses emitter.output_writer to write the
|
||||
// emitted text.
|
||||
func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
|
||||
_, err := emitter.output_writer.Write(buffer)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -118,12 +117,12 @@ func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]by
|
|||
}
|
||||
|
||||
// Set a file output.
|
||||
func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
|
||||
func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
|
||||
if emitter.write_handler != nil {
|
||||
panic("must set the output target only once")
|
||||
}
|
||||
emitter.write_handler = yaml_file_write_handler
|
||||
emitter.output_file = file
|
||||
emitter.write_handler = yaml_writer_write_handler
|
||||
emitter.output_writer = w
|
||||
}
|
||||
|
||||
// Set the output encoding.
|
||||
|
@ -252,41 +251,41 @@ func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
|
|||
//
|
||||
|
||||
// Create STREAM-START.
|
||||
func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
|
||||
func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_STREAM_START_EVENT,
|
||||
encoding: encoding,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create STREAM-END.
|
||||
func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
|
||||
func yaml_stream_end_event_initialize(event *yaml_event_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_STREAM_END_EVENT,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create DOCUMENT-START.
|
||||
func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
|
||||
tag_directives []yaml_tag_directive_t, implicit bool) bool {
|
||||
func yaml_document_start_event_initialize(
|
||||
event *yaml_event_t,
|
||||
version_directive *yaml_version_directive_t,
|
||||
tag_directives []yaml_tag_directive_t,
|
||||
implicit bool,
|
||||
) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_DOCUMENT_START_EVENT,
|
||||
version_directive: version_directive,
|
||||
tag_directives: tag_directives,
|
||||
implicit: implicit,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create DOCUMENT-END.
|
||||
func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
|
||||
func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_DOCUMENT_END_EVENT,
|
||||
implicit: implicit,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
///*
|
||||
|
@ -348,7 +347,7 @@ func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
|
|||
}
|
||||
|
||||
// Create MAPPING-START.
|
||||
func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
|
||||
func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_MAPPING_START_EVENT,
|
||||
anchor: anchor,
|
||||
|
@ -356,15 +355,13 @@ func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte
|
|||
implicit: implicit,
|
||||
style: yaml_style_t(style),
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Create MAPPING-END.
|
||||
func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
|
||||
func yaml_mapping_end_event_initialize(event *yaml_event_t) {
|
||||
*event = yaml_event_t{
|
||||
typ: yaml_MAPPING_END_EVENT,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Destroy an event object.
|
||||
|
@ -471,7 +468,7 @@ func yaml_event_delete(event *yaml_event_t) {
|
|||
// } context
|
||||
// tag_directive *yaml_tag_directive_t
|
||||
//
|
||||
// context.error = YAML_NO_ERROR // Eliminate a compliler warning.
|
||||
// context.error = YAML_NO_ERROR // Eliminate a compiler warning.
|
||||
//
|
||||
// assert(document) // Non-NULL document object is expected.
|
||||
//
|
||||
|
|
226
vendor/gopkg.in/yaml.v2/decode.go
generated
vendored
226
vendor/gopkg.in/yaml.v2/decode.go
generated
vendored
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
@ -22,6 +23,8 @@ type node struct {
|
|||
kind int
|
||||
line, column int
|
||||
tag string
|
||||
// For an alias node, alias holds the resolved alias.
|
||||
alias *node
|
||||
value string
|
||||
implicit bool
|
||||
children []*node
|
||||
|
@ -35,6 +38,7 @@ type parser struct {
|
|||
parser yaml_parser_t
|
||||
event yaml_event_t
|
||||
doc *node
|
||||
doneInit bool
|
||||
}
|
||||
|
||||
func newParser(b []byte) *parser {
|
||||
|
@ -42,21 +46,30 @@ func newParser(b []byte) *parser {
|
|||
if !yaml_parser_initialize(&p.parser) {
|
||||
panic("failed to initialize YAML emitter")
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
b = []byte{'\n'}
|
||||
}
|
||||
|
||||
yaml_parser_set_input_string(&p.parser, b)
|
||||
|
||||
p.skip()
|
||||
if p.event.typ != yaml_STREAM_START_EVENT {
|
||||
panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
|
||||
}
|
||||
p.skip()
|
||||
return &p
|
||||
}
|
||||
|
||||
func newParserFromReader(r io.Reader) *parser {
|
||||
p := parser{}
|
||||
if !yaml_parser_initialize(&p.parser) {
|
||||
panic("failed to initialize YAML emitter")
|
||||
}
|
||||
yaml_parser_set_input_reader(&p.parser, r)
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p *parser) init() {
|
||||
if p.doneInit {
|
||||
return
|
||||
}
|
||||
p.expect(yaml_STREAM_START_EVENT)
|
||||
p.doneInit = true
|
||||
}
|
||||
|
||||
func (p *parser) destroy() {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
yaml_event_delete(&p.event)
|
||||
|
@ -64,16 +77,35 @@ func (p *parser) destroy() {
|
|||
yaml_parser_delete(&p.parser)
|
||||
}
|
||||
|
||||
func (p *parser) skip() {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
// expect consumes an event from the event stream and
|
||||
// checks that it's of the expected type.
|
||||
func (p *parser) expect(e yaml_event_type_t) {
|
||||
if p.event.typ == yaml_NO_EVENT {
|
||||
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||
p.fail()
|
||||
}
|
||||
}
|
||||
if p.event.typ == yaml_STREAM_END_EVENT {
|
||||
failf("attempted to go past the end of stream; corrupted value?")
|
||||
}
|
||||
if p.event.typ != e {
|
||||
p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
|
||||
p.fail()
|
||||
}
|
||||
yaml_event_delete(&p.event)
|
||||
p.event.typ = yaml_NO_EVENT
|
||||
}
|
||||
|
||||
// peek peeks at the next event in the event stream,
|
||||
// puts the results into p.event and returns the event type.
|
||||
func (p *parser) peek() yaml_event_type_t {
|
||||
if p.event.typ != yaml_NO_EVENT {
|
||||
return p.event.typ
|
||||
}
|
||||
if !yaml_parser_parse(&p.parser, &p.event) {
|
||||
p.fail()
|
||||
}
|
||||
return p.event.typ
|
||||
}
|
||||
|
||||
func (p *parser) fail() {
|
||||
|
@ -81,6 +113,10 @@ func (p *parser) fail() {
|
|||
var line int
|
||||
if p.parser.problem_mark.line != 0 {
|
||||
line = p.parser.problem_mark.line
|
||||
// Scanner errors don't iterate line before returning error
|
||||
if p.parser.error == yaml_SCANNER_ERROR {
|
||||
line++
|
||||
}
|
||||
} else if p.parser.context_mark.line != 0 {
|
||||
line = p.parser.context_mark.line
|
||||
}
|
||||
|
@ -103,7 +139,8 @@ func (p *parser) anchor(n *node, anchor []byte) {
|
|||
}
|
||||
|
||||
func (p *parser) parse() *node {
|
||||
switch p.event.typ {
|
||||
p.init()
|
||||
switch p.peek() {
|
||||
case yaml_SCALAR_EVENT:
|
||||
return p.scalar()
|
||||
case yaml_ALIAS_EVENT:
|
||||
|
@ -118,9 +155,8 @@ func (p *parser) parse() *node {
|
|||
// Happens when attempting to decode an empty buffer.
|
||||
return nil
|
||||
default:
|
||||
panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
|
||||
panic("attempted to parse unknown event: " + p.event.typ.String())
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (p *parser) node(kind int) *node {
|
||||
|
@ -135,19 +171,20 @@ func (p *parser) document() *node {
|
|||
n := p.node(documentNode)
|
||||
n.anchors = make(map[string]*node)
|
||||
p.doc = n
|
||||
p.skip()
|
||||
p.expect(yaml_DOCUMENT_START_EVENT)
|
||||
n.children = append(n.children, p.parse())
|
||||
if p.event.typ != yaml_DOCUMENT_END_EVENT {
|
||||
panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
|
||||
}
|
||||
p.skip()
|
||||
p.expect(yaml_DOCUMENT_END_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) alias() *node {
|
||||
n := p.node(aliasNode)
|
||||
n.value = string(p.event.anchor)
|
||||
p.skip()
|
||||
n.alias = p.doc.anchors[n.value]
|
||||
if n.alias == nil {
|
||||
failf("unknown anchor '%s' referenced", n.value)
|
||||
}
|
||||
p.expect(yaml_ALIAS_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -157,29 +194,29 @@ func (p *parser) scalar() *node {
|
|||
n.tag = string(p.event.tag)
|
||||
n.implicit = p.event.implicit
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
p.expect(yaml_SCALAR_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) sequence() *node {
|
||||
n := p.node(sequenceNode)
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
for p.event.typ != yaml_SEQUENCE_END_EVENT {
|
||||
p.expect(yaml_SEQUENCE_START_EVENT)
|
||||
for p.peek() != yaml_SEQUENCE_END_EVENT {
|
||||
n.children = append(n.children, p.parse())
|
||||
}
|
||||
p.skip()
|
||||
p.expect(yaml_SEQUENCE_END_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
func (p *parser) mapping() *node {
|
||||
n := p.node(mappingNode)
|
||||
p.anchor(n, p.event.anchor)
|
||||
p.skip()
|
||||
for p.event.typ != yaml_MAPPING_END_EVENT {
|
||||
p.expect(yaml_MAPPING_START_EVENT)
|
||||
for p.peek() != yaml_MAPPING_END_EVENT {
|
||||
n.children = append(n.children, p.parse(), p.parse())
|
||||
}
|
||||
p.skip()
|
||||
p.expect(yaml_MAPPING_END_EVENT)
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -188,9 +225,10 @@ func (p *parser) mapping() *node {
|
|||
|
||||
type decoder struct {
|
||||
doc *node
|
||||
aliases map[string]bool
|
||||
aliases map[*node]bool
|
||||
mapType reflect.Type
|
||||
terrors []string
|
||||
strict bool
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -198,11 +236,13 @@ var (
|
|||
durationType = reflect.TypeOf(time.Duration(0))
|
||||
defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
|
||||
ifaceType = defaultMapType.Elem()
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
ptrTimeType = reflect.TypeOf(&time.Time{})
|
||||
)
|
||||
|
||||
func newDecoder() *decoder {
|
||||
d := &decoder{mapType: defaultMapType}
|
||||
d.aliases = make(map[string]bool)
|
||||
func newDecoder(strict bool) *decoder {
|
||||
d := &decoder{mapType: defaultMapType, strict: strict}
|
||||
d.aliases = make(map[*node]bool)
|
||||
return d
|
||||
}
|
||||
|
||||
|
@ -251,7 +291,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
|
|||
//
|
||||
// If n holds a null value, prepare returns before doing anything.
|
||||
func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
|
||||
if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
|
||||
if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
|
||||
return out, false, false
|
||||
}
|
||||
again := true
|
||||
|
@ -308,16 +348,13 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
|
||||
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
|
||||
an, ok := d.doc.anchors[n.value]
|
||||
if !ok {
|
||||
failf("unknown anchor '%s' referenced", n.value)
|
||||
}
|
||||
if d.aliases[n.value] {
|
||||
if d.aliases[n] {
|
||||
// TODO this could actually be allowed in some circumstances.
|
||||
failf("anchor '%s' value contains itself", n.value)
|
||||
}
|
||||
d.aliases[n.value] = true
|
||||
good = d.unmarshal(an, out)
|
||||
delete(d.aliases, n.value)
|
||||
d.aliases[n] = true
|
||||
good = d.unmarshal(n.alias, out)
|
||||
delete(d.aliases, n)
|
||||
return good
|
||||
}
|
||||
|
||||
|
@ -329,7 +366,7 @@ func resetMap(out reflect.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
||||
func (d *decoder) scalar(n *node, out reflect.Value) bool {
|
||||
var tag string
|
||||
var resolved interface{}
|
||||
if n.tag == "" && !n.implicit {
|
||||
|
@ -353,9 +390,26 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
return true
|
||||
}
|
||||
if s, ok := resolved.(string); ok && out.CanAddr() {
|
||||
if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
|
||||
err := u.UnmarshalText([]byte(s))
|
||||
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
||||
// We've resolved to exactly the type we want, so use that.
|
||||
out.Set(resolvedv)
|
||||
return true
|
||||
}
|
||||
// Perhaps we can use the value as a TextUnmarshaler to
|
||||
// set its value.
|
||||
if out.CanAddr() {
|
||||
u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
|
||||
if ok {
|
||||
var text []byte
|
||||
if tag == yaml_BINARY_TAG {
|
||||
text = []byte(resolved.(string))
|
||||
} else {
|
||||
// We let any value be unmarshaled into TextUnmarshaler.
|
||||
// That might be more lax than we'd like, but the
|
||||
// TextUnmarshaler itself should bowl out any dubious values.
|
||||
text = []byte(n.value)
|
||||
}
|
||||
err := u.UnmarshalText(text)
|
||||
if err != nil {
|
||||
fail(err)
|
||||
}
|
||||
|
@ -366,46 +420,54 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
case reflect.String:
|
||||
if tag == yaml_BINARY_TAG {
|
||||
out.SetString(resolved.(string))
|
||||
good = true
|
||||
} else if resolved != nil {
|
||||
return true
|
||||
}
|
||||
if resolved != nil {
|
||||
out.SetString(n.value)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case reflect.Interface:
|
||||
if resolved == nil {
|
||||
out.Set(reflect.Zero(out.Type()))
|
||||
} else if tag == yaml_TIMESTAMP_TAG {
|
||||
// It looks like a timestamp but for backward compatibility
|
||||
// reasons we set it as a string, so that code that unmarshals
|
||||
// timestamp-like values into interface{} will continue to
|
||||
// see a string and not a time.Time.
|
||||
// TODO(v3) Drop this.
|
||||
out.Set(reflect.ValueOf(n.value))
|
||||
} else {
|
||||
out.Set(reflect.ValueOf(resolved))
|
||||
}
|
||||
good = true
|
||||
return true
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch resolved := resolved.(type) {
|
||||
case int:
|
||||
if !out.OverflowInt(int64(resolved)) {
|
||||
out.SetInt(int64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case int64:
|
||||
if !out.OverflowInt(resolved) {
|
||||
out.SetInt(resolved)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case uint64:
|
||||
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
||||
out.SetInt(int64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case float64:
|
||||
if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
|
||||
out.SetInt(int64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case string:
|
||||
if out.Type() == durationType {
|
||||
d, err := time.ParseDuration(resolved)
|
||||
if err == nil {
|
||||
out.SetInt(int64(d))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,44 +476,49 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
case int:
|
||||
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case int64:
|
||||
if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case uint64:
|
||||
if !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case float64:
|
||||
if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
|
||||
out.SetUint(uint64(resolved))
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
case reflect.Bool:
|
||||
switch resolved := resolved.(type) {
|
||||
case bool:
|
||||
out.SetBool(resolved)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch resolved := resolved.(type) {
|
||||
case int:
|
||||
out.SetFloat(float64(resolved))
|
||||
good = true
|
||||
return true
|
||||
case int64:
|
||||
out.SetFloat(float64(resolved))
|
||||
good = true
|
||||
return true
|
||||
case uint64:
|
||||
out.SetFloat(float64(resolved))
|
||||
good = true
|
||||
return true
|
||||
case float64:
|
||||
out.SetFloat(resolved)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
case reflect.Struct:
|
||||
if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
|
||||
out.Set(resolvedv)
|
||||
return true
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if out.Type().Elem() == reflect.TypeOf(resolved) {
|
||||
|
@ -459,13 +526,11 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
|
|||
elem := reflect.New(out.Type().Elem())
|
||||
elem.Elem().Set(reflect.ValueOf(resolved))
|
||||
out.Set(elem)
|
||||
good = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !good {
|
||||
d.terror(n, tag, out)
|
||||
}
|
||||
return good
|
||||
return false
|
||||
}
|
||||
|
||||
func settableValueOf(i interface{}) reflect.Value {
|
||||
|
@ -482,6 +547,10 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
|||
switch out.Kind() {
|
||||
case reflect.Slice:
|
||||
out.Set(reflect.MakeSlice(out.Type(), l, l))
|
||||
case reflect.Array:
|
||||
if l != out.Len() {
|
||||
failf("invalid array: want %d elements but got %d", out.Len(), l)
|
||||
}
|
||||
case reflect.Interface:
|
||||
// No type hints. Will have to use a generic sequence.
|
||||
iface = out
|
||||
|
@ -500,7 +569,9 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
|
|||
j++
|
||||
}
|
||||
}
|
||||
if out.Kind() != reflect.Array {
|
||||
out.Set(out.Slice(0, j))
|
||||
}
|
||||
if iface.IsValid() {
|
||||
iface.Set(out)
|
||||
}
|
||||
|
@ -561,7 +632,7 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
e := reflect.New(et).Elem()
|
||||
if d.unmarshal(n.children[i+1], e) {
|
||||
out.SetMapIndex(k, e)
|
||||
d.setMapIndex(n.children[i+1], out, k, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -569,6 +640,14 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
|
|||
return true
|
||||
}
|
||||
|
||||
func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
|
||||
if d.strict && out.MapIndex(k) != zeroValue {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
|
||||
return
|
||||
}
|
||||
out.SetMapIndex(k, v)
|
||||
}
|
||||
|
||||
func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
|
||||
outt := out.Type()
|
||||
if outt.Elem() != mapItemType {
|
||||
|
@ -616,6 +695,10 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
|||
elemType = inlineMap.Type().Elem()
|
||||
}
|
||||
|
||||
var doneFields []bool
|
||||
if d.strict {
|
||||
doneFields = make([]bool, len(sinfo.FieldsList))
|
||||
}
|
||||
for i := 0; i < l; i += 2 {
|
||||
ni := n.children[i]
|
||||
if isMerge(ni) {
|
||||
|
@ -626,6 +709,13 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
|||
continue
|
||||
}
|
||||
if info, ok := sinfo.FieldsMap[name.String()]; ok {
|
||||
if d.strict {
|
||||
if doneFields[info.Id] {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
|
||||
continue
|
||||
}
|
||||
doneFields[info.Id] = true
|
||||
}
|
||||
var field reflect.Value
|
||||
if info.Inline == nil {
|
||||
field = out.Field(info.Num)
|
||||
|
@ -639,7 +729,9 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
|
|||
}
|
||||
value := reflect.New(elemType).Elem()
|
||||
d.unmarshal(n.children[i+1], value)
|
||||
inlineMap.SetMapIndex(name, value)
|
||||
d.setMapIndex(n.children[i+1], inlineMap, name, value)
|
||||
} else if d.strict {
|
||||
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
14
vendor/gopkg.in/yaml.v2/emitterc.go
generated
vendored
14
vendor/gopkg.in/yaml.v2/emitterc.go
generated
vendored
|
@ -2,6 +2,7 @@ package yaml
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Flush the buffer if needed.
|
||||
|
@ -664,9 +665,8 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
|
|||
return yaml_emitter_emit_mapping_start(emitter, event)
|
||||
default:
|
||||
return yaml_emitter_set_emitter_error(emitter,
|
||||
"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
|
||||
fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Expect ALIAS.
|
||||
|
@ -843,7 +843,7 @@ func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event
|
|||
return true
|
||||
}
|
||||
|
||||
// Write an achor.
|
||||
// Write an anchor.
|
||||
func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
|
||||
if emitter.anchor_data.anchor == nil {
|
||||
return true
|
||||
|
@ -995,7 +995,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
break_space = false
|
||||
space_break = false
|
||||
|
||||
preceeded_by_whitespace = false
|
||||
preceded_by_whitespace = false
|
||||
followed_by_whitespace = false
|
||||
previous_space = false
|
||||
previous_break = false
|
||||
|
@ -1017,7 +1017,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
flow_indicators = true
|
||||
}
|
||||
|
||||
preceeded_by_whitespace = true
|
||||
preceded_by_whitespace = true
|
||||
for i, w := 0, 0; i < len(value); i += w {
|
||||
w = width(value[i])
|
||||
followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
|
||||
|
@ -1048,7 +1048,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
block_indicators = true
|
||||
}
|
||||
case '#':
|
||||
if preceeded_by_whitespace {
|
||||
if preceded_by_whitespace {
|
||||
flow_indicators = true
|
||||
block_indicators = true
|
||||
}
|
||||
|
@ -1089,7 +1089,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
|
|||
}
|
||||
|
||||
// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
|
||||
preceeded_by_whitespace = is_blankz(value, i)
|
||||
preceded_by_whitespace = is_blankz(value, i)
|
||||
}
|
||||
|
||||
emitter.scalar_data.multiline = line_breaks
|
||||
|
|
132
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
132
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
|
@ -3,12 +3,14 @@ package yaml
|
|||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type encoder struct {
|
||||
|
@ -16,25 +18,39 @@ type encoder struct {
|
|||
event yaml_event_t
|
||||
out []byte
|
||||
flow bool
|
||||
// doneInit holds whether the initial stream_start_event has been
|
||||
// emitted.
|
||||
doneInit bool
|
||||
}
|
||||
|
||||
func newEncoder() (e *encoder) {
|
||||
e = &encoder{}
|
||||
e.must(yaml_emitter_initialize(&e.emitter))
|
||||
func newEncoder() *encoder {
|
||||
e := &encoder{}
|
||||
yaml_emitter_initialize(&e.emitter)
|
||||
yaml_emitter_set_output_string(&e.emitter, &e.out)
|
||||
yaml_emitter_set_unicode(&e.emitter, true)
|
||||
e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
|
||||
e.emit()
|
||||
e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
|
||||
e.emit()
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *encoder) finish() {
|
||||
e.must(yaml_document_end_event_initialize(&e.event, true))
|
||||
func newEncoderWithWriter(w io.Writer) *encoder {
|
||||
e := &encoder{}
|
||||
yaml_emitter_initialize(&e.emitter)
|
||||
yaml_emitter_set_output_writer(&e.emitter, w)
|
||||
yaml_emitter_set_unicode(&e.emitter, true)
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *encoder) init() {
|
||||
if e.doneInit {
|
||||
return
|
||||
}
|
||||
yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
|
||||
e.emit()
|
||||
e.doneInit = true
|
||||
}
|
||||
|
||||
func (e *encoder) finish() {
|
||||
e.emitter.open_ended = false
|
||||
e.must(yaml_stream_end_event_initialize(&e.event))
|
||||
yaml_stream_end_event_initialize(&e.event)
|
||||
e.emit()
|
||||
}
|
||||
|
||||
|
@ -44,9 +60,7 @@ func (e *encoder) destroy() {
|
|||
|
||||
func (e *encoder) emit() {
|
||||
// This will internally delete the e.event value.
|
||||
if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
|
||||
e.must(false)
|
||||
}
|
||||
e.must(yaml_emitter_emit(&e.emitter, &e.event))
|
||||
}
|
||||
|
||||
func (e *encoder) must(ok bool) {
|
||||
|
@ -59,13 +73,28 @@ func (e *encoder) must(ok bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func (e *encoder) marshalDoc(tag string, in reflect.Value) {
|
||||
e.init()
|
||||
yaml_document_start_event_initialize(&e.event, nil, nil, true)
|
||||
e.emit()
|
||||
e.marshal(tag, in)
|
||||
yaml_document_end_event_initialize(&e.event, true)
|
||||
e.emit()
|
||||
}
|
||||
|
||||
func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||
if !in.IsValid() {
|
||||
if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
|
||||
e.nilv()
|
||||
return
|
||||
}
|
||||
iface := in.Interface()
|
||||
if m, ok := iface.(Marshaler); ok {
|
||||
switch m := iface.(type) {
|
||||
case time.Time, *time.Time:
|
||||
// Although time.Time implements TextMarshaler,
|
||||
// we don't want to treat it as a string for YAML
|
||||
// purposes because YAML has special support for
|
||||
// timestamps.
|
||||
case Marshaler:
|
||||
v, err := m.MarshalYAML()
|
||||
if err != nil {
|
||||
fail(err)
|
||||
|
@ -75,31 +104,34 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
|
|||
return
|
||||
}
|
||||
in = reflect.ValueOf(v)
|
||||
} else if m, ok := iface.(encoding.TextMarshaler); ok {
|
||||
case encoding.TextMarshaler:
|
||||
text, err := m.MarshalText()
|
||||
if err != nil {
|
||||
fail(err)
|
||||
}
|
||||
in = reflect.ValueOf(string(text))
|
||||
case nil:
|
||||
e.nilv()
|
||||
return
|
||||
}
|
||||
switch in.Kind() {
|
||||
case reflect.Interface:
|
||||
if in.IsNil() {
|
||||
e.nilv()
|
||||
} else {
|
||||
e.marshal(tag, in.Elem())
|
||||
}
|
||||
case reflect.Map:
|
||||
e.mapv(tag, in)
|
||||
case reflect.Ptr:
|
||||
if in.IsNil() {
|
||||
e.nilv()
|
||||
if in.Type() == ptrTimeType {
|
||||
e.timev(tag, in.Elem())
|
||||
} else {
|
||||
e.marshal(tag, in.Elem())
|
||||
}
|
||||
case reflect.Struct:
|
||||
if in.Type() == timeType {
|
||||
e.timev(tag, in)
|
||||
} else {
|
||||
e.structv(tag, in)
|
||||
case reflect.Slice:
|
||||
}
|
||||
case reflect.Slice, reflect.Array:
|
||||
if in.Type().Elem() == mapItemType {
|
||||
e.itemsv(tag, in)
|
||||
} else {
|
||||
|
@ -191,10 +223,10 @@ func (e *encoder) mappingv(tag string, f func()) {
|
|||
e.flow = false
|
||||
style = yaml_FLOW_MAPPING_STYLE
|
||||
}
|
||||
e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
|
||||
yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
|
||||
e.emit()
|
||||
f()
|
||||
e.must(yaml_mapping_end_event_initialize(&e.event))
|
||||
yaml_mapping_end_event_initialize(&e.event)
|
||||
e.emit()
|
||||
}
|
||||
|
||||
|
@ -240,23 +272,36 @@ var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0
|
|||
func (e *encoder) stringv(tag string, in reflect.Value) {
|
||||
var style yaml_scalar_style_t
|
||||
s := in.String()
|
||||
rtag, rs := resolve("", s)
|
||||
if rtag == yaml_BINARY_TAG {
|
||||
if tag == "" || tag == yaml_STR_TAG {
|
||||
tag = rtag
|
||||
s = rs.(string)
|
||||
} else if tag == yaml_BINARY_TAG {
|
||||
canUsePlain := true
|
||||
switch {
|
||||
case !utf8.ValidString(s):
|
||||
if tag == yaml_BINARY_TAG {
|
||||
failf("explicitly tagged !!binary data must be base64-encoded")
|
||||
} else {
|
||||
}
|
||||
if tag != "" {
|
||||
failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
|
||||
}
|
||||
// It can't be encoded directly as YAML so use a binary tag
|
||||
// and encode it as base64.
|
||||
tag = yaml_BINARY_TAG
|
||||
s = encodeBase64(s)
|
||||
case tag == "":
|
||||
// Check to see if it would resolve to a specific
|
||||
// tag when encoded unquoted. If it doesn't,
|
||||
// there's no need to quote it.
|
||||
rtag, _ := resolve("", s)
|
||||
canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
|
||||
}
|
||||
if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
|
||||
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
||||
} else if strings.Contains(s, "\n") {
|
||||
// Note: it's possible for user code to emit invalid YAML
|
||||
// if they explicitly specify a tag and a string containing
|
||||
// text that's incompatible with that tag.
|
||||
switch {
|
||||
case strings.Contains(s, "\n"):
|
||||
style = yaml_LITERAL_SCALAR_STYLE
|
||||
} else {
|
||||
case canUsePlain:
|
||||
style = yaml_PLAIN_SCALAR_STYLE
|
||||
default:
|
||||
style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
|
||||
}
|
||||
e.emitScalar(s, "", tag, style)
|
||||
}
|
||||
|
@ -281,9 +326,20 @@ func (e *encoder) uintv(tag string, in reflect.Value) {
|
|||
e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
|
||||
}
|
||||
|
||||
func (e *encoder) timev(tag string, in reflect.Value) {
|
||||
t := in.Interface().(time.Time)
|
||||
s := t.Format(time.RFC3339Nano)
|
||||
e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
|
||||
}
|
||||
|
||||
func (e *encoder) floatv(tag string, in reflect.Value) {
|
||||
// FIXME: Handle 64 bits here.
|
||||
s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
|
||||
// Issue #352: When formatting, use the precision of the underlying value
|
||||
precision := 64
|
||||
if in.Kind() == reflect.Float32 {
|
||||
precision = 32
|
||||
}
|
||||
|
||||
s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
|
||||
switch s {
|
||||
case "+Inf":
|
||||
s = ".inf"
|
||||
|
|
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:
|
||||
panic("invalid parser state")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Parse the production:
|
||||
|
|
27
vendor/gopkg.in/yaml.v2/readerc.go
generated
vendored
27
vendor/gopkg.in/yaml.v2/readerc.go
generated
vendored
|
@ -93,9 +93,18 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
panic("read handler must be set")
|
||||
}
|
||||
|
||||
// [Go] This function was changed to guarantee the requested length size at EOF.
|
||||
// The fact we need to do this is pretty awful, but the description above implies
|
||||
// for that to be the case, and there are tests
|
||||
|
||||
// If the EOF flag is set and the raw buffer is empty, do nothing.
|
||||
if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
|
||||
return true
|
||||
// [Go] ACTUALLY! Read the documentation of this function above.
|
||||
// This is just broken. To return true, we need to have the
|
||||
// given length in the buffer. Not doing that means every single
|
||||
// check that calls this function to make sure the buffer has a
|
||||
// given length is Go) panicking; or C) accessing invalid memory.
|
||||
//return true
|
||||
}
|
||||
|
||||
// Return if the buffer contains enough characters.
|
||||
|
@ -247,7 +256,7 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
if parser.encoding == yaml_UTF16LE_ENCODING {
|
||||
low, high = 0, 1
|
||||
} else {
|
||||
high, low = 1, 0
|
||||
low, high = 1, 0
|
||||
}
|
||||
|
||||
// The UTF-16 encoding is not as simple as one might
|
||||
|
@ -357,23 +366,26 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
if value <= 0x7F {
|
||||
// 0000 0000-0000 007F . 0xxxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(value)
|
||||
buffer_len += 1
|
||||
} else if value <= 0x7FF {
|
||||
// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
|
||||
parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
|
||||
buffer_len += 2
|
||||
} else if value <= 0xFFFF {
|
||||
// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
|
||||
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
|
||||
parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
|
||||
buffer_len += 3
|
||||
} else {
|
||||
// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
|
||||
parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
|
||||
parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
|
||||
parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
|
||||
buffer_len += 4
|
||||
}
|
||||
buffer_len += width
|
||||
|
||||
parser.unread++
|
||||
}
|
||||
|
@ -386,6 +398,15 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
|
|||
break
|
||||
}
|
||||
}
|
||||
// [Go] Read the documentation of this function above. To return true,
|
||||
// we need to have the given length in the buffer. Not doing that means
|
||||
// every single check that calls this function to make sure the buffer
|
||||
// has a given length is Go) panicking; or C) accessing invalid memory.
|
||||
// This happens here due to the EOF above breaking early.
|
||||
for buffer_len < length {
|
||||
parser.buffer[buffer_len] = 0
|
||||
buffer_len++
|
||||
}
|
||||
parser.buffer = parser.buffer[:buffer_len]
|
||||
return true
|
||||
}
|
||||
|
|
83
vendor/gopkg.in/yaml.v2/resolve.go
generated
vendored
83
vendor/gopkg.in/yaml.v2/resolve.go
generated
vendored
|
@ -3,9 +3,10 @@ package yaml
|
|||
import (
|
||||
"encoding/base64"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
"time"
|
||||
)
|
||||
|
||||
type resolveMapItem struct {
|
||||
|
@ -74,12 +75,14 @@ func longTag(tag string) string {
|
|||
|
||||
func resolvableTag(tag string) bool {
|
||||
switch tag {
|
||||
case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
|
||||
case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
|
||||
|
||||
func resolve(tag string, in string) (rtag string, out interface{}) {
|
||||
if !resolvableTag(tag) {
|
||||
return tag, in
|
||||
|
@ -89,6 +92,19 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
switch tag {
|
||||
case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
|
||||
return
|
||||
case yaml_FLOAT_TAG:
|
||||
if rtag == yaml_INT_TAG {
|
||||
switch v := out.(type) {
|
||||
case int64:
|
||||
rtag = yaml_FLOAT_TAG
|
||||
out = float64(v)
|
||||
return
|
||||
case int:
|
||||
rtag = yaml_FLOAT_TAG
|
||||
out = float64(v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
|
||||
}()
|
||||
|
@ -122,6 +138,15 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
|
||||
case 'D', 'S':
|
||||
// Int, float, or timestamp.
|
||||
// Only try values as a timestamp if the value is unquoted or there's an explicit
|
||||
// !!timestamp tag.
|
||||
if tag == "" || tag == yaml_TIMESTAMP_TAG {
|
||||
t, ok := parseTimestamp(in)
|
||||
if ok {
|
||||
return yaml_TIMESTAMP_TAG, t
|
||||
}
|
||||
}
|
||||
|
||||
plain := strings.Replace(in, "_", "", -1)
|
||||
intv, err := strconv.ParseInt(plain, 0, 64)
|
||||
if err == nil {
|
||||
|
@ -135,10 +160,12 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
if err == nil {
|
||||
return yaml_INT_TAG, uintv
|
||||
}
|
||||
if yamlStyleFloat.MatchString(plain) {
|
||||
floatv, err := strconv.ParseFloat(plain, 64)
|
||||
if err == nil {
|
||||
return yaml_FLOAT_TAG, floatv
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(plain, "0b") {
|
||||
intv, err := strconv.ParseInt(plain[2:], 2, 64)
|
||||
if err == nil {
|
||||
|
@ -153,28 +180,20 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
|
|||
return yaml_INT_TAG, uintv
|
||||
}
|
||||
} else if strings.HasPrefix(plain, "-0b") {
|
||||
intv, err := strconv.ParseInt(plain[3:], 2, 64)
|
||||
intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
|
||||
if err == nil {
|
||||
if intv == int64(int(intv)) {
|
||||
return yaml_INT_TAG, -int(intv)
|
||||
if true || intv == int64(int(intv)) {
|
||||
return yaml_INT_TAG, int(intv)
|
||||
} else {
|
||||
return yaml_INT_TAG, -intv
|
||||
return yaml_INT_TAG, intv
|
||||
}
|
||||
}
|
||||
}
|
||||
// XXX Handle timestamps here.
|
||||
|
||||
default:
|
||||
panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
|
||||
}
|
||||
}
|
||||
if tag == yaml_BINARY_TAG {
|
||||
return yaml_BINARY_TAG, in
|
||||
}
|
||||
if utf8.ValidString(in) {
|
||||
return yaml_STR_TAG, in
|
||||
}
|
||||
return yaml_BINARY_TAG, encodeBase64(in)
|
||||
}
|
||||
|
||||
// encodeBase64 encodes s as base64 that is broken up into multiple lines
|
||||
|
@ -201,3 +220,39 @@ func encodeBase64(s string) string {
|
|||
}
|
||||
return string(out[:k])
|
||||
}
|
||||
|
||||
// This is a subset of the formats allowed by the regular expression
|
||||
// defined at http://yaml.org/type/timestamp.html.
|
||||
var allowedTimestampFormats = []string{
|
||||
"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
|
||||
"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
|
||||
"2006-1-2 15:4:5.999999999", // space separated with no time zone
|
||||
"2006-1-2", // date only
|
||||
// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
|
||||
// from the set of examples.
|
||||
}
|
||||
|
||||
// parseTimestamp parses s as a timestamp string and
|
||||
// returns the timestamp and reports whether it succeeded.
|
||||
// Timestamp formats are defined at http://yaml.org/type/timestamp.html
|
||||
func parseTimestamp(s string) (time.Time, bool) {
|
||||
// TODO write code to check all the formats supported by
|
||||
// http://yaml.org/type/timestamp.html instead of using time.Parse.
|
||||
|
||||
// Quick check: all date formats start with YYYY-.
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if c := s[i]; c < '0' || c > '9' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i != 4 || i == len(s) || s[i] != '-' {
|
||||
return time.Time{}, false
|
||||
}
|
||||
for _, format := range allowedTimestampFormats {
|
||||
if t, err := time.Parse(format, s); err == nil {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
|
42
vendor/gopkg.in/yaml.v2/scannerc.go
generated
vendored
42
vendor/gopkg.in/yaml.v2/scannerc.go
generated
vendored
|
@ -9,7 +9,7 @@ import (
|
|||
// ************
|
||||
//
|
||||
// The following notes assume that you are familiar with the YAML specification
|
||||
// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
|
||||
// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in
|
||||
// some cases we are less restrictive that it requires.
|
||||
//
|
||||
// The process of transforming a YAML stream into a sequence of events is
|
||||
|
@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
|
|||
if directive {
|
||||
context = "while parsing a %TAG directive"
|
||||
}
|
||||
return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
|
||||
return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
|
||||
}
|
||||
|
||||
func trace(args ...interface{}) func() {
|
||||
|
@ -871,12 +871,6 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
|
|||
|
||||
required := parser.flow_level == 0 && parser.indent == parser.mark.column
|
||||
|
||||
// A simple key is required only when it is the first token in the current
|
||||
// line. Therefore it is always allowed. But we add a check anyway.
|
||||
if required && !parser.simple_key_allowed {
|
||||
panic("should not happen")
|
||||
}
|
||||
|
||||
//
|
||||
// If the current position may start a simple key, save it.
|
||||
//
|
||||
|
@ -1546,7 +1540,7 @@ func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool
|
|||
// Unknown directive.
|
||||
} else {
|
||||
yaml_parser_set_scanner_error(parser, "while scanning a directive",
|
||||
start_mark, "found uknown directive name")
|
||||
start_mark, "found unknown directive name")
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -1944,7 +1938,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
|
|||
} else {
|
||||
// It's either the '!' tag or not really a tag handle. If it's a %TAG
|
||||
// directive, it's an error. If it's a tag token, it must be a part of URI.
|
||||
if directive && !(s[0] == '!' && s[1] == 0) {
|
||||
if directive && string(s) != "!" {
|
||||
yaml_parser_set_scanner_tag_error(parser, directive,
|
||||
start_mark, "did not find expected '!'")
|
||||
return false
|
||||
|
@ -1959,6 +1953,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
|
|||
func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
|
||||
//size_t length = head ? strlen((char *)head) : 0
|
||||
var s []byte
|
||||
hasTag := len(head) > 0
|
||||
|
||||
// Copy the head if needed.
|
||||
//
|
||||
|
@ -2000,10 +1995,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
|
|||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||
return false
|
||||
}
|
||||
hasTag = true
|
||||
}
|
||||
|
||||
// Check if the tag is non-empty.
|
||||
if len(s) == 0 {
|
||||
if !hasTag {
|
||||
yaml_parser_set_scanner_tag_error(parser, directive,
|
||||
start_mark, "did not find expected tag URI")
|
||||
return false
|
||||
|
@ -2474,6 +2469,10 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
|
|||
}
|
||||
}
|
||||
|
||||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if we are at the end of the scalar.
|
||||
if single {
|
||||
if parser.buffer[parser.buffer_pos] == '\'' {
|
||||
|
@ -2486,10 +2485,6 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
|
|||
}
|
||||
|
||||
// Consume blank characters.
|
||||
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
|
||||
if is_blank(parser.buffer, parser.buffer_pos) {
|
||||
// Consume a space or a tab character.
|
||||
|
@ -2591,19 +2586,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
|
|||
// Consume non-blank characters.
|
||||
for !is_blankz(parser.buffer, parser.buffer_pos) {
|
||||
|
||||
// Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
|
||||
if parser.flow_level > 0 &&
|
||||
parser.buffer[parser.buffer_pos] == ':' &&
|
||||
!is_blankz(parser.buffer, parser.buffer_pos+1) {
|
||||
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
|
||||
start_mark, "found unexpected ':'")
|
||||
return false
|
||||
}
|
||||
|
||||
// Check for indicators that may end a plain scalar.
|
||||
if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
|
||||
(parser.flow_level > 0 &&
|
||||
(parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
|
||||
(parser.buffer[parser.buffer_pos] == ',' ||
|
||||
parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
|
||||
parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
|
||||
parser.buffer[parser.buffer_pos] == '}')) {
|
||||
|
@ -2655,10 +2641,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
|
|||
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
|
||||
if is_blank(parser.buffer, parser.buffer_pos) {
|
||||
|
||||
// Check for tab character that abuse indentation.
|
||||
// Check for tab characters that abuse indentation.
|
||||
if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
|
||||
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
|
||||
start_mark, "found a tab character that violate indentation")
|
||||
start_mark, "found a tab character that violates indentation")
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
9
vendor/gopkg.in/yaml.v2/sorter.go
generated
vendored
9
vendor/gopkg.in/yaml.v2/sorter.go
generated
vendored
|
@ -51,6 +51,15 @@ func (l keyList) Less(i, j int) bool {
|
|||
}
|
||||
var ai, bi int
|
||||
var an, bn int64
|
||||
if ar[i] == '0' || br[i] == '0' {
|
||||
for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
|
||||
if ar[j] != '0' {
|
||||
an = 1
|
||||
bn = 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
|
||||
an = an*10 + int64(ar[ai]-'0')
|
||||
}
|
||||
|
|
63
vendor/gopkg.in/yaml.v2/writerc.go
generated
vendored
63
vendor/gopkg.in/yaml.v2/writerc.go
generated
vendored
|
@ -18,72 +18,9 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// If the output encoding is UTF-8, we don't need to recode the buffer.
|
||||
if emitter.encoding == yaml_UTF8_ENCODING {
|
||||
if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
|
||||
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
|
||||
}
|
||||
emitter.buffer_pos = 0
|
||||
return true
|
||||
}
|
||||
|
||||
// Recode the buffer into the raw buffer.
|
||||
var low, high int
|
||||
if emitter.encoding == yaml_UTF16LE_ENCODING {
|
||||
low, high = 0, 1
|
||||
} else {
|
||||
high, low = 1, 0
|
||||
}
|
||||
|
||||
pos := 0
|
||||
for pos < emitter.buffer_pos {
|
||||
// See the "reader.c" code for more details on UTF-8 encoding. Note
|
||||
// that we assume that the buffer contains a valid UTF-8 sequence.
|
||||
|
||||
// Read the next UTF-8 character.
|
||||
octet := emitter.buffer[pos]
|
||||
|
||||
var w int
|
||||
var value rune
|
||||
switch {
|
||||
case octet&0x80 == 0x00:
|
||||
w, value = 1, rune(octet&0x7F)
|
||||
case octet&0xE0 == 0xC0:
|
||||
w, value = 2, rune(octet&0x1F)
|
||||
case octet&0xF0 == 0xE0:
|
||||
w, value = 3, rune(octet&0x0F)
|
||||
case octet&0xF8 == 0xF0:
|
||||
w, value = 4, rune(octet&0x07)
|
||||
}
|
||||
for k := 1; k < w; k++ {
|
||||
octet = emitter.buffer[pos+k]
|
||||
value = (value << 6) + (rune(octet) & 0x3F)
|
||||
}
|
||||
pos += w
|
||||
|
||||
// Write the character.
|
||||
if value < 0x10000 {
|
||||
var b [2]byte
|
||||
b[high] = byte(value >> 8)
|
||||
b[low] = byte(value & 0xFF)
|
||||
emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
|
||||
} else {
|
||||
// Write the character using a surrogate pair (check "reader.c").
|
||||
var b [4]byte
|
||||
value -= 0x10000
|
||||
b[high] = byte(0xD8 + (value >> 18))
|
||||
b[low] = byte((value >> 10) & 0xFF)
|
||||
b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
|
||||
b[low+2] = byte(value & 0xFF)
|
||||
emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
|
||||
}
|
||||
}
|
||||
|
||||
// Write the raw buffer.
|
||||
if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
|
||||
return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
|
||||
}
|
||||
emitter.buffer_pos = 0
|
||||
emitter.raw_buffer = emitter.raw_buffer[:0]
|
||||
return true
|
||||
}
|
||||
|
|
138
vendor/gopkg.in/yaml.v2/yaml.go
generated
vendored
138
vendor/gopkg.in/yaml.v2/yaml.go
generated
vendored
|
@ -9,6 +9,7 @@ package yaml
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -77,8 +78,65 @@ type Marshaler interface {
|
|||
// supported tag options.
|
||||
//
|
||||
func Unmarshal(in []byte, out interface{}) (err error) {
|
||||
return unmarshal(in, out, false)
|
||||
}
|
||||
|
||||
// UnmarshalStrict is like Unmarshal except that any fields that are found
|
||||
// in the data that do not have corresponding struct members, or mapping
|
||||
// keys that are duplicates, will result in
|
||||
// an error.
|
||||
func UnmarshalStrict(in []byte, out interface{}) (err error) {
|
||||
return unmarshal(in, out, true)
|
||||
}
|
||||
|
||||
// A Decorder reads and decodes YAML values from an input stream.
|
||||
type Decoder struct {
|
||||
strict bool
|
||||
parser *parser
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder that reads from r.
|
||||
//
|
||||
// The decoder introduces its own buffering and may read
|
||||
// data from r beyond the YAML values requested.
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
return &Decoder{
|
||||
parser: newParserFromReader(r),
|
||||
}
|
||||
}
|
||||
|
||||
// SetStrict sets whether strict decoding behaviour is enabled when
|
||||
// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
|
||||
func (dec *Decoder) SetStrict(strict bool) {
|
||||
dec.strict = strict
|
||||
}
|
||||
|
||||
// Decode reads the next YAML-encoded value from its input
|
||||
// and stores it in the value pointed to by v.
|
||||
//
|
||||
// See the documentation for Unmarshal for details about the
|
||||
// conversion of YAML into a Go value.
|
||||
func (dec *Decoder) Decode(v interface{}) (err error) {
|
||||
d := newDecoder(dec.strict)
|
||||
defer handleErr(&err)
|
||||
d := newDecoder()
|
||||
node := dec.parser.parse()
|
||||
if node == nil {
|
||||
return io.EOF
|
||||
}
|
||||
out := reflect.ValueOf(v)
|
||||
if out.Kind() == reflect.Ptr && !out.IsNil() {
|
||||
out = out.Elem()
|
||||
}
|
||||
d.unmarshal(node, out)
|
||||
if len(d.terrors) > 0 {
|
||||
return &TypeError{d.terrors}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshal(in []byte, out interface{}, strict bool) (err error) {
|
||||
defer handleErr(&err)
|
||||
d := newDecoder(strict)
|
||||
p := newParser(in)
|
||||
defer p.destroy()
|
||||
node := p.parse()
|
||||
|
@ -99,8 +157,8 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||
// of the generated document will reflect the structure of the value itself.
|
||||
// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
|
||||
//
|
||||
// Struct fields are only unmarshalled if they are exported (have an upper case
|
||||
// first letter), and are unmarshalled using the field name lowercased as the
|
||||
// Struct fields are only marshalled if they are exported (have an upper case
|
||||
// first letter), and are marshalled using the field name lowercased as the
|
||||
// default key. Custom keys may be defined via the "yaml" name in the field
|
||||
// tag: the content preceding the first comma is used as the key, and the
|
||||
// following comma-separated options are used to tweak the marshalling process.
|
||||
|
@ -114,7 +172,10 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||
//
|
||||
// omitempty Only include the field if it's not set to the zero
|
||||
// value for the type or to empty slices or maps.
|
||||
// Does not apply to zero valued structs.
|
||||
// Zero valued structs will be omitted if all their public
|
||||
// fields are zero, unless they implement an IsZero
|
||||
// method (see the IsZeroer interface type), in which
|
||||
// case the field will be included if that method returns true.
|
||||
//
|
||||
// flow Marshal using a flow style (useful for structs,
|
||||
// sequences and maps).
|
||||
|
@ -129,7 +190,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
|
|||
// For example:
|
||||
//
|
||||
// type T struct {
|
||||
// F int "a,omitempty"
|
||||
// F int `yaml:"a,omitempty"`
|
||||
// B int
|
||||
// }
|
||||
// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
|
||||
|
@ -139,12 +200,47 @@ func Marshal(in interface{}) (out []byte, err error) {
|
|||
defer handleErr(&err)
|
||||
e := newEncoder()
|
||||
defer e.destroy()
|
||||
e.marshal("", reflect.ValueOf(in))
|
||||
e.marshalDoc("", reflect.ValueOf(in))
|
||||
e.finish()
|
||||
out = e.out
|
||||
return
|
||||
}
|
||||
|
||||
// An Encoder writes YAML values to an output stream.
|
||||
type Encoder struct {
|
||||
encoder *encoder
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
// The Encoder should be closed after use to flush all data
|
||||
// to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{
|
||||
encoder: newEncoderWithWriter(w),
|
||||
}
|
||||
}
|
||||
|
||||
// Encode writes the YAML encoding of v to the stream.
|
||||
// If multiple items are encoded to the stream, the
|
||||
// second and subsequent document will be preceded
|
||||
// with a "---" document separator, but the first will not.
|
||||
//
|
||||
// See the documentation for Marshal for details about the conversion of Go
|
||||
// values to YAML.
|
||||
func (e *Encoder) Encode(v interface{}) (err error) {
|
||||
defer handleErr(&err)
|
||||
e.encoder.marshalDoc("", reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the encoder by writing any remaining data.
|
||||
// It does not write a stream terminating string "...".
|
||||
func (e *Encoder) Close() (err error) {
|
||||
defer handleErr(&err)
|
||||
e.encoder.finish()
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleErr(err *error) {
|
||||
if v := recover(); v != nil {
|
||||
if e, ok := v.(yamlError); ok {
|
||||
|
@ -200,6 +296,9 @@ type fieldInfo struct {
|
|||
Num int
|
||||
OmitEmpty bool
|
||||
Flow bool
|
||||
// Id holds the unique field identifier, so we can cheaply
|
||||
// check for field duplicates without maintaining an extra map.
|
||||
Id int
|
||||
|
||||
// Inline holds the field index if the field is part of an inlined struct.
|
||||
Inline []int
|
||||
|
@ -222,7 +321,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
inlineMap := -1
|
||||
for i := 0; i != n; i++ {
|
||||
field := st.Field(i)
|
||||
if field.PkgPath != "" {
|
||||
if field.PkgPath != "" && !field.Anonymous {
|
||||
continue // Private field
|
||||
}
|
||||
|
||||
|
@ -279,6 +378,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
} else {
|
||||
finfo.Inline = append([]int{i}, finfo.Inline...)
|
||||
}
|
||||
finfo.Id = len(fieldsList)
|
||||
fieldsMap[finfo.Key] = finfo
|
||||
fieldsList = append(fieldsList, finfo)
|
||||
}
|
||||
|
@ -300,11 +400,16 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
return nil, errors.New(msg)
|
||||
}
|
||||
|
||||
info.Id = len(fieldsList)
|
||||
fieldsList = append(fieldsList, info)
|
||||
fieldsMap[info.Key] = info
|
||||
}
|
||||
|
||||
sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
|
||||
sinfo = &structInfo{
|
||||
FieldsMap: fieldsMap,
|
||||
FieldsList: fieldsList,
|
||||
InlineMap: inlineMap,
|
||||
}
|
||||
|
||||
fieldMapMutex.Lock()
|
||||
structMap[st] = sinfo
|
||||
|
@ -312,8 +417,23 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
|
|||
return sinfo, nil
|
||||
}
|
||||
|
||||
// IsZeroer is used to check whether an object is zero to
|
||||
// determine whether it should be omitted when marshaling
|
||||
// with the omitempty flag. One notable implementation
|
||||
// is time.Time.
|
||||
type IsZeroer interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func isZero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
kind := v.Kind()
|
||||
if z, ok := v.Interface().(IsZeroer); ok {
|
||||
if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
|
||||
return true
|
||||
}
|
||||
return z.IsZero()
|
||||
}
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
return len(v.String()) == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
|
|
28
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
28
vendor/gopkg.in/yaml.v2/yamlh.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package yaml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
|
@ -239,6 +240,27 @@ const (
|
|||
yaml_MAPPING_END_EVENT // A MAPPING-END event.
|
||||
)
|
||||
|
||||
var eventStrings = []string{
|
||||
yaml_NO_EVENT: "none",
|
||||
yaml_STREAM_START_EVENT: "stream start",
|
||||
yaml_STREAM_END_EVENT: "stream end",
|
||||
yaml_DOCUMENT_START_EVENT: "document start",
|
||||
yaml_DOCUMENT_END_EVENT: "document end",
|
||||
yaml_ALIAS_EVENT: "alias",
|
||||
yaml_SCALAR_EVENT: "scalar",
|
||||
yaml_SEQUENCE_START_EVENT: "sequence start",
|
||||
yaml_SEQUENCE_END_EVENT: "sequence end",
|
||||
yaml_MAPPING_START_EVENT: "mapping start",
|
||||
yaml_MAPPING_END_EVENT: "mapping end",
|
||||
}
|
||||
|
||||
func (e yaml_event_type_t) String() string {
|
||||
if e < 0 || int(e) >= len(eventStrings) {
|
||||
return fmt.Sprintf("unknown event %d", e)
|
||||
}
|
||||
return eventStrings[e]
|
||||
}
|
||||
|
||||
// The event structure.
|
||||
type yaml_event_t struct {
|
||||
|
||||
|
@ -508,7 +530,7 @@ type yaml_parser_t struct {
|
|||
|
||||
problem string // Error description.
|
||||
|
||||
// The byte about which the problem occured.
|
||||
// The byte about which the problem occurred.
|
||||
problem_offset int
|
||||
problem_value int
|
||||
problem_mark yaml_mark_t
|
||||
|
@ -521,7 +543,7 @@ type yaml_parser_t struct {
|
|||
|
||||
read_handler yaml_read_handler_t // Read handler.
|
||||
|
||||
input_file io.Reader // File input data.
|
||||
input_reader io.Reader // File input data.
|
||||
input []byte // String input data.
|
||||
input_pos int
|
||||
|
||||
|
@ -632,7 +654,7 @@ type yaml_emitter_t struct {
|
|||
write_handler yaml_write_handler_t // Write handler.
|
||||
|
||||
output_buffer *[]byte // String output data.
|
||||
output_file io.Writer // File output data.
|
||||
output_writer io.Writer // File output data.
|
||||
|
||||
buffer []byte // The working buffer.
|
||||
buffer_pos int // The current position of the buffer.
|
||||
|
|
Loading…
Reference in a new issue