mirror of
https://github.com/Luzifer/yaml-vault.git
synced 2024-12-20 12:01:18 +00:00
add vendored dependencies
This commit is contained in:
parent
4edd2e64d9
commit
da8a107b7e
114 changed files with 22426 additions and 0 deletions
77
Godeps/Godeps.json
generated
Normal file
77
Godeps/Godeps.json
generated
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"ImportPath": "github.com/Jimdo/yaml-vault",
|
||||
"GoVersion": "go1.6",
|
||||
"GodepVersion": "v74",
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/Luzifer/rconfig",
|
||||
"Comment": "v1.1.0",
|
||||
"Rev": "c27bd3a64b5b19556914d9fec69922cf3852d585"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fatih/structs",
|
||||
"Rev": "9a7733345ff091c5457cb963f498a79ecd0bdbaa"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-cleanhttp",
|
||||
"Rev": "5df5ddc69534f1a4697289f1dca2193fbb40213f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/hcl/ast",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/hcl/parser",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/hcl/scanner",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/hcl/strconv",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/hcl/token",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/json/parser",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/json/scanner",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl/json/token",
|
||||
"Rev": "c40ec20b1285f01e9e75ec39f2bf2cff132891d3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/vault/api",
|
||||
"Comment": "v0.5.0",
|
||||
"Rev": "a7b0aadc9ea6a33875dd6bdd9d11d3146b29beb1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/go-homedir",
|
||||
"Rev": "756f7b183b7ab78acdbbee5c7f392838ed459dda"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/mapstructure",
|
||||
"Rev": "281073eb9eb092240d33ef253c404f1cca550309"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
"Rev": "b084184666e02084b8ccb9b704bf0d79c466eb1d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/yaml.v2",
|
||||
"Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
|
||||
}
|
||||
]
|
||||
}
|
5
Godeps/Readme
generated
Normal file
5
Godeps/Readme
generated
Normal file
|
@ -0,0 +1,5 @@
|
|||
This directory tree is generated automatically by godep.
|
||||
|
||||
Please do not edit.
|
||||
|
||||
See https://github.com/tools/godep for more information.
|
8
vendor/github.com/Luzifer/rconfig/.travis.yml
generated
vendored
Normal file
8
vendor/github.com/Luzifer/rconfig/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.5
|
||||
- tip
|
||||
|
||||
script: go test -v -race -cover ./...
|
5
vendor/github.com/Luzifer/rconfig/History.md
generated
vendored
Normal file
5
vendor/github.com/Luzifer/rconfig/History.md
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# 1.1.0 / 2016-06-28
|
||||
|
||||
* Support time.Duration config parameters
|
||||
* Added goreportcard badge
|
||||
* Added testcase for using bool with ENV and default
|
13
vendor/github.com/Luzifer/rconfig/LICENSE
generated
vendored
Normal file
13
vendor/github.com/Luzifer/rconfig/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright 2015 Knut Ahlers <knut@ahlers.me>
|
||||
|
||||
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.
|
94
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
Normal file
94
vendor/github.com/Luzifer/rconfig/README.md
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
[![Build Status](https://travis-ci.org/Luzifer/rconfig.svg?branch=master)](https://travis-ci.org/Luzifer/rconfig)
|
||||
[![License: Apache v2.0](https://badge.luzifer.io/v1/badge?color=5d79b5&title=license&text=Apache+v2.0)](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
[![Documentation](https://badge.luzifer.io/v1/badge?title=godoc&text=reference)](https://godoc.org/github.com/Luzifer/rconfig)
|
||||
[![Go Report](http://goreportcard.com/badge/Luzifer/rconfig)](http://goreportcard.com/report/Luzifer/rconfig)
|
||||
|
||||
## Description
|
||||
|
||||
> Package rconfig implements a CLI configuration reader with struct-embedded defaults, environment variables and posix compatible flag parsing using the [pflag](https://github.com/spf13/pflag) library.
|
||||
|
||||
## Installation
|
||||
|
||||
Install by running:
|
||||
|
||||
```
|
||||
go get -u github.com/Luzifer/rconfig
|
||||
```
|
||||
|
||||
OR fetch a specific version:
|
||||
|
||||
```
|
||||
go get -u gopkg.in/luzifer/rconfig.v1
|
||||
```
|
||||
|
||||
Run tests by running:
|
||||
|
||||
```
|
||||
go test -v -race -cover github.com/Luzifer/rconfig
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
As a first step define a struct holding your configuration:
|
||||
|
||||
```go
|
||||
type config struct {
|
||||
Username string `default:"unknown" flag:"user" description:"Your name"`
|
||||
Details struct {
|
||||
Age int `default:"25" flag:"age" env:"age" description:"Your age"`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next create an instance of that struct and let `rconfig` fill that config:
|
||||
|
||||
```go
|
||||
var cfg config
|
||||
func init() {
|
||||
cfg = config{}
|
||||
rconfig.Parse(&cfg)
|
||||
}
|
||||
```
|
||||
|
||||
You're ready to access your configuration:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
fmt.Printf("Hello %s, happy birthday for your %dth birthday.",
|
||||
cfg.Username,
|
||||
cfg.Details.Age)
|
||||
}
|
||||
```
|
||||
|
||||
### Provide variable defaults by using a file
|
||||
|
||||
Given you have a file `~/.myapp.yml` containing some secrets or usernames (for the example below username is assumed to be "luzifer") as a default configuration for your application you can use this source code to load the defaults from that file using the `vardefault` tag in your configuration struct.
|
||||
|
||||
The order of the directives (lower number = higher precedence):
|
||||
|
||||
1. Flags provided in command line
|
||||
1. Environment variables
|
||||
1. Variable defaults (`vardefault` tag in the struct)
|
||||
1. `default` tag in the struct
|
||||
|
||||
```go
|
||||
type config struct {
|
||||
Username string `vardefault:"username" flag:"username" description:"Your username"`
|
||||
}
|
||||
|
||||
var cfg = config{}
|
||||
|
||||
func init() {
|
||||
rconfig.SetVariableDefaults(rconfig.VarDefaultsFromYAMLFile("~/.myapp.yml"))
|
||||
rconfig.Parse(&cfg)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Username = %s", cfg.Username)
|
||||
// Output: Username = luzifer
|
||||
}
|
||||
```
|
||||
|
||||
## More info
|
||||
|
||||
You can see the full reference documentation of the rconfig package [at godoc.org](https://godoc.org/github.com/Luzifer/rconfig), or through go's standard documentation system by running `godoc -http=:6060` and browsing to [http://localhost:6060/pkg/github.com/Luzifer/rconfig](http://localhost:6060/pkg/github.com/Luzifer/rconfig) after installation.
|
338
vendor/github.com/Luzifer/rconfig/config.go
generated
vendored
Normal file
338
vendor/github.com/Luzifer/rconfig/config.go
generated
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
// Package rconfig implements a CLI configuration reader with struct-embedded
|
||||
// defaults, environment variables and posix compatible flag parsing using
|
||||
// the pflag library.
|
||||
package rconfig
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var (
|
||||
fs *pflag.FlagSet
|
||||
variableDefaults map[string]string
|
||||
)
|
||||
|
||||
func init() {
|
||||
variableDefaults = make(map[string]string)
|
||||
}
|
||||
|
||||
// Parse takes the pointer to a struct filled with variables which should be read
|
||||
// from ENV, default or flag. The precedence in this is flag > ENV > default. So
|
||||
// if a flag is specified on the CLI it will overwrite the ENV and otherwise ENV
|
||||
// overwrites the default specified.
|
||||
//
|
||||
// For your configuration struct you can use the following struct-tags to control
|
||||
// the behavior of rconfig:
|
||||
//
|
||||
// default: Set a default value
|
||||
// vardefault: Read the default value from the variable defaults
|
||||
// env: Read the value from this environment variable
|
||||
// flag: Flag to read in format "long,short" (for example "listen,l")
|
||||
// description: A help text for Usage output to guide your users
|
||||
//
|
||||
// The format you need to specify those values you can see in the example to this
|
||||
// function.
|
||||
//
|
||||
func Parse(config interface{}) error {
|
||||
return parse(config, nil)
|
||||
}
|
||||
|
||||
// Args returns the non-flag command-line arguments.
|
||||
func Args() []string {
|
||||
return fs.Args()
|
||||
}
|
||||
|
||||
// Usage prints a basic usage with the corresponding defaults for the flags to
|
||||
// os.Stdout. The defaults are derived from the `default` struct-tag and the ENV.
|
||||
func Usage() {
|
||||
if fs != nil && fs.Parsed() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
fs.PrintDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
// SetVariableDefaults presets the parser with a map of default values to be used
|
||||
// when specifying the vardefault tag
|
||||
func SetVariableDefaults(defaults map[string]string) {
|
||||
variableDefaults = defaults
|
||||
}
|
||||
|
||||
func parse(in interface{}, args []string) error {
|
||||
if args == nil {
|
||||
args = os.Args
|
||||
}
|
||||
|
||||
fs = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
|
||||
if err := execTags(in, fs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fs.Parse(args)
|
||||
}
|
||||
|
||||
func execTags(in interface{}, fs *pflag.FlagSet) error {
|
||||
if reflect.TypeOf(in).Kind() != reflect.Ptr {
|
||||
return errors.New("Calling parser with non-pointer")
|
||||
}
|
||||
|
||||
if reflect.ValueOf(in).Elem().Kind() != reflect.Struct {
|
||||
return errors.New("Calling parser with pointer to non-struct")
|
||||
}
|
||||
|
||||
st := reflect.ValueOf(in).Elem()
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
valField := st.Field(i)
|
||||
typeField := st.Type().Field(i)
|
||||
|
||||
if typeField.Tag.Get("default") == "" && typeField.Tag.Get("env") == "" && typeField.Tag.Get("flag") == "" && typeField.Type.Kind() != reflect.Struct {
|
||||
// None of our supported tags is present and it's not a sub-struct
|
||||
continue
|
||||
}
|
||||
|
||||
value := varDefault(typeField.Tag.Get("vardefault"), typeField.Tag.Get("default"))
|
||||
value = envDefault(typeField.Tag.Get("env"), value)
|
||||
parts := strings.Split(typeField.Tag.Get("flag"), ",")
|
||||
|
||||
switch typeField.Type {
|
||||
case reflect.TypeOf(time.Duration(0)):
|
||||
v, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
if value == "" {
|
||||
v = time.Duration(0)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if typeField.Tag.Get("flag") != "" {
|
||||
if len(parts) == 1 {
|
||||
fs.DurationVar(valField.Addr().Interface().(*time.Duration), parts[0], v, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
fs.DurationVarP(valField.Addr().Interface().(*time.Duration), parts[0], parts[1], v, typeField.Tag.Get("description"))
|
||||
}
|
||||
} else {
|
||||
valField.Set(reflect.ValueOf(v))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch typeField.Type.Kind() {
|
||||
case reflect.String:
|
||||
if typeField.Tag.Get("flag") != "" {
|
||||
if len(parts) == 1 {
|
||||
fs.StringVar(valField.Addr().Interface().(*string), parts[0], value, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
fs.StringVarP(valField.Addr().Interface().(*string), parts[0], parts[1], value, typeField.Tag.Get("description"))
|
||||
}
|
||||
} else {
|
||||
valField.SetString(value)
|
||||
}
|
||||
|
||||
case reflect.Bool:
|
||||
v := value == "true"
|
||||
if typeField.Tag.Get("flag") != "" {
|
||||
if len(parts) == 1 {
|
||||
fs.BoolVar(valField.Addr().Interface().(*bool), parts[0], v, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
fs.BoolVarP(valField.Addr().Interface().(*bool), parts[0], parts[1], v, typeField.Tag.Get("description"))
|
||||
}
|
||||
} else {
|
||||
valField.SetBool(v)
|
||||
}
|
||||
|
||||
case reflect.Int, reflect.Int8, reflect.Int32, reflect.Int64:
|
||||
vt, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
if value == "" {
|
||||
vt = 0
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if typeField.Tag.Get("flag") != "" {
|
||||
registerFlagInt(typeField.Type.Kind(), fs, valField.Addr().Interface(), parts, vt, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
valField.SetInt(vt)
|
||||
}
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
vt, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
if value == "" {
|
||||
vt = 0
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if typeField.Tag.Get("flag") != "" {
|
||||
registerFlagUint(typeField.Type.Kind(), fs, valField.Addr().Interface(), parts, vt, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
valField.SetUint(vt)
|
||||
}
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
vt, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
if value == "" {
|
||||
vt = 0.0
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if typeField.Tag.Get("flag") != "" {
|
||||
registerFlagFloat(typeField.Type.Kind(), fs, valField.Addr().Interface(), parts, vt, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
valField.SetFloat(vt)
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
if err := execTags(valField.Addr().Interface(), fs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
switch typeField.Type.Elem().Kind() {
|
||||
case reflect.Int:
|
||||
def := []int{}
|
||||
for _, v := range strings.Split(value, ",") {
|
||||
it, err := strconv.ParseInt(strings.TrimSpace(v), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
def = append(def, int(it))
|
||||
}
|
||||
if len(parts) == 1 {
|
||||
fs.IntSliceVar(valField.Addr().Interface().(*[]int), parts[0], def, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
fs.IntSliceVarP(valField.Addr().Interface().(*[]int), parts[0], parts[1], def, typeField.Tag.Get("description"))
|
||||
}
|
||||
case reflect.String:
|
||||
del := typeField.Tag.Get("delimiter")
|
||||
if len(del) == 0 {
|
||||
del = ","
|
||||
}
|
||||
def := strings.Split(value, del)
|
||||
if len(parts) == 1 {
|
||||
fs.StringSliceVar(valField.Addr().Interface().(*[]string), parts[0], def, typeField.Tag.Get("description"))
|
||||
} else {
|
||||
fs.StringSliceVarP(valField.Addr().Interface().(*[]string), parts[0], parts[1], def, typeField.Tag.Get("description"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func registerFlagFloat(t reflect.Kind, fs *pflag.FlagSet, field interface{}, parts []string, vt float64, desc string) {
|
||||
switch t {
|
||||
case reflect.Float32:
|
||||
if len(parts) == 1 {
|
||||
fs.Float32Var(field.(*float32), parts[0], float32(vt), desc)
|
||||
} else {
|
||||
fs.Float32VarP(field.(*float32), parts[0], parts[1], float32(vt), desc)
|
||||
}
|
||||
case reflect.Float64:
|
||||
if len(parts) == 1 {
|
||||
fs.Float64Var(field.(*float64), parts[0], float64(vt), desc)
|
||||
} else {
|
||||
fs.Float64VarP(field.(*float64), parts[0], parts[1], float64(vt), desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func registerFlagInt(t reflect.Kind, fs *pflag.FlagSet, field interface{}, parts []string, vt int64, desc string) {
|
||||
switch t {
|
||||
case reflect.Int:
|
||||
if len(parts) == 1 {
|
||||
fs.IntVar(field.(*int), parts[0], int(vt), desc)
|
||||
} else {
|
||||
fs.IntVarP(field.(*int), parts[0], parts[1], int(vt), desc)
|
||||
}
|
||||
case reflect.Int8:
|
||||
if len(parts) == 1 {
|
||||
fs.Int8Var(field.(*int8), parts[0], int8(vt), desc)
|
||||
} else {
|
||||
fs.Int8VarP(field.(*int8), parts[0], parts[1], int8(vt), desc)
|
||||
}
|
||||
case reflect.Int32:
|
||||
if len(parts) == 1 {
|
||||
fs.Int32Var(field.(*int32), parts[0], int32(vt), desc)
|
||||
} else {
|
||||
fs.Int32VarP(field.(*int32), parts[0], parts[1], int32(vt), desc)
|
||||
}
|
||||
case reflect.Int64:
|
||||
if len(parts) == 1 {
|
||||
fs.Int64Var(field.(*int64), parts[0], int64(vt), desc)
|
||||
} else {
|
||||
fs.Int64VarP(field.(*int64), parts[0], parts[1], int64(vt), desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func registerFlagUint(t reflect.Kind, fs *pflag.FlagSet, field interface{}, parts []string, vt uint64, desc string) {
|
||||
switch t {
|
||||
case reflect.Uint:
|
||||
if len(parts) == 1 {
|
||||
fs.UintVar(field.(*uint), parts[0], uint(vt), desc)
|
||||
} else {
|
||||
fs.UintVarP(field.(*uint), parts[0], parts[1], uint(vt), desc)
|
||||
}
|
||||
case reflect.Uint8:
|
||||
if len(parts) == 1 {
|
||||
fs.Uint8Var(field.(*uint8), parts[0], uint8(vt), desc)
|
||||
} else {
|
||||
fs.Uint8VarP(field.(*uint8), parts[0], parts[1], uint8(vt), desc)
|
||||
}
|
||||
case reflect.Uint16:
|
||||
if len(parts) == 1 {
|
||||
fs.Uint16Var(field.(*uint16), parts[0], uint16(vt), desc)
|
||||
} else {
|
||||
fs.Uint16VarP(field.(*uint16), parts[0], parts[1], uint16(vt), desc)
|
||||
}
|
||||
case reflect.Uint32:
|
||||
if len(parts) == 1 {
|
||||
fs.Uint32Var(field.(*uint32), parts[0], uint32(vt), desc)
|
||||
} else {
|
||||
fs.Uint32VarP(field.(*uint32), parts[0], parts[1], uint32(vt), desc)
|
||||
}
|
||||
case reflect.Uint64:
|
||||
if len(parts) == 1 {
|
||||
fs.Uint64Var(field.(*uint64), parts[0], uint64(vt), desc)
|
||||
} else {
|
||||
fs.Uint64VarP(field.(*uint64), parts[0], parts[1], uint64(vt), desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func envDefault(env, def string) string {
|
||||
value := def
|
||||
|
||||
if env != "" {
|
||||
if e := os.Getenv(env); e != "" {
|
||||
value = e
|
||||
}
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func varDefault(name, def string) string {
|
||||
value := def
|
||||
|
||||
if name != "" {
|
||||
if v, ok := variableDefaults[name]; ok {
|
||||
value = v
|
||||
}
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
27
vendor/github.com/Luzifer/rconfig/vardefault_providers.go
generated
vendored
Normal file
27
vendor/github.com/Luzifer/rconfig/vardefault_providers.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
package rconfig
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// VarDefaultsFromYAMLFile reads contents of a file and calls VarDefaultsFromYAML
|
||||
func VarDefaultsFromYAMLFile(filename string) map[string]string {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return make(map[string]string)
|
||||
}
|
||||
|
||||
return VarDefaultsFromYAML(data)
|
||||
}
|
||||
|
||||
// VarDefaultsFromYAML creates a vardefaults map from YAML raw data
|
||||
func VarDefaultsFromYAML(in []byte) map[string]string {
|
||||
out := make(map[string]string)
|
||||
err := yaml.Unmarshal(in, &out)
|
||||
if err != nil {
|
||||
return make(map[string]string)
|
||||
}
|
||||
return out
|
||||
}
|
23
vendor/github.com/fatih/structs/.gitignore
generated
vendored
Normal file
23
vendor/github.com/fatih/structs/.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
|
9
vendor/github.com/fatih/structs/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/fatih/structs/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
language: go
|
||||
go: 1.5
|
||||
sudo: false
|
||||
before_install:
|
||||
- go get github.com/axw/gocov/gocov
|
||||
- go get github.com/mattn/goveralls
|
||||
- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
21
vendor/github.com/fatih/structs/LICENSE
generated
vendored
Normal file
21
vendor/github.com/fatih/structs/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Fatih Arslan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
164
vendor/github.com/fatih/structs/README.md
generated
vendored
Normal file
164
vendor/github.com/fatih/structs/README.md
generated
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
# Structs [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/structs) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/fatih/structs) [![Coverage Status](http://img.shields.io/coveralls/fatih/structs.svg?style=flat-square)](https://coveralls.io/r/fatih/structs)
|
||||
|
||||
Structs contains various utilities to work with Go (Golang) structs. It was
|
||||
initially used by me to convert a struct into a `map[string]interface{}`. With
|
||||
time I've added other utilities for structs. It's basically a high level
|
||||
package based on primitives from the reflect package. Feel free to add new
|
||||
functions or improve the existing code.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get github.com/fatih/structs
|
||||
```
|
||||
|
||||
## Usage and Examples
|
||||
|
||||
Just like the standard lib `strings`, `bytes` and co packages, `structs` has
|
||||
many global functions to manipulate or organize your struct data. Lets define
|
||||
and declare a struct:
|
||||
|
||||
```go
|
||||
type Server struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ID int
|
||||
Enabled bool
|
||||
users []string // not exported
|
||||
http.Server // embedded
|
||||
}
|
||||
|
||||
server := &Server{
|
||||
Name: "gopher",
|
||||
ID: 123456,
|
||||
Enabled: true,
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// Convert a struct to a map[string]interface{}
|
||||
// => {"Name":"gopher", "ID":123456, "Enabled":true}
|
||||
m := structs.Map(server)
|
||||
|
||||
// Convert the values of a struct to a []interface{}
|
||||
// => ["gopher", 123456, true]
|
||||
v := structs.Values(server)
|
||||
|
||||
// Convert the names of a struct to a []string
|
||||
// (see "Names methods" for more info about fields)
|
||||
n := structs.Names(server)
|
||||
|
||||
// Convert the values of a struct to a []*Field
|
||||
// (see "Field methods" for more info about fields)
|
||||
f := structs.Fields(server)
|
||||
|
||||
// Return the struct name => "Server"
|
||||
n := structs.Name(server)
|
||||
|
||||
// Check if any field of a struct is initialized or not.
|
||||
h := structs.HasZero(server)
|
||||
|
||||
// Check if all fields of a struct is initialized or not.
|
||||
z := structs.IsZero(server)
|
||||
|
||||
// Check if server is a struct or a pointer to struct
|
||||
i := structs.IsStruct(server)
|
||||
```
|
||||
|
||||
### Struct methods
|
||||
|
||||
The structs functions can be also used as independent methods by creating a new
|
||||
`*structs.Struct`. This is handy if you want to have more control over the
|
||||
structs (such as retrieving a single Field).
|
||||
|
||||
```go
|
||||
// Create a new struct type:
|
||||
s := structs.New(server)
|
||||
|
||||
m := s.Map() // Get a map[string]interface{}
|
||||
v := s.Values() // Get a []interface{}
|
||||
f := s.Fields() // Get a []*Field
|
||||
n := s.Names() // Get a []string
|
||||
f := s.Field(name) // Get a *Field based on the given field name
|
||||
f, ok := s.FieldOk(name) // Get a *Field based on the given field name
|
||||
n := s.Name() // Get the struct name
|
||||
h := s.HasZero() // Check if any field is initialized
|
||||
z := s.IsZero() // Check if all fields are initialized
|
||||
```
|
||||
|
||||
### Field methods
|
||||
|
||||
We can easily examine a single Field for more detail. Below you can see how we
|
||||
get and interact with various field methods:
|
||||
|
||||
|
||||
```go
|
||||
s := structs.New(server)
|
||||
|
||||
// Get the Field struct for the "Name" field
|
||||
name := s.Field("Name")
|
||||
|
||||
// Get the underlying value, value => "gopher"
|
||||
value := name.Value().(string)
|
||||
|
||||
// Set the field's value
|
||||
name.Set("another gopher")
|
||||
|
||||
// Get the field's kind, kind => "string"
|
||||
name.Kind()
|
||||
|
||||
// Check if the field is exported or not
|
||||
if name.IsExported() {
|
||||
fmt.Println("Name field is exported")
|
||||
}
|
||||
|
||||
// Check if the value is a zero value, such as "" for string, 0 for int
|
||||
if !name.IsZero() {
|
||||
fmt.Println("Name is initialized")
|
||||
}
|
||||
|
||||
// Check if the field is an anonymous (embedded) field
|
||||
if !name.IsEmbedded() {
|
||||
fmt.Println("Name is not an embedded field")
|
||||
}
|
||||
|
||||
// Get the Field's tag value for tag name "json", tag value => "name,omitempty"
|
||||
tagValue := name.Tag("json")
|
||||
```
|
||||
|
||||
Nested structs are supported too:
|
||||
|
||||
```go
|
||||
addrField := s.Field("Server").Field("Addr")
|
||||
|
||||
// Get the value for addr
|
||||
a := addrField.Value().(string)
|
||||
|
||||
// Or get all fields
|
||||
httpServer := s.Field("Server").Fields()
|
||||
```
|
||||
|
||||
We can also get a slice of Fields from the Struct type to iterate over all
|
||||
fields. This is handy if you wish to examine all fields:
|
||||
|
||||
```go
|
||||
// Convert the fields of a struct to a []*Field
|
||||
fields := s.Fields()
|
||||
|
||||
for _, f := range fields {
|
||||
fmt.Printf("field name: %+v\n", f.Name())
|
||||
|
||||
if f.IsExported() {
|
||||
fmt.Printf("value : %+v\n", f.Value())
|
||||
fmt.Printf("is zero : %+v\n", f.IsZero())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
* [Fatih Arslan](https://github.com/fatih)
|
||||
* [Cihangir Savas](https://github.com/cihangir)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) - see LICENSE.md for more details
|
133
vendor/github.com/fatih/structs/field.go
generated
vendored
Normal file
133
vendor/github.com/fatih/structs/field.go
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
package structs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
errNotExported = errors.New("field is not exported")
|
||||
errNotSettable = errors.New("field is not settable")
|
||||
)
|
||||
|
||||
// Field represents a single struct field that encapsulates high level
|
||||
// functions around the field.
|
||||
type Field struct {
|
||||
value reflect.Value
|
||||
field reflect.StructField
|
||||
defaultTag string
|
||||
}
|
||||
|
||||
// Tag returns the value associated with key in the tag string. If there is no
|
||||
// such key in the tag, Tag returns the empty string.
|
||||
func (f *Field) Tag(key string) string {
|
||||
return f.field.Tag.Get(key)
|
||||
}
|
||||
|
||||
// Value returns the underlying value of of the field. It panics if the field
|
||||
// is not exported.
|
||||
func (f *Field) Value() interface{} {
|
||||
return f.value.Interface()
|
||||
}
|
||||
|
||||
// IsEmbedded returns true if the given field is an anonymous field (embedded)
|
||||
func (f *Field) IsEmbedded() bool {
|
||||
return f.field.Anonymous
|
||||
}
|
||||
|
||||
// IsExported returns true if the given field is exported.
|
||||
func (f *Field) IsExported() bool {
|
||||
return f.field.PkgPath == ""
|
||||
}
|
||||
|
||||
// IsZero returns true if the given field is not initalized (has a zero value).
|
||||
// It panics if the field is not exported.
|
||||
func (f *Field) IsZero() bool {
|
||||
zero := reflect.Zero(f.value.Type()).Interface()
|
||||
current := f.Value()
|
||||
|
||||
return reflect.DeepEqual(current, zero)
|
||||
}
|
||||
|
||||
// Name returns the name of the given field
|
||||
func (f *Field) Name() string {
|
||||
return f.field.Name
|
||||
}
|
||||
|
||||
// Kind returns the fields kind, such as "string", "map", "bool", etc ..
|
||||
func (f *Field) Kind() reflect.Kind {
|
||||
return f.value.Kind()
|
||||
}
|
||||
|
||||
// Set sets the field to given value v. It retuns an error if the field is not
|
||||
// settable (not addresable or not exported) or if the given value's type
|
||||
// doesn't match the fields type.
|
||||
func (f *Field) Set(val interface{}) error {
|
||||
// we can't set unexported fields, so be sure this field is exported
|
||||
if !f.IsExported() {
|
||||
return errNotExported
|
||||
}
|
||||
|
||||
// do we get here? not sure...
|
||||
if !f.value.CanSet() {
|
||||
return errNotSettable
|
||||
}
|
||||
|
||||
given := reflect.ValueOf(val)
|
||||
|
||||
if f.value.Kind() != given.Kind() {
|
||||
return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind())
|
||||
}
|
||||
|
||||
f.value.Set(given)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Zero sets the field to its zero value. It returns an error if the field is not
|
||||
// settable (not addressable or not exported).
|
||||
func (f *Field) Zero() error {
|
||||
zero := reflect.Zero(f.value.Type()).Interface()
|
||||
return f.Set(zero)
|
||||
}
|
||||
|
||||
// Fields returns a slice of Fields. This is particular handy to get the fields
|
||||
// of a nested struct . A struct tag with the content of "-" ignores the
|
||||
// checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field *http.Request `structs:"-"`
|
||||
//
|
||||
// It panics if field is not exported or if field's kind is not struct
|
||||
func (f *Field) Fields() []*Field {
|
||||
return getFields(f.value, f.defaultTag)
|
||||
}
|
||||
|
||||
// Field returns the field from a nested struct. It panics if the nested struct
|
||||
// is not exported or if the field was not found.
|
||||
func (f *Field) Field(name string) *Field {
|
||||
field, ok := f.FieldOk(name)
|
||||
if !ok {
|
||||
panic("field not found")
|
||||
}
|
||||
|
||||
return field
|
||||
}
|
||||
|
||||
// Field returns the field from a nested struct. The boolean returns true if
|
||||
// the field was found. It panics if the nested struct is not exported or if
|
||||
// the field was not found.
|
||||
func (f *Field) FieldOk(name string) (*Field, bool) {
|
||||
v := strctVal(f.value.Interface())
|
||||
t := v.Type()
|
||||
|
||||
field, ok := t.FieldByName(name)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &Field{
|
||||
field: field,
|
||||
value: v.FieldByName(name),
|
||||
}, true
|
||||
}
|
454
vendor/github.com/fatih/structs/structs.go
generated
vendored
Normal file
454
vendor/github.com/fatih/structs/structs.go
generated
vendored
Normal file
|
@ -0,0 +1,454 @@
|
|||
// Package structs contains various utilities functions to work with structs.
|
||||
package structs
|
||||
|
||||
import "reflect"
|
||||
|
||||
var (
|
||||
// DefaultTagName is the default tag name for struct fields which provides
|
||||
// a more granular to tweak certain structs. Lookup the necessary functions
|
||||
// for more info.
|
||||
DefaultTagName = "structs" // struct's field default tag name
|
||||
)
|
||||
|
||||
// Struct encapsulates a struct type to provide several high level functions
|
||||
// around the struct.
|
||||
type Struct struct {
|
||||
raw interface{}
|
||||
value reflect.Value
|
||||
TagName string
|
||||
}
|
||||
|
||||
// New returns a new *Struct with the struct s. It panics if the s's kind is
|
||||
// not struct.
|
||||
func New(s interface{}) *Struct {
|
||||
return &Struct{
|
||||
raw: s,
|
||||
value: strctVal(s),
|
||||
TagName: DefaultTagName,
|
||||
}
|
||||
}
|
||||
|
||||
// Map converts the given struct to a map[string]interface{}, where the keys
|
||||
// of the map are the field names and the values of the map the associated
|
||||
// values of the fields. The default key string is the struct field name but
|
||||
// can be changed in the struct field's tag value. The "structs" key in the
|
||||
// struct's field tag value is the key name. Example:
|
||||
//
|
||||
// // Field appears in map as key "myName".
|
||||
// Name string `structs:"myName"`
|
||||
//
|
||||
// A tag value with the content of "-" ignores that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structs:"-"`
|
||||
//
|
||||
// A tag value with the option of "omitnested" stops iterating further if the type
|
||||
// is a struct. Example:
|
||||
//
|
||||
// // Field is not processed further by this package.
|
||||
// Field time.Time `structs:"myName,omitnested"`
|
||||
// Field *http.Request `structs:",omitnested"`
|
||||
//
|
||||
// A tag value with the option of "omitempty" ignores that particular field if
|
||||
// the field value is empty. Example:
|
||||
//
|
||||
// // Field appears in map as key "myName", but the field is
|
||||
// // skipped if empty.
|
||||
// Field string `structs:"myName,omitempty"`
|
||||
//
|
||||
// // Field appears in map as key "Field" (the default), but
|
||||
// // the field is skipped if empty.
|
||||
// Field string `structs:",omitempty"`
|
||||
//
|
||||
// Note that only exported fields of a struct can be accessed, non exported
|
||||
// fields will be neglected.
|
||||
func (s *Struct) Map() map[string]interface{} {
|
||||
out := make(map[string]interface{})
|
||||
|
||||
fields := s.structFields()
|
||||
|
||||
for _, field := range fields {
|
||||
name := field.Name
|
||||
val := s.value.FieldByName(name)
|
||||
|
||||
var finalVal interface{}
|
||||
|
||||
tagName, tagOpts := parseTag(field.Tag.Get(s.TagName))
|
||||
if tagName != "" {
|
||||
name = tagName
|
||||
}
|
||||
|
||||
// if the value is a zero value and the field is marked as omitempty do
|
||||
// not include
|
||||
if tagOpts.Has("omitempty") {
|
||||
zero := reflect.Zero(val.Type()).Interface()
|
||||
current := val.Interface()
|
||||
|
||||
if reflect.DeepEqual(current, zero) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
// look out for embedded structs, and convert them to a
|
||||
// map[string]interface{} too
|
||||
n := New(val.Interface())
|
||||
n.TagName = s.TagName
|
||||
m := n.Map()
|
||||
if len(m) == 0 {
|
||||
finalVal = val.Interface()
|
||||
} else {
|
||||
finalVal = m
|
||||
}
|
||||
} else {
|
||||
finalVal = val.Interface()
|
||||
}
|
||||
|
||||
out[name] = finalVal
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// Values converts the given s struct's field values to a []interface{}. A
|
||||
// struct tag with the content of "-" ignores the that particular field.
|
||||
// Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field int `structs:"-"`
|
||||
//
|
||||
// A value with the option of "omitnested" stops iterating further if the type
|
||||
// is a struct. Example:
|
||||
//
|
||||
// // Fields is not processed further by this package.
|
||||
// Field time.Time `structs:",omitnested"`
|
||||
// Field *http.Request `structs:",omitnested"`
|
||||
//
|
||||
// A tag value with the option of "omitempty" ignores that particular field and
|
||||
// is not added to the values if the field value is empty. Example:
|
||||
//
|
||||
// // Field is skipped if empty
|
||||
// Field string `structs:",omitempty"`
|
||||
//
|
||||
// Note that only exported fields of a struct can be accessed, non exported
|
||||
// fields will be neglected.
|
||||
func (s *Struct) Values() []interface{} {
|
||||
fields := s.structFields()
|
||||
|
||||
var t []interface{}
|
||||
|
||||
for _, field := range fields {
|
||||
val := s.value.FieldByName(field.Name)
|
||||
|
||||
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
|
||||
|
||||
// if the value is a zero value and the field is marked as omitempty do
|
||||
// not include
|
||||
if tagOpts.Has("omitempty") {
|
||||
zero := reflect.Zero(val.Type()).Interface()
|
||||
current := val.Interface()
|
||||
|
||||
if reflect.DeepEqual(current, zero) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
// look out for embedded structs, and convert them to a
|
||||
// []interface{} to be added to the final values slice
|
||||
for _, embeddedVal := range Values(val.Interface()) {
|
||||
t = append(t, embeddedVal)
|
||||
}
|
||||
} else {
|
||||
t = append(t, val.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// Fields returns a slice of Fields. A struct tag with the content of "-"
|
||||
// ignores the checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structs:"-"`
|
||||
//
|
||||
// It panics if s's kind is not struct.
|
||||
func (s *Struct) Fields() []*Field {
|
||||
return getFields(s.value, s.TagName)
|
||||
}
|
||||
|
||||
// Names returns a slice of field names. A struct tag with the content of "-"
|
||||
// ignores the checking of that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structs:"-"`
|
||||
//
|
||||
// It panics if s's kind is not struct.
|
||||
func (s *Struct) Names() []string {
|
||||
fields := getFields(s.value, s.TagName)
|
||||
|
||||
names := make([]string, len(fields))
|
||||
|
||||
for i, field := range fields {
|
||||
names[i] = field.Name()
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
func getFields(v reflect.Value, tagName string) []*Field {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
t := v.Type()
|
||||
|
||||
var fields []*Field
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
|
||||
if tag := field.Tag.Get(tagName); tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
f := &Field{
|
||||
field: field,
|
||||
value: v.FieldByName(field.Name),
|
||||
}
|
||||
|
||||
fields = append(fields, f)
|
||||
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
// Field returns a new Field struct that provides several high level functions
|
||||
// around a single struct field entity. It panics if the field is not found.
|
||||
func (s *Struct) Field(name string) *Field {
|
||||
f, ok := s.FieldOk(name)
|
||||
if !ok {
|
||||
panic("field not found")
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// Field returns a new Field struct that provides several high level functions
|
||||
// around a single struct field entity. The boolean returns true if the field
|
||||
// was found.
|
||||
func (s *Struct) FieldOk(name string) (*Field, bool) {
|
||||
t := s.value.Type()
|
||||
|
||||
field, ok := t.FieldByName(name)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &Field{
|
||||
field: field,
|
||||
value: s.value.FieldByName(name),
|
||||
defaultTag: s.TagName,
|
||||
}, true
|
||||
}
|
||||
|
||||
// IsZero returns true if all fields in a struct is a zero value (not
|
||||
// initialized) A struct tag with the content of "-" ignores the checking of
|
||||
// that particular field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structs:"-"`
|
||||
//
|
||||
// A value with the option of "omitnested" stops iterating further if the type
|
||||
// is a struct. Example:
|
||||
//
|
||||
// // Field is not processed further by this package.
|
||||
// Field time.Time `structs:"myName,omitnested"`
|
||||
// Field *http.Request `structs:",omitnested"`
|
||||
//
|
||||
// Note that only exported fields of a struct can be accessed, non exported
|
||||
// fields will be neglected. It panics if s's kind is not struct.
|
||||
func (s *Struct) IsZero() bool {
|
||||
fields := s.structFields()
|
||||
|
||||
for _, field := range fields {
|
||||
val := s.value.FieldByName(field.Name)
|
||||
|
||||
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
|
||||
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
ok := IsZero(val.Interface())
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// zero value of the given field, such as "" for string, 0 for int
|
||||
zero := reflect.Zero(val.Type()).Interface()
|
||||
|
||||
// current value of the given field
|
||||
current := val.Interface()
|
||||
|
||||
if !reflect.DeepEqual(current, zero) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// HasZero returns true if a field in a struct is not initialized (zero value).
|
||||
// A struct tag with the content of "-" ignores the checking of that particular
|
||||
// field. Example:
|
||||
//
|
||||
// // Field is ignored by this package.
|
||||
// Field bool `structs:"-"`
|
||||
//
|
||||
// A value with the option of "omitnested" stops iterating further if the type
|
||||
// is a struct. Example:
|
||||
//
|
||||
// // Field is not processed further by this package.
|
||||
// Field time.Time `structs:"myName,omitnested"`
|
||||
// Field *http.Request `structs:",omitnested"`
|
||||
//
|
||||
// Note that only exported fields of a struct can be accessed, non exported
|
||||
// fields will be neglected. It panics if s's kind is not struct.
|
||||
func (s *Struct) HasZero() bool {
|
||||
fields := s.structFields()
|
||||
|
||||
for _, field := range fields {
|
||||
val := s.value.FieldByName(field.Name)
|
||||
|
||||
_, tagOpts := parseTag(field.Tag.Get(s.TagName))
|
||||
|
||||
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
|
||||
ok := HasZero(val.Interface())
|
||||
if ok {
|
||||
return true
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// zero value of the given field, such as "" for string, 0 for int
|
||||
zero := reflect.Zero(val.Type()).Interface()
|
||||
|
||||
// current value of the given field
|
||||
current := val.Interface()
|
||||
|
||||
if reflect.DeepEqual(current, zero) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Name returns the structs's type name within its package. For more info refer
|
||||
// to Name() function.
|
||||
func (s *Struct) Name() string {
|
||||
return s.value.Type().Name()
|
||||
}
|
||||
|
||||
// structFields returns the exported struct fields for a given s struct. This
|
||||
// is a convenient helper method to avoid duplicate code in some of the
|
||||
// functions.
|
||||
func (s *Struct) structFields() []reflect.StructField {
|
||||
t := s.value.Type()
|
||||
|
||||
var f []reflect.StructField
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
// we can't access the value of unexported fields
|
||||
if field.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// don't check if it's omitted
|
||||
if tag := field.Tag.Get(s.TagName); tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
f = append(f, field)
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func strctVal(s interface{}) reflect.Value {
|
||||
v := reflect.ValueOf(s)
|
||||
|
||||
// if pointer get the underlying element≤
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if v.Kind() != reflect.Struct {
|
||||
panic("not struct")
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Map converts the given struct to a map[string]interface{}. For more info
|
||||
// refer to Struct types Map() method. It panics if s's kind is not struct.
|
||||
func Map(s interface{}) map[string]interface{} {
|
||||
return New(s).Map()
|
||||
}
|
||||
|
||||
// Values converts the given struct to a []interface{}. For more info refer to
|
||||
// Struct types Values() method. It panics if s's kind is not struct.
|
||||
func Values(s interface{}) []interface{} {
|
||||
return New(s).Values()
|
||||
}
|
||||
|
||||
// Fields returns a slice of *Field. For more info refer to Struct types
|
||||
// Fields() method. It panics if s's kind is not struct.
|
||||
func Fields(s interface{}) []*Field {
|
||||
return New(s).Fields()
|
||||
}
|
||||
|
||||
// Names returns a slice of field names. For more info refer to Struct types
|
||||
// Names() method. It panics if s's kind is not struct.
|
||||
func Names(s interface{}) []string {
|
||||
return New(s).Names()
|
||||
}
|
||||
|
||||
// IsZero returns true if all fields is equal to a zero value. For more info
|
||||
// refer to Struct types IsZero() method. It panics if s's kind is not struct.
|
||||
func IsZero(s interface{}) bool {
|
||||
return New(s).IsZero()
|
||||
}
|
||||
|
||||
// HasZero returns true if any field is equal to a zero value. For more info
|
||||
// refer to Struct types HasZero() method. It panics if s's kind is not struct.
|
||||
func HasZero(s interface{}) bool {
|
||||
return New(s).HasZero()
|
||||
}
|
||||
|
||||
// IsStruct returns true if the given variable is a struct or a pointer to
|
||||
// struct.
|
||||
func IsStruct(s interface{}) bool {
|
||||
v := reflect.ValueOf(s)
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
// uninitialized zero value of a struct
|
||||
if v.Kind() == reflect.Invalid {
|
||||
return false
|
||||
}
|
||||
|
||||
return v.Kind() == reflect.Struct
|
||||
}
|
||||
|
||||
// Name returns the structs's type name within its package. It returns an
|
||||
// empty string for unnamed types. It panics if s's kind is not struct.
|
||||
func Name(s interface{}) string {
|
||||
return New(s).Name()
|
||||
}
|
32
vendor/github.com/fatih/structs/tags.go
generated
vendored
Normal file
32
vendor/github.com/fatih/structs/tags.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
package structs
|
||||
|
||||
import "strings"
|
||||
|
||||
// tagOptions contains a slice of tag options
|
||||
type tagOptions []string
|
||||
|
||||
// Has returns true if the given optiton is available in tagOptions
|
||||
func (t tagOptions) Has(opt string) bool {
|
||||
for _, tagOpt := range t {
|
||||
if tagOpt == opt {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// parseTag splits a struct field's tag into its name and a list of options
|
||||
// which comes after a name. A tag is in the form of: "name,option1,option2".
|
||||
// The name can be neglectected.
|
||||
func parseTag(tag string) (string, tagOptions) {
|
||||
// tag is one of followings:
|
||||
// ""
|
||||
// "name"
|
||||
// "name,opt"
|
||||
// "name,opt,opt2"
|
||||
// ",opt"
|
||||
|
||||
res := strings.Split(tag, ",")
|
||||
return res[0], res[1:]
|
||||
}
|
363
vendor/github.com/hashicorp/go-cleanhttp/LICENSE
generated
vendored
Normal file
363
vendor/github.com/hashicorp/go-cleanhttp/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
30
vendor/github.com/hashicorp/go-cleanhttp/README.md
generated
vendored
Normal file
30
vendor/github.com/hashicorp/go-cleanhttp/README.md
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# cleanhttp
|
||||
|
||||
Functions for accessing "clean" Go http.Client values
|
||||
|
||||
-------------
|
||||
|
||||
The Go standard library contains a default `http.Client` called
|
||||
`http.DefaultClient`. It is a common idiom in Go code to start with
|
||||
`http.DefaultClient` and tweak it as necessary, and in fact, this is
|
||||
encouraged; from the `http` package documentation:
|
||||
|
||||
> The Client's Transport typically has internal state (cached TCP connections),
|
||||
so Clients should be reused instead of created as needed. Clients are safe for
|
||||
concurrent use by multiple goroutines.
|
||||
|
||||
Unfortunately, this is a shared value, and it is not uncommon for libraries to
|
||||
assume that they are free to modify it at will. With enough dependencies, it
|
||||
can be very easy to encounter strange problems and race conditions due to
|
||||
manipulation of this shared value across libraries and goroutines (clients are
|
||||
safe for concurrent use, but writing values to the client struct itself is not
|
||||
protected).
|
||||
|
||||
Making things worse is the fact that a bare `http.Client` will use a default
|
||||
`http.Transport` called `http.DefaultTransport`, which is another global value
|
||||
that behaves the same way. So it is not simply enough to replace
|
||||
`http.DefaultClient` with `&http.Client{}`.
|
||||
|
||||
This repository provides some simple functions to get a "clean" `http.Client`
|
||||
-- one that uses the same default values as the Go standard library, but
|
||||
returns a client that does not share any state with other clients.
|
28
vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
generated
vendored
Normal file
28
vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
package cleanhttp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultTransport returns a new http.Transport with the same default values
|
||||
// as http.DefaultTransport
|
||||
func DefaultTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultClient returns a new http.Client with the same default values as
|
||||
// http.Client, but with a non-shared Transport
|
||||
func DefaultClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: DefaultTransport(),
|
||||
}
|
||||
}
|
1
vendor/github.com/hashicorp/hcl/.gitignore
generated
vendored
Normal file
1
vendor/github.com/hashicorp/hcl/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
y.output
|
3
vendor/github.com/hashicorp/hcl/.travis.yml
generated
vendored
Normal file
3
vendor/github.com/hashicorp/hcl/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
sudo: false
|
||||
language: go
|
||||
go: 1.5
|
354
vendor/github.com/hashicorp/hcl/LICENSE
generated
vendored
Normal file
354
vendor/github.com/hashicorp/hcl/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,354 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. “Contributor”
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. “Contributor Version”
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor’s Contribution.
|
||||
|
||||
1.3. “Contribution”
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. “Covered Software”
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. “Incompatible With Secondary Licenses”
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of version
|
||||
1.1 or earlier of the License, but not also under the terms of a
|
||||
Secondary License.
|
||||
|
||||
1.6. “Executable Form”
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. “Larger Work”
|
||||
|
||||
means a work that combines Covered Software with other material, in a separate
|
||||
file or files, that is not Covered Software.
|
||||
|
||||
1.8. “License”
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. “Licensable”
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether at the
|
||||
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||
this License.
|
||||
|
||||
1.10. “Modifications”
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to, deletion
|
||||
from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. “Patent Claims” of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by such Contributor that
|
||||
would be infringed, but for the grant of the License, by the making,
|
||||
using, selling, offering for sale, having made, import, or transfer of
|
||||
either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. “Secondary License”
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. “Source Code Form”
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. “You” (or “Your”)
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, “You” includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, “control” means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or as
|
||||
part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its Contributions
|
||||
or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||
effective for each Contribution on the date the Contributor first distributes
|
||||
such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under this
|
||||
License. No additional rights or licenses will be implied from the distribution
|
||||
or licensing of Covered Software under this License. Notwithstanding Section
|
||||
2.1(b) above, no patent license is granted by a Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party’s
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||
Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks, or
|
||||
logos of any Contributor (except as may be necessary to comply with the
|
||||
notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this License
|
||||
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||
under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its Contributions
|
||||
are its original creation(s) or it has sufficient rights to grant the
|
||||
rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under applicable
|
||||
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under the
|
||||
terms of this License. You must inform recipients that the Source Code Form
|
||||
of the Covered Software is governed by the terms of this License, and how
|
||||
they can obtain a copy of this License. You may not attempt to alter or
|
||||
restrict the recipients’ rights in the Source Code Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this License,
|
||||
or sublicense it under different terms, provided that the license for
|
||||
the Executable Form does not attempt to limit or alter the recipients’
|
||||
rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for the
|
||||
Covered Software. If the Larger Work is a combination of Covered Software
|
||||
with a work governed by one or more Secondary Licenses, and the Covered
|
||||
Software is not Incompatible With Secondary Licenses, this License permits
|
||||
You to additionally distribute such Covered Software under the terms of
|
||||
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||
their option, further distribute the Covered Software under the terms of
|
||||
either this License or such Secondary License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices (including
|
||||
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||
of liability) contained within the Source Code Form of the Covered
|
||||
Software, except that You may alter any license notices to the extent
|
||||
required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||
of any Contributor. You must make it absolutely clear that any such
|
||||
warranty, support, indemnity, or liability obligation is offered by You
|
||||
alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute, judicial
|
||||
order, or regulation then You must: (a) comply with the terms of this License
|
||||
to the maximum extent possible; and (b) describe the limitations and the code
|
||||
they affect. Such description must be placed in a text file included with all
|
||||
distributions of the Covered Software under this License. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||
if such Contributor fails to notify You of the non-compliance by some
|
||||
reasonable means prior to 60 days after You have come back into compliance.
|
||||
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||
some reasonable means, this is the first time You have received notice of
|
||||
non-compliance with this License from such Contributor, and You become
|
||||
compliant prior to 30 days after Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||
and cross-claims) alleging that a Contributor Version directly or
|
||||
indirectly infringes any patent, then the rights granted to You by any and
|
||||
all Contributors for the Covered Software under Section 2.1 of this License
|
||||
shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an “as is” basis, without
|
||||
warranty of any kind, either expressed, implied, or statutory, including,
|
||||
without limitation, warranties that the Covered Software is free of defects,
|
||||
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||
risk as to the quality and performance of the Covered Software is with You.
|
||||
Should any Covered Software prove defective in any respect, You (not any
|
||||
Contributor) assume the cost of any necessary servicing, repair, or
|
||||
correction. This disclaimer of warranty constitutes an essential part of this
|
||||
License. No use of any Covered Software is authorized under this License
|
||||
except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from such
|
||||
party’s negligence to the extent applicable law prohibits such limitation.
|
||||
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||
consequential damages, so this exclusion and limitation may not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts of
|
||||
a jurisdiction where the defendant maintains its principal place of business
|
||||
and such litigation shall be governed by laws of that jurisdiction, without
|
||||
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject matter
|
||||
hereof. If any provision of this License is held to be unenforceable, such
|
||||
provision shall be reformed only to the extent necessary to make it
|
||||
enforceable. Any law or regulation which provides that the language of a
|
||||
contract shall be construed against the drafter shall not be used to construe
|
||||
this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version of
|
||||
the License under which You originally received the Covered Software, or
|
||||
under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a modified
|
||||
version of this License if you rename the license and remove any
|
||||
references to the name of the license steward (except to note that such
|
||||
modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||
directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||
|
||||
This Source Code Form is “Incompatible
|
||||
With Secondary Licenses”, as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
17
vendor/github.com/hashicorp/hcl/Makefile
generated
vendored
Normal file
17
vendor/github.com/hashicorp/hcl/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
TEST?=./...
|
||||
|
||||
default: test
|
||||
|
||||
fmt: generate
|
||||
go fmt ./...
|
||||
|
||||
test: generate
|
||||
go test $(TEST) $(TESTARGS)
|
||||
|
||||
generate:
|
||||
go generate ./...
|
||||
|
||||
updatedeps:
|
||||
go get -u golang.org/x/tools/cmd/stringer
|
||||
|
||||
.PHONY: default generate test updatedeps
|
94
vendor/github.com/hashicorp/hcl/README.md
generated
vendored
Normal file
94
vendor/github.com/hashicorp/hcl/README.md
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
# HCL
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/hashicorp/hcl?status.png)](https://godoc.org/github.com/hashicorp/hcl) [![Build Status](https://travis-ci.org/hashicorp/hcl.svg?branch=master)](https://travis-ci.org/hashicorp/hcl)
|
||||
|
||||
HCL (HashiCorp Configuration Language) is a configuration language built
|
||||
by HashiCorp. The goal of HCL is to build a structured configuration language
|
||||
that is both human and machine friendly for use with command-line tools, but
|
||||
specifically targeted towards DevOps tools, servers, etc.
|
||||
|
||||
HCL is also fully JSON compatible. That is, JSON can be used as completely
|
||||
valid input to a system expecting HCL. This helps makes systems
|
||||
interoperable with other systems.
|
||||
|
||||
HCL is heavily inspired by
|
||||
[libucl](https://github.com/vstakhov/libucl),
|
||||
nginx configuration, and others similar.
|
||||
|
||||
## Why?
|
||||
|
||||
A common question when viewing HCL is to ask the question: why not
|
||||
JSON, YAML, etc.?
|
||||
|
||||
Prior to HCL, the tools we built at [HashiCorp](http://www.hashicorp.com)
|
||||
used a variety of configuration languages from full programming languages
|
||||
such as Ruby to complete data structure languages such as JSON. What we
|
||||
learned is that some people wanted human-friendly configuration languages
|
||||
and some people wanted machine-friendly languages.
|
||||
|
||||
JSON fits a nice balance in this, but is fairly verbose and most
|
||||
importantly doesn't support comments. With YAML, we found that beginners
|
||||
had a really hard time determining what the actual structure was, and
|
||||
ended up guessing more than not whether to use a hyphen, colon, etc.
|
||||
in order to represent some configuration key.
|
||||
|
||||
Full programming languages such as Ruby enable complex behavior
|
||||
a configuration language shouldn't usually allow, and also forces
|
||||
people to learn some set of Ruby.
|
||||
|
||||
Because of this, we decided to create our own configuration language
|
||||
that is JSON-compatible. Our configuration language (HCL) is designed
|
||||
to be written and modified by humans. The API for HCL allows JSON
|
||||
as an input so that it is also machine-friendly (machines can generate
|
||||
JSON instead of trying to generate HCL).
|
||||
|
||||
Our goal with HCL is not to alienate other configuration languages.
|
||||
It is instead to provide HCL as a specialized language for our tools,
|
||||
and JSON as the interoperability layer.
|
||||
|
||||
## Syntax
|
||||
|
||||
For a complete grammar, please see the parser itself. A high-level overview
|
||||
of the syntax and grammer is listed here.
|
||||
|
||||
* Single line comments start with `#` or `//`
|
||||
|
||||
* Multi-line comments are wrapped in `/*` and `*/`. Nested block comments
|
||||
are not allowed. A multi-line comment (also known as a block comment)
|
||||
terminates at the first `*/` found.
|
||||
|
||||
* Values are assigned with the syntax `key = value` (whitespace doesn't
|
||||
matter). The value can be any primitive: a string, number, boolean,
|
||||
object, or list.
|
||||
|
||||
* Strings are double-quoted and can contain any UTF-8 characters.
|
||||
Example: `"Hello, World"`
|
||||
|
||||
* Numbers are assumed to be base 10. If you prefix a number with 0x,
|
||||
it is treated as a hexadecimal. If it is prefixed with 0, it is
|
||||
treated as an octal. Numbers can be in scientific notation: "1e10".
|
||||
|
||||
* Boolean values: `true`, `false`
|
||||
|
||||
* Arrays can be made by wrapping it in `[]`. Example:
|
||||
`["foo", "bar", 42]`. Arrays can contain primitives
|
||||
and other arrays, but cannot contain objects. Objects must
|
||||
use the block syntax shown below.
|
||||
|
||||
Objects and nested objects are created using the structure shown below:
|
||||
|
||||
```
|
||||
variable "ami" {
|
||||
description = "the AMI to use"
|
||||
}
|
||||
```
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to:
|
||||
|
||||
* [@vstakhov](https://github.com/vstakhov) - The original libucl parser
|
||||
and syntax that HCL was based off of.
|
||||
|
||||
* [@fatih](https://github.com/fatih) - The rewritten HCL parser
|
||||
in pure Go (no goyacc) and support for a printer.
|
576
vendor/github.com/hashicorp/hcl/decoder.go
generated
vendored
Normal file
576
vendor/github.com/hashicorp/hcl/decoder.go
generated
vendored
Normal file
|
@ -0,0 +1,576 @@
|
|||
package hcl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"github.com/hashicorp/hcl/hcl/token"
|
||||
)
|
||||
|
||||
// This is the tag to use with structures to have settings for HCL
|
||||
const tagName = "hcl"
|
||||
|
||||
// Decode reads the given input and decodes it into the structure
|
||||
// given by `out`.
|
||||
func Decode(out interface{}, in string) error {
|
||||
obj, err := Parse(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return DecodeObject(out, obj)
|
||||
}
|
||||
|
||||
// DecodeObject is a lower-level version of Decode. It decodes a
|
||||
// raw Object into the given output.
|
||||
func DecodeObject(out interface{}, n ast.Node) error {
|
||||
val := reflect.ValueOf(out)
|
||||
if val.Kind() != reflect.Ptr {
|
||||
return errors.New("result must be a pointer")
|
||||
}
|
||||
|
||||
// If we have the file, we really decode the root node
|
||||
if f, ok := n.(*ast.File); ok {
|
||||
n = f.Node
|
||||
}
|
||||
|
||||
var d decoder
|
||||
return d.decode("root", n, val.Elem())
|
||||
}
|
||||
|
||||
type decoder struct {
|
||||
stack []reflect.Kind
|
||||
}
|
||||
|
||||
func (d *decoder) decode(name string, node ast.Node, result reflect.Value) error {
|
||||
k := result
|
||||
|
||||
// If we have an interface with a valid value, we use that
|
||||
// for the check.
|
||||
if result.Kind() == reflect.Interface {
|
||||
elem := result.Elem()
|
||||
if elem.IsValid() {
|
||||
k = elem
|
||||
}
|
||||
}
|
||||
|
||||
// Push current onto stack unless it is an interface.
|
||||
if k.Kind() != reflect.Interface {
|
||||
d.stack = append(d.stack, k.Kind())
|
||||
|
||||
// Schedule a pop
|
||||
defer func() {
|
||||
d.stack = d.stack[:len(d.stack)-1]
|
||||
}()
|
||||
}
|
||||
|
||||
switch k.Kind() {
|
||||
case reflect.Bool:
|
||||
return d.decodeBool(name, node, result)
|
||||
case reflect.Float64:
|
||||
return d.decodeFloat(name, node, result)
|
||||
case reflect.Int:
|
||||
return d.decodeInt(name, node, result)
|
||||
case reflect.Interface:
|
||||
// When we see an interface, we make our own thing
|
||||
return d.decodeInterface(name, node, result)
|
||||
case reflect.Map:
|
||||
return d.decodeMap(name, node, result)
|
||||
case reflect.Ptr:
|
||||
return d.decodePtr(name, node, result)
|
||||
case reflect.Slice:
|
||||
return d.decodeSlice(name, node, result)
|
||||
case reflect.String:
|
||||
return d.decodeString(name, node, result)
|
||||
case reflect.Struct:
|
||||
return d.decodeStruct(name, node, result)
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"%s: unknown kind to decode into: %s", name, k.Kind())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) error {
|
||||
switch n := node.(type) {
|
||||
case *ast.LiteralType:
|
||||
if n.Token.Type == token.BOOL {
|
||||
v, err := strconv.ParseBool(n.Token.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.Set(reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s: unknown type %T", name, node)
|
||||
}
|
||||
|
||||
func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error {
|
||||
switch n := node.(type) {
|
||||
case *ast.LiteralType:
|
||||
if n.Token.Type == token.FLOAT {
|
||||
v, err := strconv.ParseFloat(n.Token.Text, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.Set(reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s: unknown type %T", name, node)
|
||||
}
|
||||
|
||||
func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) error {
|
||||
switch n := node.(type) {
|
||||
case *ast.LiteralType:
|
||||
switch n.Token.Type {
|
||||
case token.NUMBER:
|
||||
v, err := strconv.ParseInt(n.Token.Text, 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.Set(reflect.ValueOf(int(v)))
|
||||
return nil
|
||||
case token.STRING:
|
||||
v, err := strconv.ParseInt(n.Token.Value().(string), 0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.Set(reflect.ValueOf(int(v)))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s: unknown type %T", name, node)
|
||||
}
|
||||
|
||||
func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Value) error {
|
||||
var set reflect.Value
|
||||
redecode := true
|
||||
|
||||
// For testing types, ObjectType should just be treated as a list. We
|
||||
// set this to a temporary var because we want to pass in the real node.
|
||||
testNode := node
|
||||
if ot, ok := node.(*ast.ObjectType); ok {
|
||||
testNode = ot.List
|
||||
}
|
||||
|
||||
switch n := testNode.(type) {
|
||||
case *ast.ObjectList:
|
||||
// If we're at the root or we're directly within a slice, then we
|
||||
// decode objects into map[string]interface{}, otherwise we decode
|
||||
// them into lists.
|
||||
if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice {
|
||||
var temp map[string]interface{}
|
||||
tempVal := reflect.ValueOf(temp)
|
||||
result := reflect.MakeMap(
|
||||
reflect.MapOf(
|
||||
reflect.TypeOf(""),
|
||||
tempVal.Type().Elem()))
|
||||
|
||||
set = result
|
||||
} else {
|
||||
var temp []map[string]interface{}
|
||||
tempVal := reflect.ValueOf(temp)
|
||||
result := reflect.MakeSlice(
|
||||
reflect.SliceOf(tempVal.Type().Elem()), 0, len(n.Items))
|
||||
set = result
|
||||
}
|
||||
case *ast.ObjectType:
|
||||
// If we're at the root or we're directly within a slice, then we
|
||||
// decode objects into map[string]interface{}, otherwise we decode
|
||||
// them into lists.
|
||||
if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice {
|
||||
var temp map[string]interface{}
|
||||
tempVal := reflect.ValueOf(temp)
|
||||
result := reflect.MakeMap(
|
||||
reflect.MapOf(
|
||||
reflect.TypeOf(""),
|
||||
tempVal.Type().Elem()))
|
||||
|
||||
set = result
|
||||
} else {
|
||||
var temp []map[string]interface{}
|
||||
tempVal := reflect.ValueOf(temp)
|
||||
result := reflect.MakeSlice(
|
||||
reflect.SliceOf(tempVal.Type().Elem()), 0, 1)
|
||||
set = result
|
||||
}
|
||||
case *ast.ListType:
|
||||
var temp []interface{}
|
||||
tempVal := reflect.ValueOf(temp)
|
||||
result := reflect.MakeSlice(
|
||||
reflect.SliceOf(tempVal.Type().Elem()), 0, 0)
|
||||
set = result
|
||||
case *ast.LiteralType:
|
||||
switch n.Token.Type {
|
||||
case token.BOOL:
|
||||
var result bool
|
||||
set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
|
||||
case token.FLOAT:
|
||||
var result float64
|
||||
set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
|
||||
case token.NUMBER:
|
||||
var result int
|
||||
set = reflect.Indirect(reflect.New(reflect.TypeOf(result)))
|
||||
case token.STRING, token.HEREDOC:
|
||||
set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"%s: cannot decode into interface: %T",
|
||||
name, node)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"%s: cannot decode into interface: %T",
|
||||
name, node)
|
||||
}
|
||||
|
||||
// Set the result to what its supposed to be, then reset
|
||||
// result so we don't reflect into this method anymore.
|
||||
result.Set(set)
|
||||
|
||||
if redecode {
|
||||
// Revisit the node so that we can use the newly instantiated
|
||||
// thing and populate it.
|
||||
if err := d.decode(name, node, result); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) error {
|
||||
if item, ok := node.(*ast.ObjectItem); ok {
|
||||
node = &ast.ObjectList{Items: []*ast.ObjectItem{item}}
|
||||
}
|
||||
|
||||
if ot, ok := node.(*ast.ObjectType); ok {
|
||||
node = ot.List
|
||||
}
|
||||
|
||||
n, ok := node.(*ast.ObjectList)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s: not an object type for map (%T)", name, node)
|
||||
}
|
||||
|
||||
// If we have an interface, then we can address the interface,
|
||||
// but not the slice itself, so get the element but set the interface
|
||||
set := result
|
||||
if result.Kind() == reflect.Interface {
|
||||
result = result.Elem()
|
||||
}
|
||||
|
||||
resultType := result.Type()
|
||||
resultElemType := resultType.Elem()
|
||||
resultKeyType := resultType.Key()
|
||||
if resultKeyType.Kind() != reflect.String {
|
||||
return fmt.Errorf(
|
||||
"%s: map must have string keys", name)
|
||||
}
|
||||
|
||||
// Make a map if it is nil
|
||||
resultMap := result
|
||||
if result.IsNil() {
|
||||
resultMap = reflect.MakeMap(
|
||||
reflect.MapOf(resultKeyType, resultElemType))
|
||||
}
|
||||
|
||||
// Go through each element and decode it.
|
||||
done := make(map[string]struct{})
|
||||
for _, item := range n.Items {
|
||||
if item.Val == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get the key we're dealing with, which is the first item
|
||||
keyStr := item.Keys[0].Token.Value().(string)
|
||||
|
||||
// If we've already processed this key, then ignore it
|
||||
if _, ok := done[keyStr]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Determine the value. If we have more than one key, then we
|
||||
// get the objectlist of only these keys.
|
||||
itemVal := item.Val
|
||||
if len(item.Keys) > 1 {
|
||||
itemVal = n.Filter(keyStr)
|
||||
done[keyStr] = struct{}{}
|
||||
}
|
||||
|
||||
// Make the field name
|
||||
fieldName := fmt.Sprintf("%s.%s", name, keyStr)
|
||||
|
||||
// Get the key/value as reflection values
|
||||
key := reflect.ValueOf(keyStr)
|
||||
val := reflect.Indirect(reflect.New(resultElemType))
|
||||
|
||||
// If we have a pre-existing value in the map, use that
|
||||
oldVal := resultMap.MapIndex(key)
|
||||
if oldVal.IsValid() {
|
||||
val.Set(oldVal)
|
||||
}
|
||||
|
||||
// Decode!
|
||||
if err := d.decode(fieldName, itemVal, val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the value on the map
|
||||
resultMap.SetMapIndex(key, val)
|
||||
}
|
||||
|
||||
// Set the final map if we can
|
||||
set.Set(resultMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) decodePtr(name string, node ast.Node, result reflect.Value) error {
|
||||
// Create an element of the concrete (non pointer) type and decode
|
||||
// into that. Then set the value of the pointer to this type.
|
||||
resultType := result.Type()
|
||||
resultElemType := resultType.Elem()
|
||||
val := reflect.New(resultElemType)
|
||||
if err := d.decode(name, node, reflect.Indirect(val)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.Set(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) error {
|
||||
// If we have an interface, then we can address the interface,
|
||||
// but not the slice itself, so get the element but set the interface
|
||||
set := result
|
||||
if result.Kind() == reflect.Interface {
|
||||
result = result.Elem()
|
||||
}
|
||||
|
||||
// Create the slice if it isn't nil
|
||||
resultType := result.Type()
|
||||
resultElemType := resultType.Elem()
|
||||
if result.IsNil() {
|
||||
resultSliceType := reflect.SliceOf(resultElemType)
|
||||
result = reflect.MakeSlice(
|
||||
resultSliceType, 0, 0)
|
||||
}
|
||||
|
||||
// Figure out the items we'll be copying into the slice
|
||||
var items []ast.Node
|
||||
switch n := node.(type) {
|
||||
case *ast.ObjectList:
|
||||
items = make([]ast.Node, len(n.Items))
|
||||
for i, item := range n.Items {
|
||||
items[i] = item
|
||||
}
|
||||
case *ast.ObjectType:
|
||||
items = []ast.Node{n}
|
||||
case *ast.ListType:
|
||||
items = n.List
|
||||
default:
|
||||
return fmt.Errorf("unknown slice type: %T", node)
|
||||
}
|
||||
|
||||
for i, item := range items {
|
||||
fieldName := fmt.Sprintf("%s[%d]", name, i)
|
||||
|
||||
// Decode
|
||||
val := reflect.Indirect(reflect.New(resultElemType))
|
||||
if err := d.decode(fieldName, item, val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Append it onto the slice
|
||||
result = reflect.Append(result, val)
|
||||
}
|
||||
|
||||
set.Set(result)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value) error {
|
||||
switch n := node.(type) {
|
||||
case *ast.LiteralType:
|
||||
switch n.Token.Type {
|
||||
case token.NUMBER:
|
||||
result.Set(reflect.ValueOf(n.Token.Text).Convert(result.Type()))
|
||||
return nil
|
||||
case token.STRING, token.HEREDOC:
|
||||
result.Set(reflect.ValueOf(n.Token.Value()).Convert(result.Type()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s: unknown type for string %T", name, node)
|
||||
}
|
||||
|
||||
func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) error {
|
||||
var item *ast.ObjectItem
|
||||
if it, ok := node.(*ast.ObjectItem); ok {
|
||||
item = it
|
||||
node = it.Val
|
||||
}
|
||||
|
||||
if ot, ok := node.(*ast.ObjectType); ok {
|
||||
node = ot.List
|
||||
}
|
||||
|
||||
list, ok := node.(*ast.ObjectList)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s: not an object type for struct (%T)", name, node)
|
||||
}
|
||||
|
||||
// This slice will keep track of all the structs we'll be decoding.
|
||||
// There can be more than one struct if there are embedded structs
|
||||
// that are squashed.
|
||||
structs := make([]reflect.Value, 1, 5)
|
||||
structs[0] = result
|
||||
|
||||
// Compile the list of all the fields that we're going to be decoding
|
||||
// from all the structs.
|
||||
fields := make(map[*reflect.StructField]reflect.Value)
|
||||
for len(structs) > 0 {
|
||||
structVal := structs[0]
|
||||
structs = structs[1:]
|
||||
|
||||
structType := structVal.Type()
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
fieldType := structType.Field(i)
|
||||
|
||||
if fieldType.Anonymous {
|
||||
fieldKind := fieldType.Type.Kind()
|
||||
if fieldKind != reflect.Struct {
|
||||
return fmt.Errorf(
|
||||
"%s: unsupported type to struct: %s",
|
||||
fieldType.Name, fieldKind)
|
||||
}
|
||||
|
||||
// We have an embedded field. We "squash" the fields down
|
||||
// if specified in the tag.
|
||||
squash := false
|
||||
tagParts := strings.Split(fieldType.Tag.Get(tagName), ",")
|
||||
for _, tag := range tagParts[1:] {
|
||||
if tag == "squash" {
|
||||
squash = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if squash {
|
||||
structs = append(
|
||||
structs, result.FieldByName(fieldType.Name))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Normal struct field, store it away
|
||||
fields[&fieldType] = structVal.Field(i)
|
||||
}
|
||||
}
|
||||
|
||||
usedKeys := make(map[string]struct{})
|
||||
decodedFields := make([]string, 0, len(fields))
|
||||
decodedFieldsVal := make([]reflect.Value, 0)
|
||||
unusedKeysVal := make([]reflect.Value, 0)
|
||||
for fieldType, field := range fields {
|
||||
if !field.IsValid() {
|
||||
// This should never happen
|
||||
panic("field is not valid")
|
||||
}
|
||||
|
||||
// If we can't set the field, then it is unexported or something,
|
||||
// and we just continue onwards.
|
||||
if !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldName := fieldType.Name
|
||||
|
||||
tagValue := fieldType.Tag.Get(tagName)
|
||||
tagParts := strings.SplitN(tagValue, ",", 2)
|
||||
if len(tagParts) >= 2 {
|
||||
switch tagParts[1] {
|
||||
case "decodedFields":
|
||||
decodedFieldsVal = append(decodedFieldsVal, field)
|
||||
continue
|
||||
case "key":
|
||||
if item == nil {
|
||||
return fmt.Errorf(
|
||||
"%s: %s asked for 'key', impossible",
|
||||
name, fieldName)
|
||||
}
|
||||
|
||||
field.SetString(item.Keys[0].Token.Value().(string))
|
||||
continue
|
||||
case "unusedKeys":
|
||||
unusedKeysVal = append(unusedKeysVal, field)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if tagParts[0] != "" {
|
||||
fieldName = tagParts[0]
|
||||
}
|
||||
|
||||
// Determine the element we'll use to decode. If it is a single
|
||||
// match (only object with the field), then we decode it exactly.
|
||||
// If it is a prefix match, then we decode the matches.
|
||||
filter := list.Filter(fieldName)
|
||||
prefixMatches := filter.Children()
|
||||
matches := filter.Elem()
|
||||
if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Track the used key
|
||||
usedKeys[fieldName] = struct{}{}
|
||||
|
||||
// Create the field name and decode. We range over the elements
|
||||
// because we actually want the value.
|
||||
fieldName = fmt.Sprintf("%s.%s", name, fieldName)
|
||||
if len(prefixMatches.Items) > 0 {
|
||||
if err := d.decode(fieldName, prefixMatches, field); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, match := range matches.Items {
|
||||
var decodeNode ast.Node = match.Val
|
||||
if ot, ok := decodeNode.(*ast.ObjectType); ok {
|
||||
decodeNode = &ast.ObjectList{Items: ot.List.Items}
|
||||
}
|
||||
|
||||
if err := d.decode(fieldName, decodeNode, field); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
decodedFields = append(decodedFields, fieldType.Name)
|
||||
}
|
||||
|
||||
if len(decodedFieldsVal) > 0 {
|
||||
// Sort it so that it is deterministic
|
||||
sort.Strings(decodedFields)
|
||||
|
||||
for _, v := range decodedFieldsVal {
|
||||
v.Set(reflect.ValueOf(decodedFields))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
11
vendor/github.com/hashicorp/hcl/hcl.go
generated
vendored
Normal file
11
vendor/github.com/hashicorp/hcl/hcl.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Package hcl decodes HCL into usable Go structures.
|
||||
//
|
||||
// hcl input can come in either pure HCL format or JSON format.
|
||||
// It can be parsed into an AST, and then decoded into a structure,
|
||||
// or it can be decoded directly from a string into a structure.
|
||||
//
|
||||
// If you choose to parse HCL into a raw AST, the benefit is that you
|
||||
// can write custom visitor implementations to implement custom
|
||||
// semantic checks. By default, HCL does not perform any semantic
|
||||
// checks.
|
||||
package hcl
|
204
vendor/github.com/hashicorp/hcl/hcl/ast/ast.go
generated
vendored
Normal file
204
vendor/github.com/hashicorp/hcl/hcl/ast/ast.go
generated
vendored
Normal file
|
@ -0,0 +1,204 @@
|
|||
// Package ast declares the types used to represent syntax trees for HCL
|
||||
// (HashiCorp Configuration Language)
|
||||
package ast
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/token"
|
||||
)
|
||||
|
||||
// Node is an element in the abstract syntax tree.
|
||||
type Node interface {
|
||||
node()
|
||||
Pos() token.Pos
|
||||
}
|
||||
|
||||
func (File) node() {}
|
||||
func (ObjectList) node() {}
|
||||
func (ObjectKey) node() {}
|
||||
func (ObjectItem) node() {}
|
||||
func (Comment) node() {}
|
||||
func (CommentGroup) node() {}
|
||||
func (ObjectType) node() {}
|
||||
func (LiteralType) node() {}
|
||||
func (ListType) node() {}
|
||||
|
||||
// File represents a single HCL file
|
||||
type File struct {
|
||||
Node Node // usually a *ObjectList
|
||||
Comments []*CommentGroup // list of all comments in the source
|
||||
}
|
||||
|
||||
func (f *File) Pos() token.Pos {
|
||||
return f.Node.Pos()
|
||||
}
|
||||
|
||||
// ObjectList represents a list of ObjectItems. An HCL file itself is an
|
||||
// ObjectList.
|
||||
type ObjectList struct {
|
||||
Items []*ObjectItem
|
||||
}
|
||||
|
||||
func (o *ObjectList) Add(item *ObjectItem) {
|
||||
o.Items = append(o.Items, item)
|
||||
}
|
||||
|
||||
// Filter filters out the objects with the given key list as a prefix.
|
||||
//
|
||||
// The returned list of objects contain ObjectItems where the keys have
|
||||
// this prefix already stripped off. This might result in objects with
|
||||
// zero-length key lists if they have no children.
|
||||
//
|
||||
// If no matches are found, an empty ObjectList (non-nil) is returned.
|
||||
func (o *ObjectList) Filter(keys ...string) *ObjectList {
|
||||
var result ObjectList
|
||||
for _, item := range o.Items {
|
||||
// If there aren't enough keys, then ignore this
|
||||
if len(item.Keys) < len(keys) {
|
||||
continue
|
||||
}
|
||||
|
||||
match := true
|
||||
for i, key := range item.Keys[:len(keys)] {
|
||||
key := key.Token.Value().(string)
|
||||
if key != keys[i] && !strings.EqualFold(key, keys[i]) {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
continue
|
||||
}
|
||||
|
||||
// Strip off the prefix from the children
|
||||
newItem := *item
|
||||
newItem.Keys = newItem.Keys[len(keys):]
|
||||
result.Add(&newItem)
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
// Children returns further nested objects (key length > 0) within this
|
||||
// ObjectList. This should be used with Filter to get at child items.
|
||||
func (o *ObjectList) Children() *ObjectList {
|
||||
var result ObjectList
|
||||
for _, item := range o.Items {
|
||||
if len(item.Keys) > 0 {
|
||||
result.Add(item)
|
||||
}
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
// Elem returns items in the list that are direct element assignments
|
||||
// (key length == 0). This should be used with Filter to get at elements.
|
||||
func (o *ObjectList) Elem() *ObjectList {
|
||||
var result ObjectList
|
||||
for _, item := range o.Items {
|
||||
if len(item.Keys) == 0 {
|
||||
result.Add(item)
|
||||
}
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
func (o *ObjectList) Pos() token.Pos {
|
||||
// always returns the uninitiliazed position
|
||||
return o.Items[0].Pos()
|
||||
}
|
||||
|
||||
// ObjectItem represents a HCL Object Item. An item is represented with a key
|
||||
// (or keys). It can be an assignment or an object (both normal and nested)
|
||||
type ObjectItem struct {
|
||||
// keys is only one length long if it's of type assignment. If it's a
|
||||
// nested object it can be larger than one. In that case "assign" is
|
||||
// invalid as there is no assignments for a nested object.
|
||||
Keys []*ObjectKey
|
||||
|
||||
// assign contains the position of "=", if any
|
||||
Assign token.Pos
|
||||
|
||||
// val is the item itself. It can be an object,list, number, bool or a
|
||||
// string. If key length is larger than one, val can be only of type
|
||||
// Object.
|
||||
Val Node
|
||||
|
||||
LeadComment *CommentGroup // associated lead comment
|
||||
LineComment *CommentGroup // associated line comment
|
||||
}
|
||||
|
||||
func (o *ObjectItem) Pos() token.Pos {
|
||||
return o.Keys[0].Pos()
|
||||
}
|
||||
|
||||
// ObjectKeys are either an identifier or of type string.
|
||||
type ObjectKey struct {
|
||||
Token token.Token
|
||||
}
|
||||
|
||||
func (o *ObjectKey) Pos() token.Pos {
|
||||
return o.Token.Pos
|
||||
}
|
||||
|
||||
// LiteralType represents a literal of basic type. Valid types are:
|
||||
// token.NUMBER, token.FLOAT, token.BOOL and token.STRING
|
||||
type LiteralType struct {
|
||||
Token token.Token
|
||||
|
||||
// associated line comment, only when used in a list
|
||||
LineComment *CommentGroup
|
||||
}
|
||||
|
||||
func (l *LiteralType) Pos() token.Pos {
|
||||
return l.Token.Pos
|
||||
}
|
||||
|
||||
// ListStatement represents a HCL List type
|
||||
type ListType struct {
|
||||
Lbrack token.Pos // position of "["
|
||||
Rbrack token.Pos // position of "]"
|
||||
List []Node // the elements in lexical order
|
||||
}
|
||||
|
||||
func (l *ListType) Pos() token.Pos {
|
||||
return l.Lbrack
|
||||
}
|
||||
|
||||
func (l *ListType) Add(node Node) {
|
||||
l.List = append(l.List, node)
|
||||
}
|
||||
|
||||
// ObjectType represents a HCL Object Type
|
||||
type ObjectType struct {
|
||||
Lbrace token.Pos // position of "{"
|
||||
Rbrace token.Pos // position of "}"
|
||||
List *ObjectList // the nodes in lexical order
|
||||
}
|
||||
|
||||
func (o *ObjectType) Pos() token.Pos {
|
||||
return o.Lbrace
|
||||
}
|
||||
|
||||
// Comment node represents a single //, # style or /*- style commment
|
||||
type Comment struct {
|
||||
Start token.Pos // position of / or #
|
||||
Text string
|
||||
}
|
||||
|
||||
func (c *Comment) Pos() token.Pos {
|
||||
return c.Start
|
||||
}
|
||||
|
||||
// CommentGroup node represents a sequence of comments with no other tokens and
|
||||
// no empty lines between.
|
||||
type CommentGroup struct {
|
||||
List []*Comment // len(List) > 0
|
||||
}
|
||||
|
||||
func (c *CommentGroup) Pos() token.Pos {
|
||||
return c.List[0].Pos()
|
||||
}
|
52
vendor/github.com/hashicorp/hcl/hcl/ast/walk.go
generated
vendored
Normal file
52
vendor/github.com/hashicorp/hcl/hcl/ast/walk.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
package ast
|
||||
|
||||
import "fmt"
|
||||
|
||||
// WalkFunc describes a function to be called for each node during a Walk. The
|
||||
// returned node can be used to rewrite the AST. Walking stops the returned
|
||||
// bool is false.
|
||||
type WalkFunc func(Node) (Node, bool)
|
||||
|
||||
// Walk traverses an AST in depth-first order: It starts by calling fn(node);
|
||||
// node must not be nil. If fn returns true, Walk invokes fn recursively for
|
||||
// each of the non-nil children of node, followed by a call of fn(nil). The
|
||||
// returned node of fn can be used to rewrite the passed node to fn.
|
||||
func Walk(node Node, fn WalkFunc) Node {
|
||||
rewritten, ok := fn(node)
|
||||
if !ok {
|
||||
return rewritten
|
||||
}
|
||||
|
||||
switch n := node.(type) {
|
||||
case *File:
|
||||
n.Node = Walk(n.Node, fn)
|
||||
case *ObjectList:
|
||||
for i, item := range n.Items {
|
||||
n.Items[i] = Walk(item, fn).(*ObjectItem)
|
||||
}
|
||||
case *ObjectKey:
|
||||
// nothing to do
|
||||
case *ObjectItem:
|
||||
for i, k := range n.Keys {
|
||||
n.Keys[i] = Walk(k, fn).(*ObjectKey)
|
||||
}
|
||||
|
||||
if n.Val != nil {
|
||||
n.Val = Walk(n.Val, fn)
|
||||
}
|
||||
case *LiteralType:
|
||||
// nothing to do
|
||||
case *ListType:
|
||||
for i, l := range n.List {
|
||||
n.List[i] = Walk(l, fn)
|
||||
}
|
||||
case *ObjectType:
|
||||
n.List = Walk(n.List, fn).(*ObjectList)
|
||||
default:
|
||||
// should we panic here?
|
||||
fmt.Printf("unknown type: %T\n", n)
|
||||
}
|
||||
|
||||
fn(nil)
|
||||
return rewritten
|
||||
}
|
17
vendor/github.com/hashicorp/hcl/hcl/parser/error.go
generated
vendored
Normal file
17
vendor/github.com/hashicorp/hcl/hcl/parser/error.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/token"
|
||||
)
|
||||
|
||||
// PosError is a parse error that contains a position.
|
||||
type PosError struct {
|
||||
Pos token.Pos
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *PosError) Error() string {
|
||||
return fmt.Sprintf("At %s: %s", e.Pos, e.Err)
|
||||
}
|
417
vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
generated
vendored
Normal file
417
vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,417 @@
|
|||
// Package parser implements a parser for HCL (HashiCorp Configuration
|
||||
// Language)
|
||||
package parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"github.com/hashicorp/hcl/hcl/scanner"
|
||||
"github.com/hashicorp/hcl/hcl/token"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
sc *scanner.Scanner
|
||||
|
||||
// Last read token
|
||||
tok token.Token
|
||||
commaPrev token.Token
|
||||
|
||||
comments []*ast.CommentGroup
|
||||
leadComment *ast.CommentGroup // last lead comment
|
||||
lineComment *ast.CommentGroup // last line comment
|
||||
|
||||
enableTrace bool
|
||||
indent int
|
||||
n int // buffer size (max = 1)
|
||||
}
|
||||
|
||||
func newParser(src []byte) *Parser {
|
||||
return &Parser{
|
||||
sc: scanner.New(src),
|
||||
}
|
||||
}
|
||||
|
||||
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
||||
func Parse(src []byte) (*ast.File, error) {
|
||||
p := newParser(src)
|
||||
return p.Parse()
|
||||
}
|
||||
|
||||
var errEofToken = errors.New("EOF token found")
|
||||
|
||||
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
||||
func (p *Parser) Parse() (*ast.File, error) {
|
||||
f := &ast.File{}
|
||||
var err, scerr error
|
||||
p.sc.Error = func(pos token.Pos, msg string) {
|
||||
scerr = &PosError{Pos: pos, Err: errors.New(msg)}
|
||||
}
|
||||
|
||||
f.Node, err = p.objectList()
|
||||
if scerr != nil {
|
||||
return nil, scerr
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f.Comments = p.comments
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *Parser) objectList() (*ast.ObjectList, error) {
|
||||
defer un(trace(p, "ParseObjectList"))
|
||||
node := &ast.ObjectList{}
|
||||
|
||||
for {
|
||||
n, err := p.objectItem()
|
||||
if err == errEofToken {
|
||||
break // we are finished
|
||||
}
|
||||
|
||||
// we don't return a nil node, because might want to use already
|
||||
// collected items.
|
||||
if err != nil {
|
||||
return node, err
|
||||
}
|
||||
|
||||
node.Add(n)
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func (p *Parser) consumeComment() (comment *ast.Comment, endline int) {
|
||||
endline = p.tok.Pos.Line
|
||||
|
||||
// count the endline if it's multiline comment, ie starting with /*
|
||||
if len(p.tok.Text) > 1 && p.tok.Text[1] == '*' {
|
||||
// don't use range here - no need to decode Unicode code points
|
||||
for i := 0; i < len(p.tok.Text); i++ {
|
||||
if p.tok.Text[i] == '\n' {
|
||||
endline++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
comment = &ast.Comment{Start: p.tok.Pos, Text: p.tok.Text}
|
||||
p.tok = p.sc.Scan()
|
||||
return
|
||||
}
|
||||
|
||||
func (p *Parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
|
||||
var list []*ast.Comment
|
||||
endline = p.tok.Pos.Line
|
||||
|
||||
for p.tok.Type == token.COMMENT && p.tok.Pos.Line <= endline+n {
|
||||
var comment *ast.Comment
|
||||
comment, endline = p.consumeComment()
|
||||
list = append(list, comment)
|
||||
}
|
||||
|
||||
// add comment group to the comments list
|
||||
comments = &ast.CommentGroup{List: list}
|
||||
p.comments = append(p.comments, comments)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// objectItem parses a single object item
|
||||
func (p *Parser) objectItem() (*ast.ObjectItem, error) {
|
||||
defer un(trace(p, "ParseObjectItem"))
|
||||
|
||||
keys, err := p.objectKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o := &ast.ObjectItem{
|
||||
Keys: keys,
|
||||
}
|
||||
|
||||
if p.leadComment != nil {
|
||||
o.LeadComment = p.leadComment
|
||||
p.leadComment = nil
|
||||
}
|
||||
|
||||
switch p.tok.Type {
|
||||
case token.ASSIGN:
|
||||
o.Assign = p.tok.Pos
|
||||
o.Val, err = p.object()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case token.LBRACE:
|
||||
o.Val, err = p.objectType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// do a look-ahead for line comment
|
||||
p.scan()
|
||||
if o.Val.Pos().Line == keys[0].Pos().Line && p.lineComment != nil {
|
||||
o.LineComment = p.lineComment
|
||||
p.lineComment = nil
|
||||
}
|
||||
p.unscan()
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// objectKey parses an object key and returns a ObjectKey AST
|
||||
func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
|
||||
keyCount := 0
|
||||
keys := make([]*ast.ObjectKey, 0)
|
||||
|
||||
for {
|
||||
tok := p.scan()
|
||||
switch tok.Type {
|
||||
case token.EOF:
|
||||
return nil, errEofToken
|
||||
case token.ASSIGN:
|
||||
// assignment or object only, but not nested objects. this is not
|
||||
// allowed: `foo bar = {}`
|
||||
if keyCount > 1 {
|
||||
return nil, &PosError{
|
||||
Pos: p.tok.Pos,
|
||||
Err: fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type),
|
||||
}
|
||||
}
|
||||
|
||||
if keyCount == 0 {
|
||||
return nil, &PosError{
|
||||
Pos: p.tok.Pos,
|
||||
Err: errors.New("no object keys found!"),
|
||||
}
|
||||
}
|
||||
|
||||
return keys, nil
|
||||
case token.LBRACE:
|
||||
// object
|
||||
return keys, nil
|
||||
case token.IDENT, token.STRING:
|
||||
keyCount++
|
||||
keys = append(keys, &ast.ObjectKey{Token: p.tok})
|
||||
case token.ILLEGAL:
|
||||
fmt.Println("illegal")
|
||||
default:
|
||||
return nil, &PosError{
|
||||
Pos: p.tok.Pos,
|
||||
Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// object parses any type of object, such as number, bool, string, object or
|
||||
// list.
|
||||
func (p *Parser) object() (ast.Node, error) {
|
||||
defer un(trace(p, "ParseType"))
|
||||
tok := p.scan()
|
||||
|
||||
switch tok.Type {
|
||||
case token.NUMBER, token.FLOAT, token.BOOL, token.STRING, token.HEREDOC:
|
||||
return p.literalType()
|
||||
case token.LBRACE:
|
||||
return p.objectType()
|
||||
case token.LBRACK:
|
||||
return p.listType()
|
||||
case token.COMMENT:
|
||||
// implement comment
|
||||
case token.EOF:
|
||||
return nil, errEofToken
|
||||
}
|
||||
|
||||
return nil, &PosError{
|
||||
Pos: tok.Pos,
|
||||
Err: fmt.Errorf("Unknown token: %+v", tok),
|
||||
}
|
||||
}
|
||||
|
||||
// objectType parses an object type and returns a ObjectType AST
|
||||
func (p *Parser) objectType() (*ast.ObjectType, error) {
|
||||
defer un(trace(p, "ParseObjectType"))
|
||||
|
||||
// we assume that the currently scanned token is a LBRACE
|
||||
o := &ast.ObjectType{
|
||||
Lbrace: p.tok.Pos,
|
||||
}
|
||||
|
||||
l, err := p.objectList()
|
||||
|
||||
// if we hit RBRACE, we are good to go (means we parsed all Items), if it's
|
||||
// not a RBRACE, it's an syntax error and we just return it.
|
||||
if err != nil && p.tok.Type != token.RBRACE {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.List = l
|
||||
o.Rbrace = p.tok.Pos // advanced via parseObjectList
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// listType parses a list type and returns a ListType AST
|
||||
func (p *Parser) listType() (*ast.ListType, error) {
|
||||
defer un(trace(p, "ParseListType"))
|
||||
|
||||
// we assume that the currently scanned token is a LBRACK
|
||||
l := &ast.ListType{
|
||||
Lbrack: p.tok.Pos,
|
||||
}
|
||||
|
||||
needComma := false
|
||||
for {
|
||||
tok := p.scan()
|
||||
switch tok.Type {
|
||||
case token.NUMBER, token.FLOAT, token.STRING, token.HEREDOC:
|
||||
if needComma {
|
||||
return nil, &PosError{
|
||||
Pos: tok.Pos,
|
||||
Err: fmt.Errorf("unexpected token: %s. Expecting %s", tok.Type, token.COMMA),
|
||||
}
|
||||
}
|
||||
|
||||
node, err := p.literalType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.Add(node)
|
||||
needComma = true
|
||||
case token.COMMA:
|
||||
// get next list item or we are at the end
|
||||
// do a look-ahead for line comment
|
||||
p.scan()
|
||||
if p.lineComment != nil {
|
||||
lit, ok := l.List[len(l.List)-1].(*ast.LiteralType)
|
||||
if ok {
|
||||
lit.LineComment = p.lineComment
|
||||
l.List[len(l.List)-1] = lit
|
||||
p.lineComment = nil
|
||||
}
|
||||
}
|
||||
p.unscan()
|
||||
|
||||
needComma = false
|
||||
continue
|
||||
case token.BOOL:
|
||||
// TODO(arslan) should we support? not supported by HCL yet
|
||||
case token.LBRACK:
|
||||
// TODO(arslan) should we support nested lists? Even though it's
|
||||
// written in README of HCL, it's not a part of the grammar
|
||||
// (not defined in parse.y)
|
||||
case token.RBRACK:
|
||||
// finished
|
||||
l.Rbrack = p.tok.Pos
|
||||
return l, nil
|
||||
default:
|
||||
return nil, &PosError{
|
||||
Pos: tok.Pos,
|
||||
Err: fmt.Errorf("unexpected token while parsing list: %s", tok.Type),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// literalType parses a literal type and returns a LiteralType AST
|
||||
func (p *Parser) literalType() (*ast.LiteralType, error) {
|
||||
defer un(trace(p, "ParseLiteral"))
|
||||
|
||||
return &ast.LiteralType{
|
||||
Token: p.tok,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// scan returns the next token from the underlying scanner. If a token has
|
||||
// been unscanned then read that instead. In the process, it collects any
|
||||
// comment groups encountered, and remembers the last lead and line comments.
|
||||
func (p *Parser) scan() token.Token {
|
||||
// If we have a token on the buffer, then return it.
|
||||
if p.n != 0 {
|
||||
p.n = 0
|
||||
return p.tok
|
||||
}
|
||||
|
||||
// Otherwise read the next token from the scanner and Save it to the buffer
|
||||
// in case we unscan later.
|
||||
prev := p.tok
|
||||
p.tok = p.sc.Scan()
|
||||
|
||||
if p.tok.Type == token.COMMENT {
|
||||
var comment *ast.CommentGroup
|
||||
var endline int
|
||||
|
||||
// fmt.Printf("p.tok.Pos.Line = %+v prev: %d endline %d \n",
|
||||
// p.tok.Pos.Line, prev.Pos.Line, endline)
|
||||
if p.tok.Pos.Line == prev.Pos.Line {
|
||||
// The comment is on same line as the previous token; it
|
||||
// cannot be a lead comment but may be a line comment.
|
||||
comment, endline = p.consumeCommentGroup(0)
|
||||
if p.tok.Pos.Line != endline {
|
||||
// The next token is on a different line, thus
|
||||
// the last comment group is a line comment.
|
||||
p.lineComment = comment
|
||||
}
|
||||
}
|
||||
|
||||
// consume successor comments, if any
|
||||
endline = -1
|
||||
for p.tok.Type == token.COMMENT {
|
||||
comment, endline = p.consumeCommentGroup(1)
|
||||
}
|
||||
|
||||
if endline+1 == p.tok.Pos.Line && p.tok.Type != token.RBRACE {
|
||||
switch p.tok.Type {
|
||||
case token.RBRACE, token.RBRACK:
|
||||
// Do not count for these cases
|
||||
default:
|
||||
// The next token is following on the line immediately after the
|
||||
// comment group, thus the last comment group is a lead comment.
|
||||
p.leadComment = comment
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return p.tok
|
||||
}
|
||||
|
||||
// unscan pushes the previously read token back onto the buffer.
|
||||
func (p *Parser) unscan() {
|
||||
p.n = 1
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Parsing support
|
||||
|
||||
func (p *Parser) printTrace(a ...interface{}) {
|
||||
if !p.enableTrace {
|
||||
return
|
||||
}
|
||||
|
||||
const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
|
||||
const n = len(dots)
|
||||
fmt.Printf("%5d:%3d: ", p.tok.Pos.Line, p.tok.Pos.Column)
|
||||
|
||||
i := 2 * p.indent
|
||||
for i > n {
|
||||
fmt.Print(dots)
|
||||
i -= n
|
||||
}
|
||||
// i <= n
|
||||
fmt.Print(dots[0:i])
|
||||
fmt.Println(a...)
|
||||
}
|
||||
|
||||
func trace(p *Parser, msg string) *Parser {
|
||||
p.printTrace(msg, "(")
|
||||
p.indent++
|
||||
return p
|
||||
}
|
||||
|
||||
// Usage pattern: defer un(trace(p, "..."))
|
||||
func un(p *Parser) {
|
||||
p.indent--
|
||||
p.printTrace(")")
|
||||
}
|
612
vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go
generated
vendored
Normal file
612
vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go
generated
vendored
Normal file
|
@ -0,0 +1,612 @@
|
|||
// Package scanner implements a scanner for HCL (HashiCorp Configuration
|
||||
// Language) source text.
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/token"
|
||||
)
|
||||
|
||||
// eof represents a marker rune for the end of the reader.
|
||||
const eof = rune(0)
|
||||
|
||||
// Scanner defines a lexical scanner
|
||||
type Scanner struct {
|
||||
buf *bytes.Buffer // Source buffer for advancing and scanning
|
||||
src []byte // Source buffer for immutable access
|
||||
|
||||
// Source Position
|
||||
srcPos token.Pos // current position
|
||||
prevPos token.Pos // previous position, used for peek() method
|
||||
|
||||
lastCharLen int // length of last character in bytes
|
||||
lastLineLen int // length of last line in characters (for correct column reporting)
|
||||
|
||||
tokStart int // token text start position
|
||||
tokEnd int // token text end position
|
||||
|
||||
// Error is called for each error encountered. If no Error
|
||||
// function is set, the error is reported to os.Stderr.
|
||||
Error func(pos token.Pos, msg string)
|
||||
|
||||
// ErrorCount is incremented by one for each error encountered.
|
||||
ErrorCount int
|
||||
|
||||
// tokPos is the start position of most recently scanned token; set by
|
||||
// Scan. The Filename field is always left untouched by the Scanner. If
|
||||
// an error is reported (via Error) and Position is invalid, the scanner is
|
||||
// not inside a token.
|
||||
tokPos token.Pos
|
||||
}
|
||||
|
||||
// New creates and initializes a new instance of Scanner using src as
|
||||
// its source content.
|
||||
func New(src []byte) *Scanner {
|
||||
// even though we accept a src, we read from a io.Reader compatible type
|
||||
// (*bytes.Buffer). So in the future we might easily change it to streaming
|
||||
// read.
|
||||
b := bytes.NewBuffer(src)
|
||||
s := &Scanner{
|
||||
buf: b,
|
||||
src: src,
|
||||
}
|
||||
|
||||
// srcPosition always starts with 1
|
||||
s.srcPos.Line = 1
|
||||
return s
|
||||
}
|
||||
|
||||
// next reads the next rune from the bufferred reader. Returns the rune(0) if
|
||||
// an error occurs (or io.EOF is returned).
|
||||
func (s *Scanner) next() rune {
|
||||
ch, size, err := s.buf.ReadRune()
|
||||
if err != nil {
|
||||
// advance for error reporting
|
||||
s.srcPos.Column++
|
||||
s.srcPos.Offset += size
|
||||
s.lastCharLen = size
|
||||
return eof
|
||||
}
|
||||
|
||||
if ch == utf8.RuneError && size == 1 {
|
||||
s.srcPos.Column++
|
||||
s.srcPos.Offset += size
|
||||
s.lastCharLen = size
|
||||
s.err("illegal UTF-8 encoding")
|
||||
return ch
|
||||
}
|
||||
|
||||
// remember last position
|
||||
s.prevPos = s.srcPos
|
||||
|
||||
s.srcPos.Column++
|
||||
s.lastCharLen = size
|
||||
s.srcPos.Offset += size
|
||||
|
||||
if ch == '\n' {
|
||||
s.srcPos.Line++
|
||||
s.lastLineLen = s.srcPos.Column
|
||||
s.srcPos.Column = 0
|
||||
}
|
||||
|
||||
// debug
|
||||
// fmt.Printf("ch: %q, offset:column: %d:%d\n", ch, s.srcPos.Offset, s.srcPos.Column)
|
||||
return ch
|
||||
}
|
||||
|
||||
// unread unreads the previous read Rune and updates the source position
|
||||
func (s *Scanner) unread() {
|
||||
if err := s.buf.UnreadRune(); err != nil {
|
||||
panic(err) // this is user fault, we should catch it
|
||||
}
|
||||
s.srcPos = s.prevPos // put back last position
|
||||
}
|
||||
|
||||
// peek returns the next rune without advancing the reader.
|
||||
func (s *Scanner) peek() rune {
|
||||
peek, _, err := s.buf.ReadRune()
|
||||
if err != nil {
|
||||
return eof
|
||||
}
|
||||
|
||||
s.buf.UnreadRune()
|
||||
return peek
|
||||
}
|
||||
|
||||
// Scan scans the next token and returns the token.
|
||||
func (s *Scanner) Scan() token.Token {
|
||||
ch := s.next()
|
||||
|
||||
// skip white space
|
||||
for isWhitespace(ch) {
|
||||
ch = s.next()
|
||||
}
|
||||
|
||||
var tok token.Type
|
||||
|
||||
// token text markings
|
||||
s.tokStart = s.srcPos.Offset - s.lastCharLen
|
||||
|
||||
// token position, initial next() is moving the offset by one(size of rune
|
||||
// actually), though we are interested with the starting point
|
||||
s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen
|
||||
if s.srcPos.Column > 0 {
|
||||
// common case: last character was not a '\n'
|
||||
s.tokPos.Line = s.srcPos.Line
|
||||
s.tokPos.Column = s.srcPos.Column
|
||||
} else {
|
||||
// last character was a '\n'
|
||||
// (we cannot be at the beginning of the source
|
||||
// since we have called next() at least once)
|
||||
s.tokPos.Line = s.srcPos.Line - 1
|
||||
s.tokPos.Column = s.lastLineLen
|
||||
}
|
||||
|
||||
switch {
|
||||
case isLetter(ch):
|
||||
tok = token.IDENT
|
||||
lit := s.scanIdentifier()
|
||||
if lit == "true" || lit == "false" {
|
||||
tok = token.BOOL
|
||||
}
|
||||
case isDecimal(ch):
|
||||
tok = s.scanNumber(ch)
|
||||
default:
|
||||
switch ch {
|
||||
case eof:
|
||||
tok = token.EOF
|
||||
case '"':
|
||||
tok = token.STRING
|
||||
s.scanString()
|
||||
case '#', '/':
|
||||
tok = token.COMMENT
|
||||
s.scanComment(ch)
|
||||
case '.':
|
||||
tok = token.PERIOD
|
||||
ch = s.peek()
|
||||
if isDecimal(ch) {
|
||||
tok = token.FLOAT
|
||||
ch = s.scanMantissa(ch)
|
||||
ch = s.scanExponent(ch)
|
||||
}
|
||||
case '<':
|
||||
tok = token.HEREDOC
|
||||
s.scanHeredoc()
|
||||
case '[':
|
||||
tok = token.LBRACK
|
||||
case ']':
|
||||
tok = token.RBRACK
|
||||
case '{':
|
||||
tok = token.LBRACE
|
||||
case '}':
|
||||
tok = token.RBRACE
|
||||
case ',':
|
||||
tok = token.COMMA
|
||||
case '=':
|
||||
tok = token.ASSIGN
|
||||
case '+':
|
||||
tok = token.ADD
|
||||
case '-':
|
||||
if isDecimal(s.peek()) {
|
||||
ch := s.next()
|
||||
tok = s.scanNumber(ch)
|
||||
} else {
|
||||
tok = token.SUB
|
||||
}
|
||||
default:
|
||||
s.err("illegal char")
|
||||
}
|
||||
}
|
||||
|
||||
// finish token ending
|
||||
s.tokEnd = s.srcPos.Offset
|
||||
|
||||
// create token literal
|
||||
var tokenText string
|
||||
if s.tokStart >= 0 {
|
||||
tokenText = string(s.src[s.tokStart:s.tokEnd])
|
||||
}
|
||||
s.tokStart = s.tokEnd // ensure idempotency of tokenText() call
|
||||
|
||||
return token.Token{
|
||||
Type: tok,
|
||||
Pos: s.tokPos,
|
||||
Text: tokenText,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scanner) scanComment(ch rune) {
|
||||
// single line comments
|
||||
if ch == '#' || (ch == '/' && s.peek() != '*') {
|
||||
ch = s.next()
|
||||
for ch != '\n' && ch >= 0 && ch != eof {
|
||||
ch = s.next()
|
||||
}
|
||||
if ch != eof && ch >= 0 {
|
||||
s.unread()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// be sure we get the character after /* This allows us to find comment's
|
||||
// that are not erminated
|
||||
if ch == '/' {
|
||||
s.next()
|
||||
ch = s.next() // read character after "/*"
|
||||
}
|
||||
|
||||
// look for /* - style comments
|
||||
for {
|
||||
if ch < 0 || ch == eof {
|
||||
s.err("comment not terminated")
|
||||
break
|
||||
}
|
||||
|
||||
ch0 := ch
|
||||
ch = s.next()
|
||||
if ch0 == '*' && ch == '/' {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scanNumber scans a HCL number definition starting with the given rune
|
||||
func (s *Scanner) scanNumber(ch rune) token.Type {
|
||||
if ch == '0' {
|
||||
// check for hexadecimal, octal or float
|
||||
ch = s.next()
|
||||
if ch == 'x' || ch == 'X' {
|
||||
// hexadecimal
|
||||
ch = s.next()
|
||||
found := false
|
||||
for isHexadecimal(ch) {
|
||||
ch = s.next()
|
||||
found = true
|
||||
}
|
||||
|
||||
if !found {
|
||||
s.err("illegal hexadecimal number")
|
||||
}
|
||||
|
||||
if ch != eof {
|
||||
s.unread()
|
||||
}
|
||||
|
||||
return token.NUMBER
|
||||
}
|
||||
|
||||
// now it's either something like: 0421(octal) or 0.1231(float)
|
||||
illegalOctal := false
|
||||
for isDecimal(ch) {
|
||||
ch = s.next()
|
||||
if ch == '8' || ch == '9' {
|
||||
// this is just a possibility. For example 0159 is illegal, but
|
||||
// 0159.23 is valid. So we mark a possible illegal octal. If
|
||||
// the next character is not a period, we'll print the error.
|
||||
illegalOctal = true
|
||||
}
|
||||
}
|
||||
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.scanExponent(ch)
|
||||
return token.FLOAT
|
||||
}
|
||||
|
||||
if ch == '.' {
|
||||
ch = s.scanFraction(ch)
|
||||
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.next()
|
||||
ch = s.scanExponent(ch)
|
||||
}
|
||||
return token.FLOAT
|
||||
}
|
||||
|
||||
if illegalOctal {
|
||||
s.err("illegal octal number")
|
||||
}
|
||||
|
||||
if ch != eof {
|
||||
s.unread()
|
||||
}
|
||||
return token.NUMBER
|
||||
}
|
||||
|
||||
s.scanMantissa(ch)
|
||||
ch = s.next() // seek forward
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.scanExponent(ch)
|
||||
return token.FLOAT
|
||||
}
|
||||
|
||||
if ch == '.' {
|
||||
ch = s.scanFraction(ch)
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.next()
|
||||
ch = s.scanExponent(ch)
|
||||
}
|
||||
return token.FLOAT
|
||||
}
|
||||
|
||||
if ch != eof {
|
||||
s.unread()
|
||||
}
|
||||
return token.NUMBER
|
||||
}
|
||||
|
||||
// scanMantissa scans the mantissa begining from the rune. It returns the next
|
||||
// non decimal rune. It's used to determine wheter it's a fraction or exponent.
|
||||
func (s *Scanner) scanMantissa(ch rune) rune {
|
||||
scanned := false
|
||||
for isDecimal(ch) {
|
||||
ch = s.next()
|
||||
scanned = true
|
||||
}
|
||||
|
||||
if scanned && ch != eof {
|
||||
s.unread()
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanFraction scans the fraction after the '.' rune
|
||||
func (s *Scanner) scanFraction(ch rune) rune {
|
||||
if ch == '.' {
|
||||
ch = s.peek() // we peek just to see if we can move forward
|
||||
ch = s.scanMantissa(ch)
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanExponent scans the remaining parts of an exponent after the 'e' or 'E'
|
||||
// rune.
|
||||
func (s *Scanner) scanExponent(ch rune) rune {
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.next()
|
||||
if ch == '-' || ch == '+' {
|
||||
ch = s.next()
|
||||
}
|
||||
ch = s.scanMantissa(ch)
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanHeredoc scans a heredoc string.
|
||||
func (s *Scanner) scanHeredoc() {
|
||||
// Scan the second '<' in example: '<<EOF'
|
||||
if s.next() != '<' {
|
||||
s.err("heredoc expected second '<', didn't see it")
|
||||
return
|
||||
}
|
||||
|
||||
// Get the original offset so we can read just the heredoc ident
|
||||
offs := s.srcPos.Offset
|
||||
|
||||
// Scan the identifier
|
||||
ch := s.next()
|
||||
for isLetter(ch) || isDigit(ch) {
|
||||
ch = s.next()
|
||||
}
|
||||
|
||||
// If we reached an EOF then that is not good
|
||||
if ch == eof {
|
||||
s.err("heredoc not terminated")
|
||||
return
|
||||
}
|
||||
|
||||
// Ignore the '\r' in Windows line endings
|
||||
if ch == '\r' {
|
||||
if s.peek() == '\n' {
|
||||
ch = s.next()
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't reach a newline then that is also not good
|
||||
if ch != '\n' {
|
||||
s.err("invalid characters in heredoc anchor")
|
||||
return
|
||||
}
|
||||
|
||||
// Read the identifier
|
||||
identBytes := s.src[offs : s.srcPos.Offset-s.lastCharLen]
|
||||
|
||||
// Read the actual string value
|
||||
lineStart := s.srcPos.Offset
|
||||
for {
|
||||
ch := s.next()
|
||||
|
||||
// Special newline handling.
|
||||
if ch == '\n' {
|
||||
// Math is fast, so we first compare the byte counts to
|
||||
// see if we have a chance of seeing the same identifier. If those
|
||||
// match, then we compare the string values directly.
|
||||
lineBytesLen := s.srcPos.Offset - s.lastCharLen - lineStart
|
||||
if lineBytesLen == len(identBytes) &&
|
||||
bytes.Equal(identBytes, s.src[lineStart:s.srcPos.Offset-s.lastCharLen]) {
|
||||
break
|
||||
}
|
||||
|
||||
// Not an anchor match, record the start of a new line
|
||||
lineStart = s.srcPos.Offset
|
||||
}
|
||||
|
||||
if ch == eof {
|
||||
s.err("heredoc not terminated")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// scanString scans a quoted string
|
||||
func (s *Scanner) scanString() {
|
||||
braces := 0
|
||||
for {
|
||||
// '"' opening already consumed
|
||||
// read character after quote
|
||||
ch := s.next()
|
||||
|
||||
if ch == '\n' || ch < 0 || ch == eof {
|
||||
s.err("literal not terminated")
|
||||
return
|
||||
}
|
||||
|
||||
if ch == '"' && braces == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// If we're going into a ${} then we can ignore quotes for awhile
|
||||
if braces == 0 && ch == '$' && s.peek() == '{' {
|
||||
braces++
|
||||
s.next()
|
||||
} else if braces > 0 && ch == '{' {
|
||||
braces++
|
||||
}
|
||||
if braces > 0 && ch == '}' {
|
||||
braces--
|
||||
}
|
||||
|
||||
if ch == '\\' {
|
||||
s.scanEscape()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// scanEscape scans an escape sequence
|
||||
func (s *Scanner) scanEscape() rune {
|
||||
// http://en.cppreference.com/w/cpp/language/escape
|
||||
ch := s.next() // read character after '/'
|
||||
switch ch {
|
||||
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"':
|
||||
// nothing to do
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
// octal notation
|
||||
ch = s.scanDigits(ch, 8, 3)
|
||||
case 'x':
|
||||
// hexademical notation
|
||||
ch = s.scanDigits(s.next(), 16, 2)
|
||||
case 'u':
|
||||
// universal character name
|
||||
ch = s.scanDigits(s.next(), 16, 4)
|
||||
case 'U':
|
||||
// universal character name
|
||||
ch = s.scanDigits(s.next(), 16, 8)
|
||||
default:
|
||||
s.err("illegal char escape")
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanDigits scans a rune with the given base for n times. For example an
|
||||
// octal notation \184 would yield in scanDigits(ch, 8, 3)
|
||||
func (s *Scanner) scanDigits(ch rune, base, n int) rune {
|
||||
for n > 0 && digitVal(ch) < base {
|
||||
ch = s.next()
|
||||
n--
|
||||
}
|
||||
if n > 0 {
|
||||
s.err("illegal char escape")
|
||||
}
|
||||
|
||||
// we scanned all digits, put the last non digit char back
|
||||
s.unread()
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanIdentifier scans an identifier and returns the literal string
|
||||
func (s *Scanner) scanIdentifier() string {
|
||||
offs := s.srcPos.Offset - s.lastCharLen
|
||||
ch := s.next()
|
||||
for isLetter(ch) || isDigit(ch) || ch == '-' || ch == '.' {
|
||||
ch = s.next()
|
||||
}
|
||||
|
||||
if ch != eof {
|
||||
s.unread() // we got identifier, put back latest char
|
||||
}
|
||||
|
||||
return string(s.src[offs:s.srcPos.Offset])
|
||||
}
|
||||
|
||||
// recentPosition returns the position of the character immediately after the
|
||||
// character or token returned by the last call to Scan.
|
||||
func (s *Scanner) recentPosition() (pos token.Pos) {
|
||||
pos.Offset = s.srcPos.Offset - s.lastCharLen
|
||||
switch {
|
||||
case s.srcPos.Column > 0:
|
||||
// common case: last character was not a '\n'
|
||||
pos.Line = s.srcPos.Line
|
||||
pos.Column = s.srcPos.Column
|
||||
case s.lastLineLen > 0:
|
||||
// last character was a '\n'
|
||||
// (we cannot be at the beginning of the source
|
||||
// since we have called next() at least once)
|
||||
pos.Line = s.srcPos.Line - 1
|
||||
pos.Column = s.lastLineLen
|
||||
default:
|
||||
// at the beginning of the source
|
||||
pos.Line = 1
|
||||
pos.Column = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// err prints the error of any scanning to s.Error function. If the function is
|
||||
// not defined, by default it prints them to os.Stderr
|
||||
func (s *Scanner) err(msg string) {
|
||||
s.ErrorCount++
|
||||
pos := s.recentPosition()
|
||||
|
||||
if s.Error != nil {
|
||||
s.Error(pos, msg)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
|
||||
}
|
||||
|
||||
// isHexadecimal returns true if the given rune is a letter
|
||||
func isLetter(ch rune) bool {
|
||||
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch)
|
||||
}
|
||||
|
||||
// isDigit returns true if the given rune is a decimal digit
|
||||
func isDigit(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
|
||||
}
|
||||
|
||||
// isDecimal returns true if the given rune is a decimal number
|
||||
func isDecimal(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9'
|
||||
}
|
||||
|
||||
// isHexadecimal returns true if the given rune is an hexadecimal number
|
||||
func isHexadecimal(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F'
|
||||
}
|
||||
|
||||
// isWhitespace returns true if the rune is a space, tab, newline or carriage return
|
||||
func isWhitespace(ch rune) bool {
|
||||
return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'
|
||||
}
|
||||
|
||||
// digitVal returns the integer value of a given octal,decimal or hexadecimal rune
|
||||
func digitVal(ch rune) int {
|
||||
switch {
|
||||
case '0' <= ch && ch <= '9':
|
||||
return int(ch - '0')
|
||||
case 'a' <= ch && ch <= 'f':
|
||||
return int(ch - 'a' + 10)
|
||||
case 'A' <= ch && ch <= 'F':
|
||||
return int(ch - 'A' + 10)
|
||||
}
|
||||
return 16 // larger than any legal digit val
|
||||
}
|
245
vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go
generated
vendored
Normal file
245
vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go
generated
vendored
Normal file
|
@ -0,0 +1,245 @@
|
|||
package strconv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// ErrSyntax indicates that a value does not have the right syntax for the target type.
|
||||
var ErrSyntax = errors.New("invalid syntax")
|
||||
|
||||
// Unquote interprets s as a single-quoted, double-quoted,
|
||||
// or backquoted Go string literal, returning the string value
|
||||
// that s quotes. (If s is single-quoted, it would be a Go
|
||||
// character literal; Unquote returns the corresponding
|
||||
// one-character string.)
|
||||
func Unquote(s string) (t string, err error) {
|
||||
n := len(s)
|
||||
if n < 2 {
|
||||
return "", ErrSyntax
|
||||
}
|
||||
quote := s[0]
|
||||
if quote != s[n-1] {
|
||||
return "", ErrSyntax
|
||||
}
|
||||
s = s[1 : n-1]
|
||||
|
||||
if quote != '"' {
|
||||
return "", ErrSyntax
|
||||
}
|
||||
if contains(s, '\n') {
|
||||
return "", ErrSyntax
|
||||
}
|
||||
|
||||
// Is it trivial? Avoid allocation.
|
||||
if !contains(s, '\\') && !contains(s, quote) && !contains(s, '$') {
|
||||
switch quote {
|
||||
case '"':
|
||||
return s, nil
|
||||
case '\'':
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
if size == len(s) && (r != utf8.RuneError || size != 1) {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var runeTmp [utf8.UTFMax]byte
|
||||
buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
|
||||
for len(s) > 0 {
|
||||
// If we're starting a '${}' then let it through un-unquoted.
|
||||
// Specifically: we don't unquote any characters within the `${}`
|
||||
// section, except for escaped quotes, which we handle specifically.
|
||||
if s[0] == '$' && len(s) > 1 && s[1] == '{' {
|
||||
buf = append(buf, '$', '{')
|
||||
s = s[2:]
|
||||
|
||||
// Continue reading until we find the closing brace, copying as-is
|
||||
braces := 1
|
||||
for len(s) > 0 && braces > 0 {
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
if r == utf8.RuneError {
|
||||
return "", ErrSyntax
|
||||
}
|
||||
|
||||
s = s[size:]
|
||||
|
||||
// We special case escaped double quotes in interpolations, converting
|
||||
// them to straight double quotes.
|
||||
if r == '\\' {
|
||||
if q, _ := utf8.DecodeRuneInString(s); q == '"' {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
n := utf8.EncodeRune(runeTmp[:], r)
|
||||
buf = append(buf, runeTmp[:n]...)
|
||||
|
||||
switch r {
|
||||
case '{':
|
||||
braces++
|
||||
case '}':
|
||||
braces--
|
||||
}
|
||||
}
|
||||
if braces != 0 {
|
||||
return "", ErrSyntax
|
||||
}
|
||||
if len(s) == 0 {
|
||||
// If there's no string left, we're done!
|
||||
break
|
||||
} else {
|
||||
// If there's more left, we need to pop back up to the top of the loop
|
||||
// in case there's another interpolation in this string.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
c, multibyte, ss, err := unquoteChar(s, quote)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s = ss
|
||||
if c < utf8.RuneSelf || !multibyte {
|
||||
buf = append(buf, byte(c))
|
||||
} else {
|
||||
n := utf8.EncodeRune(runeTmp[:], c)
|
||||
buf = append(buf, runeTmp[:n]...)
|
||||
}
|
||||
if quote == '\'' && len(s) != 0 {
|
||||
// single-quoted must be single character
|
||||
return "", ErrSyntax
|
||||
}
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
// contains reports whether the string contains the byte c.
|
||||
func contains(s string, c byte) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == c {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func unhex(b byte) (v rune, ok bool) {
|
||||
c := rune(b)
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
return c - '0', true
|
||||
case 'a' <= c && c <= 'f':
|
||||
return c - 'a' + 10, true
|
||||
case 'A' <= c && c <= 'F':
|
||||
return c - 'A' + 10, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func unquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) {
|
||||
// easy cases
|
||||
switch c := s[0]; {
|
||||
case c == quote && (quote == '\'' || quote == '"'):
|
||||
err = ErrSyntax
|
||||
return
|
||||
case c >= utf8.RuneSelf:
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
return r, true, s[size:], nil
|
||||
case c != '\\':
|
||||
return rune(s[0]), false, s[1:], nil
|
||||
}
|
||||
|
||||
// hard case: c is backslash
|
||||
if len(s) <= 1 {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
c := s[1]
|
||||
s = s[2:]
|
||||
|
||||
switch c {
|
||||
case 'a':
|
||||
value = '\a'
|
||||
case 'b':
|
||||
value = '\b'
|
||||
case 'f':
|
||||
value = '\f'
|
||||
case 'n':
|
||||
value = '\n'
|
||||
case 'r':
|
||||
value = '\r'
|
||||
case 't':
|
||||
value = '\t'
|
||||
case 'v':
|
||||
value = '\v'
|
||||
case 'x', 'u', 'U':
|
||||
n := 0
|
||||
switch c {
|
||||
case 'x':
|
||||
n = 2
|
||||
case 'u':
|
||||
n = 4
|
||||
case 'U':
|
||||
n = 8
|
||||
}
|
||||
var v rune
|
||||
if len(s) < n {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
for j := 0; j < n; j++ {
|
||||
x, ok := unhex(s[j])
|
||||
if !ok {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
v = v<<4 | x
|
||||
}
|
||||
s = s[n:]
|
||||
if c == 'x' {
|
||||
// single-byte string, possibly not UTF-8
|
||||
value = v
|
||||
break
|
||||
}
|
||||
if v > utf8.MaxRune {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
value = v
|
||||
multibyte = true
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
v := rune(c) - '0'
|
||||
if len(s) < 2 {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
for j := 0; j < 2; j++ { // one digit already; two more
|
||||
x := rune(s[j]) - '0'
|
||||
if x < 0 || x > 7 {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
v = (v << 3) | x
|
||||
}
|
||||
s = s[2:]
|
||||
if v > 255 {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
value = v
|
||||
case '\\':
|
||||
value = '\\'
|
||||
case '\'', '"':
|
||||
if c != quote {
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
value = rune(c)
|
||||
default:
|
||||
err = ErrSyntax
|
||||
return
|
||||
}
|
||||
tail = s
|
||||
return
|
||||
}
|
46
vendor/github.com/hashicorp/hcl/hcl/token/position.go
generated
vendored
Normal file
46
vendor/github.com/hashicorp/hcl/hcl/token/position.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package token
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Pos describes an arbitrary source position
|
||||
// including the file, line, and column location.
|
||||
// A Position is valid if the line number is > 0.
|
||||
type Pos struct {
|
||||
Filename string // filename, if any
|
||||
Offset int // offset, starting at 0
|
||||
Line int // line number, starting at 1
|
||||
Column int // column number, starting at 1 (character count)
|
||||
}
|
||||
|
||||
// IsValid returns true if the position is valid.
|
||||
func (p *Pos) IsValid() bool { return p.Line > 0 }
|
||||
|
||||
// String returns a string in one of several forms:
|
||||
//
|
||||
// file:line:column valid position with file name
|
||||
// line:column valid position without file name
|
||||
// file invalid position with file name
|
||||
// - invalid position without file name
|
||||
func (p Pos) String() string {
|
||||
s := p.Filename
|
||||
if p.IsValid() {
|
||||
if s != "" {
|
||||
s += ":"
|
||||
}
|
||||
s += fmt.Sprintf("%d:%d", p.Line, p.Column)
|
||||
}
|
||||
if s == "" {
|
||||
s = "-"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Before reports whether the position p is before u.
|
||||
func (p Pos) Before(u Pos) bool {
|
||||
return u.Offset > p.Offset || u.Line > p.Line
|
||||
}
|
||||
|
||||
// After reports whether the position p is after u.
|
||||
func (p Pos) After(u Pos) bool {
|
||||
return u.Offset < p.Offset || u.Line < p.Line
|
||||
}
|
170
vendor/github.com/hashicorp/hcl/hcl/token/token.go
generated
vendored
Normal file
170
vendor/github.com/hashicorp/hcl/hcl/token/token.go
generated
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
// Package token defines constants representing the lexical tokens for HCL
|
||||
// (HashiCorp Configuration Language)
|
||||
package token
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
hclstrconv "github.com/hashicorp/hcl/hcl/strconv"
|
||||
)
|
||||
|
||||
// Token defines a single HCL token which can be obtained via the Scanner
|
||||
type Token struct {
|
||||
Type Type
|
||||
Pos Pos
|
||||
Text string
|
||||
JSON bool
|
||||
}
|
||||
|
||||
// Type is the set of lexical tokens of the HCL (HashiCorp Configuration Language)
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// Special tokens
|
||||
ILLEGAL Type = iota
|
||||
EOF
|
||||
COMMENT
|
||||
|
||||
identifier_beg
|
||||
IDENT // literals
|
||||
literal_beg
|
||||
NUMBER // 12345
|
||||
FLOAT // 123.45
|
||||
BOOL // true,false
|
||||
STRING // "abc"
|
||||
HEREDOC // <<FOO\nbar\nFOO
|
||||
literal_end
|
||||
identifier_end
|
||||
|
||||
operator_beg
|
||||
LBRACK // [
|
||||
LBRACE // {
|
||||
COMMA // ,
|
||||
PERIOD // .
|
||||
|
||||
RBRACK // ]
|
||||
RBRACE // }
|
||||
|
||||
ASSIGN // =
|
||||
ADD // +
|
||||
SUB // -
|
||||
operator_end
|
||||
)
|
||||
|
||||
var tokens = [...]string{
|
||||
ILLEGAL: "ILLEGAL",
|
||||
|
||||
EOF: "EOF",
|
||||
COMMENT: "COMMENT",
|
||||
|
||||
IDENT: "IDENT",
|
||||
NUMBER: "NUMBER",
|
||||
FLOAT: "FLOAT",
|
||||
BOOL: "BOOL",
|
||||
STRING: "STRING",
|
||||
|
||||
LBRACK: "LBRACK",
|
||||
LBRACE: "LBRACE",
|
||||
COMMA: "COMMA",
|
||||
PERIOD: "PERIOD",
|
||||
HEREDOC: "HEREDOC",
|
||||
|
||||
RBRACK: "RBRACK",
|
||||
RBRACE: "RBRACE",
|
||||
|
||||
ASSIGN: "ASSIGN",
|
||||
ADD: "ADD",
|
||||
SUB: "SUB",
|
||||
}
|
||||
|
||||
// String returns the string corresponding to the token tok.
|
||||
func (t Type) String() string {
|
||||
s := ""
|
||||
if 0 <= t && t < Type(len(tokens)) {
|
||||
s = tokens[t]
|
||||
}
|
||||
if s == "" {
|
||||
s = "token(" + strconv.Itoa(int(t)) + ")"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// IsIdentifier returns true for tokens corresponding to identifiers and basic
|
||||
// type literals; it returns false otherwise.
|
||||
func (t Type) IsIdentifier() bool { return identifier_beg < t && t < identifier_end }
|
||||
|
||||
// IsLiteral returns true for tokens corresponding to basic type literals; it
|
||||
// returns false otherwise.
|
||||
func (t Type) IsLiteral() bool { return literal_beg < t && t < literal_end }
|
||||
|
||||
// IsOperator returns true for tokens corresponding to operators and
|
||||
// delimiters; it returns false otherwise.
|
||||
func (t Type) IsOperator() bool { return operator_beg < t && t < operator_end }
|
||||
|
||||
// String returns the token's literal text. Note that this is only
|
||||
// applicable for certain token types, such as token.IDENT,
|
||||
// token.STRING, etc..
|
||||
func (t Token) String() string {
|
||||
return fmt.Sprintf("%s %s %s", t.Pos.String(), t.Type.String(), t.Text)
|
||||
}
|
||||
|
||||
// Value returns the properly typed value for this token. The type of
|
||||
// the returned interface{} is guaranteed based on the Type field.
|
||||
//
|
||||
// This can only be called for literal types. If it is called for any other
|
||||
// type, this will panic.
|
||||
func (t Token) Value() interface{} {
|
||||
switch t.Type {
|
||||
case BOOL:
|
||||
if t.Text == "true" {
|
||||
return true
|
||||
} else if t.Text == "false" {
|
||||
return false
|
||||
}
|
||||
|
||||
panic("unknown bool value: " + t.Text)
|
||||
case FLOAT:
|
||||
v, err := strconv.ParseFloat(t.Text, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return float64(v)
|
||||
case NUMBER:
|
||||
v, err := strconv.ParseInt(t.Text, 0, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return int64(v)
|
||||
case IDENT:
|
||||
return t.Text
|
||||
case HEREDOC:
|
||||
// We need to find the end of the marker
|
||||
idx := strings.IndexByte(t.Text, '\n')
|
||||
if idx == -1 {
|
||||
panic("heredoc doesn't contain newline")
|
||||
}
|
||||
|
||||
return string(t.Text[idx+1 : len(t.Text)-idx+1])
|
||||
case STRING:
|
||||
// Determine the Unquote method to use. If it came from JSON,
|
||||
// then we need to use the built-in unquote since we have to
|
||||
// escape interpolations there.
|
||||
f := hclstrconv.Unquote
|
||||
if t.JSON {
|
||||
f = strconv.Unquote
|
||||
}
|
||||
|
||||
v, err := f(t.Text)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unquote %s err: %s", t.Text, err))
|
||||
}
|
||||
|
||||
return v
|
||||
default:
|
||||
panic(fmt.Sprintf("unimplemented Value for type: %s", t.Type))
|
||||
}
|
||||
}
|
111
vendor/github.com/hashicorp/hcl/json/parser/flatten.go
generated
vendored
Normal file
111
vendor/github.com/hashicorp/hcl/json/parser/flatten.go
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
package parser
|
||||
|
||||
import "github.com/hashicorp/hcl/hcl/ast"
|
||||
|
||||
// flattenObjects takes an AST node, walks it, and flattens
|
||||
func flattenObjects(node ast.Node) {
|
||||
ast.Walk(node, func(n ast.Node) (ast.Node, bool) {
|
||||
// We only care about lists, because this is what we modify
|
||||
list, ok := n.(*ast.ObjectList)
|
||||
if !ok {
|
||||
return n, true
|
||||
}
|
||||
|
||||
// Rebuild the item list
|
||||
items := make([]*ast.ObjectItem, 0, len(list.Items))
|
||||
frontier := make([]*ast.ObjectItem, len(list.Items))
|
||||
copy(frontier, list.Items)
|
||||
for len(frontier) > 0 {
|
||||
// Pop the current item
|
||||
n := len(frontier)
|
||||
item := frontier[n-1]
|
||||
frontier = frontier[:n-1]
|
||||
|
||||
switch v := item.Val.(type) {
|
||||
case *ast.ObjectType:
|
||||
items, frontier = flattenObjectType(v, item, items, frontier)
|
||||
case *ast.ListType:
|
||||
items, frontier = flattenListType(v, item, items, frontier)
|
||||
default:
|
||||
items = append(items, item)
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse the list since the frontier model runs things backwards
|
||||
for i := len(items)/2 - 1; i >= 0; i-- {
|
||||
opp := len(items) - 1 - i
|
||||
items[i], items[opp] = items[opp], items[i]
|
||||
}
|
||||
|
||||
// Done! Set the original items
|
||||
list.Items = items
|
||||
return n, true
|
||||
})
|
||||
}
|
||||
|
||||
func flattenListType(
|
||||
ot *ast.ListType,
|
||||
item *ast.ObjectItem,
|
||||
items []*ast.ObjectItem,
|
||||
frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) {
|
||||
// All the elements of this object must also be objects!
|
||||
for _, subitem := range ot.List {
|
||||
if _, ok := subitem.(*ast.ObjectType); !ok {
|
||||
items = append(items, item)
|
||||
return items, frontier
|
||||
}
|
||||
}
|
||||
|
||||
// Great! We have a match go through all the items and flatten
|
||||
for _, elem := range ot.List {
|
||||
// Add it to the frontier so that we can recurse
|
||||
frontier = append(frontier, &ast.ObjectItem{
|
||||
Keys: item.Keys,
|
||||
Assign: item.Assign,
|
||||
Val: elem,
|
||||
LeadComment: item.LeadComment,
|
||||
LineComment: item.LineComment,
|
||||
})
|
||||
}
|
||||
|
||||
return items, frontier
|
||||
}
|
||||
|
||||
func flattenObjectType(
|
||||
ot *ast.ObjectType,
|
||||
item *ast.ObjectItem,
|
||||
items []*ast.ObjectItem,
|
||||
frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) {
|
||||
// If the list has no items we do not have to flatten anything
|
||||
if ot.List.Items == nil {
|
||||
items = append(items, item)
|
||||
return items, frontier
|
||||
}
|
||||
|
||||
// All the elements of this object must also be objects!
|
||||
for _, subitem := range ot.List.Items {
|
||||
if _, ok := subitem.Val.(*ast.ObjectType); !ok {
|
||||
items = append(items, item)
|
||||
return items, frontier
|
||||
}
|
||||
}
|
||||
|
||||
// Great! We have a match go through all the items and flatten
|
||||
for _, subitem := range ot.List.Items {
|
||||
// Copy the new key
|
||||
keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys))
|
||||
copy(keys, item.Keys)
|
||||
copy(keys[len(item.Keys):], subitem.Keys)
|
||||
|
||||
// Add it to the frontier so that we can recurse
|
||||
frontier = append(frontier, &ast.ObjectItem{
|
||||
Keys: keys,
|
||||
Assign: item.Assign,
|
||||
Val: subitem.Val,
|
||||
LeadComment: item.LeadComment,
|
||||
LineComment: item.LineComment,
|
||||
})
|
||||
}
|
||||
|
||||
return items, frontier
|
||||
}
|
297
vendor/github.com/hashicorp/hcl/json/parser/parser.go
generated
vendored
Normal file
297
vendor/github.com/hashicorp/hcl/json/parser/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,297 @@
|
|||
package parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"github.com/hashicorp/hcl/json/scanner"
|
||||
"github.com/hashicorp/hcl/json/token"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
sc *scanner.Scanner
|
||||
|
||||
// Last read token
|
||||
tok token.Token
|
||||
commaPrev token.Token
|
||||
|
||||
enableTrace bool
|
||||
indent int
|
||||
n int // buffer size (max = 1)
|
||||
}
|
||||
|
||||
func newParser(src []byte) *Parser {
|
||||
return &Parser{
|
||||
sc: scanner.New(src),
|
||||
}
|
||||
}
|
||||
|
||||
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
||||
func Parse(src []byte) (*ast.File, error) {
|
||||
p := newParser(src)
|
||||
return p.Parse()
|
||||
}
|
||||
|
||||
var errEofToken = errors.New("EOF token found")
|
||||
|
||||
// Parse returns the fully parsed source and returns the abstract syntax tree.
|
||||
func (p *Parser) Parse() (*ast.File, error) {
|
||||
f := &ast.File{}
|
||||
var err, scerr error
|
||||
p.sc.Error = func(pos token.Pos, msg string) {
|
||||
scerr = fmt.Errorf("%s: %s", pos, msg)
|
||||
}
|
||||
|
||||
// The root must be an object in JSON
|
||||
object, err := p.object()
|
||||
if scerr != nil {
|
||||
return nil, scerr
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We make our final node an object list so it is more HCL compatible
|
||||
f.Node = object.List
|
||||
|
||||
// Flatten it, which finds patterns and turns them into more HCL-like
|
||||
// AST trees.
|
||||
flattenObjects(f.Node)
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *Parser) objectList() (*ast.ObjectList, error) {
|
||||
defer un(trace(p, "ParseObjectList"))
|
||||
node := &ast.ObjectList{}
|
||||
|
||||
for {
|
||||
n, err := p.objectItem()
|
||||
if err == errEofToken {
|
||||
break // we are finished
|
||||
}
|
||||
|
||||
// we don't return a nil node, because might want to use already
|
||||
// collected items.
|
||||
if err != nil {
|
||||
return node, err
|
||||
}
|
||||
|
||||
node.Add(n)
|
||||
|
||||
// Check for a followup comma. If it isn't a comma, then we're done
|
||||
if tok := p.scan(); tok.Type != token.COMMA {
|
||||
break
|
||||
}
|
||||
}
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// objectItem parses a single object item
|
||||
func (p *Parser) objectItem() (*ast.ObjectItem, error) {
|
||||
defer un(trace(p, "ParseObjectItem"))
|
||||
|
||||
keys, err := p.objectKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o := &ast.ObjectItem{
|
||||
Keys: keys,
|
||||
}
|
||||
|
||||
switch p.tok.Type {
|
||||
case token.COLON:
|
||||
o.Val, err = p.objectValue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// objectKey parses an object key and returns a ObjectKey AST
|
||||
func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
|
||||
keyCount := 0
|
||||
keys := make([]*ast.ObjectKey, 0)
|
||||
|
||||
for {
|
||||
tok := p.scan()
|
||||
switch tok.Type {
|
||||
case token.EOF:
|
||||
return nil, errEofToken
|
||||
case token.STRING:
|
||||
keyCount++
|
||||
keys = append(keys, &ast.ObjectKey{
|
||||
Token: p.tok.HCLToken(),
|
||||
})
|
||||
case token.COLON:
|
||||
// Done
|
||||
return keys, nil
|
||||
case token.ILLEGAL:
|
||||
fmt.Println("illegal")
|
||||
default:
|
||||
return nil, fmt.Errorf("expected: STRING got: %s", p.tok.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// object parses any type of object, such as number, bool, string, object or
|
||||
// list.
|
||||
func (p *Parser) objectValue() (ast.Node, error) {
|
||||
defer un(trace(p, "ParseObjectValue"))
|
||||
tok := p.scan()
|
||||
|
||||
switch tok.Type {
|
||||
case token.NUMBER, token.FLOAT, token.BOOL, token.NULL, token.STRING:
|
||||
return p.literalType()
|
||||
case token.LBRACE:
|
||||
return p.objectType()
|
||||
case token.LBRACK:
|
||||
return p.listType()
|
||||
case token.EOF:
|
||||
return nil, errEofToken
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Expected object value, got unknown token: %+v", tok)
|
||||
}
|
||||
|
||||
// object parses any type of object, such as number, bool, string, object or
|
||||
// list.
|
||||
func (p *Parser) object() (*ast.ObjectType, error) {
|
||||
defer un(trace(p, "ParseType"))
|
||||
tok := p.scan()
|
||||
|
||||
switch tok.Type {
|
||||
case token.LBRACE:
|
||||
return p.objectType()
|
||||
case token.EOF:
|
||||
return nil, errEofToken
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Expected object, got unknown token: %+v", tok)
|
||||
}
|
||||
|
||||
// objectType parses an object type and returns a ObjectType AST
|
||||
func (p *Parser) objectType() (*ast.ObjectType, error) {
|
||||
defer un(trace(p, "ParseObjectType"))
|
||||
|
||||
// we assume that the currently scanned token is a LBRACE
|
||||
o := &ast.ObjectType{}
|
||||
|
||||
l, err := p.objectList()
|
||||
|
||||
// if we hit RBRACE, we are good to go (means we parsed all Items), if it's
|
||||
// not a RBRACE, it's an syntax error and we just return it.
|
||||
if err != nil && p.tok.Type != token.RBRACE {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o.List = l
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// listType parses a list type and returns a ListType AST
|
||||
func (p *Parser) listType() (*ast.ListType, error) {
|
||||
defer un(trace(p, "ParseListType"))
|
||||
|
||||
// we assume that the currently scanned token is a LBRACK
|
||||
l := &ast.ListType{}
|
||||
|
||||
for {
|
||||
tok := p.scan()
|
||||
switch tok.Type {
|
||||
case token.NUMBER, token.FLOAT, token.STRING:
|
||||
node, err := p.literalType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.Add(node)
|
||||
case token.COMMA:
|
||||
continue
|
||||
case token.LBRACE:
|
||||
node, err := p.objectType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l.Add(node)
|
||||
case token.BOOL:
|
||||
// TODO(arslan) should we support? not supported by HCL yet
|
||||
case token.LBRACK:
|
||||
// TODO(arslan) should we support nested lists? Even though it's
|
||||
// written in README of HCL, it's not a part of the grammar
|
||||
// (not defined in parse.y)
|
||||
case token.RBRACK:
|
||||
// finished
|
||||
return l, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected token while parsing list: %s", tok.Type)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// literalType parses a literal type and returns a LiteralType AST
|
||||
func (p *Parser) literalType() (*ast.LiteralType, error) {
|
||||
defer un(trace(p, "ParseLiteral"))
|
||||
|
||||
return &ast.LiteralType{
|
||||
Token: p.tok.HCLToken(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// scan returns the next token from the underlying scanner. If a token has
|
||||
// been unscanned then read that instead.
|
||||
func (p *Parser) scan() token.Token {
|
||||
// If we have a token on the buffer, then return it.
|
||||
if p.n != 0 {
|
||||
p.n = 0
|
||||
return p.tok
|
||||
}
|
||||
|
||||
p.tok = p.sc.Scan()
|
||||
return p.tok
|
||||
}
|
||||
|
||||
// unscan pushes the previously read token back onto the buffer.
|
||||
func (p *Parser) unscan() {
|
||||
p.n = 1
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Parsing support
|
||||
|
||||
func (p *Parser) printTrace(a ...interface{}) {
|
||||
if !p.enableTrace {
|
||||
return
|
||||
}
|
||||
|
||||
const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
|
||||
const n = len(dots)
|
||||
fmt.Printf("%5d:%3d: ", p.tok.Pos.Line, p.tok.Pos.Column)
|
||||
|
||||
i := 2 * p.indent
|
||||
for i > n {
|
||||
fmt.Print(dots)
|
||||
i -= n
|
||||
}
|
||||
// i <= n
|
||||
fmt.Print(dots[0:i])
|
||||
fmt.Println(a...)
|
||||
}
|
||||
|
||||
func trace(p *Parser, msg string) *Parser {
|
||||
p.printTrace(msg, "(")
|
||||
p.indent++
|
||||
return p
|
||||
}
|
||||
|
||||
// Usage pattern: defer un(trace(p, "..."))
|
||||
func un(p *Parser) {
|
||||
p.indent--
|
||||
p.printTrace(")")
|
||||
}
|
451
vendor/github.com/hashicorp/hcl/json/scanner/scanner.go
generated
vendored
Normal file
451
vendor/github.com/hashicorp/hcl/json/scanner/scanner.go
generated
vendored
Normal file
|
@ -0,0 +1,451 @@
|
|||
package scanner
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/hashicorp/hcl/json/token"
|
||||
)
|
||||
|
||||
// eof represents a marker rune for the end of the reader.
|
||||
const eof = rune(0)
|
||||
|
||||
// Scanner defines a lexical scanner
|
||||
type Scanner struct {
|
||||
buf *bytes.Buffer // Source buffer for advancing and scanning
|
||||
src []byte // Source buffer for immutable access
|
||||
|
||||
// Source Position
|
||||
srcPos token.Pos // current position
|
||||
prevPos token.Pos // previous position, used for peek() method
|
||||
|
||||
lastCharLen int // length of last character in bytes
|
||||
lastLineLen int // length of last line in characters (for correct column reporting)
|
||||
|
||||
tokStart int // token text start position
|
||||
tokEnd int // token text end position
|
||||
|
||||
// Error is called for each error encountered. If no Error
|
||||
// function is set, the error is reported to os.Stderr.
|
||||
Error func(pos token.Pos, msg string)
|
||||
|
||||
// ErrorCount is incremented by one for each error encountered.
|
||||
ErrorCount int
|
||||
|
||||
// tokPos is the start position of most recently scanned token; set by
|
||||
// Scan. The Filename field is always left untouched by the Scanner. If
|
||||
// an error is reported (via Error) and Position is invalid, the scanner is
|
||||
// not inside a token.
|
||||
tokPos token.Pos
|
||||
}
|
||||
|
||||
// New creates and initializes a new instance of Scanner using src as
|
||||
// its source content.
|
||||
func New(src []byte) *Scanner {
|
||||
// even though we accept a src, we read from a io.Reader compatible type
|
||||
// (*bytes.Buffer). So in the future we might easily change it to streaming
|
||||
// read.
|
||||
b := bytes.NewBuffer(src)
|
||||
s := &Scanner{
|
||||
buf: b,
|
||||
src: src,
|
||||
}
|
||||
|
||||
// srcPosition always starts with 1
|
||||
s.srcPos.Line = 1
|
||||
return s
|
||||
}
|
||||
|
||||
// next reads the next rune from the bufferred reader. Returns the rune(0) if
|
||||
// an error occurs (or io.EOF is returned).
|
||||
func (s *Scanner) next() rune {
|
||||
ch, size, err := s.buf.ReadRune()
|
||||
if err != nil {
|
||||
// advance for error reporting
|
||||
s.srcPos.Column++
|
||||
s.srcPos.Offset += size
|
||||
s.lastCharLen = size
|
||||
return eof
|
||||
}
|
||||
|
||||
if ch == utf8.RuneError && size == 1 {
|
||||
s.srcPos.Column++
|
||||
s.srcPos.Offset += size
|
||||
s.lastCharLen = size
|
||||
s.err("illegal UTF-8 encoding")
|
||||
return ch
|
||||
}
|
||||
|
||||
// remember last position
|
||||
s.prevPos = s.srcPos
|
||||
|
||||
s.srcPos.Column++
|
||||
s.lastCharLen = size
|
||||
s.srcPos.Offset += size
|
||||
|
||||
if ch == '\n' {
|
||||
s.srcPos.Line++
|
||||
s.lastLineLen = s.srcPos.Column
|
||||
s.srcPos.Column = 0
|
||||
}
|
||||
|
||||
// debug
|
||||
// fmt.Printf("ch: %q, offset:column: %d:%d\n", ch, s.srcPos.Offset, s.srcPos.Column)
|
||||
return ch
|
||||
}
|
||||
|
||||
// unread unreads the previous read Rune and updates the source position
|
||||
func (s *Scanner) unread() {
|
||||
if err := s.buf.UnreadRune(); err != nil {
|
||||
panic(err) // this is user fault, we should catch it
|
||||
}
|
||||
s.srcPos = s.prevPos // put back last position
|
||||
}
|
||||
|
||||
// peek returns the next rune without advancing the reader.
|
||||
func (s *Scanner) peek() rune {
|
||||
peek, _, err := s.buf.ReadRune()
|
||||
if err != nil {
|
||||
return eof
|
||||
}
|
||||
|
||||
s.buf.UnreadRune()
|
||||
return peek
|
||||
}
|
||||
|
||||
// Scan scans the next token and returns the token.
|
||||
func (s *Scanner) Scan() token.Token {
|
||||
ch := s.next()
|
||||
|
||||
// skip white space
|
||||
for isWhitespace(ch) {
|
||||
ch = s.next()
|
||||
}
|
||||
|
||||
var tok token.Type
|
||||
|
||||
// token text markings
|
||||
s.tokStart = s.srcPos.Offset - s.lastCharLen
|
||||
|
||||
// token position, initial next() is moving the offset by one(size of rune
|
||||
// actually), though we are interested with the starting point
|
||||
s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen
|
||||
if s.srcPos.Column > 0 {
|
||||
// common case: last character was not a '\n'
|
||||
s.tokPos.Line = s.srcPos.Line
|
||||
s.tokPos.Column = s.srcPos.Column
|
||||
} else {
|
||||
// last character was a '\n'
|
||||
// (we cannot be at the beginning of the source
|
||||
// since we have called next() at least once)
|
||||
s.tokPos.Line = s.srcPos.Line - 1
|
||||
s.tokPos.Column = s.lastLineLen
|
||||
}
|
||||
|
||||
switch {
|
||||
case isLetter(ch):
|
||||
lit := s.scanIdentifier()
|
||||
if lit == "true" || lit == "false" {
|
||||
tok = token.BOOL
|
||||
} else if lit == "null" {
|
||||
tok = token.NULL
|
||||
} else {
|
||||
s.err("illegal char")
|
||||
}
|
||||
case isDecimal(ch):
|
||||
tok = s.scanNumber(ch)
|
||||
default:
|
||||
switch ch {
|
||||
case eof:
|
||||
tok = token.EOF
|
||||
case '"':
|
||||
tok = token.STRING
|
||||
s.scanString()
|
||||
case '.':
|
||||
tok = token.PERIOD
|
||||
ch = s.peek()
|
||||
if isDecimal(ch) {
|
||||
tok = token.FLOAT
|
||||
ch = s.scanMantissa(ch)
|
||||
ch = s.scanExponent(ch)
|
||||
}
|
||||
case '[':
|
||||
tok = token.LBRACK
|
||||
case ']':
|
||||
tok = token.RBRACK
|
||||
case '{':
|
||||
tok = token.LBRACE
|
||||
case '}':
|
||||
tok = token.RBRACE
|
||||
case ',':
|
||||
tok = token.COMMA
|
||||
case ':':
|
||||
tok = token.COLON
|
||||
case '-':
|
||||
if isDecimal(s.peek()) {
|
||||
ch := s.next()
|
||||
tok = s.scanNumber(ch)
|
||||
} else {
|
||||
s.err("illegal char")
|
||||
}
|
||||
default:
|
||||
s.err("illegal char: " + string(ch))
|
||||
}
|
||||
}
|
||||
|
||||
// finish token ending
|
||||
s.tokEnd = s.srcPos.Offset
|
||||
|
||||
// create token literal
|
||||
var tokenText string
|
||||
if s.tokStart >= 0 {
|
||||
tokenText = string(s.src[s.tokStart:s.tokEnd])
|
||||
}
|
||||
s.tokStart = s.tokEnd // ensure idempotency of tokenText() call
|
||||
|
||||
return token.Token{
|
||||
Type: tok,
|
||||
Pos: s.tokPos,
|
||||
Text: tokenText,
|
||||
}
|
||||
}
|
||||
|
||||
// scanNumber scans a HCL number definition starting with the given rune
|
||||
func (s *Scanner) scanNumber(ch rune) token.Type {
|
||||
zero := ch == '0'
|
||||
pos := s.srcPos
|
||||
|
||||
s.scanMantissa(ch)
|
||||
ch = s.next() // seek forward
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.scanExponent(ch)
|
||||
return token.FLOAT
|
||||
}
|
||||
|
||||
if ch == '.' {
|
||||
ch = s.scanFraction(ch)
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.next()
|
||||
ch = s.scanExponent(ch)
|
||||
}
|
||||
return token.FLOAT
|
||||
}
|
||||
|
||||
if ch != eof {
|
||||
s.unread()
|
||||
}
|
||||
|
||||
// If we have a larger number and this is zero, error
|
||||
if zero && pos != s.srcPos {
|
||||
s.err("numbers cannot start with 0")
|
||||
}
|
||||
|
||||
return token.NUMBER
|
||||
}
|
||||
|
||||
// scanMantissa scans the mantissa begining from the rune. It returns the next
|
||||
// non decimal rune. It's used to determine wheter it's a fraction or exponent.
|
||||
func (s *Scanner) scanMantissa(ch rune) rune {
|
||||
scanned := false
|
||||
for isDecimal(ch) {
|
||||
ch = s.next()
|
||||
scanned = true
|
||||
}
|
||||
|
||||
if scanned && ch != eof {
|
||||
s.unread()
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanFraction scans the fraction after the '.' rune
|
||||
func (s *Scanner) scanFraction(ch rune) rune {
|
||||
if ch == '.' {
|
||||
ch = s.peek() // we peek just to see if we can move forward
|
||||
ch = s.scanMantissa(ch)
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanExponent scans the remaining parts of an exponent after the 'e' or 'E'
|
||||
// rune.
|
||||
func (s *Scanner) scanExponent(ch rune) rune {
|
||||
if ch == 'e' || ch == 'E' {
|
||||
ch = s.next()
|
||||
if ch == '-' || ch == '+' {
|
||||
ch = s.next()
|
||||
}
|
||||
ch = s.scanMantissa(ch)
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanString scans a quoted string
|
||||
func (s *Scanner) scanString() {
|
||||
braces := 0
|
||||
for {
|
||||
// '"' opening already consumed
|
||||
// read character after quote
|
||||
ch := s.next()
|
||||
|
||||
if ch == '\n' || ch < 0 || ch == eof {
|
||||
s.err("literal not terminated")
|
||||
return
|
||||
}
|
||||
|
||||
if ch == '"' && braces == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// If we're going into a ${} then we can ignore quotes for awhile
|
||||
if braces == 0 && ch == '$' && s.peek() == '{' {
|
||||
braces++
|
||||
s.next()
|
||||
} else if braces > 0 && ch == '{' {
|
||||
braces++
|
||||
}
|
||||
if braces > 0 && ch == '}' {
|
||||
braces--
|
||||
}
|
||||
|
||||
if ch == '\\' {
|
||||
s.scanEscape()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// scanEscape scans an escape sequence
|
||||
func (s *Scanner) scanEscape() rune {
|
||||
// http://en.cppreference.com/w/cpp/language/escape
|
||||
ch := s.next() // read character after '/'
|
||||
switch ch {
|
||||
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"':
|
||||
// nothing to do
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
// octal notation
|
||||
ch = s.scanDigits(ch, 8, 3)
|
||||
case 'x':
|
||||
// hexademical notation
|
||||
ch = s.scanDigits(s.next(), 16, 2)
|
||||
case 'u':
|
||||
// universal character name
|
||||
ch = s.scanDigits(s.next(), 16, 4)
|
||||
case 'U':
|
||||
// universal character name
|
||||
ch = s.scanDigits(s.next(), 16, 8)
|
||||
default:
|
||||
s.err("illegal char escape")
|
||||
}
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanDigits scans a rune with the given base for n times. For example an
|
||||
// octal notation \184 would yield in scanDigits(ch, 8, 3)
|
||||
func (s *Scanner) scanDigits(ch rune, base, n int) rune {
|
||||
for n > 0 && digitVal(ch) < base {
|
||||
ch = s.next()
|
||||
n--
|
||||
}
|
||||
if n > 0 {
|
||||
s.err("illegal char escape")
|
||||
}
|
||||
|
||||
// we scanned all digits, put the last non digit char back
|
||||
s.unread()
|
||||
return ch
|
||||
}
|
||||
|
||||
// scanIdentifier scans an identifier and returns the literal string
|
||||
func (s *Scanner) scanIdentifier() string {
|
||||
offs := s.srcPos.Offset - s.lastCharLen
|
||||
ch := s.next()
|
||||
for isLetter(ch) || isDigit(ch) || ch == '-' {
|
||||
ch = s.next()
|
||||
}
|
||||
|
||||
if ch != eof {
|
||||
s.unread() // we got identifier, put back latest char
|
||||
}
|
||||
|
||||
return string(s.src[offs:s.srcPos.Offset])
|
||||
}
|
||||
|
||||
// recentPosition returns the position of the character immediately after the
|
||||
// character or token returned by the last call to Scan.
|
||||
func (s *Scanner) recentPosition() (pos token.Pos) {
|
||||
pos.Offset = s.srcPos.Offset - s.lastCharLen
|
||||
switch {
|
||||
case s.srcPos.Column > 0:
|
||||
// common case: last character was not a '\n'
|
||||
pos.Line = s.srcPos.Line
|
||||
pos.Column = s.srcPos.Column
|
||||
case s.lastLineLen > 0:
|
||||
// last character was a '\n'
|
||||
// (we cannot be at the beginning of the source
|
||||
// since we have called next() at least once)
|
||||
pos.Line = s.srcPos.Line - 1
|
||||
pos.Column = s.lastLineLen
|
||||
default:
|
||||
// at the beginning of the source
|
||||
pos.Line = 1
|
||||
pos.Column = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// err prints the error of any scanning to s.Error function. If the function is
|
||||
// not defined, by default it prints them to os.Stderr
|
||||
func (s *Scanner) err(msg string) {
|
||||
s.ErrorCount++
|
||||
pos := s.recentPosition()
|
||||
|
||||
if s.Error != nil {
|
||||
s.Error(pos, msg)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
|
||||
}
|
||||
|
||||
// isHexadecimal returns true if the given rune is a letter
|
||||
func isLetter(ch rune) bool {
|
||||
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch)
|
||||
}
|
||||
|
||||
// isHexadecimal returns true if the given rune is a decimal digit
|
||||
func isDigit(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
|
||||
}
|
||||
|
||||
// isHexadecimal returns true if the given rune is a decimal number
|
||||
func isDecimal(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9'
|
||||
}
|
||||
|
||||
// isHexadecimal returns true if the given rune is an hexadecimal number
|
||||
func isHexadecimal(ch rune) bool {
|
||||
return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F'
|
||||
}
|
||||
|
||||
// isWhitespace returns true if the rune is a space, tab, newline or carriage return
|
||||
func isWhitespace(ch rune) bool {
|
||||
return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'
|
||||
}
|
||||
|
||||
// digitVal returns the integer value of a given octal,decimal or hexadecimal rune
|
||||
func digitVal(ch rune) int {
|
||||
switch {
|
||||
case '0' <= ch && ch <= '9':
|
||||
return int(ch - '0')
|
||||
case 'a' <= ch && ch <= 'f':
|
||||
return int(ch - 'a' + 10)
|
||||
case 'A' <= ch && ch <= 'F':
|
||||
return int(ch - 'A' + 10)
|
||||
}
|
||||
return 16 // larger than any legal digit val
|
||||
}
|
46
vendor/github.com/hashicorp/hcl/json/token/position.go
generated
vendored
Normal file
46
vendor/github.com/hashicorp/hcl/json/token/position.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package token
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Pos describes an arbitrary source position
|
||||
// including the file, line, and column location.
|
||||
// A Position is valid if the line number is > 0.
|
||||
type Pos struct {
|
||||
Filename string // filename, if any
|
||||
Offset int // offset, starting at 0
|
||||
Line int // line number, starting at 1
|
||||
Column int // column number, starting at 1 (character count)
|
||||
}
|
||||
|
||||
// IsValid returns true if the position is valid.
|
||||
func (p *Pos) IsValid() bool { return p.Line > 0 }
|
||||
|
||||
// String returns a string in one of several forms:
|
||||
//
|
||||
// file:line:column valid position with file name
|
||||
// line:column valid position without file name
|
||||
// file invalid position with file name
|
||||
// - invalid position without file name
|
||||
func (p Pos) String() string {
|
||||
s := p.Filename
|
||||
if p.IsValid() {
|
||||
if s != "" {
|
||||
s += ":"
|
||||
}
|
||||
s += fmt.Sprintf("%d:%d", p.Line, p.Column)
|
||||
}
|
||||
if s == "" {
|
||||
s = "-"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Before reports whether the position p is before u.
|
||||
func (p Pos) Before(u Pos) bool {
|
||||
return u.Offset > p.Offset || u.Line > p.Line
|
||||
}
|
||||
|
||||
// After reports whether the position p is after u.
|
||||
func (p Pos) After(u Pos) bool {
|
||||
return u.Offset < p.Offset || u.Line < p.Line
|
||||
}
|
118
vendor/github.com/hashicorp/hcl/json/token/token.go
generated
vendored
Normal file
118
vendor/github.com/hashicorp/hcl/json/token/token.go
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
package token
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
hcltoken "github.com/hashicorp/hcl/hcl/token"
|
||||
)
|
||||
|
||||
// Token defines a single HCL token which can be obtained via the Scanner
|
||||
type Token struct {
|
||||
Type Type
|
||||
Pos Pos
|
||||
Text string
|
||||
}
|
||||
|
||||
// Type is the set of lexical tokens of the HCL (HashiCorp Configuration Language)
|
||||
type Type int
|
||||
|
||||
const (
|
||||
// Special tokens
|
||||
ILLEGAL Type = iota
|
||||
EOF
|
||||
|
||||
identifier_beg
|
||||
literal_beg
|
||||
NUMBER // 12345
|
||||
FLOAT // 123.45
|
||||
BOOL // true,false
|
||||
STRING // "abc"
|
||||
NULL // null
|
||||
literal_end
|
||||
identifier_end
|
||||
|
||||
operator_beg
|
||||
LBRACK // [
|
||||
LBRACE // {
|
||||
COMMA // ,
|
||||
PERIOD // .
|
||||
COLON // :
|
||||
|
||||
RBRACK // ]
|
||||
RBRACE // }
|
||||
|
||||
operator_end
|
||||
)
|
||||
|
||||
var tokens = [...]string{
|
||||
ILLEGAL: "ILLEGAL",
|
||||
|
||||
EOF: "EOF",
|
||||
|
||||
NUMBER: "NUMBER",
|
||||
FLOAT: "FLOAT",
|
||||
BOOL: "BOOL",
|
||||
STRING: "STRING",
|
||||
NULL: "NULL",
|
||||
|
||||
LBRACK: "LBRACK",
|
||||
LBRACE: "LBRACE",
|
||||
COMMA: "COMMA",
|
||||
PERIOD: "PERIOD",
|
||||
COLON: "COLON",
|
||||
|
||||
RBRACK: "RBRACK",
|
||||
RBRACE: "RBRACE",
|
||||
}
|
||||
|
||||
// String returns the string corresponding to the token tok.
|
||||
func (t Type) String() string {
|
||||
s := ""
|
||||
if 0 <= t && t < Type(len(tokens)) {
|
||||
s = tokens[t]
|
||||
}
|
||||
if s == "" {
|
||||
s = "token(" + strconv.Itoa(int(t)) + ")"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// IsIdentifier returns true for tokens corresponding to identifiers and basic
|
||||
// type literals; it returns false otherwise.
|
||||
func (t Type) IsIdentifier() bool { return identifier_beg < t && t < identifier_end }
|
||||
|
||||
// IsLiteral returns true for tokens corresponding to basic type literals; it
|
||||
// returns false otherwise.
|
||||
func (t Type) IsLiteral() bool { return literal_beg < t && t < literal_end }
|
||||
|
||||
// IsOperator returns true for tokens corresponding to operators and
|
||||
// delimiters; it returns false otherwise.
|
||||
func (t Type) IsOperator() bool { return operator_beg < t && t < operator_end }
|
||||
|
||||
// String returns the token's literal text. Note that this is only
|
||||
// applicable for certain token types, such as token.IDENT,
|
||||
// token.STRING, etc..
|
||||
func (t Token) String() string {
|
||||
return fmt.Sprintf("%s %s %s", t.Pos.String(), t.Type.String(), t.Text)
|
||||
}
|
||||
|
||||
// HCLToken converts this token to an HCL token.
|
||||
//
|
||||
// The token type must be a literal type or this will panic.
|
||||
func (t Token) HCLToken() hcltoken.Token {
|
||||
switch t.Type {
|
||||
case BOOL:
|
||||
return hcltoken.Token{Type: hcltoken.BOOL, Text: t.Text}
|
||||
case FLOAT:
|
||||
return hcltoken.Token{Type: hcltoken.FLOAT, Text: t.Text}
|
||||
case NULL:
|
||||
return hcltoken.Token{Type: hcltoken.STRING, Text: ""}
|
||||
case NUMBER:
|
||||
return hcltoken.Token{Type: hcltoken.NUMBER, Text: t.Text}
|
||||
case STRING:
|
||||
return hcltoken.Token{Type: hcltoken.STRING, Text: t.Text, JSON: true}
|
||||
default:
|
||||
panic(fmt.Sprintf("unimplemented HCLToken for type: %s", t.Type))
|
||||
}
|
||||
}
|
31
vendor/github.com/hashicorp/hcl/lex.go
generated
vendored
Normal file
31
vendor/github.com/hashicorp/hcl/lex.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
package hcl
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type lexModeValue byte
|
||||
|
||||
const (
|
||||
lexModeUnknown lexModeValue = iota
|
||||
lexModeHcl
|
||||
lexModeJson
|
||||
)
|
||||
|
||||
// lexMode returns whether we're going to be parsing in JSON
|
||||
// mode or HCL mode.
|
||||
func lexMode(v string) lexModeValue {
|
||||
for _, r := range v {
|
||||
if unicode.IsSpace(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
if r == '{' {
|
||||
return lexModeJson
|
||||
} else {
|
||||
return lexModeHcl
|
||||
}
|
||||
}
|
||||
|
||||
return lexModeHcl
|
||||
}
|
23
vendor/github.com/hashicorp/hcl/parse.go
generated
vendored
Normal file
23
vendor/github.com/hashicorp/hcl/parse.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
package hcl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
hclParser "github.com/hashicorp/hcl/hcl/parser"
|
||||
jsonParser "github.com/hashicorp/hcl/json/parser"
|
||||
)
|
||||
|
||||
// Parse parses the given input and returns the root object.
|
||||
//
|
||||
// The input format can be either HCL or JSON.
|
||||
func Parse(input string) (*ast.File, error) {
|
||||
switch lexMode(input) {
|
||||
case lexModeHcl:
|
||||
return hclParser.Parse([]byte(input))
|
||||
case lexModeJson:
|
||||
return jsonParser.Parse([]byte(input))
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown config format")
|
||||
}
|
363
vendor/github.com/hashicorp/vault/LICENSE
generated
vendored
Normal file
363
vendor/github.com/hashicorp/vault/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
611
vendor/github.com/hashicorp/vault/api/SPEC.md
generated
vendored
Normal file
611
vendor/github.com/hashicorp/vault/api/SPEC.md
generated
vendored
Normal file
|
@ -0,0 +1,611 @@
|
|||
FORMAT: 1A
|
||||
|
||||
# vault
|
||||
|
||||
The Vault API gives you full access to the Vault project.
|
||||
|
||||
If you're browsing this API specifiction in GitHub or in raw
|
||||
format, please excuse some of the odd formatting. This document
|
||||
is in api-blueprint format that is read by viewers such as
|
||||
Apiary.
|
||||
|
||||
## Sealed vs. Unsealed
|
||||
|
||||
Whenever an individual Vault server is started, it is started
|
||||
in the _sealed_ state. In this state, it knows where its data
|
||||
is located, but the data is encrypted and Vault doesn't have the
|
||||
encryption keys to access it. Before Vault can operate, it must
|
||||
be _unsealed_.
|
||||
|
||||
**Note:** Sealing/unsealing has no relationship to _authentication_
|
||||
which is separate and still required once the Vault is unsealed.
|
||||
|
||||
Instead of being sealed with a single key, we utilize
|
||||
[Shamir's Secret Sharing](http://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing)
|
||||
to shard a key into _n_ parts such that _t_ parts are required
|
||||
to reconstruct the original key, where `t <= n`. This means that
|
||||
Vault itself doesn't know the original key, and no single person
|
||||
has the original key (unless `n = 1`, or `t` parts are given to
|
||||
a single person).
|
||||
|
||||
Unsealing is done via an unauthenticated
|
||||
[unseal API](#reference/seal/unseal/unseal). This API takes a single
|
||||
master shard and progresses the unsealing process. Once all shards
|
||||
are given, the Vault is either unsealed or resets the unsealing
|
||||
process if the key was invalid.
|
||||
|
||||
The entire seal/unseal state is server-wide. This allows multiple
|
||||
distinct operators to use the unseal API (or more likely the
|
||||
`vault unseal` command) from separate computers/networks and never
|
||||
have to transmit their key in order to unseal the vault in a
|
||||
distributed fashion.
|
||||
|
||||
## Transport
|
||||
|
||||
The API is expected to be accessed over a TLS connection at
|
||||
all times, with a valid certificate that is verified by a well
|
||||
behaved client.
|
||||
|
||||
## Authentication
|
||||
|
||||
Once the Vault is unsealed, every other operation requires
|
||||
authentication. There are multiple methods for authentication
|
||||
that can be enabled (see
|
||||
[authentication](#reference/authentication)).
|
||||
|
||||
Authentication is done with the login endpoint. The login endpoint
|
||||
returns an access token that is set as the `X-Vault-Token` header.
|
||||
|
||||
## Help
|
||||
|
||||
To retrieve the help for any API within Vault, including mounted
|
||||
backends, credential providers, etc. then append `?help=1` to any
|
||||
URL. If you have valid permission to access the path, then the help text
|
||||
will be returned with the following structure:
|
||||
|
||||
{
|
||||
"help": "help text"
|
||||
}
|
||||
|
||||
## Error Response
|
||||
|
||||
A common JSON structure is always returned to return errors:
|
||||
|
||||
{
|
||||
"errors": [
|
||||
"message",
|
||||
"another message"
|
||||
]
|
||||
}
|
||||
|
||||
This structure will be sent down for any non-20x HTTP status.
|
||||
|
||||
## HTTP Status Codes
|
||||
|
||||
The following HTTP status codes are used throughout the API.
|
||||
|
||||
- `200` - Success with data.
|
||||
- `204` - Success, no data returned.
|
||||
- `400` - Invalid request, missing or invalid data.
|
||||
- `403` - Forbidden, your authentication details are either
|
||||
incorrect or you don't have access to this feature.
|
||||
- `404` - Invalid path. This can both mean that the path truly
|
||||
doesn't exist or that you don't have permission to view a
|
||||
specific path. We use 404 in some cases to avoid state leakage.
|
||||
- `429` - Rate limit exceeded. Try again after waiting some period
|
||||
of time.
|
||||
- `500` - Internal server error. An internal error has occurred,
|
||||
try again later. If the error persists, report a bug.
|
||||
- `503` - Vault is down for maintenance or is currently sealed.
|
||||
Try again later.
|
||||
|
||||
# Group Initialization
|
||||
|
||||
## Initialization [/sys/init]
|
||||
### Initialization Status [GET]
|
||||
Returns the status of whether the vault is initialized or not. The
|
||||
vault doesn't have to be unsealed for this operation.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"initialized": true
|
||||
}
|
||||
|
||||
### Initialize [POST]
|
||||
Initialize the vault. This is an unauthenticated request to initially
|
||||
setup a new vault. Although this is unauthenticated, it is still safe:
|
||||
data cannot be in vault prior to initialization, and any future
|
||||
authentication will fail if you didn't initialize it yourself.
|
||||
Additionally, once initialized, a vault cannot be reinitialized.
|
||||
|
||||
This API is the only time Vault will ever be aware of your keys, and
|
||||
the only time the keys will ever be returned in one unit. Care should
|
||||
be taken to ensure that the output of this request is never logged,
|
||||
and that the keys are properly distributed.
|
||||
|
||||
The response also contains the initial root token that can be used
|
||||
as authentication in order to initially configure Vault once it is
|
||||
unsealed. Just as with the unseal keys, this is the only time Vault is
|
||||
ever aware of this token.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"secret_shares": 5,
|
||||
"secret_threshold": 3,
|
||||
}
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"keys": ["one", "two", "three"],
|
||||
"root_token": "foo"
|
||||
}
|
||||
|
||||
# Group Seal/Unseal
|
||||
|
||||
## Seal Status [/sys/seal-status]
|
||||
### Seal Status [GET]
|
||||
Returns the status of whether the vault is currently
|
||||
sealed or not, as well as the progress of unsealing.
|
||||
|
||||
The response has the following attributes:
|
||||
|
||||
- sealed (boolean) - If true, the vault is sealed. Otherwise,
|
||||
it is unsealed.
|
||||
- t (int) - The "t" value for the master key, or the number
|
||||
of shards needed total to unseal the vault.
|
||||
- n (int) - The "n" value for the master key, or the total
|
||||
number of shards of the key distributed.
|
||||
- progress (int) - The number of master key shards that have
|
||||
been entered so far towards unsealing the vault.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"sealed": true,
|
||||
"t": 3,
|
||||
"n": 5,
|
||||
"progress": 1
|
||||
}
|
||||
|
||||
## Seal [/sys/seal]
|
||||
### Seal [PUT]
|
||||
Seal the vault.
|
||||
|
||||
Sealing the vault locks Vault from any future operations on any
|
||||
secrets or system configuration until the vault is once again
|
||||
unsealed. Internally, sealing throws away the keys to access the
|
||||
encrypted vault data, so Vault is unable to access the data without
|
||||
unsealing to get the encryption keys.
|
||||
|
||||
+ Response 204
|
||||
|
||||
## Unseal [/sys/unseal]
|
||||
### Unseal [PUT]
|
||||
Unseal the vault.
|
||||
|
||||
Unseal the vault by entering a portion of the master key. The
|
||||
response object will tell you if the unseal is complete or
|
||||
only partial.
|
||||
|
||||
If the vault is already unsealed, this does nothing. It is
|
||||
not an error, the return value just says the vault is unsealed.
|
||||
Due to the architecture of Vault, we cannot validate whether
|
||||
any portion of the unseal key given is valid until all keys
|
||||
are inputted, therefore unsealing an already unsealed vault
|
||||
is still a success even if the input key is invalid.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"key": "value"
|
||||
}
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"sealed": true,
|
||||
"t": 3,
|
||||
"n": 5,
|
||||
"progress": 1
|
||||
}
|
||||
|
||||
# Group Authentication
|
||||
|
||||
## List Auth Methods [/sys/auth]
|
||||
### List all auth methods [GET]
|
||||
Lists all available authentication methods.
|
||||
|
||||
This returns the name of the authentication method as well as
|
||||
a human-friendly long-form help text for the method that can be
|
||||
shown to the user as documentation.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"token": {
|
||||
"type": "token",
|
||||
"description": "Token authentication"
|
||||
},
|
||||
"oauth": {
|
||||
"type": "oauth",
|
||||
"description": "OAuth authentication"
|
||||
}
|
||||
}
|
||||
|
||||
## Single Auth Method [/sys/auth/{id}]
|
||||
|
||||
+ Parameters
|
||||
+ id (required, string) ... The ID of the auth method.
|
||||
|
||||
### Enable an auth method [PUT]
|
||||
Enables an authentication method.
|
||||
|
||||
The body of the request depends on the authentication method
|
||||
being used. Please reference the documentation for the specific
|
||||
authentication method you're enabling in order to determine what
|
||||
parameters you must give it.
|
||||
|
||||
If an authentication method is already enabled, then this can be
|
||||
used to change the configuration, including even the type of
|
||||
the configuration.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"type": "type",
|
||||
"key": "value",
|
||||
"key2": "value2"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
### Disable an auth method [DELETE]
|
||||
Disables an authentication method. Previously authenticated sessions
|
||||
are immediately invalidated.
|
||||
|
||||
+ Response 204
|
||||
|
||||
# Group Policies
|
||||
|
||||
Policies are named permission sets that identities returned by
|
||||
credential stores are bound to. This separates _authentication_
|
||||
from _authorization_.
|
||||
|
||||
## Policies [/sys/policy]
|
||||
### List all Policies [GET]
|
||||
|
||||
List all the policies.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"policies": ["root"]
|
||||
}
|
||||
|
||||
## Single Policy [/sys/policy/{id}]
|
||||
|
||||
+ Parameters
|
||||
+ id (required, string) ... The name of the policy
|
||||
|
||||
### Upsert [PUT]
|
||||
|
||||
Create or update a policy with the given ID.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"rules": "HCL"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
### Delete [DELETE]
|
||||
|
||||
Delete a policy with the given ID. Any identities bound to this
|
||||
policy will immediately become "deny all" despite already being
|
||||
authenticated.
|
||||
|
||||
+ Response 204
|
||||
|
||||
# Group Mounts
|
||||
|
||||
Logical backends are mounted at _mount points_, similar to
|
||||
filesystems. This allows you to mount the "aws" logical backend
|
||||
at the "aws-us-east" path, so all access is at `/aws-us-east/keys/foo`
|
||||
for example. This enables multiple logical backends to be enabled.
|
||||
|
||||
## Mounts [/sys/mounts]
|
||||
### List all mounts [GET]
|
||||
|
||||
Lists all the active mount points.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"aws": {
|
||||
"type": "aws",
|
||||
"description": "AWS"
|
||||
},
|
||||
"pg": {
|
||||
"type": "postgresql",
|
||||
"description": "PostgreSQL dynamic users"
|
||||
}
|
||||
}
|
||||
|
||||
## Single Mount [/sys/mounts/{path}]
|
||||
### New Mount [POST]
|
||||
|
||||
Mount a logical backend to a new path.
|
||||
|
||||
Configuration for this new backend is done via the normal
|
||||
read/write mechanism once it is mounted.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"type": "aws",
|
||||
"description": "EU AWS tokens"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
### Unmount [DELETE]
|
||||
|
||||
Unmount a mount point.
|
||||
|
||||
+ Response 204
|
||||
|
||||
## Remount [/sys/remount]
|
||||
### Remount [POST]
|
||||
|
||||
Move an already-mounted backend to a new path.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"from": "aws",
|
||||
"to": "aws-east"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
# Group Audit Backends
|
||||
|
||||
Audit backends are responsible for shuttling the audit logs that
|
||||
Vault generates to a durable system for future querying. By default,
|
||||
audit logs are not stored anywhere.
|
||||
|
||||
## Audit Backends [/sys/audit]
|
||||
### List Enabled Audit Backends [GET]
|
||||
|
||||
List all the enabled audit backends
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"file": {
|
||||
"type": "file",
|
||||
"description": "Send audit logs to a file",
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
|
||||
## Single Audit Backend [/sys/audit/{path}]
|
||||
|
||||
+ Parameters
|
||||
+ path (required, string) ... The path where the audit backend is mounted
|
||||
|
||||
### Enable [PUT]
|
||||
|
||||
Enable an audit backend.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"type": "file",
|
||||
"description": "send to a file",
|
||||
"options": {
|
||||
"path": "/var/log/vault.audit.log"
|
||||
}
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
### Disable [DELETE]
|
||||
|
||||
Disable an audit backend.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
+ Response 204
|
||||
|
||||
# Group Secrets
|
||||
|
||||
## Generic [/{mount}/{path}]
|
||||
|
||||
This group documents the general format of reading and writing
|
||||
to Vault. The exact structure of the keyspace is defined by the
|
||||
logical backends in use, so documentation related to
|
||||
a specific backend should be referenced for details on what keys
|
||||
and routes are expected.
|
||||
|
||||
The path for examples are `/prefix/path`, but in practice
|
||||
these will be defined by the backends that are mounted. For
|
||||
example, reading an AWS key might be at the `/aws/root` path.
|
||||
These paths are defined by the logical backends.
|
||||
|
||||
+ Parameters
|
||||
+ mount (required, string) ... The mount point for the
|
||||
logical backend. Example: `aws`.
|
||||
+ path (optional, string) ... The path within the backend
|
||||
to read or write data.
|
||||
|
||||
### Read [GET]
|
||||
|
||||
Read data from vault.
|
||||
|
||||
The data read from the vault can either be a secret or
|
||||
arbitrary configuration data. The type of data returned
|
||||
depends on the path, and is defined by the logical backend.
|
||||
|
||||
If the return value is a secret, then the return structure
|
||||
is a mixture of arbitrary key/value along with the following
|
||||
fields which are guaranteed to exist:
|
||||
|
||||
- `lease_id` (string) - A unique ID used for renewal and
|
||||
revocation.
|
||||
|
||||
- `renewable` (bool) - If true, then this key can be renewed.
|
||||
If a key can't be renewed, then a new key must be requested
|
||||
after the lease duration period.
|
||||
|
||||
- `lease_duration` (int) - The time in seconds that a secret is
|
||||
valid for before it must be renewed.
|
||||
|
||||
- `lease_duration_max` (int) - The maximum amount of time in
|
||||
seconds that a secret is valid for. This will always be
|
||||
greater than or equal to `lease_duration`. The difference
|
||||
between this and `lease_duration` is an overlap window
|
||||
where multiple keys may be valid.
|
||||
|
||||
If the return value is not a secret, then the return structure
|
||||
is an arbitrary JSON object.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"lease_id": "UUID",
|
||||
"lease_duration": 3600,
|
||||
"key": "value"
|
||||
}
|
||||
|
||||
### Write [PUT]
|
||||
|
||||
Write data to vault.
|
||||
|
||||
The behavior and arguments to the write are defined by
|
||||
the logical backend.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"key": "value"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
# Group Lease Management
|
||||
|
||||
## Renew Key [/sys/renew/{id}]
|
||||
|
||||
+ Parameters
|
||||
+ id (required, string) ... The `lease_id` of the secret
|
||||
to renew.
|
||||
|
||||
### Renew [PUT]
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"lease_id": "...",
|
||||
"lease_duration": 3600,
|
||||
"access_key": "foo",
|
||||
"secret_key": "bar"
|
||||
}
|
||||
|
||||
## Revoke Key [/sys/revoke/{id}]
|
||||
|
||||
+ Parameters
|
||||
+ id (required, string) ... The `lease_id` of the secret
|
||||
to revoke.
|
||||
|
||||
### Revoke [PUT]
|
||||
|
||||
+ Response 204
|
||||
|
||||
# Group Backend: AWS
|
||||
|
||||
## Root Key [/aws/root]
|
||||
### Set the Key [PUT]
|
||||
|
||||
Set the root key that the logical backend will use to create
|
||||
new secrets, IAM policies, etc.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"access_key": "key",
|
||||
"secret_key": "key",
|
||||
"region": "us-east-1"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
## Policies [/aws/policies]
|
||||
### List Policies [GET]
|
||||
|
||||
List all the policies that can be used to create keys.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
[{
|
||||
"name": "root",
|
||||
"description": "Root access"
|
||||
}, {
|
||||
"name": "web-deploy",
|
||||
"description": "Enough permissions to deploy the web app."
|
||||
}]
|
||||
|
||||
## Single Policy [/aws/policies/{name}]
|
||||
|
||||
+ Parameters
|
||||
+ name (required, string) ... Name of the policy.
|
||||
|
||||
### Read [GET]
|
||||
|
||||
Read a policy.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"policy": "base64-encoded policy"
|
||||
}
|
||||
|
||||
### Upsert [PUT]
|
||||
|
||||
Create or update a policy.
|
||||
|
||||
+ Request (application/json)
|
||||
|
||||
{
|
||||
"policy": "base64-encoded policy"
|
||||
}
|
||||
|
||||
+ Response 204
|
||||
|
||||
### Delete [DELETE]
|
||||
|
||||
Delete the policy with the given name.
|
||||
|
||||
+ Response 204
|
||||
|
||||
## Generate Access Keys [/aws/keys/{policy}]
|
||||
### Create [GET]
|
||||
|
||||
This generates a new keypair for the given policy.
|
||||
|
||||
+ Parameters
|
||||
+ policy (required, string) ... The policy under which to create
|
||||
the key pair.
|
||||
|
||||
+ Response 200 (application/json)
|
||||
|
||||
{
|
||||
"lease_id": "...",
|
||||
"lease_duration": 3600,
|
||||
"access_key": "foo",
|
||||
"secret_key": "bar"
|
||||
}
|
11
vendor/github.com/hashicorp/vault/api/auth.go
generated
vendored
Normal file
11
vendor/github.com/hashicorp/vault/api/auth.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package api
|
||||
|
||||
// Auth is used to perform credential backend related operations.
|
||||
type Auth struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Auth is used to return the client for logical-backend API calls.
|
||||
func (c *Client) Auth() *Auth {
|
||||
return &Auth{c: c}
|
||||
}
|
149
vendor/github.com/hashicorp/vault/api/auth_token.go
generated
vendored
Normal file
149
vendor/github.com/hashicorp/vault/api/auth_token.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
package api
|
||||
|
||||
// TokenAuth is used to perform token backend operations on Vault.
|
||||
type TokenAuth struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Token is used to return the client for logical-backend API calls.
|
||||
func (a *Auth) Token() *TokenAuth {
|
||||
return &TokenAuth{c: a.c}
|
||||
}
|
||||
|
||||
func (c *TokenAuth) Create(opts *TokenCreateRequest) (*Secret, error) {
|
||||
r := c.c.NewRequest("POST", "/v1/auth/token/create")
|
||||
if err := r.SetJSONBody(opts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *TokenAuth) Lookup(token string) (*Secret, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/auth/token/lookup/"+token)
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *TokenAuth) LookupSelf() (*Secret, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/auth/token/lookup-self")
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *TokenAuth) Renew(token string, increment int) (*Secret, error) {
|
||||
r := c.c.NewRequest("PUT", "/v1/auth/token/renew/"+token)
|
||||
|
||||
body := map[string]interface{}{"increment": increment}
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *TokenAuth) RenewSelf(increment int) (*Secret, error) {
|
||||
r := c.c.NewRequest("PUT", "/v1/auth/token/renew-self")
|
||||
|
||||
body := map[string]interface{}{"increment": increment}
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
// RevokeOrphan revokes a token without revoking the tree underneath it (so
|
||||
// child tokens are orphaned rather than revoked)
|
||||
func (c *TokenAuth) RevokeOrphan(token string) error {
|
||||
r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-orphan/"+token)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RevokePrefix revokes a token based on a prefix, which can be used to revoke
|
||||
// e.g. all tokens issued by a certain credential mount
|
||||
func (c *TokenAuth) RevokePrefix(token string) error {
|
||||
r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-prefix/"+token)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RevokeSelf revokes the token making the call
|
||||
func (c *TokenAuth) RevokeSelf() error {
|
||||
r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-self")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RevokeTree is the "normal" revoke operation that revokes the given token and
|
||||
// the entire tree underneath -- all of its child tokens, their child tokens,
|
||||
// etc.
|
||||
func (c *TokenAuth) RevokeTree(token string) error {
|
||||
r := c.c.NewRequest("PUT", "/v1/auth/token/revoke/"+token)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TokenCreateRequest is the options structure for creating a token.
|
||||
type TokenCreateRequest struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Policies []string `json:"policies,omitempty"`
|
||||
Metadata map[string]string `json:"meta,omitempty"`
|
||||
Lease string `json:"lease,omitempty"`
|
||||
TTL string `json:"ttl,omitempty"`
|
||||
NoParent bool `json:"no_parent,omitempty"`
|
||||
NoDefaultPolicy bool `json:"no_default_policy,omitempty"`
|
||||
DisplayName string `json:"display_name"`
|
||||
NumUses int `json:"num_uses"`
|
||||
}
|
375
vendor/github.com/hashicorp/vault/api/client.go
generated
vendored
Normal file
375
vendor/github.com/hashicorp/vault/api/client.go
generated
vendored
Normal file
|
@ -0,0 +1,375 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
)
|
||||
|
||||
const EnvVaultAddress = "VAULT_ADDR"
|
||||
const EnvVaultCACert = "VAULT_CACERT"
|
||||
const EnvVaultCAPath = "VAULT_CAPATH"
|
||||
const EnvVaultClientCert = "VAULT_CLIENT_CERT"
|
||||
const EnvVaultClientKey = "VAULT_CLIENT_KEY"
|
||||
const EnvVaultInsecure = "VAULT_SKIP_VERIFY"
|
||||
|
||||
var (
|
||||
errRedirect = errors.New("redirect")
|
||||
)
|
||||
|
||||
// Config is used to configure the creation of the client.
|
||||
type Config struct {
|
||||
// Address is the address of the Vault server. This should be a complete
|
||||
// URL such as "http://vault.example.com". If you need a custom SSL
|
||||
// cert or want to enable insecure mode, you need to specify a custom
|
||||
// HttpClient.
|
||||
Address string
|
||||
|
||||
// HttpClient is the HTTP client to use, which will currently always have the
|
||||
// same values as http.DefaultClient. This is used to control redirect behavior.
|
||||
HttpClient *http.Client
|
||||
|
||||
redirectSetup sync.Once
|
||||
}
|
||||
|
||||
// DefaultConfig returns a default configuration for the client. It is
|
||||
// safe to modify the return value of this function.
|
||||
//
|
||||
// The default Address is https://127.0.0.1:8200, but this can be overridden by
|
||||
// setting the `VAULT_ADDR` environment variable.
|
||||
func DefaultConfig() *Config {
|
||||
config := &Config{
|
||||
Address: "https://127.0.0.1:8200",
|
||||
|
||||
HttpClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
config.HttpClient.Timeout = time.Second * 60
|
||||
transport := config.HttpClient.Transport.(*http.Transport)
|
||||
transport.TLSHandshakeTimeout = 10 * time.Second
|
||||
transport.TLSClientConfig = &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
}
|
||||
|
||||
if v := os.Getenv(EnvVaultAddress); v != "" {
|
||||
config.Address = v
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// ReadEnvironment reads configuration information from the
|
||||
// environment. If there is an error, no configuration value
|
||||
// is updated.
|
||||
func (c *Config) ReadEnvironment() error {
|
||||
var envAddress string
|
||||
var envCACert string
|
||||
var envCAPath string
|
||||
var envClientCert string
|
||||
var envClientKey string
|
||||
var envInsecure bool
|
||||
var foundInsecure bool
|
||||
|
||||
var newCertPool *x509.CertPool
|
||||
var clientCert tls.Certificate
|
||||
var foundClientCert bool
|
||||
|
||||
if v := os.Getenv(EnvVaultAddress); v != "" {
|
||||
envAddress = v
|
||||
}
|
||||
if v := os.Getenv(EnvVaultCACert); v != "" {
|
||||
envCACert = v
|
||||
}
|
||||
if v := os.Getenv(EnvVaultCAPath); v != "" {
|
||||
envCAPath = v
|
||||
}
|
||||
if v := os.Getenv(EnvVaultClientCert); v != "" {
|
||||
envClientCert = v
|
||||
}
|
||||
if v := os.Getenv(EnvVaultClientKey); v != "" {
|
||||
envClientKey = v
|
||||
}
|
||||
if v := os.Getenv(EnvVaultInsecure); v != "" {
|
||||
var err error
|
||||
envInsecure, err = strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not parse VAULT_SKIP_VERIFY")
|
||||
}
|
||||
foundInsecure = true
|
||||
}
|
||||
// If we need custom TLS configuration, then set it
|
||||
if envCACert != "" || envCAPath != "" || envClientCert != "" || envClientKey != "" || envInsecure {
|
||||
var err error
|
||||
if envCACert != "" {
|
||||
newCertPool, err = LoadCACert(envCACert)
|
||||
} else if envCAPath != "" {
|
||||
newCertPool, err = LoadCAPath(envCAPath)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error setting up CA path: %s", err)
|
||||
}
|
||||
|
||||
if envClientCert != "" && envClientKey != "" {
|
||||
clientCert, err = tls.LoadX509KeyPair(envClientCert, envClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
foundClientCert = true
|
||||
} else if envClientCert != "" || envClientKey != "" {
|
||||
return fmt.Errorf("Both client cert and client key must be provided")
|
||||
}
|
||||
}
|
||||
|
||||
if envAddress != "" {
|
||||
c.Address = envAddress
|
||||
}
|
||||
|
||||
clientTLSConfig := c.HttpClient.Transport.(*http.Transport).TLSClientConfig
|
||||
if foundInsecure {
|
||||
clientTLSConfig.InsecureSkipVerify = envInsecure
|
||||
}
|
||||
if newCertPool != nil {
|
||||
clientTLSConfig.RootCAs = newCertPool
|
||||
}
|
||||
if foundClientCert {
|
||||
clientTLSConfig.Certificates = []tls.Certificate{clientCert}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Client is the client to the Vault API. Create a client with
|
||||
// NewClient.
|
||||
type Client struct {
|
||||
addr *url.URL
|
||||
config *Config
|
||||
token string
|
||||
}
|
||||
|
||||
// NewClient returns a new client for the given configuration.
|
||||
//
|
||||
// If the environment variable `VAULT_TOKEN` is present, the token will be
|
||||
// automatically added to the client. Otherwise, you must manually call
|
||||
// `SetToken()`.
|
||||
func NewClient(c *Config) (*Client, error) {
|
||||
|
||||
u, err := url.Parse(c.Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.HttpClient == nil {
|
||||
c.HttpClient = DefaultConfig().HttpClient
|
||||
}
|
||||
|
||||
redirFunc := func() {
|
||||
// Ensure redirects are not automatically followed
|
||||
// Note that this is sane for the API client as it has its own
|
||||
// redirect handling logic (and thus also for command/meta),
|
||||
// but in e.g. http_test actual redirect handling is necessary
|
||||
c.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return errRedirect
|
||||
}
|
||||
}
|
||||
|
||||
c.redirectSetup.Do(redirFunc)
|
||||
|
||||
client := &Client{
|
||||
addr: u,
|
||||
config: c,
|
||||
}
|
||||
|
||||
if token := os.Getenv("VAULT_TOKEN"); token != "" {
|
||||
client.SetToken(token)
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// Token returns the access token being used by this client. It will
|
||||
// return the empty string if there is no token set.
|
||||
func (c *Client) Token() string {
|
||||
return c.token
|
||||
}
|
||||
|
||||
// SetToken sets the token directly. This won't perform any auth
|
||||
// verification, it simply sets the token properly for future requests.
|
||||
func (c *Client) SetToken(v string) {
|
||||
c.token = v
|
||||
}
|
||||
|
||||
// ClearToken deletes the token if it is set or does nothing otherwise.
|
||||
func (c *Client) ClearToken() {
|
||||
c.token = ""
|
||||
}
|
||||
|
||||
// NewRequest creates a new raw request object to query the Vault server
|
||||
// configured for this client. This is an advanced method and generally
|
||||
// doesn't need to be called externally.
|
||||
func (c *Client) NewRequest(method, path string) *Request {
|
||||
req := &Request{
|
||||
Method: method,
|
||||
URL: &url.URL{
|
||||
Scheme: c.addr.Scheme,
|
||||
Host: c.addr.Host,
|
||||
Path: path,
|
||||
},
|
||||
ClientToken: c.token,
|
||||
Params: make(map[string][]string),
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
// RawRequest performs the raw request given. This request may be against
|
||||
// a Vault server not configured with this client. This is an advanced operation
|
||||
// that generally won't need to be called externally.
|
||||
func (c *Client) RawRequest(r *Request) (*Response, error) {
|
||||
redirectCount := 0
|
||||
START:
|
||||
req, err := r.ToHTTP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result *Response
|
||||
resp, err := c.config.HttpClient.Do(req)
|
||||
if resp != nil {
|
||||
result = &Response{Response: resp}
|
||||
}
|
||||
if err != nil {
|
||||
if urlErr, ok := err.(*url.Error); ok && urlErr.Err == errRedirect {
|
||||
err = nil
|
||||
} else if strings.Contains(err.Error(), "tls: oversized") {
|
||||
err = fmt.Errorf(
|
||||
"%s\n\n"+
|
||||
"This error usually means that the server is running with TLS disabled\n"+
|
||||
"but the client is configured to use TLS. Please either enable TLS\n"+
|
||||
"on the server or run the client with -address set to an address\n"+
|
||||
"that uses the http protocol:\n\n"+
|
||||
" vault <command> -address http://<address>\n\n"+
|
||||
"You can also set the VAULT_ADDR environment variable:\n\n\n"+
|
||||
" VAULT_ADDR=http://<address> vault <command>\n\n"+
|
||||
"where <address> is replaced by the actual address to the server.",
|
||||
err)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Check for a redirect, only allowing for a single redirect
|
||||
if (resp.StatusCode == 301 || resp.StatusCode == 302 || resp.StatusCode == 307) && redirectCount == 0 {
|
||||
// Parse the updated location
|
||||
respLoc, err := resp.Location()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Ensure a protocol downgrade doesn't happen
|
||||
if req.URL.Scheme == "https" && respLoc.Scheme != "https" {
|
||||
return result, fmt.Errorf("redirect would cause protocol downgrade")
|
||||
}
|
||||
|
||||
// Update the request
|
||||
r.URL = respLoc
|
||||
|
||||
// Reset the request body if any
|
||||
if err := r.ResetJSONBody(); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Retry the request
|
||||
redirectCount++
|
||||
goto START
|
||||
}
|
||||
|
||||
if err := result.Error(); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Loads the certificate from given path and creates a certificate pool from it.
|
||||
func LoadCACert(path string) (*x509.CertPool, error) {
|
||||
certs, err := loadCertFromPEM(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := x509.NewCertPool()
|
||||
for _, cert := range certs {
|
||||
result.AddCert(cert)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Loads the certificates present in the given directory and creates a
|
||||
// certificate pool from it.
|
||||
func LoadCAPath(path string) (*x509.CertPool, error) {
|
||||
result := x509.NewCertPool()
|
||||
fn := func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
certs, err := loadCertFromPEM(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, cert := range certs {
|
||||
result.AddCert(cert)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return result, filepath.Walk(path, fn)
|
||||
}
|
||||
|
||||
// Creates a certificate from the given path
|
||||
func loadCertFromPEM(path string) ([]*x509.Certificate, error) {
|
||||
pemCerts, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certs := make([]*x509.Certificate, 0, 5)
|
||||
for len(pemCerts) > 0 {
|
||||
var block *pem.Block
|
||||
block, pemCerts = pem.Decode(pemCerts)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certs = append(certs, cert)
|
||||
}
|
||||
|
||||
return certs, nil
|
||||
}
|
25
vendor/github.com/hashicorp/vault/api/help.go
generated
vendored
Normal file
25
vendor/github.com/hashicorp/vault/api/help.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Help reads the help information for the given path.
|
||||
func (c *Client) Help(path string) (*Help, error) {
|
||||
r := c.NewRequest("GET", fmt.Sprintf("/v1/%s", path))
|
||||
r.Params.Add("help", "1")
|
||||
resp, err := c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result Help
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type Help struct {
|
||||
Help string `json:"help"`
|
||||
SeeAlso []string `json:"see_also"`
|
||||
}
|
82
vendor/github.com/hashicorp/vault/api/logical.go
generated
vendored
Normal file
82
vendor/github.com/hashicorp/vault/api/logical.go
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
package api
|
||||
|
||||
// Logical is used to perform logical backend operations on Vault.
|
||||
type Logical struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Logical is used to return the client for logical-backend API calls.
|
||||
func (c *Client) Logical() *Logical {
|
||||
return &Logical{c: c}
|
||||
}
|
||||
|
||||
func (c *Logical) Read(path string) (*Secret, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/"+path)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
if resp != nil && resp.StatusCode == 404 {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *Logical) List(path string) (*Secret, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/"+path)
|
||||
r.Params.Set("list", "true")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
if resp != nil && resp.StatusCode == 404 {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *Logical) Write(path string, data map[string]interface{}) (*Secret, error) {
|
||||
r := c.c.NewRequest("PUT", "/v1/"+path)
|
||||
if err := r.SetJSONBody(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *Logical) Delete(path string) (*Secret, error) {
|
||||
r := c.c.NewRequest("DELETE", "/v1/"+path)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
66
vendor/github.com/hashicorp/vault/api/request.go
generated
vendored
Normal file
66
vendor/github.com/hashicorp/vault/api/request.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// Request is a raw request configuration structure used to initiate
|
||||
// API requests to the Vault server.
|
||||
type Request struct {
|
||||
Method string
|
||||
URL *url.URL
|
||||
Params url.Values
|
||||
ClientToken string
|
||||
Obj interface{}
|
||||
Body io.Reader
|
||||
BodySize int64
|
||||
}
|
||||
|
||||
// SetJSONBody is used to set a request body that is a JSON-encoded value.
|
||||
func (r *Request) SetJSONBody(val interface{}) error {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
enc := json.NewEncoder(buf)
|
||||
if err := enc.Encode(val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.Obj = val
|
||||
r.Body = buf
|
||||
r.BodySize = int64(buf.Len())
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetJSONBody is used to reset the body for a redirect
|
||||
func (r *Request) ResetJSONBody() error {
|
||||
if r.Body == nil {
|
||||
return nil
|
||||
}
|
||||
return r.SetJSONBody(r.Obj)
|
||||
}
|
||||
|
||||
// ToHTTP turns this request into a valid *http.Request for use with the
|
||||
// net/http package.
|
||||
func (r *Request) ToHTTP() (*http.Request, error) {
|
||||
// Encode the query parameters
|
||||
r.URL.RawQuery = r.Params.Encode()
|
||||
|
||||
// Create the HTTP request
|
||||
req, err := http.NewRequest(r.Method, r.URL.RequestURI(), r.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.URL.Scheme = r.URL.Scheme
|
||||
req.URL.Host = r.URL.Host
|
||||
req.Host = r.URL.Host
|
||||
|
||||
if len(r.ClientToken) != 0 {
|
||||
req.Header.Set("X-Vault-Token", r.ClientToken)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
73
vendor/github.com/hashicorp/vault/api/response.go
generated
vendored
Normal file
73
vendor/github.com/hashicorp/vault/api/response.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Response is a raw response that wraps an HTTP response.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
}
|
||||
|
||||
// DecodeJSON will decode the response body to a JSON structure. This
|
||||
// will consume the response body, but will not close it. Close must
|
||||
// still be called.
|
||||
func (r *Response) DecodeJSON(out interface{}) error {
|
||||
dec := json.NewDecoder(r.Body)
|
||||
return dec.Decode(out)
|
||||
}
|
||||
|
||||
// Error returns an error response if there is one. If there is an error,
|
||||
// this will fully consume the response body, but will not close it. The
|
||||
// body must still be closed manually.
|
||||
func (r *Response) Error() error {
|
||||
// 200 to 399 are okay status codes
|
||||
if r.StatusCode >= 200 && r.StatusCode < 400 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// We have an error. Let's copy the body into our own buffer first,
|
||||
// so that if we can't decode JSON, we can at least copy it raw.
|
||||
var bodyBuf bytes.Buffer
|
||||
if _, err := io.Copy(&bodyBuf, r.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode the error response if we can. Note that we wrap the bodyBuf
|
||||
// in a bytes.Reader here so that the JSON decoder doesn't move the
|
||||
// read pointer for the original buffer.
|
||||
var resp ErrorResponse
|
||||
dec := json.NewDecoder(bytes.NewReader(bodyBuf.Bytes()))
|
||||
if err := dec.Decode(&resp); err != nil {
|
||||
// Ignore the decoding error and just drop the raw response
|
||||
return fmt.Errorf(
|
||||
"Error making API request.\n\n"+
|
||||
"URL: %s %s\n"+
|
||||
"Code: %d. Raw Message:\n\n%s",
|
||||
r.Request.Method, r.Request.URL.String(),
|
||||
r.StatusCode, bodyBuf.String())
|
||||
}
|
||||
|
||||
var errBody bytes.Buffer
|
||||
errBody.WriteString(fmt.Sprintf(
|
||||
"Error making API request.\n\n"+
|
||||
"URL: %s %s\n"+
|
||||
"Code: %d. Errors:\n\n",
|
||||
r.Request.Method, r.Request.URL.String(),
|
||||
r.StatusCode))
|
||||
for _, err := range resp.Errors {
|
||||
errBody.WriteString(fmt.Sprintf("* %s", err))
|
||||
}
|
||||
|
||||
return fmt.Errorf(errBody.String())
|
||||
}
|
||||
|
||||
// ErrorResponse is the raw structure of errors when they're returned by the
|
||||
// HTTP API.
|
||||
type ErrorResponse struct {
|
||||
Errors []string
|
||||
}
|
48
vendor/github.com/hashicorp/vault/api/secret.go
generated
vendored
Normal file
48
vendor/github.com/hashicorp/vault/api/secret.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Secret is the structure returned for every secret within Vault.
|
||||
type Secret struct {
|
||||
LeaseID string `json:"lease_id"`
|
||||
LeaseDuration int `json:"lease_duration"`
|
||||
Renewable bool `json:"renewable"`
|
||||
|
||||
// Data is the actual contents of the secret. The format of the data
|
||||
// is arbitrary and up to the secret backend.
|
||||
Data map[string]interface{} `json:"data"`
|
||||
|
||||
// Warnings contains any warnings related to the operation. These
|
||||
// are not issues that caused the command to fail, but that the
|
||||
// client should be aware of.
|
||||
Warnings []string `json:"warnings"`
|
||||
|
||||
// Auth, if non-nil, means that there was authentication information
|
||||
// attached to this response.
|
||||
Auth *SecretAuth `json:"auth,omitempty"`
|
||||
}
|
||||
|
||||
// SecretAuth is the structure containing auth information if we have it.
|
||||
type SecretAuth struct {
|
||||
ClientToken string `json:"client_token"`
|
||||
Policies []string `json:"policies"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
|
||||
LeaseDuration int `json:"lease_duration"`
|
||||
Renewable bool `json:"renewable"`
|
||||
}
|
||||
|
||||
// ParseSecret is used to parse a secret value from JSON from an io.Reader.
|
||||
func ParseSecret(r io.Reader) (*Secret, error) {
|
||||
// First decode the JSON into a map[string]interface{}
|
||||
var secret Secret
|
||||
dec := json.NewDecoder(r)
|
||||
if err := dec.Decode(&secret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &secret, nil
|
||||
}
|
38
vendor/github.com/hashicorp/vault/api/ssh.go
generated
vendored
Normal file
38
vendor/github.com/hashicorp/vault/api/ssh.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
package api
|
||||
|
||||
import "fmt"
|
||||
|
||||
// SSH is used to return a client to invoke operations on SSH backend.
|
||||
type SSH struct {
|
||||
c *Client
|
||||
MountPoint string
|
||||
}
|
||||
|
||||
// SSH returns the client for logical-backend API calls.
|
||||
func (c *Client) SSH() *SSH {
|
||||
return c.SSHWithMountPoint(SSHAgentDefaultMountPoint)
|
||||
}
|
||||
|
||||
// SSHWithMountPoint returns the client with specific SSH mount point.
|
||||
func (c *Client) SSHWithMountPoint(mountPoint string) *SSH {
|
||||
return &SSH{
|
||||
c: c,
|
||||
MountPoint: mountPoint,
|
||||
}
|
||||
}
|
||||
|
||||
// Credential invokes the SSH backend API to create a credential to establish an SSH session.
|
||||
func (c *SSH) Credential(role string, data map[string]interface{}) (*Secret, error) {
|
||||
r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/%s/creds/%s", c.MountPoint, role))
|
||||
if err := r.SetJSONBody(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
191
vendor/github.com/hashicorp/vault/api/ssh_agent.go
generated
vendored
Normal file
191
vendor/github.com/hashicorp/vault/api/ssh_agent.go
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/hashicorp/hcl"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
const (
|
||||
// Default path at which SSH backend will be mounted in Vault server
|
||||
SSHAgentDefaultMountPoint = "ssh"
|
||||
|
||||
// Echo request message sent as OTP by the agent
|
||||
VerifyEchoRequest = "verify-echo-request"
|
||||
|
||||
// Echo response message sent as a response to OTP matching echo request
|
||||
VerifyEchoResponse = "verify-echo-response"
|
||||
)
|
||||
|
||||
// SSHAgent is a structure representing an SSH agent which can talk to vault server
|
||||
// in order to verify the OTP entered by the user. It contains the path at which
|
||||
// SSH backend is mounted at the server.
|
||||
type SSHAgent struct {
|
||||
c *Client
|
||||
MountPoint string
|
||||
}
|
||||
|
||||
// SSHVerifyResponse is a structure representing the fields in Vault server's
|
||||
// response.
|
||||
type SSHVerifyResponse struct {
|
||||
// Usually empty. If the request OTP is echo request message, this will
|
||||
// be set to the corresponding echo response message.
|
||||
Message string `mapstructure:"message"`
|
||||
|
||||
// Username associated with the OTP
|
||||
Username string `mapstructure:"username"`
|
||||
|
||||
// IP associated with the OTP
|
||||
IP string `mapstructure:"ip"`
|
||||
}
|
||||
|
||||
// SSHAgentConfig is a structure which represents the entries from the agent's configuration file.
|
||||
type SSHAgentConfig struct {
|
||||
VaultAddr string `hcl:"vault_addr"`
|
||||
SSHMountPoint string `hcl:"ssh_mount_point"`
|
||||
CACert string `hcl:"ca_cert"`
|
||||
CAPath string `hcl:"ca_path"`
|
||||
TLSSkipVerify bool `hcl:"tls_skip_verify"`
|
||||
AllowedCidrList string `hcl:"allowed_cidr_list"`
|
||||
}
|
||||
|
||||
// TLSClient returns a HTTP client that uses TLS verification (TLS 1.2) for a given
|
||||
// certificate pool.
|
||||
func (c *SSHAgentConfig) SetTLSParameters(clientConfig *Config, certPool *x509.CertPool) {
|
||||
tlsConfig := &tls.Config{
|
||||
InsecureSkipVerify: c.TLSSkipVerify,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
RootCAs: certPool,
|
||||
}
|
||||
|
||||
transport := cleanhttp.DefaultTransport()
|
||||
transport.TLSClientConfig = tlsConfig
|
||||
clientConfig.HttpClient.Transport = transport
|
||||
}
|
||||
|
||||
// NewClient returns a new client for the configuration. This client will be used by the
|
||||
// SSH agent to communicate with Vault server and verify the OTP entered by user.
|
||||
// If the configuration supplies Vault SSL certificates, then the client will
|
||||
// have TLS configured in its transport.
|
||||
func (c *SSHAgentConfig) NewClient() (*Client, error) {
|
||||
// Creating a default client configuration for communicating with vault server.
|
||||
clientConfig := DefaultConfig()
|
||||
|
||||
// Pointing the client to the actual address of vault server.
|
||||
clientConfig.Address = c.VaultAddr
|
||||
|
||||
// Check if certificates are provided via config file.
|
||||
if c.CACert != "" || c.CAPath != "" || c.TLSSkipVerify {
|
||||
var certPool *x509.CertPool
|
||||
var err error
|
||||
if c.CACert != "" {
|
||||
certPool, err = LoadCACert(c.CACert)
|
||||
} else if c.CAPath != "" {
|
||||
certPool, err = LoadCAPath(c.CAPath)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Enable TLS on the HTTP client information
|
||||
c.SetTLSParameters(clientConfig, certPool)
|
||||
}
|
||||
|
||||
// Creating the client object for the given configuration
|
||||
client, err := NewClient(clientConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// LoadSSHAgentConfig loads agent's configuration from the file and populates the corresponding
|
||||
// in-memory structure.
|
||||
//
|
||||
// Vault address is a required parameter.
|
||||
// Mount point defaults to "ssh".
|
||||
func LoadSSHAgentConfig(path string) (*SSHAgentConfig, error) {
|
||||
var config SSHAgentConfig
|
||||
contents, err := ioutil.ReadFile(path)
|
||||
if !os.IsNotExist(err) {
|
||||
obj, err := hcl.Parse(string(contents))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := hcl.DecodeObject(&config, obj); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config.VaultAddr == "" {
|
||||
return nil, fmt.Errorf("config missing vault_addr")
|
||||
}
|
||||
if config.SSHMountPoint == "" {
|
||||
config.SSHMountPoint = SSHAgentDefaultMountPoint
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// SSHAgent creates an SSHAgent object which can talk to Vault server with SSH backend
|
||||
// mounted at default path ("ssh").
|
||||
func (c *Client) SSHAgent() *SSHAgent {
|
||||
return c.SSHAgentWithMountPoint(SSHAgentDefaultMountPoint)
|
||||
}
|
||||
|
||||
// SSHAgentWithMountPoint creates an SSHAgent object which can talk to Vault server with SSH backend
|
||||
// mounted at a specific mount point.
|
||||
func (c *Client) SSHAgentWithMountPoint(mountPoint string) *SSHAgent {
|
||||
return &SSHAgent{
|
||||
c: c,
|
||||
MountPoint: mountPoint,
|
||||
}
|
||||
}
|
||||
|
||||
// Verify verifies if the key provided by user is present in Vault server. The response
|
||||
// will contain the IP address and username associated with the OTP. In case the
|
||||
// OTP matches the echo request message, instead of searching an entry for the OTP,
|
||||
// an echo response message is returned. This feature is used by agent to verify if
|
||||
// its configured correctly.
|
||||
func (c *SSHAgent) Verify(otp string) (*SSHVerifyResponse, error) {
|
||||
data := map[string]interface{}{
|
||||
"otp": otp,
|
||||
}
|
||||
verifyPath := fmt.Sprintf("/v1/%s/verify", c.MountPoint)
|
||||
r := c.c.NewRequest("PUT", verifyPath)
|
||||
if err := r.SetJSONBody(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
secret, err := ParseSecret(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if secret.Data == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var verifyResp SSHVerifyResponse
|
||||
err = mapstructure.Decode(secret.Data, &verifyResp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &verifyResp, nil
|
||||
}
|
11
vendor/github.com/hashicorp/vault/api/sys.go
generated
vendored
Normal file
11
vendor/github.com/hashicorp/vault/api/sys.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package api
|
||||
|
||||
// Sys is used to perform system-related operations on Vault.
|
||||
type Sys struct {
|
||||
c *Client
|
||||
}
|
||||
|
||||
// Sys is used to return the client for sys-related API calls.
|
||||
func (c *Client) Sys() *Sys {
|
||||
return &Sys{c: c}
|
||||
}
|
84
vendor/github.com/hashicorp/vault/api/sys_audit.go
generated
vendored
Normal file
84
vendor/github.com/hashicorp/vault/api/sys_audit.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c *Sys) AuditHash(path string, input string) (string, error) {
|
||||
body := map[string]interface{}{
|
||||
"input": input,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/audit-hash/%s", path))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
type d struct {
|
||||
Hash string
|
||||
}
|
||||
|
||||
var result d
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result.Hash, err
|
||||
}
|
||||
|
||||
func (c *Sys) ListAudit() (map[string]*Audit, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/audit")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]*Audit
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (c *Sys) EnableAudit(
|
||||
path string, auditType string, desc string, opts map[string]string) error {
|
||||
body := map[string]interface{}{
|
||||
"type": auditType,
|
||||
"description": desc,
|
||||
"options": opts,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/audit/%s", path))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Sys) DisableAudit(path string) error {
|
||||
r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/audit/%s", path))
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Structures for the requests/resposne are all down here. They aren't
|
||||
// individually documentd because the map almost directly to the raw HTTP API
|
||||
// documentation. Please refer to that documentation for more details.
|
||||
|
||||
type Audit struct {
|
||||
Type string
|
||||
Description string
|
||||
Options map[string]string
|
||||
}
|
72
vendor/github.com/hashicorp/vault/api/sys_auth.go
generated
vendored
Normal file
72
vendor/github.com/hashicorp/vault/api/sys_auth.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c *Sys) ListAuth() (map[string]*AuthMount, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/auth")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]*AuthMount
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (c *Sys) EnableAuth(path, authType, desc string) error {
|
||||
if err := c.checkAuthPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body := map[string]string{
|
||||
"type": authType,
|
||||
"description": desc,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("POST", fmt.Sprintf("/v1/sys/auth/%s", path))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Sys) DisableAuth(path string) error {
|
||||
if err := c.checkAuthPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/auth/%s", path))
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) checkAuthPath(path string) error {
|
||||
if path[0] == '/' {
|
||||
return fmt.Errorf("path must not start with /: %s", path)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Structures for the requests/resposne are all down here. They aren't
|
||||
// individually documentd because the map almost directly to the raw HTTP API
|
||||
// documentation. Please refer to that documentation for more details.
|
||||
|
||||
type AuthMount struct {
|
||||
Type string
|
||||
Description string
|
||||
}
|
73
vendor/github.com/hashicorp/vault/api/sys_generate_root.go
generated
vendored
Normal file
73
vendor/github.com/hashicorp/vault/api/sys_generate_root.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
package api
|
||||
|
||||
func (c *Sys) GenerateRootStatus() (*GenerateRootStatusResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/generate-root/attempt")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result GenerateRootStatusResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (c *Sys) GenerateRootInit(otp, pgpKey string) error {
|
||||
body := map[string]interface{}{
|
||||
"otp": otp,
|
||||
"pgp_key": pgpKey,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/generate-root/attempt")
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) GenerateRootCancel() error {
|
||||
r := c.c.NewRequest("DELETE", "/v1/sys/generate-root/attempt")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) GenerateRootUpdate(shard, nonce string) (*GenerateRootStatusResponse, error) {
|
||||
body := map[string]interface{}{
|
||||
"key": shard,
|
||||
"nonce": nonce,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/generate-root/update")
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result GenerateRootStatusResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type GenerateRootStatusResponse struct {
|
||||
Nonce string
|
||||
Started bool
|
||||
Progress int
|
||||
Required int
|
||||
Complete bool
|
||||
EncodedRootToken string `json:"encoded_root_token"`
|
||||
PGPFingerprint string `json:"pgp_fingerprint"`
|
||||
}
|
46
vendor/github.com/hashicorp/vault/api/sys_init.go
generated
vendored
Normal file
46
vendor/github.com/hashicorp/vault/api/sys_init.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package api
|
||||
|
||||
func (c *Sys) InitStatus() (bool, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/init")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result InitStatusResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result.Initialized, err
|
||||
}
|
||||
|
||||
func (c *Sys) Init(opts *InitRequest) (*InitResponse, error) {
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/init")
|
||||
if err := r.SetJSONBody(opts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result InitResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type InitRequest struct {
|
||||
SecretShares int `json:"secret_shares"`
|
||||
SecretThreshold int `json:"secret_threshold"`
|
||||
PGPKeys []string `json:"pgp_keys"`
|
||||
}
|
||||
|
||||
type InitStatusResponse struct {
|
||||
Initialized bool
|
||||
}
|
||||
|
||||
type InitResponse struct {
|
||||
Keys []string
|
||||
RootToken string `json:"root_token"`
|
||||
}
|
20
vendor/github.com/hashicorp/vault/api/sys_leader.go
generated
vendored
Normal file
20
vendor/github.com/hashicorp/vault/api/sys_leader.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
package api
|
||||
|
||||
func (c *Sys) Leader() (*LeaderResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/leader")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result LeaderResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type LeaderResponse struct {
|
||||
HAEnabled bool `json:"ha_enabled"`
|
||||
IsSelf bool `json:"is_self"`
|
||||
LeaderAddress string `json:"leader_address"`
|
||||
}
|
36
vendor/github.com/hashicorp/vault/api/sys_lease.go
generated
vendored
Normal file
36
vendor/github.com/hashicorp/vault/api/sys_lease.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
package api
|
||||
|
||||
func (c *Sys) Renew(id string, increment int) (*Secret, error) {
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/renew/"+id)
|
||||
|
||||
body := map[string]interface{}{"increment": increment}
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return ParseSecret(resp.Body)
|
||||
}
|
||||
|
||||
func (c *Sys) Revoke(id string) error {
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/revoke/"+id)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) RevokePrefix(id string) error {
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/revoke-prefix/"+id)
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
144
vendor/github.com/hashicorp/vault/api/sys_mounts.go
generated
vendored
Normal file
144
vendor/github.com/hashicorp/vault/api/sys_mounts.go
generated
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
)
|
||||
|
||||
func (c *Sys) ListMounts() (map[string]*MountOutput, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/mounts")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]*MountOutput
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (c *Sys) Mount(path string, mountInfo *MountInput) error {
|
||||
if err := c.checkMountPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body := structs.Map(mountInfo)
|
||||
|
||||
r := c.c.NewRequest("POST", fmt.Sprintf("/v1/sys/mounts/%s", path))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Sys) Unmount(path string) error {
|
||||
if err := c.checkMountPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/mounts/%s", path))
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) Remount(from, to string) error {
|
||||
if err := c.checkMountPath(from); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.checkMountPath(to); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body := map[string]interface{}{
|
||||
"from": from,
|
||||
"to": to,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("POST", "/v1/sys/remount")
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) TuneMount(path string, config MountConfigInput) error {
|
||||
if err := c.checkMountPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body := structs.Map(config)
|
||||
r := c.c.NewRequest("POST", fmt.Sprintf("/v1/sys/mounts/%s/tune", path))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) MountConfig(path string) (*MountConfigOutput, error) {
|
||||
if err := c.checkMountPath(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/mounts/%s/tune", path))
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var result MountConfigOutput
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (c *Sys) checkMountPath(path string) error {
|
||||
if path[0] == '/' {
|
||||
return fmt.Errorf("path must not start with /: %s", path)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type MountInput struct {
|
||||
Type string `json:"type" structs:"type"`
|
||||
Description string `json:"description" structs:"description"`
|
||||
Config MountConfigInput `json:"config" structs:"config"`
|
||||
}
|
||||
|
||||
type MountConfigInput struct {
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
}
|
||||
|
||||
type MountOutput struct {
|
||||
Type string `json:"type" structs:"type"`
|
||||
Description string `json:"description" structs:"description"`
|
||||
Config MountConfigOutput `json:"config" structs:"config"`
|
||||
}
|
||||
|
||||
type MountConfigOutput struct {
|
||||
DefaultLeaseTTL int `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL int `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
}
|
72
vendor/github.com/hashicorp/vault/api/sys_policy.go
generated
vendored
Normal file
72
vendor/github.com/hashicorp/vault/api/sys_policy.go
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c *Sys) ListPolicies() ([]string, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/policy")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result listPoliciesResp
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result.Policies, err
|
||||
}
|
||||
|
||||
func (c *Sys) GetPolicy(name string) (string, error) {
|
||||
r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/policy/%s", name))
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == 404 {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var result getPoliciesResp
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result.Rules, err
|
||||
}
|
||||
|
||||
func (c *Sys) PutPolicy(name, rules string) error {
|
||||
body := map[string]string{
|
||||
"rules": rules,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/policy/%s", name))
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Sys) DeletePolicy(name string) error {
|
||||
r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/policy/%s", name))
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type getPoliciesResp struct {
|
||||
Rules string `json:"rules"`
|
||||
}
|
||||
|
||||
type listPoliciesResp struct {
|
||||
Policies []string `json:"policies"`
|
||||
}
|
112
vendor/github.com/hashicorp/vault/api/sys_rekey.go
generated
vendored
Normal file
112
vendor/github.com/hashicorp/vault/api/sys_rekey.go
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
package api
|
||||
|
||||
func (c *Sys) RekeyStatus() (*RekeyStatusResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/rekey/init")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result RekeyStatusResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (c *Sys) RekeyInit(config *RekeyInitRequest) error {
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/rekey/init")
|
||||
if err := r.SetJSONBody(config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) RekeyCancel() error {
|
||||
r := c.c.NewRequest("DELETE", "/v1/sys/rekey/init")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) RekeyUpdate(shard, nonce string) (*RekeyUpdateResponse, error) {
|
||||
body := map[string]interface{}{
|
||||
"key": shard,
|
||||
"nonce": nonce,
|
||||
}
|
||||
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/rekey/update")
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result RekeyUpdateResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (c *Sys) RekeyRetrieveBackup() (*RekeyRetrieveResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/rekey/backup")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result RekeyRetrieveResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (c *Sys) RekeyDeleteBackup() error {
|
||||
r := c.c.NewRequest("DELETE", "/v1/sys/rekey/backup")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
type RekeyInitRequest struct {
|
||||
SecretShares int `json:"secret_shares"`
|
||||
SecretThreshold int `json:"secret_threshold"`
|
||||
PGPKeys []string `json:"pgp_keys"`
|
||||
Backup bool
|
||||
}
|
||||
|
||||
type RekeyStatusResponse struct {
|
||||
Nonce string
|
||||
Started bool
|
||||
T int
|
||||
N int
|
||||
Progress int
|
||||
Required int
|
||||
PGPFingerprints []string `json:"pgp_fingerprints"`
|
||||
Backup bool
|
||||
}
|
||||
|
||||
type RekeyUpdateResponse struct {
|
||||
Nonce string
|
||||
Complete bool
|
||||
Keys []string
|
||||
PGPFingerprints []string `json:"pgp_fingerprints"`
|
||||
Backup bool
|
||||
}
|
||||
|
||||
type RekeyRetrieveResponse struct {
|
||||
Nonce string
|
||||
Keys map[string][]string
|
||||
}
|
30
vendor/github.com/hashicorp/vault/api/sys_rotate.go
generated
vendored
Normal file
30
vendor/github.com/hashicorp/vault/api/sys_rotate.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
package api
|
||||
|
||||
import "time"
|
||||
|
||||
func (c *Sys) Rotate() error {
|
||||
r := c.c.NewRequest("POST", "/v1/sys/rotate")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) KeyStatus() (*KeyStatus, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/key-status")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
result := new(KeyStatus)
|
||||
err = resp.DecodeJSON(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
type KeyStatus struct {
|
||||
Term int
|
||||
InstallTime time.Time `json:"install_time"`
|
||||
}
|
56
vendor/github.com/hashicorp/vault/api/sys_seal.go
generated
vendored
Normal file
56
vendor/github.com/hashicorp/vault/api/sys_seal.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
package api
|
||||
|
||||
func (c *Sys) SealStatus() (*SealStatusResponse, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/seal-status")
|
||||
return sealStatusRequest(c, r)
|
||||
}
|
||||
|
||||
func (c *Sys) Seal() error {
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/seal")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err == nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) ResetUnsealProcess() (*SealStatusResponse, error) {
|
||||
body := map[string]interface{}{"reset": true}
|
||||
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/unseal")
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sealStatusRequest(c, r)
|
||||
}
|
||||
|
||||
func (c *Sys) Unseal(shard string) (*SealStatusResponse, error) {
|
||||
body := map[string]interface{}{"key": shard}
|
||||
|
||||
r := c.c.NewRequest("PUT", "/v1/sys/unseal")
|
||||
if err := r.SetJSONBody(body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sealStatusRequest(c, r)
|
||||
}
|
||||
|
||||
func sealStatusRequest(c *Sys, r *Request) (*SealStatusResponse, error) {
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result SealStatusResponse
|
||||
err = resp.DecodeJSON(&result)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
type SealStatusResponse struct {
|
||||
Sealed bool
|
||||
T int
|
||||
N int
|
||||
Progress int
|
||||
}
|
21
vendor/github.com/mitchellh/go-homedir/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mitchellh/go-homedir/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Mitchell Hashimoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
14
vendor/github.com/mitchellh/go-homedir/README.md
generated
vendored
Normal file
14
vendor/github.com/mitchellh/go-homedir/README.md
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
# go-homedir
|
||||
|
||||
This is a Go library for detecting the user's home directory without
|
||||
the use of cgo, so the library can be used in cross-compilation environments.
|
||||
|
||||
Usage is incredibly simple, just call `homedir.Dir()` to get the home directory
|
||||
for a user, and `homedir.Expand()` to expand the `~` in a path to the home
|
||||
directory.
|
||||
|
||||
**Why not just use `os/user`?** The built-in `os/user` package requires
|
||||
cgo on Darwin systems. This means that any Go code that uses that package
|
||||
cannot cross compile. But 99% of the time the use for `os/user` is just to
|
||||
retrieve the home directory, which we can do for the current user without
|
||||
cgo. This library does that, enabling cross-compilation.
|
137
vendor/github.com/mitchellh/go-homedir/homedir.go
generated
vendored
Normal file
137
vendor/github.com/mitchellh/go-homedir/homedir.go
generated
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
package homedir
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// DisableCache will disable caching of the home directory. Caching is enabled
|
||||
// by default.
|
||||
var DisableCache bool
|
||||
|
||||
var homedirCache string
|
||||
var cacheLock sync.RWMutex
|
||||
|
||||
// Dir returns the home directory for the executing user.
|
||||
//
|
||||
// This uses an OS-specific method for discovering the home directory.
|
||||
// An error is returned if a home directory cannot be detected.
|
||||
func Dir() (string, error) {
|
||||
if !DisableCache {
|
||||
cacheLock.RLock()
|
||||
cached := homedirCache
|
||||
cacheLock.RUnlock()
|
||||
if cached != "" {
|
||||
return cached, nil
|
||||
}
|
||||
}
|
||||
|
||||
cacheLock.Lock()
|
||||
defer cacheLock.Unlock()
|
||||
|
||||
var result string
|
||||
var err error
|
||||
if runtime.GOOS == "windows" {
|
||||
result, err = dirWindows()
|
||||
} else {
|
||||
// Unix-like system, so just assume Unix
|
||||
result, err = dirUnix()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
homedirCache = result
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Expand expands the path to include the home directory if the path
|
||||
// is prefixed with `~`. If it isn't prefixed with `~`, the path is
|
||||
// returned as-is.
|
||||
func Expand(path string) (string, error) {
|
||||
if len(path) == 0 {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
if path[0] != '~' {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
|
||||
return "", errors.New("cannot expand user-specific home dir")
|
||||
}
|
||||
|
||||
dir, err := Dir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filepath.Join(dir, path[1:]), nil
|
||||
}
|
||||
|
||||
func dirUnix() (string, error) {
|
||||
// First prefer the HOME environmental variable
|
||||
if home := os.Getenv("HOME"); home != "" {
|
||||
return home, nil
|
||||
}
|
||||
|
||||
// If that fails, try getent
|
||||
var stdout bytes.Buffer
|
||||
cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid()))
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
// If "getent" is missing, ignore it
|
||||
if err == exec.ErrNotFound {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
if passwd := strings.TrimSpace(stdout.String()); passwd != "" {
|
||||
// username:password:uid:gid:gecos:home:shell
|
||||
passwdParts := strings.SplitN(passwd, ":", 7)
|
||||
if len(passwdParts) > 5 {
|
||||
return passwdParts[5], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all else fails, try the shell
|
||||
stdout.Reset()
|
||||
cmd = exec.Command("sh", "-c", "cd && pwd")
|
||||
cmd.Stdout = &stdout
|
||||
if err := cmd.Run(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
result := strings.TrimSpace(stdout.String())
|
||||
if result == "" {
|
||||
return "", errors.New("blank output when reading home directory")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func dirWindows() (string, error) {
|
||||
// First prefer the HOME environmental variable
|
||||
if home := os.Getenv("HOME"); home != "" {
|
||||
return home, nil
|
||||
}
|
||||
|
||||
drive := os.Getenv("HOMEDRIVE")
|
||||
path := os.Getenv("HOMEPATH")
|
||||
home := drive + path
|
||||
if drive == "" || path == "" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
if home == "" {
|
||||
return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
|
||||
}
|
||||
|
||||
return home, nil
|
||||
}
|
7
vendor/github.com/mitchellh/mapstructure/.travis.yml
generated
vendored
Normal file
7
vendor/github.com/mitchellh/mapstructure/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
|
||||
script:
|
||||
- go test
|
21
vendor/github.com/mitchellh/mapstructure/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mitchellh/mapstructure/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Mitchell Hashimoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
46
vendor/github.com/mitchellh/mapstructure/README.md
generated
vendored
Normal file
46
vendor/github.com/mitchellh/mapstructure/README.md
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
# mapstructure
|
||||
|
||||
mapstructure is a Go library for decoding generic map values to structures
|
||||
and vice versa, while providing helpful error handling.
|
||||
|
||||
This library is most useful when decoding values from some data stream (JSON,
|
||||
Gob, etc.) where you don't _quite_ know the structure of the underlying data
|
||||
until you read a part of it. You can therefore read a `map[string]interface{}`
|
||||
and use this library to decode it into the proper underlying native Go
|
||||
structure.
|
||||
|
||||
## Installation
|
||||
|
||||
Standard `go get`:
|
||||
|
||||
```
|
||||
$ go get github.com/mitchellh/mapstructure
|
||||
```
|
||||
|
||||
## Usage & Example
|
||||
|
||||
For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure).
|
||||
|
||||
The `Decode` function has examples associated with it there.
|
||||
|
||||
## But Why?!
|
||||
|
||||
Go offers fantastic standard libraries for decoding formats such as JSON.
|
||||
The standard method is to have a struct pre-created, and populate that struct
|
||||
from the bytes of the encoded format. This is great, but the problem is if
|
||||
you have configuration or an encoding that changes slightly depending on
|
||||
specific fields. For example, consider this JSON:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "person",
|
||||
"name": "Mitchell"
|
||||
}
|
||||
```
|
||||
|
||||
Perhaps we can't populate a specific structure without first reading
|
||||
the "type" field from the JSON. We could always do two passes over the
|
||||
decoding of the JSON (reading the "type" first, and the rest later).
|
||||
However, it is much simpler to just decode this into a `map[string]interface{}`
|
||||
structure, read the "type" key, then use something like this library
|
||||
to decode it into the proper structure.
|
151
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
Normal file
151
vendor/github.com/mitchellh/mapstructure/decode_hooks.go
generated
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
package mapstructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns
|
||||
// it into the proper DecodeHookFunc type, such as DecodeHookFuncType.
|
||||
func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
|
||||
// Create variables here so we can reference them with the reflect pkg
|
||||
var f1 DecodeHookFuncType
|
||||
var f2 DecodeHookFuncKind
|
||||
|
||||
// Fill in the variables into this interface and the rest is done
|
||||
// automatically using the reflect package.
|
||||
potential := []interface{}{f1, f2}
|
||||
|
||||
v := reflect.ValueOf(h)
|
||||
vt := v.Type()
|
||||
for _, raw := range potential {
|
||||
pt := reflect.ValueOf(raw).Type()
|
||||
if vt.ConvertibleTo(pt) {
|
||||
return v.Convert(pt).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecodeHookExec executes the given decode hook. This should be used
|
||||
// since it'll naturally degrade to the older backwards compatible DecodeHookFunc
|
||||
// that took reflect.Kind instead of reflect.Type.
|
||||
func DecodeHookExec(
|
||||
raw DecodeHookFunc,
|
||||
from reflect.Type, to reflect.Type,
|
||||
data interface{}) (interface{}, error) {
|
||||
// Build our arguments that reflect expects
|
||||
argVals := make([]reflect.Value, 3)
|
||||
argVals[0] = reflect.ValueOf(from)
|
||||
argVals[1] = reflect.ValueOf(to)
|
||||
argVals[2] = reflect.ValueOf(data)
|
||||
|
||||
switch f := typedDecodeHook(raw).(type) {
|
||||
case DecodeHookFuncType:
|
||||
return f(from, to, data)
|
||||
case DecodeHookFuncKind:
|
||||
return f(from.Kind(), to.Kind(), data)
|
||||
default:
|
||||
return nil, errors.New("invalid decode hook signature")
|
||||
}
|
||||
}
|
||||
|
||||
// ComposeDecodeHookFunc creates a single DecodeHookFunc that
|
||||
// automatically composes multiple DecodeHookFuncs.
|
||||
//
|
||||
// The composed funcs are called in order, with the result of the
|
||||
// previous transformation.
|
||||
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
|
||||
return func(
|
||||
f reflect.Type,
|
||||
t reflect.Type,
|
||||
data interface{}) (interface{}, error) {
|
||||
var err error
|
||||
for _, f1 := range fs {
|
||||
data, err = DecodeHookExec(f1, f, t, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Modify the from kind to be correct with the new data
|
||||
f = reflect.ValueOf(data).Type()
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
}
|
||||
|
||||
// StringToSliceHookFunc returns a DecodeHookFunc that converts
|
||||
// string to []string by splitting on the given sep.
|
||||
func StringToSliceHookFunc(sep string) DecodeHookFunc {
|
||||
return func(
|
||||
f reflect.Kind,
|
||||
t reflect.Kind,
|
||||
data interface{}) (interface{}, error) {
|
||||
if f != reflect.String || t != reflect.Slice {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
raw := data.(string)
|
||||
if raw == "" {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return strings.Split(raw, sep), nil
|
||||
}
|
||||
}
|
||||
|
||||
// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts
|
||||
// strings to time.Duration.
|
||||
func StringToTimeDurationHookFunc() DecodeHookFunc {
|
||||
return func(
|
||||
f reflect.Type,
|
||||
t reflect.Type,
|
||||
data interface{}) (interface{}, error) {
|
||||
if f.Kind() != reflect.String {
|
||||
return data, nil
|
||||
}
|
||||
if t != reflect.TypeOf(time.Duration(5)) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Convert it by parsing
|
||||
return time.ParseDuration(data.(string))
|
||||
}
|
||||
}
|
||||
|
||||
func WeaklyTypedHook(
|
||||
f reflect.Kind,
|
||||
t reflect.Kind,
|
||||
data interface{}) (interface{}, error) {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
switch t {
|
||||
case reflect.String:
|
||||
switch f {
|
||||
case reflect.Bool:
|
||||
if dataVal.Bool() {
|
||||
return "1", nil
|
||||
} else {
|
||||
return "0", nil
|
||||
}
|
||||
case reflect.Float32:
|
||||
return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil
|
||||
case reflect.Int:
|
||||
return strconv.FormatInt(dataVal.Int(), 10), nil
|
||||
case reflect.Slice:
|
||||
dataType := dataVal.Type()
|
||||
elemKind := dataType.Elem().Kind()
|
||||
if elemKind == reflect.Uint8 {
|
||||
return string(dataVal.Interface().([]uint8)), nil
|
||||
}
|
||||
case reflect.Uint:
|
||||
return strconv.FormatUint(dataVal.Uint(), 10), nil
|
||||
}
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
50
vendor/github.com/mitchellh/mapstructure/error.go
generated
vendored
Normal file
50
vendor/github.com/mitchellh/mapstructure/error.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
package mapstructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Error implements the error interface and can represents multiple
|
||||
// errors that occur in the course of a single decode.
|
||||
type Error struct {
|
||||
Errors []string
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
points := make([]string, len(e.Errors))
|
||||
for i, err := range e.Errors {
|
||||
points[i] = fmt.Sprintf("* %s", err)
|
||||
}
|
||||
|
||||
sort.Strings(points)
|
||||
return fmt.Sprintf(
|
||||
"%d error(s) decoding:\n\n%s",
|
||||
len(e.Errors), strings.Join(points, "\n"))
|
||||
}
|
||||
|
||||
// WrappedErrors implements the errwrap.Wrapper interface to make this
|
||||
// return value more useful with the errwrap and go-multierror libraries.
|
||||
func (e *Error) WrappedErrors() []error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make([]error, len(e.Errors))
|
||||
for i, e := range e.Errors {
|
||||
result[i] = errors.New(e)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func appendErrors(errors []string, err error) []string {
|
||||
switch e := err.(type) {
|
||||
case *Error:
|
||||
return append(errors, e.Errors...)
|
||||
default:
|
||||
return append(errors, e.Error())
|
||||
}
|
||||
}
|
745
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
Normal file
745
vendor/github.com/mitchellh/mapstructure/mapstructure.go
generated
vendored
Normal file
|
@ -0,0 +1,745 @@
|
|||
// The mapstructure package exposes functionality to convert an
|
||||
// abitrary map[string]interface{} into a native Go structure.
|
||||
//
|
||||
// The Go structure can be arbitrarily complex, containing slices,
|
||||
// other structs, etc. and the decoder will properly decode nested
|
||||
// maps and so on into the proper structures in the native Go struct.
|
||||
// See the examples to see what the decoder is capable of.
|
||||
package mapstructure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DecodeHookFunc is the callback function that can be used for
|
||||
// data transformations. See "DecodeHook" in the DecoderConfig
|
||||
// struct.
|
||||
//
|
||||
// The type should be DecodeHookFuncType or DecodeHookFuncKind.
|
||||
// Either is accepted. Types are a superset of Kinds (Types can return
|
||||
// Kinds) and are generally a richer thing to use, but Kinds are simpler
|
||||
// if you only need those.
|
||||
//
|
||||
// The reason DecodeHookFunc is multi-typed is for backwards compatibility:
|
||||
// we started with Kinds and then realized Types were the better solution,
|
||||
// but have a promise to not break backwards compat so we now support
|
||||
// both.
|
||||
type DecodeHookFunc interface{}
|
||||
|
||||
type DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)
|
||||
type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
|
||||
|
||||
// DecoderConfig is the configuration that is used to create a new decoder
|
||||
// and allows customization of various aspects of decoding.
|
||||
type DecoderConfig struct {
|
||||
// DecodeHook, if set, will be called before any decoding and any
|
||||
// type conversion (if WeaklyTypedInput is on). This lets you modify
|
||||
// the values before they're set down onto the resulting struct.
|
||||
//
|
||||
// If an error is returned, the entire decode will fail with that
|
||||
// error.
|
||||
DecodeHook DecodeHookFunc
|
||||
|
||||
// If ErrorUnused is true, then it is an error for there to exist
|
||||
// keys in the original map that were unused in the decoding process
|
||||
// (extra keys).
|
||||
ErrorUnused bool
|
||||
|
||||
// ZeroFields, if set to true, will zero fields before writing them.
|
||||
// For example, a map will be emptied before decoded values are put in
|
||||
// it. If this is false, a map will be merged.
|
||||
ZeroFields bool
|
||||
|
||||
// If WeaklyTypedInput is true, the decoder will make the following
|
||||
// "weak" conversions:
|
||||
//
|
||||
// - bools to string (true = "1", false = "0")
|
||||
// - numbers to string (base 10)
|
||||
// - bools to int/uint (true = 1, false = 0)
|
||||
// - strings to int/uint (base implied by prefix)
|
||||
// - int to bool (true if value != 0)
|
||||
// - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
|
||||
// FALSE, false, False. Anything else is an error)
|
||||
// - empty array = empty map and vice versa
|
||||
// - negative numbers to overflowed uint values (base 10)
|
||||
//
|
||||
WeaklyTypedInput bool
|
||||
|
||||
// Metadata is the struct that will contain extra metadata about
|
||||
// the decoding. If this is nil, then no metadata will be tracked.
|
||||
Metadata *Metadata
|
||||
|
||||
// Result is a pointer to the struct that will contain the decoded
|
||||
// value.
|
||||
Result interface{}
|
||||
|
||||
// The tag name that mapstructure reads for field names. This
|
||||
// defaults to "mapstructure"
|
||||
TagName string
|
||||
}
|
||||
|
||||
// A Decoder takes a raw interface value and turns it into structured
|
||||
// data, keeping track of rich error information along the way in case
|
||||
// anything goes wrong. Unlike the basic top-level Decode method, you can
|
||||
// more finely control how the Decoder behaves using the DecoderConfig
|
||||
// structure. The top-level Decode method is just a convenience that sets
|
||||
// up the most basic Decoder.
|
||||
type Decoder struct {
|
||||
config *DecoderConfig
|
||||
}
|
||||
|
||||
// Metadata contains information about decoding a structure that
|
||||
// is tedious or difficult to get otherwise.
|
||||
type Metadata struct {
|
||||
// Keys are the keys of the structure which were successfully decoded
|
||||
Keys []string
|
||||
|
||||
// Unused is a slice of keys that were found in the raw value but
|
||||
// weren't decoded since there was no matching field in the result interface
|
||||
Unused []string
|
||||
}
|
||||
|
||||
// Decode takes a map and uses reflection to convert it into the
|
||||
// given Go native structure. val must be a pointer to a struct.
|
||||
func Decode(m interface{}, rawVal interface{}) error {
|
||||
config := &DecoderConfig{
|
||||
Metadata: nil,
|
||||
Result: rawVal,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decoder.Decode(m)
|
||||
}
|
||||
|
||||
// WeakDecode is the same as Decode but is shorthand to enable
|
||||
// WeaklyTypedInput. See DecoderConfig for more info.
|
||||
func WeakDecode(input, output interface{}) error {
|
||||
config := &DecoderConfig{
|
||||
Metadata: nil,
|
||||
Result: output,
|
||||
WeaklyTypedInput: true,
|
||||
}
|
||||
|
||||
decoder, err := NewDecoder(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decoder.Decode(input)
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder for the given configuration. Once
|
||||
// a decoder has been returned, the same configuration must not be used
|
||||
// again.
|
||||
func NewDecoder(config *DecoderConfig) (*Decoder, error) {
|
||||
val := reflect.ValueOf(config.Result)
|
||||
if val.Kind() != reflect.Ptr {
|
||||
return nil, errors.New("result must be a pointer")
|
||||
}
|
||||
|
||||
val = val.Elem()
|
||||
if !val.CanAddr() {
|
||||
return nil, errors.New("result must be addressable (a pointer)")
|
||||
}
|
||||
|
||||
if config.Metadata != nil {
|
||||
if config.Metadata.Keys == nil {
|
||||
config.Metadata.Keys = make([]string, 0)
|
||||
}
|
||||
|
||||
if config.Metadata.Unused == nil {
|
||||
config.Metadata.Unused = make([]string, 0)
|
||||
}
|
||||
}
|
||||
|
||||
if config.TagName == "" {
|
||||
config.TagName = "mapstructure"
|
||||
}
|
||||
|
||||
result := &Decoder{
|
||||
config: config,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Decode decodes the given raw interface to the target pointer specified
|
||||
// by the configuration.
|
||||
func (d *Decoder) Decode(raw interface{}) error {
|
||||
return d.decode("", raw, reflect.ValueOf(d.config.Result).Elem())
|
||||
}
|
||||
|
||||
// Decodes an unknown data type into a specific reflection value.
|
||||
func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {
|
||||
if data == nil {
|
||||
// If the data is nil, then we don't set anything.
|
||||
return nil
|
||||
}
|
||||
|
||||
dataVal := reflect.ValueOf(data)
|
||||
if !dataVal.IsValid() {
|
||||
// If the data value is invalid, then we just set the value
|
||||
// to be the zero value.
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
if d.config.DecodeHook != nil {
|
||||
// We have a DecodeHook, so let's pre-process the data.
|
||||
var err error
|
||||
data, err = DecodeHookExec(
|
||||
d.config.DecodeHook,
|
||||
dataVal.Type(), val.Type(), data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
dataKind := getKind(val)
|
||||
switch dataKind {
|
||||
case reflect.Bool:
|
||||
err = d.decodeBool(name, data, val)
|
||||
case reflect.Interface:
|
||||
err = d.decodeBasic(name, data, val)
|
||||
case reflect.String:
|
||||
err = d.decodeString(name, data, val)
|
||||
case reflect.Int:
|
||||
err = d.decodeInt(name, data, val)
|
||||
case reflect.Uint:
|
||||
err = d.decodeUint(name, data, val)
|
||||
case reflect.Float32:
|
||||
err = d.decodeFloat(name, data, val)
|
||||
case reflect.Struct:
|
||||
err = d.decodeStruct(name, data, val)
|
||||
case reflect.Map:
|
||||
err = d.decodeMap(name, data, val)
|
||||
case reflect.Ptr:
|
||||
err = d.decodePtr(name, data, val)
|
||||
case reflect.Slice:
|
||||
err = d.decodeSlice(name, data, val)
|
||||
default:
|
||||
// If we reached this point then we weren't able to decode it
|
||||
return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
|
||||
}
|
||||
|
||||
// If we reached here, then we successfully decoded SOMETHING, so
|
||||
// mark the key as used if we're tracking metadata.
|
||||
if d.config.Metadata != nil && name != "" {
|
||||
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// This decodes a basic type (bool, int, string, etc.) and sets the
|
||||
// value to "data" of that type.
|
||||
func (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
dataValType := dataVal.Type()
|
||||
if !dataValType.AssignableTo(val.Type()) {
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got '%s'",
|
||||
name, val.Type(), dataValType)
|
||||
}
|
||||
|
||||
val.Set(dataVal)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
dataKind := getKind(dataVal)
|
||||
|
||||
converted := true
|
||||
switch {
|
||||
case dataKind == reflect.String:
|
||||
val.SetString(dataVal.String())
|
||||
case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
|
||||
if dataVal.Bool() {
|
||||
val.SetString("1")
|
||||
} else {
|
||||
val.SetString("0")
|
||||
}
|
||||
case dataKind == reflect.Int && d.config.WeaklyTypedInput:
|
||||
val.SetString(strconv.FormatInt(dataVal.Int(), 10))
|
||||
case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
|
||||
val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
|
||||
case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
|
||||
val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
|
||||
case dataKind == reflect.Slice && d.config.WeaklyTypedInput:
|
||||
dataType := dataVal.Type()
|
||||
elemKind := dataType.Elem().Kind()
|
||||
switch {
|
||||
case elemKind == reflect.Uint8:
|
||||
val.SetString(string(dataVal.Interface().([]uint8)))
|
||||
default:
|
||||
converted = false
|
||||
}
|
||||
default:
|
||||
converted = false
|
||||
}
|
||||
|
||||
if !converted {
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||
name, val.Type(), dataVal.Type())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
dataKind := getKind(dataVal)
|
||||
|
||||
switch {
|
||||
case dataKind == reflect.Int:
|
||||
val.SetInt(dataVal.Int())
|
||||
case dataKind == reflect.Uint:
|
||||
val.SetInt(int64(dataVal.Uint()))
|
||||
case dataKind == reflect.Float32:
|
||||
val.SetInt(int64(dataVal.Float()))
|
||||
case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
|
||||
if dataVal.Bool() {
|
||||
val.SetInt(1)
|
||||
} else {
|
||||
val.SetInt(0)
|
||||
}
|
||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||
i, err := strconv.ParseInt(dataVal.String(), 0, val.Type().Bits())
|
||||
if err == nil {
|
||||
val.SetInt(i)
|
||||
} else {
|
||||
return fmt.Errorf("cannot parse '%s' as int: %s", name, err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||
name, val.Type(), dataVal.Type())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
dataKind := getKind(dataVal)
|
||||
|
||||
switch {
|
||||
case dataKind == reflect.Int:
|
||||
i := dataVal.Int()
|
||||
if i < 0 && !d.config.WeaklyTypedInput {
|
||||
return fmt.Errorf("cannot parse '%s', %d overflows uint",
|
||||
name, i)
|
||||
}
|
||||
val.SetUint(uint64(i))
|
||||
case dataKind == reflect.Uint:
|
||||
val.SetUint(dataVal.Uint())
|
||||
case dataKind == reflect.Float32:
|
||||
f := dataVal.Float()
|
||||
if f < 0 && !d.config.WeaklyTypedInput {
|
||||
return fmt.Errorf("cannot parse '%s', %f overflows uint",
|
||||
name, f)
|
||||
}
|
||||
val.SetUint(uint64(f))
|
||||
case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
|
||||
if dataVal.Bool() {
|
||||
val.SetUint(1)
|
||||
} else {
|
||||
val.SetUint(0)
|
||||
}
|
||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||
i, err := strconv.ParseUint(dataVal.String(), 0, val.Type().Bits())
|
||||
if err == nil {
|
||||
val.SetUint(i)
|
||||
} else {
|
||||
return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||
name, val.Type(), dataVal.Type())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
dataKind := getKind(dataVal)
|
||||
|
||||
switch {
|
||||
case dataKind == reflect.Bool:
|
||||
val.SetBool(dataVal.Bool())
|
||||
case dataKind == reflect.Int && d.config.WeaklyTypedInput:
|
||||
val.SetBool(dataVal.Int() != 0)
|
||||
case dataKind == reflect.Uint && d.config.WeaklyTypedInput:
|
||||
val.SetBool(dataVal.Uint() != 0)
|
||||
case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
|
||||
val.SetBool(dataVal.Float() != 0)
|
||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||
b, err := strconv.ParseBool(dataVal.String())
|
||||
if err == nil {
|
||||
val.SetBool(b)
|
||||
} else if dataVal.String() == "" {
|
||||
val.SetBool(false)
|
||||
} else {
|
||||
return fmt.Errorf("cannot parse '%s' as bool: %s", name, err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||
name, val.Type(), dataVal.Type())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.ValueOf(data)
|
||||
dataKind := getKind(dataVal)
|
||||
|
||||
switch {
|
||||
case dataKind == reflect.Int:
|
||||
val.SetFloat(float64(dataVal.Int()))
|
||||
case dataKind == reflect.Uint:
|
||||
val.SetFloat(float64(dataVal.Uint()))
|
||||
case dataKind == reflect.Float32:
|
||||
val.SetFloat(float64(dataVal.Float()))
|
||||
case dataKind == reflect.Bool && d.config.WeaklyTypedInput:
|
||||
if dataVal.Bool() {
|
||||
val.SetFloat(1)
|
||||
} else {
|
||||
val.SetFloat(0)
|
||||
}
|
||||
case dataKind == reflect.String && d.config.WeaklyTypedInput:
|
||||
f, err := strconv.ParseFloat(dataVal.String(), val.Type().Bits())
|
||||
if err == nil {
|
||||
val.SetFloat(f)
|
||||
} else {
|
||||
return fmt.Errorf("cannot parse '%s' as float: %s", name, err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"'%s' expected type '%s', got unconvertible type '%s'",
|
||||
name, val.Type(), dataVal.Type())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {
|
||||
valType := val.Type()
|
||||
valKeyType := valType.Key()
|
||||
valElemType := valType.Elem()
|
||||
|
||||
// By default we overwrite keys in the current map
|
||||
valMap := val
|
||||
|
||||
// If the map is nil or we're purposely zeroing fields, make a new map
|
||||
if valMap.IsNil() || d.config.ZeroFields {
|
||||
// Make a new map to hold our result
|
||||
mapType := reflect.MapOf(valKeyType, valElemType)
|
||||
valMap = reflect.MakeMap(mapType)
|
||||
}
|
||||
|
||||
// Check input type
|
||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||
if dataVal.Kind() != reflect.Map {
|
||||
// Accept empty array/slice instead of an empty map in weakly typed mode
|
||||
if d.config.WeaklyTypedInput &&
|
||||
(dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) &&
|
||||
dataVal.Len() == 0 {
|
||||
val.Set(valMap)
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate errors
|
||||
errors := make([]string, 0)
|
||||
|
||||
for _, k := range dataVal.MapKeys() {
|
||||
fieldName := fmt.Sprintf("%s[%s]", name, k)
|
||||
|
||||
// First decode the key into the proper type
|
||||
currentKey := reflect.Indirect(reflect.New(valKeyType))
|
||||
if err := d.decode(fieldName, k.Interface(), currentKey); err != nil {
|
||||
errors = appendErrors(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Next decode the data into the proper type
|
||||
v := dataVal.MapIndex(k).Interface()
|
||||
currentVal := reflect.Indirect(reflect.New(valElemType))
|
||||
if err := d.decode(fieldName, v, currentVal); err != nil {
|
||||
errors = appendErrors(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
valMap.SetMapIndex(currentKey, currentVal)
|
||||
}
|
||||
|
||||
// Set the built up map to the value
|
||||
val.Set(valMap)
|
||||
|
||||
// If we had errors, return those
|
||||
if len(errors) > 0 {
|
||||
return &Error{errors}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) error {
|
||||
// Create an element of the concrete (non pointer) type and decode
|
||||
// into that. Then set the value of the pointer to this type.
|
||||
valType := val.Type()
|
||||
valElemType := valType.Elem()
|
||||
realVal := reflect.New(valElemType)
|
||||
if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(realVal)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||
dataValKind := dataVal.Kind()
|
||||
valType := val.Type()
|
||||
valElemType := valType.Elem()
|
||||
sliceType := reflect.SliceOf(valElemType)
|
||||
|
||||
// Check input type
|
||||
if dataValKind != reflect.Array && dataValKind != reflect.Slice {
|
||||
// Accept empty map instead of array/slice in weakly typed mode
|
||||
if d.config.WeaklyTypedInput && dataVal.Kind() == reflect.Map && dataVal.Len() == 0 {
|
||||
val.Set(reflect.MakeSlice(sliceType, 0, 0))
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf(
|
||||
"'%s': source data must be an array or slice, got %s", name, dataValKind)
|
||||
}
|
||||
}
|
||||
|
||||
// Make a new slice to hold our result, same size as the original data.
|
||||
valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
|
||||
|
||||
// Accumulate any errors
|
||||
errors := make([]string, 0)
|
||||
|
||||
for i := 0; i < dataVal.Len(); i++ {
|
||||
currentData := dataVal.Index(i).Interface()
|
||||
currentField := valSlice.Index(i)
|
||||
|
||||
fieldName := fmt.Sprintf("%s[%d]", name, i)
|
||||
if err := d.decode(fieldName, currentData, currentField); err != nil {
|
||||
errors = appendErrors(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, set the value to the slice we built up
|
||||
val.Set(valSlice)
|
||||
|
||||
// If there were errors, we return those
|
||||
if len(errors) > 0 {
|
||||
return &Error{errors}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
|
||||
dataVal := reflect.Indirect(reflect.ValueOf(data))
|
||||
|
||||
// If the type of the value to write to and the data match directly,
|
||||
// then we just set it directly instead of recursing into the structure.
|
||||
if dataVal.Type() == val.Type() {
|
||||
val.Set(dataVal)
|
||||
return nil
|
||||
}
|
||||
|
||||
dataValKind := dataVal.Kind()
|
||||
if dataValKind != reflect.Map {
|
||||
return fmt.Errorf("'%s' expected a map, got '%s'", name, dataValKind)
|
||||
}
|
||||
|
||||
dataValType := dataVal.Type()
|
||||
if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
|
||||
return fmt.Errorf(
|
||||
"'%s' needs a map with string keys, has '%s' keys",
|
||||
name, dataValType.Key().Kind())
|
||||
}
|
||||
|
||||
dataValKeys := make(map[reflect.Value]struct{})
|
||||
dataValKeysUnused := make(map[interface{}]struct{})
|
||||
for _, dataValKey := range dataVal.MapKeys() {
|
||||
dataValKeys[dataValKey] = struct{}{}
|
||||
dataValKeysUnused[dataValKey.Interface()] = struct{}{}
|
||||
}
|
||||
|
||||
errors := make([]string, 0)
|
||||
|
||||
// This slice will keep track of all the structs we'll be decoding.
|
||||
// There can be more than one struct if there are embedded structs
|
||||
// that are squashed.
|
||||
structs := make([]reflect.Value, 1, 5)
|
||||
structs[0] = val
|
||||
|
||||
// Compile the list of all the fields that we're going to be decoding
|
||||
// from all the structs.
|
||||
fields := make(map[*reflect.StructField]reflect.Value)
|
||||
for len(structs) > 0 {
|
||||
structVal := structs[0]
|
||||
structs = structs[1:]
|
||||
|
||||
structType := structVal.Type()
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
fieldType := structType.Field(i)
|
||||
|
||||
if fieldType.Anonymous {
|
||||
fieldKind := fieldType.Type.Kind()
|
||||
if fieldKind != reflect.Struct {
|
||||
errors = appendErrors(errors,
|
||||
fmt.Errorf("%s: unsupported type: %s", fieldType.Name, fieldKind))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// If "squash" is specified in the tag, we squash the field down.
|
||||
squash := false
|
||||
tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
|
||||
for _, tag := range tagParts[1:] {
|
||||
if tag == "squash" {
|
||||
squash = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if squash {
|
||||
structs = append(structs, val.FieldByName(fieldType.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
// Normal struct field, store it away
|
||||
fields[&fieldType] = structVal.Field(i)
|
||||
}
|
||||
}
|
||||
|
||||
for fieldType, field := range fields {
|
||||
fieldName := fieldType.Name
|
||||
|
||||
tagValue := fieldType.Tag.Get(d.config.TagName)
|
||||
tagValue = strings.SplitN(tagValue, ",", 2)[0]
|
||||
if tagValue != "" {
|
||||
fieldName = tagValue
|
||||
}
|
||||
|
||||
rawMapKey := reflect.ValueOf(fieldName)
|
||||
rawMapVal := dataVal.MapIndex(rawMapKey)
|
||||
if !rawMapVal.IsValid() {
|
||||
// Do a slower search by iterating over each key and
|
||||
// doing case-insensitive search.
|
||||
for dataValKey, _ := range dataValKeys {
|
||||
mK, ok := dataValKey.Interface().(string)
|
||||
if !ok {
|
||||
// Not a string key
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.EqualFold(mK, fieldName) {
|
||||
rawMapKey = dataValKey
|
||||
rawMapVal = dataVal.MapIndex(dataValKey)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !rawMapVal.IsValid() {
|
||||
// There was no matching key in the map for the value in
|
||||
// the struct. Just ignore.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the key we're using from the unused map so we stop tracking
|
||||
delete(dataValKeysUnused, rawMapKey.Interface())
|
||||
|
||||
if !field.IsValid() {
|
||||
// This should never happen
|
||||
panic("field is not valid")
|
||||
}
|
||||
|
||||
// If we can't set the field, then it is unexported or something,
|
||||
// and we just continue onwards.
|
||||
if !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the name is empty string, then we're at the root, and we
|
||||
// don't dot-join the fields.
|
||||
if name != "" {
|
||||
fieldName = fmt.Sprintf("%s.%s", name, fieldName)
|
||||
}
|
||||
|
||||
if err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil {
|
||||
errors = appendErrors(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
|
||||
keys := make([]string, 0, len(dataValKeysUnused))
|
||||
for rawKey, _ := range dataValKeysUnused {
|
||||
keys = append(keys, rawKey.(string))
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
|
||||
errors = appendErrors(errors, err)
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return &Error{errors}
|
||||
}
|
||||
|
||||
// Add the unused keys to the list of unused keys if we're tracking metadata
|
||||
if d.config.Metadata != nil {
|
||||
for rawKey, _ := range dataValKeysUnused {
|
||||
key := rawKey.(string)
|
||||
if name != "" {
|
||||
key = fmt.Sprintf("%s.%s", name, key)
|
||||
}
|
||||
|
||||
d.config.Metadata.Unused = append(d.config.Metadata.Unused, key)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getKind(val reflect.Value) reflect.Kind {
|
||||
kind := val.Kind()
|
||||
|
||||
switch {
|
||||
case kind >= reflect.Int && kind <= reflect.Int64:
|
||||
return reflect.Int
|
||||
case kind >= reflect.Uint && kind <= reflect.Uint64:
|
||||
return reflect.Uint
|
||||
case kind >= reflect.Float32 && kind <= reflect.Float64:
|
||||
return reflect.Float32
|
||||
default:
|
||||
return kind
|
||||
}
|
||||
}
|
17
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
Normal file
17
vendor/github.com/spf13/pflag/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
sudo: false
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go get github.com/golang/lint/golint
|
||||
- export PATH=$GOPATH/bin:$PATH
|
||||
- go install ./...
|
||||
|
||||
script:
|
||||
- verify/all.sh
|
||||
- go test ./...
|
28
vendor/github.com/spf13/pflag/LICENSE
generated
vendored
Normal file
28
vendor/github.com/spf13/pflag/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
Copyright (c) 2012 Alex Ogier. All rights reserved.
|
||||
Copyright (c) 2012 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.
|
256
vendor/github.com/spf13/pflag/README.md
generated
vendored
Normal file
256
vendor/github.com/spf13/pflag/README.md
generated
vendored
Normal file
|
@ -0,0 +1,256 @@
|
|||
[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)
|
||||
|
||||
## Description
|
||||
|
||||
pflag is a drop-in replacement for Go's flag package, implementing
|
||||
POSIX/GNU-style --flags.
|
||||
|
||||
pflag is compatible with the [GNU extensions to the POSIX recommendations
|
||||
for command-line options][1]. For a more precise description, see the
|
||||
"Command-line flag syntax" section below.
|
||||
|
||||
[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
||||
|
||||
pflag is available under the same style of BSD license as the Go language,
|
||||
which can be found in the LICENSE file.
|
||||
|
||||
## Installation
|
||||
|
||||
pflag is available using the standard `go get` command.
|
||||
|
||||
Install by running:
|
||||
|
||||
go get github.com/spf13/pflag
|
||||
|
||||
Run tests by running:
|
||||
|
||||
go test github.com/spf13/pflag
|
||||
|
||||
## Usage
|
||||
|
||||
pflag is a drop-in replacement of Go's native flag package. If you import
|
||||
pflag under the name "flag" then all code should continue to function
|
||||
with no changes.
|
||||
|
||||
``` go
|
||||
import flag "github.com/spf13/pflag"
|
||||
```
|
||||
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
there is one more field "Shorthand" that you will need to set.
|
||||
Most code never instantiates this struct directly, and instead uses
|
||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||
unaffected.
|
||||
|
||||
Define flags using flag.String(), Bool(), Int(), etc.
|
||||
|
||||
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
|
||||
|
||||
``` go
|
||||
var ip *int = flag.Int("flagname", 1234, "help message for flagname")
|
||||
```
|
||||
|
||||
If you like, you can bind the flag to a variable using the Var() functions.
|
||||
|
||||
``` go
|
||||
var flagvar int
|
||||
func init() {
|
||||
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
|
||||
}
|
||||
```
|
||||
|
||||
Or you can create custom flags that satisfy the Value interface (with
|
||||
pointer receivers) and couple them to flag parsing by
|
||||
|
||||
``` go
|
||||
flag.Var(&flagVal, "name", "help message for flagname")
|
||||
```
|
||||
|
||||
For such flags, the default value is just the initial value of the variable.
|
||||
|
||||
After all flags are defined, call
|
||||
|
||||
``` go
|
||||
flag.Parse()
|
||||
```
|
||||
|
||||
to parse the command line into the defined flags.
|
||||
|
||||
Flags may then be used directly. If you're using the flags themselves,
|
||||
they are all pointers; if you bind to variables, they're values.
|
||||
|
||||
``` go
|
||||
fmt.Println("ip has value ", *ip)
|
||||
fmt.Println("flagvar has value ", flagvar)
|
||||
```
|
||||
|
||||
There are helpers function to get values later if you have the FlagSet but
|
||||
it was difficult to keep up with all of the the flag pointers in your code.
|
||||
If you have a pflag.FlagSet with a flag called 'flagname' of type int you
|
||||
can use GetInt() to get the int value. But notice that 'flagname' must exist
|
||||
and it must be an int. GetString("flagname") will fail.
|
||||
|
||||
``` go
|
||||
i, err := flagset.GetInt("flagname")
|
||||
```
|
||||
|
||||
After parsing, the arguments after the flag are available as the
|
||||
slice flag.Args() or individually as flag.Arg(i).
|
||||
The arguments are indexed from 0 through flag.NArg()-1.
|
||||
|
||||
The pflag package also defines some new functions that are not in flag,
|
||||
that give one-letter shorthands for flags. You can use these by appending
|
||||
'P' to the name of any function that defines a flag.
|
||||
|
||||
``` go
|
||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||
var flagvar bool
|
||||
func init() {
|
||||
flag.BoolVarP("boolname", "b", true, "help message")
|
||||
}
|
||||
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
||||
```
|
||||
|
||||
Shorthand letters can be used with single dashes on the command line.
|
||||
Boolean shorthand flags can be combined with other shorthand flags.
|
||||
|
||||
The default set of command-line flags is controlled by
|
||||
top-level functions. The FlagSet type allows one to define
|
||||
independent sets of flags, such as to implement subcommands
|
||||
in a command-line interface. The methods of FlagSet are
|
||||
analogous to the top-level functions for the command-line
|
||||
flag set.
|
||||
|
||||
## Setting no option default values for flags
|
||||
|
||||
After you create a flag it is possible to set the pflag.NoOptDefVal for
|
||||
the given flag. Doing this changes the meaning of the flag slightly. If
|
||||
a flag has a NoOptDefVal and the flag is set on the command line without
|
||||
an option the flag will be set to the NoOptDefVal. For example given:
|
||||
|
||||
``` go
|
||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||
flag.Lookup("flagname").NoOptDefVal = "4321"
|
||||
```
|
||||
|
||||
Would result in something like
|
||||
|
||||
| Parsed Arguments | Resulting Value |
|
||||
| ------------- | ------------- |
|
||||
| --flagname=1357 | ip=1357 |
|
||||
| --flagname | ip=4321 |
|
||||
| [nothing] | ip=1234 |
|
||||
|
||||
## Command line flag syntax
|
||||
|
||||
```
|
||||
--flag // boolean flags, or flags with no option default values
|
||||
--flag x // only on flags without a default value
|
||||
--flag=x
|
||||
```
|
||||
|
||||
Unlike the flag package, a single dash before an option means something
|
||||
different than a double dash. Single dashes signify a series of shorthand
|
||||
letters for flags. All but the last shorthand letter must be boolean flags
|
||||
or a flag with a default value
|
||||
|
||||
```
|
||||
// boolean or flags where the 'no option default value' is set
|
||||
-f
|
||||
-f=true
|
||||
-abc
|
||||
but
|
||||
-b true is INVALID
|
||||
|
||||
// non-boolean and flags without a 'no option default value'
|
||||
-n 1234
|
||||
-n=1234
|
||||
-n1234
|
||||
|
||||
// mixed
|
||||
-abcs "hello"
|
||||
-absd="hello"
|
||||
-abcs1234
|
||||
```
|
||||
|
||||
Flag parsing stops after the terminator "--". Unlike the flag package,
|
||||
flags can be interspersed with arguments anywhere on the command line
|
||||
before this terminator.
|
||||
|
||||
Integer flags accept 1234, 0664, 0x1234 and may be negative.
|
||||
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
|
||||
TRUE, FALSE, True, False.
|
||||
Duration flags accept any input valid for time.ParseDuration.
|
||||
|
||||
## Mutating or "Normalizing" Flag names
|
||||
|
||||
It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.
|
||||
|
||||
**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag
|
||||
|
||||
``` go
|
||||
func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
from := []string{"-", "_"}
|
||||
to := "."
|
||||
for _, sep := range from {
|
||||
name = strings.Replace(name, sep, to, -1)
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
}
|
||||
|
||||
myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)
|
||||
```
|
||||
|
||||
**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name
|
||||
|
||||
``` go
|
||||
func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
switch name {
|
||||
case "old-flag-name":
|
||||
name = "new-flag-name"
|
||||
break
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
}
|
||||
|
||||
myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)
|
||||
```
|
||||
|
||||
## Deprecating a flag or its shorthand
|
||||
It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.
|
||||
|
||||
**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
|
||||
```go
|
||||
// deprecate a flag by specifying its name and a usage message
|
||||
flags.MarkDeprecated("badflag", "please use --good-flag instead")
|
||||
```
|
||||
This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.
|
||||
|
||||
**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
|
||||
```go
|
||||
// deprecate a flag shorthand by specifying its flag name and a usage message
|
||||
flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")
|
||||
```
|
||||
This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.
|
||||
|
||||
Note that usage message is essential here, and it should not be empty.
|
||||
|
||||
## Hidden flags
|
||||
It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.
|
||||
|
||||
**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.
|
||||
```go
|
||||
// hide a flag by specifying its name
|
||||
flags.MarkHidden("secretFlag")
|
||||
```
|
||||
|
||||
## More info
|
||||
|
||||
You can see the full reference documentation of the pflag package
|
||||
[at godoc.org][3], or through go's standard documentation system by
|
||||
running `godoc -http=:6060` and browsing to
|
||||
[http://localhost:6060/pkg/github.com/ogier/pflag][2] after
|
||||
installation.
|
||||
|
||||
[2]: http://localhost:6060/pkg/github.com/ogier/pflag
|
||||
[3]: http://godoc.org/github.com/ogier/pflag
|
97
vendor/github.com/spf13/pflag/bool.go
generated
vendored
Normal file
97
vendor/github.com/spf13/pflag/bool.go
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// optional interface to indicate boolean flags that can be
|
||||
// supplied without "=value" text
|
||||
type boolFlag interface {
|
||||
Value
|
||||
IsBoolFlag() bool
|
||||
}
|
||||
|
||||
// -- bool Value
|
||||
type boolValue bool
|
||||
|
||||
func newBoolValue(val bool, p *bool) *boolValue {
|
||||
*p = val
|
||||
return (*boolValue)(p)
|
||||
}
|
||||
|
||||
func (b *boolValue) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
*b = boolValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *boolValue) Type() string {
|
||||
return "bool"
|
||||
}
|
||||
|
||||
func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
|
||||
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
func boolConv(sval string) (interface{}, error) {
|
||||
return strconv.ParseBool(sval)
|
||||
}
|
||||
|
||||
// GetBool return the bool value of a flag with the given name
|
||||
func (f *FlagSet) GetBool(name string) (bool, error) {
|
||||
val, err := f.getFlagType(name, "bool", boolConv)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return val.(bool), nil
|
||||
}
|
||||
|
||||
// BoolVar 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 (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
|
||||
f.BoolVarP(p, name, "", value, usage)
|
||||
}
|
||||
|
||||
// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
|
||||
flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)
|
||||
flag.NoOptDefVal = "true"
|
||||
}
|
||||
|
||||
// BoolVar 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 BoolVar(p *bool, name string, value bool, usage string) {
|
||||
BoolVarP(p, name, "", value, usage)
|
||||
}
|
||||
|
||||
// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
|
||||
flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
|
||||
flag.NoOptDefVal = "true"
|
||||
}
|
||||
|
||||
// Bool 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) Bool(name string, value bool, usage string) *bool {
|
||||
return f.BoolP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {
|
||||
p := new(bool)
|
||||
f.BoolVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Bool 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 Bool(name string, value bool, usage string) *bool {
|
||||
return BoolP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
|
||||
func BoolP(name, shorthand string, value bool, usage string) *bool {
|
||||
b := CommandLine.BoolP(name, shorthand, value, usage)
|
||||
return b
|
||||
}
|
97
vendor/github.com/spf13/pflag/count.go
generated
vendored
Normal file
97
vendor/github.com/spf13/pflag/count.go
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- count Value
|
||||
type countValue int
|
||||
|
||||
func newCountValue(val int, p *int) *countValue {
|
||||
*p = val
|
||||
return (*countValue)(p)
|
||||
}
|
||||
|
||||
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 {
|
||||
*i = countValue(*i + 1)
|
||||
} else {
|
||||
*i = countValue(v)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *countValue) Type() string {
|
||||
return "count"
|
||||
}
|
||||
|
||||
func (i *countValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func countConv(sval string) (interface{}, error) {
|
||||
i, err := strconv.Atoi(sval)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// GetCount return the int value of a flag with the given name
|
||||
func (f *FlagSet) GetCount(name string) (int, error) {
|
||||
val, err := f.getFlagType(name, "count", countConv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int), nil
|
||||
}
|
||||
|
||||
// CountVar defines a count flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int variable in which to store the value of the flag.
|
||||
// A count flag will add 1 to its value evey time it is found on the command line
|
||||
func (f *FlagSet) CountVar(p *int, name string, usage string) {
|
||||
f.CountVarP(p, name, "", usage)
|
||||
}
|
||||
|
||||
// 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"
|
||||
}
|
||||
|
||||
// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
|
||||
func CountVar(p *int, name string, usage string) {
|
||||
CommandLine.CountVar(p, name, usage)
|
||||
}
|
||||
|
||||
// CountVarP is like CountVar only take a shorthand for the flag name.
|
||||
func CountVarP(p *int, name, shorthand string, usage string) {
|
||||
CommandLine.CountVarP(p, name, shorthand, usage)
|
||||
}
|
||||
|
||||
// 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 (f *FlagSet) Count(name string, usage string) *int {
|
||||
p := new(int)
|
||||
f.CountVarP(p, name, "", usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// CountP is like Count only takes a shorthand for the flag name.
|
||||
func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
|
||||
p := new(int)
|
||||
f.CountVarP(p, name, shorthand, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
|
||||
func Count(name string, usage string) *int {
|
||||
return CommandLine.CountP(name, "", usage)
|
||||
}
|
||||
|
||||
// CountP is like Count only takes a shorthand for the flag name.
|
||||
func CountP(name, shorthand string, usage string) *int {
|
||||
return CommandLine.CountP(name, shorthand, usage)
|
||||
}
|
86
vendor/github.com/spf13/pflag/duration.go
generated
vendored
Normal file
86
vendor/github.com/spf13/pflag/duration.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// -- time.Duration Value
|
||||
type durationValue time.Duration
|
||||
|
||||
func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
|
||||
*p = val
|
||||
return (*durationValue)(p)
|
||||
}
|
||||
|
||||
func (d *durationValue) Set(s string) error {
|
||||
v, err := time.ParseDuration(s)
|
||||
*d = durationValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *durationValue) Type() string {
|
||||
return "duration"
|
||||
}
|
||||
|
||||
func (d *durationValue) String() string { return (*time.Duration)(d).String() }
|
||||
|
||||
func durationConv(sval string) (interface{}, error) {
|
||||
return time.ParseDuration(sval)
|
||||
}
|
||||
|
||||
// GetDuration return the duration value of a flag with the given name
|
||||
func (f *FlagSet) GetDuration(name string) (time.Duration, error) {
|
||||
val, err := f.getFlagType(name, "duration", durationConv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(time.Duration), nil
|
||||
}
|
||||
|
||||
// DurationVar defines a time.Duration 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) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
|
||||
f.VarP(newDurationValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
||||
f.VarP(newDurationValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// DurationVar defines a time.Duration 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 DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
|
||||
CommandLine.VarP(newDurationValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
||||
CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Duration 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) Duration(name string, value time.Duration, usage string) *time.Duration {
|
||||
p := new(time.Duration)
|
||||
f.DurationVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
|
||||
p := new(time.Duration)
|
||||
f.DurationVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Duration 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 Duration(name string, value time.Duration, usage string) *time.Duration {
|
||||
return CommandLine.DurationP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
|
||||
func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
|
||||
return CommandLine.DurationP(name, shorthand, value, usage)
|
||||
}
|
836
vendor/github.com/spf13/pflag/flag.go
generated
vendored
Normal file
836
vendor/github.com/spf13/pflag/flag.go
generated
vendored
Normal file
|
@ -0,0 +1,836 @@
|
|||
// Copyright 2009 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 pflag is a drop-in replacement for Go's flag package, implementing
|
||||
POSIX/GNU-style --flags.
|
||||
|
||||
pflag is compatible with the GNU extensions to the POSIX recommendations
|
||||
for command-line options. See
|
||||
http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
||||
|
||||
Usage:
|
||||
|
||||
pflag is a drop-in replacement of Go's native flag package. If you import
|
||||
pflag under the name "flag" then all code should continue to function
|
||||
with no changes.
|
||||
|
||||
import flag "github.com/ogier/pflag"
|
||||
|
||||
There is one exception to this: if you directly instantiate the Flag struct
|
||||
there is one more field "Shorthand" that you will need to set.
|
||||
Most code never instantiates this struct directly, and instead uses
|
||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||
unaffected.
|
||||
|
||||
Define flags using flag.String(), Bool(), Int(), etc.
|
||||
|
||||
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
|
||||
var ip = flag.Int("flagname", 1234, "help message for flagname")
|
||||
If you like, you can bind the flag to a variable using the Var() functions.
|
||||
var flagvar int
|
||||
func init() {
|
||||
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
|
||||
}
|
||||
Or you can create custom flags that satisfy the Value interface (with
|
||||
pointer receivers) and couple them to flag parsing by
|
||||
flag.Var(&flagVal, "name", "help message for flagname")
|
||||
For such flags, the default value is just the initial value of the variable.
|
||||
|
||||
After all flags are defined, call
|
||||
flag.Parse()
|
||||
to parse the command line into the defined flags.
|
||||
|
||||
Flags may then be used directly. If you're using the flags themselves,
|
||||
they are all pointers; if you bind to variables, they're values.
|
||||
fmt.Println("ip has value ", *ip)
|
||||
fmt.Println("flagvar has value ", flagvar)
|
||||
|
||||
After parsing, the arguments after the flag are available as the
|
||||
slice flag.Args() or individually as flag.Arg(i).
|
||||
The arguments are indexed from 0 through flag.NArg()-1.
|
||||
|
||||
The pflag package also defines some new functions that are not in flag,
|
||||
that give one-letter shorthands for flags. You can use these by appending
|
||||
'P' to the name of any function that defines a flag.
|
||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||
var flagvar bool
|
||||
func init() {
|
||||
flag.BoolVarP("boolname", "b", true, "help message")
|
||||
}
|
||||
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
||||
Shorthand letters can be used with single dashes on the command line.
|
||||
Boolean shorthand flags can be combined with other shorthand flags.
|
||||
|
||||
Command line flag syntax:
|
||||
--flag // boolean flags only
|
||||
--flag=x
|
||||
|
||||
Unlike the flag package, a single dash before an option means something
|
||||
different than a double dash. Single dashes signify a series of shorthand
|
||||
letters for flags. All but the last shorthand letter must be boolean flags.
|
||||
// boolean flags
|
||||
-f
|
||||
-abc
|
||||
// non-boolean flags
|
||||
-n 1234
|
||||
-Ifile
|
||||
// mixed
|
||||
-abcs "hello"
|
||||
-abcn1234
|
||||
|
||||
Flag parsing stops after the terminator "--". Unlike the flag package,
|
||||
flags can be interspersed with arguments anywhere on the command line
|
||||
before this terminator.
|
||||
|
||||
Integer flags accept 1234, 0664, 0x1234 and may be negative.
|
||||
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
|
||||
TRUE, FALSE, True, False.
|
||||
Duration flags accept any input valid for time.ParseDuration.
|
||||
|
||||
The default set of command-line flags is controlled by
|
||||
top-level functions. The FlagSet type allows one to define
|
||||
independent sets of flags, such as to implement subcommands
|
||||
in a command-line interface. The methods of FlagSet are
|
||||
analogous to the top-level functions for the command-line
|
||||
flag set.
|
||||
*/
|
||||
package pflag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
|
||||
var ErrHelp = errors.New("pflag: help requested")
|
||||
|
||||
// ErrorHandling defines how to handle flag parsing errors.
|
||||
type ErrorHandling int
|
||||
|
||||
const (
|
||||
// ContinueOnError will return an err from Parse() if an error is found
|
||||
ContinueOnError ErrorHandling = iota
|
||||
// ExitOnError will call os.Exit(2) if an error is found when parsing
|
||||
ExitOnError
|
||||
// PanicOnError will panic() if an error is found when parsing flags
|
||||
PanicOnError
|
||||
)
|
||||
|
||||
// NormalizedName is a flag name that has been normalized according to rules
|
||||
// for the FlagSet (e.g. making '-' and '_' equivalent).
|
||||
type NormalizedName string
|
||||
|
||||
// A FlagSet represents a set of defined flags.
|
||||
type FlagSet struct {
|
||||
// Usage is the function called when an error occurs while parsing flags.
|
||||
// The field is a function (not a method) that may be changed to point to
|
||||
// a custom error handler.
|
||||
Usage func()
|
||||
|
||||
name string
|
||||
parsed bool
|
||||
actual map[NormalizedName]*Flag
|
||||
formal map[NormalizedName]*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
|
||||
}
|
||||
|
||||
// A Flag represents the state of a flag.
|
||||
type Flag struct {
|
||||
Name string // name as it appears on command line
|
||||
Shorthand string // one-letter abbreviated flag
|
||||
Usage string // help message
|
||||
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
|
||||
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
|
||||
Annotations map[string][]string // used by cobra.Command bash autocomple code
|
||||
}
|
||||
|
||||
// Value is the interface to the dynamic value stored in a flag.
|
||||
// (The default value is represented as a string.)
|
||||
type Value interface {
|
||||
String() string
|
||||
Set(string) error
|
||||
Type() string
|
||||
}
|
||||
|
||||
// sortFlags returns the flags as a slice in lexicographical sorted order.
|
||||
func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
|
||||
list := make(sort.StringSlice, len(flags))
|
||||
i := 0
|
||||
for k := range flags {
|
||||
list[i] = string(k)
|
||||
i++
|
||||
}
|
||||
list.Sort()
|
||||
result := make([]*Flag, len(list))
|
||||
for i, name := range list {
|
||||
result[i] = flags[NormalizedName(name)]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// SetNormalizeFunc allows you to add a function which can translate flag names.
|
||||
// Flags added to the FlagSet will be translated and then when anything tries to
|
||||
// look up the flag that will also be translated. So it would be possible to create
|
||||
// a flag named "getURL" and have it translated to "geturl". A user could then pass
|
||||
// "--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)
|
||||
}
|
||||
}
|
||||
|
||||
// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
|
||||
// does no translation, if not set previously.
|
||||
func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
|
||||
if f.normalizeNameFunc != nil {
|
||||
return f.normalizeNameFunc
|
||||
}
|
||||
return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
|
||||
}
|
||||
|
||||
func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
|
||||
n := f.GetNormalizeFunc()
|
||||
return n(f, name)
|
||||
}
|
||||
|
||||
func (f *FlagSet) out() io.Writer {
|
||||
if f.output == nil {
|
||||
return os.Stderr
|
||||
}
|
||||
return f.output
|
||||
}
|
||||
|
||||
// SetOutput sets the destination for usage and error messages.
|
||||
// If output is nil, os.Stderr is used.
|
||||
func (f *FlagSet) SetOutput(output io.Writer) {
|
||||
f.output = output
|
||||
}
|
||||
|
||||
// VisitAll visits the flags in lexicographical order, 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) {
|
||||
fn(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
|
||||
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.
|
||||
func VisitAll(fn func(*Flag)) {
|
||||
CommandLine.VisitAll(fn)
|
||||
}
|
||||
|
||||
// Visit visits the flags in lexicographical order, 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) {
|
||||
fn(flag)
|
||||
}
|
||||
}
|
||||
|
||||
// Visit visits the command-line flags in lexicographical order, calling fn
|
||||
// for each. It visits only those flags that have been set.
|
||||
func Visit(fn func(*Flag)) {
|
||||
CommandLine.Visit(fn)
|
||||
}
|
||||
|
||||
// Lookup returns the Flag structure of the named flag, returning nil if none exists.
|
||||
func (f *FlagSet) Lookup(name string) *Flag {
|
||||
return f.lookup(f.normalizeFlagName(name))
|
||||
}
|
||||
|
||||
// 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]
|
||||
}
|
||||
|
||||
// func to return a given type for a given flag name
|
||||
func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
|
||||
flag := f.Lookup(name)
|
||||
if flag == nil {
|
||||
err := fmt.Errorf("flag accessed but not defined: %s", name)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if flag.Value.Type() != ftype {
|
||||
err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sval := flag.Value.String()
|
||||
result, err := convFunc(sval)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
|
||||
// found during arg parsing. This allows your program to know which args were
|
||||
// before the -- and which came after.
|
||||
func (f *FlagSet) ArgsLenAtDash() int {
|
||||
return f.argsLenAtDash
|
||||
}
|
||||
|
||||
// MarkDeprecated indicated that a flag is deprecated in your program. It will
|
||||
// continue to function but will not show up in help or usage messages. Using
|
||||
// this flag will also print the given usageMessage.
|
||||
func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
|
||||
flag := f.Lookup(name)
|
||||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
if len(usageMessage) == 0 {
|
||||
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||
}
|
||||
flag.Deprecated = usageMessage
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
|
||||
// program. It will continue to function but will not show up in help or usage
|
||||
// messages. Using this flag will also print the given usageMessage.
|
||||
func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
|
||||
flag := f.Lookup(name)
|
||||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
if len(usageMessage) == 0 {
|
||||
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||
}
|
||||
flag.ShorthandDeprecated = usageMessage
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkHidden sets a flag to 'hidden' in your program. It will continue to
|
||||
// function but will not show up in help or usage messages.
|
||||
func (f *FlagSet) MarkHidden(name string) error {
|
||||
flag := f.Lookup(name)
|
||||
if flag == nil {
|
||||
return fmt.Errorf("flag %q does not exist", name)
|
||||
}
|
||||
flag.Hidden = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lookup returns the Flag structure of the named command-line flag,
|
||||
// returning nil if none exists.
|
||||
func Lookup(name string) *Flag {
|
||||
return CommandLine.Lookup(name)
|
||||
}
|
||||
|
||||
// Set sets the value of the named flag.
|
||||
func (f *FlagSet) Set(name, value string) error {
|
||||
normalName := f.normalizeFlagName(name)
|
||||
flag, ok := f.formal[normalName]
|
||||
if !ok {
|
||||
return fmt.Errorf("no such flag -%v", name)
|
||||
}
|
||||
err := flag.Value.Set(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if f.actual == nil {
|
||||
f.actual = make(map[NormalizedName]*Flag)
|
||||
}
|
||||
f.actual[normalName] = flag
|
||||
flag.Changed = true
|
||||
if len(flag.Deprecated) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
|
||||
// This is sometimes used by spf13/cobra programs which want to generate additional
|
||||
// bash completion information.
|
||||
func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
|
||||
normalName := f.normalizeFlagName(name)
|
||||
flag, ok := f.formal[normalName]
|
||||
if !ok {
|
||||
return fmt.Errorf("no such flag -%v", name)
|
||||
}
|
||||
if flag.Annotations == nil {
|
||||
flag.Annotations = map[string][]string{}
|
||||
}
|
||||
flag.Annotations[key] = values
|
||||
return nil
|
||||
}
|
||||
|
||||
// Changed returns true if the flag was explicitly set during Parse() and false
|
||||
// otherwise
|
||||
func (f *FlagSet) Changed(name string) bool {
|
||||
flag := f.Lookup(name)
|
||||
// If a flag doesn't exist, it wasn't changed....
|
||||
if flag == nil {
|
||||
return false
|
||||
}
|
||||
return flag.Changed
|
||||
}
|
||||
|
||||
// Set sets the value of the named command-line flag.
|
||||
func Set(name, value string) error {
|
||||
return CommandLine.Set(name, value)
|
||||
}
|
||||
|
||||
// PrintDefaults prints, to standard error unless configured
|
||||
// otherwise, the default values of all defined flags in the set.
|
||||
func (f *FlagSet) PrintDefaults() {
|
||||
usages := f.FlagUsages()
|
||||
fmt.Fprintf(f.out(), "%s", usages)
|
||||
}
|
||||
|
||||
// FlagUsages Returns a string containing the usage information for all flags in
|
||||
// the FlagSet
|
||||
func (f *FlagSet) FlagUsages() string {
|
||||
x := new(bytes.Buffer)
|
||||
|
||||
f.VisitAll(func(flag *Flag) {
|
||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||
return
|
||||
}
|
||||
format := ""
|
||||
if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
|
||||
format = " -%s, --%s"
|
||||
} else {
|
||||
format = " %s --%s"
|
||||
}
|
||||
if len(flag.NoOptDefVal) > 0 {
|
||||
format = format + "["
|
||||
}
|
||||
if flag.Value.Type() == "string" {
|
||||
// put quotes on the value
|
||||
format = format + "=%q"
|
||||
} else {
|
||||
format = format + "=%s"
|
||||
}
|
||||
if len(flag.NoOptDefVal) > 0 {
|
||||
format = format + "]"
|
||||
}
|
||||
format = format + ": %s\n"
|
||||
shorthand := flag.Shorthand
|
||||
if len(flag.ShorthandDeprecated) > 0 {
|
||||
shorthand = ""
|
||||
}
|
||||
fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
|
||||
})
|
||||
|
||||
return x.String()
|
||||
}
|
||||
|
||||
// PrintDefaults prints to standard error the default values of all defined command-line flags.
|
||||
func PrintDefaults() {
|
||||
CommandLine.PrintDefaults()
|
||||
}
|
||||
|
||||
// defaultUsage is the default function to print a usage message.
|
||||
func defaultUsage(f *FlagSet) {
|
||||
fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
|
||||
f.PrintDefaults()
|
||||
}
|
||||
|
||||
// NOTE: Usage is not just defaultUsage(CommandLine)
|
||||
// because it serves (via godoc flag Usage) as the example
|
||||
// for how to write your own usage function.
|
||||
|
||||
// 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.
|
||||
var Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
PrintDefaults()
|
||||
}
|
||||
|
||||
// NFlag returns the number of flags that have been set.
|
||||
func (f *FlagSet) NFlag() int { return len(f.actual) }
|
||||
|
||||
// NFlag returns the number of command-line flags that have been set.
|
||||
func NFlag() int { return len(CommandLine.actual) }
|
||||
|
||||
// Arg returns the i'th argument. Arg(0) is the first remaining argument
|
||||
// after flags have been processed.
|
||||
func (f *FlagSet) Arg(i int) string {
|
||||
if i < 0 || i >= len(f.args) {
|
||||
return ""
|
||||
}
|
||||
return f.args[i]
|
||||
}
|
||||
|
||||
// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
|
||||
// after flags have been processed.
|
||||
func Arg(i int) string {
|
||||
return CommandLine.Arg(i)
|
||||
}
|
||||
|
||||
// NArg is the number of arguments remaining after flags have been processed.
|
||||
func (f *FlagSet) NArg() int { return len(f.args) }
|
||||
|
||||
// NArg is the number of arguments remaining after flags have been processed.
|
||||
func NArg() int { return len(CommandLine.args) }
|
||||
|
||||
// Args returns the non-flag arguments.
|
||||
func (f *FlagSet) Args() []string { return f.args }
|
||||
|
||||
// Args returns the non-flag command-line arguments.
|
||||
func Args() []string { return CommandLine.args }
|
||||
|
||||
// Var defines a flag with the specified name and usage string. The type and
|
||||
// value of the flag are represented by the first argument, of type Value, which
|
||||
// typically holds a user-defined implementation of Value. For instance, the
|
||||
// caller could create a flag that turns a comma-separated string into a slice
|
||||
// of strings by giving the slice the methods of Value; in particular, Set would
|
||||
// decompose the comma-separated string into the slice.
|
||||
func (f *FlagSet) Var(value Value, name string, usage string) {
|
||||
f.VarP(value, name, "", usage)
|
||||
}
|
||||
|
||||
// VarPF is like VarP, but returns the flag created
|
||||
func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
|
||||
// Remember the default value as a string; it won't change.
|
||||
flag := &Flag{
|
||||
Name: name,
|
||||
Shorthand: shorthand,
|
||||
Usage: usage,
|
||||
Value: value,
|
||||
DefValue: value.String(),
|
||||
}
|
||||
f.AddFlag(flag)
|
||||
return 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)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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
|
||||
}
|
||||
if f.formal == nil {
|
||||
f.formal = make(map[NormalizedName]*Flag)
|
||||
}
|
||||
|
||||
flag.Name = string(normalizedFlagName)
|
||||
f.formal[normalizedFlagName] = flag
|
||||
|
||||
if len(flag.Shorthand) == 0 {
|
||||
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")
|
||||
}
|
||||
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")
|
||||
}
|
||||
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
|
||||
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
|
||||
if newSet == nil {
|
||||
return
|
||||
}
|
||||
newSet.VisitAll(func(flag *Flag) {
|
||||
if f.Lookup(flag.Name) == nil {
|
||||
f.AddFlag(flag)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Var defines a flag with the specified name and usage string. The type and
|
||||
// value of the flag are represented by the first argument, of type Value, which
|
||||
// typically holds a user-defined implementation of Value. For instance, the
|
||||
// caller could create a flag that turns a comma-separated string into a slice
|
||||
// of strings by giving the slice the methods of Value; in particular, Set would
|
||||
// decompose the comma-separated string into the slice.
|
||||
func Var(value Value, name string, usage string) {
|
||||
CommandLine.VarP(value, name, "", usage)
|
||||
}
|
||||
|
||||
// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func VarP(value Value, name, shorthand, usage string) {
|
||||
CommandLine.VarP(value, name, shorthand, usage)
|
||||
}
|
||||
|
||||
// failf prints to standard error a formatted error and usage message and
|
||||
// returns the error.
|
||||
func (f *FlagSet) failf(format string, a ...interface{}) error {
|
||||
err := fmt.Errorf(format, a...)
|
||||
fmt.Fprintln(f.out(), err)
|
||||
f.usage()
|
||||
return err
|
||||
}
|
||||
|
||||
// usage calls the Usage method for the flag set, or the usage function if
|
||||
// the flag set is CommandLine.
|
||||
func (f *FlagSet) usage() {
|
||||
if f == CommandLine {
|
||||
Usage()
|
||||
} else if f.Usage == nil {
|
||||
defaultUsage(f)
|
||||
} else {
|
||||
f.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)
|
||||
}
|
||||
// mark as visited for Visit()
|
||||
if f.actual == nil {
|
||||
f.actual = make(map[NormalizedName]*Flag)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
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.
|
||||
f.usage()
|
||||
return a, ErrHelp
|
||||
}
|
||||
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 {
|
||||
// '--flag' (arg was optional)
|
||||
value = flag.NoOptDefVal
|
||||
} else if len(a) > 0 {
|
||||
// '--flag arg'
|
||||
value = a[0]
|
||||
a = a[1:]
|
||||
} else {
|
||||
// '--flag' (arg was required)
|
||||
err = f.failf("flag needs an argument: %s", s)
|
||||
return
|
||||
}
|
||||
err = f.setFlag(flag, value, s)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
|
||||
outArgs = args
|
||||
outShorts = shorthands[1:]
|
||||
c := shorthands[0]
|
||||
|
||||
flag, alreadythere := f.shorthands[c]
|
||||
if !alreadythere {
|
||||
if c == 'h' { // special case for nice help message.
|
||||
f.usage()
|
||||
err = ErrHelp
|
||||
return
|
||||
}
|
||||
//TODO continue on error
|
||||
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
|
||||
return
|
||||
}
|
||||
var value string
|
||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||
value = shorthands[2:]
|
||||
outShorts = ""
|
||||
} else if len(flag.NoOptDefVal) > 0 {
|
||||
value = flag.NoOptDefVal
|
||||
} else if len(shorthands) > 1 {
|
||||
value = shorthands[1:]
|
||||
outShorts = ""
|
||||
} else if len(args) > 0 {
|
||||
value = args[0]
|
||||
outArgs = args[1:]
|
||||
} else {
|
||||
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
|
||||
return
|
||||
}
|
||||
err = f.setFlag(flag, value, shorthands)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) {
|
||||
a = args
|
||||
shorthands := s[1:]
|
||||
|
||||
for len(shorthands) > 0 {
|
||||
shorthands, a, err = f.parseSingleShortArg(shorthands, args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FlagSet) parseArgs(args []string) (err error) {
|
||||
for len(args) > 0 {
|
||||
s := args[0]
|
||||
args = args[1:]
|
||||
if len(s) == 0 || s[0] != '-' || len(s) == 1 {
|
||||
if !f.interspersed {
|
||||
f.args = append(f.args, s)
|
||||
f.args = append(f.args, args...)
|
||||
return nil
|
||||
}
|
||||
f.args = append(f.args, s)
|
||||
continue
|
||||
}
|
||||
|
||||
if s[1] == '-' {
|
||||
if len(s) == 2 { // "--" terminates the flags
|
||||
f.argsLenAtDash = len(f.args)
|
||||
f.args = append(f.args, args...)
|
||||
break
|
||||
}
|
||||
args, err = f.parseLongArg(s, args)
|
||||
} else {
|
||||
args, err = f.parseShortArg(s, args)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Parse parses flag definitions from the argument list, which should not
|
||||
// include the command name. 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) Parse(arguments []string) error {
|
||||
f.parsed = true
|
||||
f.args = make([]string, 0, len(arguments))
|
||||
err := f.parseArgs(arguments)
|
||||
if err != nil {
|
||||
switch f.errorHandling {
|
||||
case ContinueOnError:
|
||||
return err
|
||||
case ExitOnError:
|
||||
os.Exit(2)
|
||||
case PanicOnError:
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parsed reports whether f.Parse has been called.
|
||||
func (f *FlagSet) Parsed() bool {
|
||||
return f.parsed
|
||||
}
|
||||
|
||||
// Parse parses the command-line flags from os.Args[1:]. Must be called
|
||||
// after all flags are defined and before flags are accessed by the program.
|
||||
func Parse() {
|
||||
// Ignore errors; CommandLine is set for ExitOnError.
|
||||
CommandLine.Parse(os.Args[1:])
|
||||
}
|
||||
|
||||
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||
func SetInterspersed(interspersed bool) {
|
||||
CommandLine.SetInterspersed(interspersed)
|
||||
}
|
||||
|
||||
// Parsed returns true if the command-line flags have been parsed.
|
||||
func Parsed() bool {
|
||||
return CommandLine.Parsed()
|
||||
}
|
||||
|
||||
// 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.
|
||||
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
|
||||
f := &FlagSet{
|
||||
name: name,
|
||||
errorHandling: errorHandling,
|
||||
argsLenAtDash: -1,
|
||||
interspersed: true,
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||
func (f *FlagSet) SetInterspersed(interspersed bool) {
|
||||
f.interspersed = interspersed
|
||||
}
|
||||
|
||||
// Init sets the name and error handling property for a flag set.
|
||||
// By default, the zero FlagSet uses an empty name and the
|
||||
// ContinueOnError error handling policy.
|
||||
func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
|
||||
f.name = name
|
||||
f.errorHandling = errorHandling
|
||||
f.argsLenAtDash = -1
|
||||
}
|
91
vendor/github.com/spf13/pflag/float32.go
generated
vendored
Normal file
91
vendor/github.com/spf13/pflag/float32.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- float32 Value
|
||||
type float32Value float32
|
||||
|
||||
func newFloat32Value(val float32, p *float32) *float32Value {
|
||||
*p = val
|
||||
return (*float32Value)(p)
|
||||
}
|
||||
|
||||
func (f *float32Value) Set(s string) error {
|
||||
v, err := strconv.ParseFloat(s, 32)
|
||||
*f = float32Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *float32Value) Type() string {
|
||||
return "float32"
|
||||
}
|
||||
|
||||
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
|
||||
|
||||
func float32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseFloat(sval, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return float32(v), nil
|
||||
}
|
||||
|
||||
// GetFloat32 return the float32 value of a flag with the given name
|
||||
func (f *FlagSet) GetFloat32(name string) (float32, error) {
|
||||
val, err := f.getFlagType(name, "float32", float32Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(float32), nil
|
||||
}
|
||||
|
||||
// Float32Var defines a float32 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a float32 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) {
|
||||
f.VarP(newFloat32Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
|
||||
f.VarP(newFloat32Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float32Var defines a float32 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a float32 variable in which to store the value of the flag.
|
||||
func Float32Var(p *float32, name string, value float32, usage string) {
|
||||
CommandLine.VarP(newFloat32Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
|
||||
CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float32 defines a float32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a float32 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Float32(name string, value float32, usage string) *float32 {
|
||||
p := new(float32)
|
||||
f.Float32VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 {
|
||||
p := new(float32)
|
||||
f.Float32VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Float32 defines a float32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a float32 variable that stores the value of the flag.
|
||||
func Float32(name string, value float32, usage string) *float32 {
|
||||
return CommandLine.Float32P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float32P(name, shorthand string, value float32, usage string) *float32 {
|
||||
return CommandLine.Float32P(name, shorthand, value, usage)
|
||||
}
|
87
vendor/github.com/spf13/pflag/float64.go
generated
vendored
Normal file
87
vendor/github.com/spf13/pflag/float64.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- float64 Value
|
||||
type float64Value float64
|
||||
|
||||
func newFloat64Value(val float64, p *float64) *float64Value {
|
||||
*p = val
|
||||
return (*float64Value)(p)
|
||||
}
|
||||
|
||||
func (f *float64Value) Set(s string) error {
|
||||
v, err := strconv.ParseFloat(s, 64)
|
||||
*f = float64Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (f *float64Value) Type() string {
|
||||
return "float64"
|
||||
}
|
||||
|
||||
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
|
||||
|
||||
func float64Conv(sval string) (interface{}, error) {
|
||||
return strconv.ParseFloat(sval, 64)
|
||||
}
|
||||
|
||||
// GetFloat64 return the float64 value of a flag with the given name
|
||||
func (f *FlagSet) GetFloat64(name string) (float64, error) {
|
||||
val, err := f.getFlagType(name, "float64", float64Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(float64), nil
|
||||
}
|
||||
|
||||
// Float64Var defines a float64 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a float64 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
|
||||
f.VarP(newFloat64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
|
||||
f.VarP(newFloat64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float64Var defines a float64 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a float64 variable in which to store the value of the flag.
|
||||
func Float64Var(p *float64, name string, value float64, usage string) {
|
||||
CommandLine.VarP(newFloat64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
|
||||
CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Float64 defines a float64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a float64 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
|
||||
p := new(float64)
|
||||
f.Float64VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 {
|
||||
p := new(float64)
|
||||
f.Float64VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Float64 defines a float64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a float64 variable that stores the value of the flag.
|
||||
func Float64(name string, value float64, usage string) *float64 {
|
||||
return CommandLine.Float64P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Float64P(name, shorthand string, value float64, usage string) *float64 {
|
||||
return CommandLine.Float64P(name, shorthand, value, usage)
|
||||
}
|
97
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
Normal file
97
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Copyright 2009 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 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
|
||||
// reflection.
|
||||
type flagValueWrapper struct {
|
||||
inner goflag.Value
|
||||
flagType string
|
||||
}
|
||||
|
||||
// We are just copying the boolFlag interface out of goflag as that is what
|
||||
// they use to decide if a flag should get "true" when no arg is given.
|
||||
type goBoolFlag interface {
|
||||
goflag.Value
|
||||
IsBoolFlag() bool
|
||||
}
|
||||
|
||||
func wrapFlagValue(v goflag.Value) Value {
|
||||
// If the flag.Value happens to also be a pflag.Value, just use it directly.
|
||||
if pv, ok := v.(Value); ok {
|
||||
return pv
|
||||
}
|
||||
|
||||
pv := &flagValueWrapper{
|
||||
inner: v,
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(v)
|
||||
if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
pv.flagType = strings.TrimSuffix(t.Name(), "Value")
|
||||
return pv
|
||||
}
|
||||
|
||||
func (v *flagValueWrapper) String() string {
|
||||
return v.inner.String()
|
||||
}
|
||||
|
||||
func (v *flagValueWrapper) Set(s string) error {
|
||||
return v.inner.Set(s)
|
||||
}
|
||||
|
||||
func (v *flagValueWrapper) Type() string {
|
||||
return v.flagType
|
||||
}
|
||||
|
||||
// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
|
||||
func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
|
||||
// Remember the default value as a string; it won't change.
|
||||
flag := &Flag{
|
||||
Name: goflag.Name,
|
||||
Usage: goflag.Usage,
|
||||
Value: wrapFlagValue(goflag.Value),
|
||||
// Looks like golang flags don't set DefValue correctly :-(
|
||||
//DefValue: goflag.DefValue,
|
||||
DefValue: goflag.Value.String(),
|
||||
}
|
||||
if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
|
||||
flag.NoOptDefVal = "true"
|
||||
}
|
||||
return flag
|
||||
}
|
||||
|
||||
// AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
|
||||
func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
|
||||
if f.Lookup(goflag.Name) != nil {
|
||||
return
|
||||
}
|
||||
newflag := PFlagFromGoFlag(goflag)
|
||||
f.AddFlag(newflag)
|
||||
}
|
||||
|
||||
// AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
|
||||
func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
|
||||
if newSet == nil {
|
||||
return
|
||||
}
|
||||
newSet.VisitAll(func(goflag *goflag.Flag) {
|
||||
f.AddGoFlag(goflag)
|
||||
})
|
||||
}
|
87
vendor/github.com/spf13/pflag/int.go
generated
vendored
Normal file
87
vendor/github.com/spf13/pflag/int.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- int Value
|
||||
type intValue int
|
||||
|
||||
func newIntValue(val int, p *int) *intValue {
|
||||
*p = val
|
||||
return (*intValue)(p)
|
||||
}
|
||||
|
||||
func (i *intValue) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 64)
|
||||
*i = intValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *intValue) Type() string {
|
||||
return "int"
|
||||
}
|
||||
|
||||
func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func intConv(sval string) (interface{}, error) {
|
||||
return strconv.Atoi(sval)
|
||||
}
|
||||
|
||||
// GetInt return the int value of a flag with the given name
|
||||
func (f *FlagSet) GetInt(name string) (int, error) {
|
||||
val, err := f.getFlagType(name, "int", intConv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int), nil
|
||||
}
|
||||
|
||||
// IntVar defines an int flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
|
||||
f.VarP(newIntValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) {
|
||||
f.VarP(newIntValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IntVar defines an int flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int variable in which to store the value of the flag.
|
||||
func IntVar(p *int, name string, value int, usage string) {
|
||||
CommandLine.VarP(newIntValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IntVarP(p *int, name, shorthand string, value int, usage string) {
|
||||
CommandLine.VarP(newIntValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int defines an int 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.
|
||||
func (f *FlagSet) Int(name string, value int, usage string) *int {
|
||||
p := new(int)
|
||||
f.IntVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int {
|
||||
p := new(int)
|
||||
f.IntVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int defines an int 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.
|
||||
func Int(name string, value int, usage string) *int {
|
||||
return CommandLine.IntP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IntP(name, shorthand string, value int, usage string) *int {
|
||||
return CommandLine.IntP(name, shorthand, value, usage)
|
||||
}
|
91
vendor/github.com/spf13/pflag/int32.go
generated
vendored
Normal file
91
vendor/github.com/spf13/pflag/int32.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- int32 Value
|
||||
type int32Value int32
|
||||
|
||||
func newInt32Value(val int32, p *int32) *int32Value {
|
||||
*p = val
|
||||
return (*int32Value)(p)
|
||||
}
|
||||
|
||||
func (i *int32Value) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 32)
|
||||
*i = int32Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *int32Value) Type() string {
|
||||
return "int32"
|
||||
}
|
||||
|
||||
func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func int32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(v), nil
|
||||
}
|
||||
|
||||
// GetInt32 return the int32 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt32(name string) (int32, error) {
|
||||
val, err := f.getFlagType(name, "int32", int32Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int32), nil
|
||||
}
|
||||
|
||||
// Int32Var defines an int32 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int32 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) {
|
||||
f.VarP(newInt32Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
|
||||
f.VarP(newInt32Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int32Var defines an int32 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int32 variable in which to store the value of the flag.
|
||||
func Int32Var(p *int32, name string, value int32, usage string) {
|
||||
CommandLine.VarP(newInt32Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
|
||||
CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int32 defines an int32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int32 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int32(name string, value int32, usage string) *int32 {
|
||||
p := new(int32)
|
||||
f.Int32VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 {
|
||||
p := new(int32)
|
||||
f.Int32VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int32 defines an int32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int32 variable that stores the value of the flag.
|
||||
func Int32(name string, value int32, usage string) *int32 {
|
||||
return CommandLine.Int32P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int32P(name, shorthand string, value int32, usage string) *int32 {
|
||||
return CommandLine.Int32P(name, shorthand, value, usage)
|
||||
}
|
87
vendor/github.com/spf13/pflag/int64.go
generated
vendored
Normal file
87
vendor/github.com/spf13/pflag/int64.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- int64 Value
|
||||
type int64Value int64
|
||||
|
||||
func newInt64Value(val int64, p *int64) *int64Value {
|
||||
*p = val
|
||||
return (*int64Value)(p)
|
||||
}
|
||||
|
||||
func (i *int64Value) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 64)
|
||||
*i = int64Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *int64Value) Type() string {
|
||||
return "int64"
|
||||
}
|
||||
|
||||
func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func int64Conv(sval string) (interface{}, error) {
|
||||
return strconv.ParseInt(sval, 0, 64)
|
||||
}
|
||||
|
||||
// GetInt64 return the int64 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt64(name string) (int64, error) {
|
||||
val, err := f.getFlagType(name, "int64", int64Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int64), nil
|
||||
}
|
||||
|
||||
// Int64Var defines an int64 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int64 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
|
||||
f.VarP(newInt64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
|
||||
f.VarP(newInt64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int64Var defines an int64 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int64 variable in which to store the value of the flag.
|
||||
func Int64Var(p *int64, name string, value int64, usage string) {
|
||||
CommandLine.VarP(newInt64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
|
||||
CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int64 defines an int64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int64 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
|
||||
p := new(int64)
|
||||
f.Int64VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 {
|
||||
p := new(int64)
|
||||
f.Int64VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int64 defines an int64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int64 variable that stores the value of the flag.
|
||||
func Int64(name string, value int64, usage string) *int64 {
|
||||
return CommandLine.Int64P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int64P(name, shorthand string, value int64, usage string) *int64 {
|
||||
return CommandLine.Int64P(name, shorthand, value, usage)
|
||||
}
|
91
vendor/github.com/spf13/pflag/int8.go
generated
vendored
Normal file
91
vendor/github.com/spf13/pflag/int8.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- int8 Value
|
||||
type int8Value int8
|
||||
|
||||
func newInt8Value(val int8, p *int8) *int8Value {
|
||||
*p = val
|
||||
return (*int8Value)(p)
|
||||
}
|
||||
|
||||
func (i *int8Value) Set(s string) error {
|
||||
v, err := strconv.ParseInt(s, 0, 8)
|
||||
*i = int8Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *int8Value) Type() string {
|
||||
return "int8"
|
||||
}
|
||||
|
||||
func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func int8Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseInt(sval, 0, 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int8(v), nil
|
||||
}
|
||||
|
||||
// GetInt8 return the int8 value of a flag with the given name
|
||||
func (f *FlagSet) GetInt8(name string) (int8, error) {
|
||||
val, err := f.getFlagType(name, "int8", int8Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(int8), nil
|
||||
}
|
||||
|
||||
// Int8Var defines an int8 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int8 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) {
|
||||
f.VarP(newInt8Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
|
||||
f.VarP(newInt8Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int8Var defines an int8 flag with specified name, default value, and usage string.
|
||||
// The argument p points to an int8 variable in which to store the value of the flag.
|
||||
func Int8Var(p *int8, name string, value int8, usage string) {
|
||||
CommandLine.VarP(newInt8Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
|
||||
CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Int8 defines an int8 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int8 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Int8(name string, value int8, usage string) *int8 {
|
||||
p := new(int8)
|
||||
f.Int8VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 {
|
||||
p := new(int8)
|
||||
f.Int8VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Int8 defines an int8 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an int8 variable that stores the value of the flag.
|
||||
func Int8(name string, value int8, usage string) *int8 {
|
||||
return CommandLine.Int8P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Int8P(name, shorthand string, value int8, usage string) *int8 {
|
||||
return CommandLine.Int8P(name, shorthand, value, usage)
|
||||
}
|
128
vendor/github.com/spf13/pflag/int_slice.go
generated
vendored
Normal file
128
vendor/github.com/spf13/pflag/int_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// -- intSlice Value
|
||||
type intSliceValue struct {
|
||||
value *[]int
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newIntSliceValue(val []int, p *[]int) *intSliceValue {
|
||||
isv := new(intSliceValue)
|
||||
isv.value = p
|
||||
*isv.value = val
|
||||
return isv
|
||||
}
|
||||
|
||||
func (s *intSliceValue) Set(val string) error {
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]int, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.Atoi(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 *intSliceValue) Type() string {
|
||||
return "intSlice"
|
||||
}
|
||||
|
||||
func (s *intSliceValue) 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 intSliceConv(val string) (interface{}, error) {
|
||||
val = strings.Trim(val, "[]")
|
||||
// Empty string would cause a slice with one (empty) entry
|
||||
if len(val) == 0 {
|
||||
return []int{}, nil
|
||||
}
|
||||
ss := strings.Split(val, ",")
|
||||
out := make([]int, len(ss))
|
||||
for i, d := range ss {
|
||||
var err error
|
||||
out[i], err = strconv.Atoi(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetIntSlice return the []int value of a flag with the given name
|
||||
func (f *FlagSet) GetIntSlice(name string) ([]int, error) {
|
||||
val, err := f.getFlagType(name, "intSlice", intSliceConv)
|
||||
if err != nil {
|
||||
return []int{}, err
|
||||
}
|
||||
return val.([]int), nil
|
||||
}
|
||||
|
||||
// IntSliceVar defines a intSlice flag with specified name, default value, and usage string.
|
||||
// The argument p points to a []int variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage string) {
|
||||
f.VarP(newIntSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
|
||||
f.VarP(newIntSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IntSliceVar defines a int[] flag with specified name, default value, and usage string.
|
||||
// The argument p points to a int[] variable in which to store the value of the flag.
|
||||
func IntSliceVar(p *[]int, name string, value []int, usage string) {
|
||||
CommandLine.VarP(newIntSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
|
||||
CommandLine.VarP(newIntSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IntSlice defines a []int flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []int variable that stores the value of the flag.
|
||||
func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int {
|
||||
p := []int{}
|
||||
f.IntSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage string) *[]int {
|
||||
p := []int{}
|
||||
f.IntSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IntSlice defines a []int flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a []int variable that stores the value of the flag.
|
||||
func IntSlice(name string, value []int, usage string) *[]int {
|
||||
return CommandLine.IntSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IntSliceP(name, shorthand string, value []int, usage string) *[]int {
|
||||
return CommandLine.IntSliceP(name, shorthand, value, usage)
|
||||
}
|
96
vendor/github.com/spf13/pflag/ip.go
generated
vendored
Normal file
96
vendor/github.com/spf13/pflag/ip.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = strings.TrimSpace
|
||||
|
||||
// -- net.IP value
|
||||
type ipValue net.IP
|
||||
|
||||
func newIPValue(val net.IP, p *net.IP) *ipValue {
|
||||
*p = val
|
||||
return (*ipValue)(p)
|
||||
}
|
||||
|
||||
func (i *ipValue) String() string { return net.IP(*i).String() }
|
||||
func (i *ipValue) Set(s string) error {
|
||||
ip := net.ParseIP(strings.TrimSpace(s))
|
||||
if ip == nil {
|
||||
return fmt.Errorf("failed to parse IP: %q", s)
|
||||
}
|
||||
*i = ipValue(ip)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ipValue) Type() string {
|
||||
return "ip"
|
||||
}
|
||||
|
||||
func ipConv(sval string) (interface{}, error) {
|
||||
ip := net.ParseIP(sval)
|
||||
if ip != nil {
|
||||
return ip, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
|
||||
}
|
||||
|
||||
// GetIP return the net.IP value of a flag with the given name
|
||||
func (f *FlagSet) GetIP(name string) (net.IP, error) {
|
||||
val, err := f.getFlagType(name, "ip", ipConv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return val.(net.IP), nil
|
||||
}
|
||||
|
||||
// IPVar defines an net.IP flag with specified name, default value, and usage string.
|
||||
// The argument p points to an net.IP variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) {
|
||||
f.VarP(newIPValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
|
||||
f.VarP(newIPValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPVar defines an net.IP flag with specified name, default value, and usage string.
|
||||
// The argument p points to an net.IP variable in which to store the value of the flag.
|
||||
func IPVar(p *net.IP, name string, value net.IP, usage string) {
|
||||
CommandLine.VarP(newIPValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
|
||||
CommandLine.VarP(newIPValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IP defines an net.IP flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an net.IP variable that stores the value of the flag.
|
||||
func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP {
|
||||
p := new(net.IP)
|
||||
f.IPVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP {
|
||||
p := new(net.IP)
|
||||
f.IPVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IP defines an net.IP flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an net.IP variable that stores the value of the flag.
|
||||
func IP(name string, value net.IP, usage string) *net.IP {
|
||||
return CommandLine.IPP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPP(name, shorthand string, value net.IP, usage string) *net.IP {
|
||||
return CommandLine.IPP(name, shorthand, value, usage)
|
||||
}
|
122
vendor/github.com/spf13/pflag/ipmask.go
generated
vendored
Normal file
122
vendor/github.com/spf13/pflag/ipmask.go
generated
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- net.IPMask value
|
||||
type ipMaskValue net.IPMask
|
||||
|
||||
func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue {
|
||||
*p = val
|
||||
return (*ipMaskValue)(p)
|
||||
}
|
||||
|
||||
func (i *ipMaskValue) String() string { return net.IPMask(*i).String() }
|
||||
func (i *ipMaskValue) Set(s string) error {
|
||||
ip := ParseIPv4Mask(s)
|
||||
if ip == nil {
|
||||
return fmt.Errorf("failed to parse IP mask: %q", s)
|
||||
}
|
||||
*i = ipMaskValue(ip)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ipMaskValue) Type() string {
|
||||
return "ipMask"
|
||||
}
|
||||
|
||||
// ParseIPv4Mask written in IP form (e.g. 255.255.255.0).
|
||||
// This function should really belong to the net package.
|
||||
func ParseIPv4Mask(s string) net.IPMask {
|
||||
mask := net.ParseIP(s)
|
||||
if mask == nil {
|
||||
if len(s) != 8 {
|
||||
return nil
|
||||
}
|
||||
// net.IPMask.String() actually outputs things like ffffff00
|
||||
// so write a horrible parser for that as well :-(
|
||||
m := []int{}
|
||||
for i := 0; i < 4; i++ {
|
||||
b := "0x" + s[2*i:2*i+2]
|
||||
d, err := strconv.ParseInt(b, 0, 0)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
m = append(m, int(d))
|
||||
}
|
||||
s := fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3])
|
||||
mask = net.ParseIP(s)
|
||||
if mask == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15])
|
||||
}
|
||||
|
||||
func parseIPv4Mask(sval string) (interface{}, error) {
|
||||
mask := ParseIPv4Mask(sval)
|
||||
if mask == nil {
|
||||
return nil, fmt.Errorf("unable to parse %s as net.IPMask", sval)
|
||||
}
|
||||
return mask, nil
|
||||
}
|
||||
|
||||
// GetIPv4Mask return the net.IPv4Mask value of a flag with the given name
|
||||
func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) {
|
||||
val, err := f.getFlagType(name, "ipMask", parseIPv4Mask)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return val.(net.IPMask), nil
|
||||
}
|
||||
|
||||
// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
|
||||
// The argument p points to an net.IPMask variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
|
||||
f.VarP(newIPMaskValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
|
||||
f.VarP(newIPMaskValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
|
||||
// The argument p points to an net.IPMask variable in which to store the value of the flag.
|
||||
func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
|
||||
CommandLine.VarP(newIPMaskValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
|
||||
CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPMask defines an net.IPMask flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an net.IPMask variable that stores the value of the flag.
|
||||
func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask {
|
||||
p := new(net.IPMask)
|
||||
f.IPMaskVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IPMaskP is like IPMask, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
|
||||
p := new(net.IPMask)
|
||||
f.IPMaskVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IPMask defines an net.IPMask flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an net.IPMask variable that stores the value of the flag.
|
||||
func IPMask(name string, value net.IPMask, usage string) *net.IPMask {
|
||||
return CommandLine.IPMaskP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IPMaskP is like IP, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
|
||||
return CommandLine.IPMaskP(name, shorthand, value, usage)
|
||||
}
|
100
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
Normal file
100
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IPNet adapts net.IPNet for use as a flag.
|
||||
type ipNetValue net.IPNet
|
||||
|
||||
func (ipnet ipNetValue) String() string {
|
||||
n := net.IPNet(ipnet)
|
||||
return n.String()
|
||||
}
|
||||
|
||||
func (ipnet *ipNetValue) Set(value string) error {
|
||||
_, n, err := net.ParseCIDR(strings.TrimSpace(value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*ipnet = ipNetValue(*n)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*ipNetValue) Type() string {
|
||||
return "ipNet"
|
||||
}
|
||||
|
||||
var _ = strings.TrimSpace
|
||||
|
||||
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
|
||||
*p = val
|
||||
return (*ipNetValue)(p)
|
||||
}
|
||||
|
||||
func ipNetConv(sval string) (interface{}, error) {
|
||||
_, n, err := net.ParseCIDR(strings.TrimSpace(sval))
|
||||
if err == nil {
|
||||
return *n, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid string being converted to IPNet: %s", sval)
|
||||
}
|
||||
|
||||
// GetIPNet return the net.IPNet value of a flag with the given name
|
||||
func (f *FlagSet) GetIPNet(name string) (net.IPNet, error) {
|
||||
val, err := f.getFlagType(name, "ipNet", ipNetConv)
|
||||
if err != nil {
|
||||
return net.IPNet{}, err
|
||||
}
|
||||
return val.(net.IPNet), nil
|
||||
}
|
||||
|
||||
// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
|
||||
// The argument p points to an net.IPNet variable in which to store the value of the flag.
|
||||
func (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
|
||||
f.VarP(newIPNetValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
|
||||
f.VarP(newIPNetValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
|
||||
// The argument p points to an net.IPNet variable in which to store the value of the flag.
|
||||
func IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
|
||||
CommandLine.VarP(newIPNetValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
|
||||
CommandLine.VarP(newIPNetValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an net.IPNet variable that stores the value of the flag.
|
||||
func (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net.IPNet {
|
||||
p := new(net.IPNet)
|
||||
f.IPNetVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
|
||||
p := new(net.IPNet)
|
||||
f.IPNetVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
|
||||
// The return value is the address of an net.IPNet variable that stores the value of the flag.
|
||||
func IPNet(name string, value net.IPNet, usage string) *net.IPNet {
|
||||
return CommandLine.IPNetP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
|
||||
func IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
|
||||
return CommandLine.IPNetP(name, shorthand, value, usage)
|
||||
}
|
82
vendor/github.com/spf13/pflag/string.go
generated
vendored
Normal file
82
vendor/github.com/spf13/pflag/string.go
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
package pflag
|
||||
|
||||
import "fmt"
|
||||
|
||||
// -- string Value
|
||||
type stringValue string
|
||||
|
||||
func newStringValue(val string, p *string) *stringValue {
|
||||
*p = val
|
||||
return (*stringValue)(p)
|
||||
}
|
||||
|
||||
func (s *stringValue) Set(val string) error {
|
||||
*s = stringValue(val)
|
||||
return nil
|
||||
}
|
||||
func (s *stringValue) Type() string {
|
||||
return "string"
|
||||
}
|
||||
|
||||
func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
|
||||
|
||||
func stringConv(sval string) (interface{}, error) {
|
||||
return sval, nil
|
||||
}
|
||||
|
||||
// GetString return the string value of a flag with the given name
|
||||
func (f *FlagSet) GetString(name string) (string, error) {
|
||||
val, err := f.getFlagType(name, "string", stringConv)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return val.(string), nil
|
||||
}
|
||||
|
||||
// StringVar 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.
|
||||
func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
|
||||
f.VarP(newStringValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {
|
||||
f.VarP(newStringValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// StringVar 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.
|
||||
func StringVar(p *string, name string, value string, usage string) {
|
||||
CommandLine.VarP(newStringValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringVarP(p *string, name, shorthand string, value string, usage string) {
|
||||
CommandLine.VarP(newStringValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// String 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.
|
||||
func (f *FlagSet) String(name string, value string, usage string) *string {
|
||||
p := new(string)
|
||||
f.StringVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string {
|
||||
p := new(string)
|
||||
f.StringVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// String 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.
|
||||
func String(name string, value string, usage string) *string {
|
||||
return CommandLine.StringP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringP(name, shorthand string, value string, usage string) *string {
|
||||
return CommandLine.StringP(name, shorthand, value, usage)
|
||||
}
|
105
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
Normal file
105
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = fmt.Fprint
|
||||
|
||||
// -- stringSlice Value
|
||||
type stringSliceValue struct {
|
||||
value *[]string
|
||||
changed bool
|
||||
}
|
||||
|
||||
func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
|
||||
ssv := new(stringSliceValue)
|
||||
ssv.value = p
|
||||
*ssv.value = val
|
||||
return ssv
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) Set(val string) error {
|
||||
v := strings.Split(val, ",")
|
||||
if !s.changed {
|
||||
*s.value = v
|
||||
} else {
|
||||
*s.value = append(*s.value, v...)
|
||||
}
|
||||
s.changed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) Type() string {
|
||||
return "stringSlice"
|
||||
}
|
||||
|
||||
func (s *stringSliceValue) String() string { return "[" + strings.Join(*s.value, ",") + "]" }
|
||||
|
||||
func stringSliceConv(sval string) (interface{}, error) {
|
||||
sval = strings.Trim(sval, "[]")
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetStringSlice return the []string value of a flag with the given name
|
||||
func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
|
||||
val, err := f.getFlagType(name, "stringSlice", stringSliceConv)
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return val.([]string), nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
f.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||
f.VarP(newStringSliceValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||
CommandLine.VarP(newStringSliceValue(value, p), name, shorthand, 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.
|
||||
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringSliceVarP(&p, name, "", value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string {
|
||||
p := []string{}
|
||||
f.StringSliceVarP(&p, name, shorthand, value, usage)
|
||||
return &p
|
||||
}
|
||||
|
||||
// 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.
|
||||
func StringSlice(name string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringSliceP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||
func StringSliceP(name, shorthand string, value []string, usage string) *[]string {
|
||||
return CommandLine.StringSliceP(name, shorthand, value, usage)
|
||||
}
|
91
vendor/github.com/spf13/pflag/uint.go
generated
vendored
Normal file
91
vendor/github.com/spf13/pflag/uint.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- uint Value
|
||||
type uintValue uint
|
||||
|
||||
func newUintValue(val uint, p *uint) *uintValue {
|
||||
*p = val
|
||||
return (*uintValue)(p)
|
||||
}
|
||||
|
||||
func (i *uintValue) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 64)
|
||||
*i = uintValue(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uintValue) Type() string {
|
||||
return "uint"
|
||||
}
|
||||
|
||||
func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func uintConv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint(v), nil
|
||||
}
|
||||
|
||||
// GetUint return the uint value of a flag with the given name
|
||||
func (f *FlagSet) GetUint(name string) (uint, error) {
|
||||
val, err := f.getFlagType(name, "uint", uintConv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(uint), nil
|
||||
}
|
||||
|
||||
// UintVar 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 (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
|
||||
f.VarP(newUintValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {
|
||||
f.VarP(newUintValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// UintVar 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 UintVar(p *uint, name string, value uint, usage string) {
|
||||
CommandLine.VarP(newUintValue(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
|
||||
func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
|
||||
CommandLine.VarP(newUintValue(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint 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) Uint(name string, value uint, usage string) *uint {
|
||||
p := new(uint)
|
||||
f.UintVarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {
|
||||
p := new(uint)
|
||||
f.UintVarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint 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 Uint(name string, value uint, usage string) *uint {
|
||||
return CommandLine.UintP(name, "", value, usage)
|
||||
}
|
||||
|
||||
// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
|
||||
func UintP(name, shorthand string, value uint, usage string) *uint {
|
||||
return CommandLine.UintP(name, shorthand, value, usage)
|
||||
}
|
89
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
Normal file
89
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- uint16 value
|
||||
type uint16Value uint16
|
||||
|
||||
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)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uint16Value) Type() string {
|
||||
return "uint16"
|
||||
}
|
||||
|
||||
func uint16Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint16(v), nil
|
||||
}
|
||||
|
||||
// GetUint16 return the uint16 value of a flag with the given name
|
||||
func (f *FlagSet) GetUint16(name string) (uint16, error) {
|
||||
val, err := f.getFlagType(name, "uint16", uint16Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(uint16), nil
|
||||
}
|
||||
|
||||
// Uint16Var 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 (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {
|
||||
f.VarP(newUint16Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
|
||||
f.VarP(newUint16Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint16Var 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 Uint16Var(p *uint16, name string, value uint16, usage string) {
|
||||
CommandLine.VarP(newUint16Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
|
||||
CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint16 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) Uint16(name string, value uint16, usage string) *uint16 {
|
||||
p := new(uint16)
|
||||
f.Uint16VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
|
||||
p := new(uint16)
|
||||
f.Uint16VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint16 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 Uint16(name string, value uint16, usage string) *uint16 {
|
||||
return CommandLine.Uint16P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
|
||||
return CommandLine.Uint16P(name, shorthand, value, usage)
|
||||
}
|
89
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
Normal file
89
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- uint16 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)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uint32Value) Type() string {
|
||||
return "uint32"
|
||||
}
|
||||
|
||||
func uint32Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(v), nil
|
||||
}
|
||||
|
||||
// GetUint32 return the uint32 value of a flag with the given name
|
||||
func (f *FlagSet) GetUint32(name string) (uint32, error) {
|
||||
val, err := f.getFlagType(name, "uint32", uint32Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(uint32), nil
|
||||
}
|
||||
|
||||
// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint32 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {
|
||||
f.VarP(newUint32Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
|
||||
f.VarP(newUint32Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint32 variable in which to store the value of the flag.
|
||||
func Uint32Var(p *uint32, name string, value uint32, usage string) {
|
||||
CommandLine.VarP(newUint32Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
|
||||
CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint32 defines a uint32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a uint32 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {
|
||||
p := new(uint32)
|
||||
f.Uint32VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
|
||||
p := new(uint32)
|
||||
f.Uint32VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint32 defines a uint32 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a uint32 variable that stores the value of the flag.
|
||||
func Uint32(name string, value uint32, usage string) *uint32 {
|
||||
return CommandLine.Uint32P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
|
||||
return CommandLine.Uint32P(name, shorthand, value, usage)
|
||||
}
|
91
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
Normal file
91
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- uint64 Value
|
||||
type uint64Value uint64
|
||||
|
||||
func newUint64Value(val uint64, p *uint64) *uint64Value {
|
||||
*p = val
|
||||
return (*uint64Value)(p)
|
||||
}
|
||||
|
||||
func (i *uint64Value) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 64)
|
||||
*i = uint64Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uint64Value) Type() string {
|
||||
return "uint64"
|
||||
}
|
||||
|
||||
func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func uint64Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint64(v), nil
|
||||
}
|
||||
|
||||
// GetUint64 return the uint64 value of a flag with the given name
|
||||
func (f *FlagSet) GetUint64(name string) (uint64, error) {
|
||||
val, err := f.getFlagType(name, "uint64", uint64Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(uint64), nil
|
||||
}
|
||||
|
||||
// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint64 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
|
||||
f.VarP(newUint64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
|
||||
f.VarP(newUint64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint64 variable in which to store the value of the flag.
|
||||
func Uint64Var(p *uint64, name string, value uint64, usage string) {
|
||||
CommandLine.VarP(newUint64Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
|
||||
CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint64 defines a uint64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a uint64 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
|
||||
p := new(uint64)
|
||||
f.Uint64VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
|
||||
p := new(uint64)
|
||||
f.Uint64VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint64 defines a uint64 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a uint64 variable that stores the value of the flag.
|
||||
func Uint64(name string, value uint64, usage string) *uint64 {
|
||||
return CommandLine.Uint64P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
|
||||
return CommandLine.Uint64P(name, shorthand, value, usage)
|
||||
}
|
91
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
Normal file
91
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
package pflag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// -- uint8 Value
|
||||
type uint8Value uint8
|
||||
|
||||
func newUint8Value(val uint8, p *uint8) *uint8Value {
|
||||
*p = val
|
||||
return (*uint8Value)(p)
|
||||
}
|
||||
|
||||
func (i *uint8Value) Set(s string) error {
|
||||
v, err := strconv.ParseUint(s, 0, 8)
|
||||
*i = uint8Value(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *uint8Value) Type() string {
|
||||
return "uint8"
|
||||
}
|
||||
|
||||
func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) }
|
||||
|
||||
func uint8Conv(sval string) (interface{}, error) {
|
||||
v, err := strconv.ParseUint(sval, 0, 8)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint8(v), nil
|
||||
}
|
||||
|
||||
// GetUint8 return the uint8 value of a flag with the given name
|
||||
func (f *FlagSet) GetUint8(name string) (uint8, error) {
|
||||
val, err := f.getFlagType(name, "uint8", uint8Conv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return val.(uint8), nil
|
||||
}
|
||||
|
||||
// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint8 variable in which to store the value of the flag.
|
||||
func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) {
|
||||
f.VarP(newUint8Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
|
||||
f.VarP(newUint8Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
|
||||
// The argument p points to a uint8 variable in which to store the value of the flag.
|
||||
func Uint8Var(p *uint8, name string, value uint8, usage string) {
|
||||
CommandLine.VarP(newUint8Value(value, p), name, "", usage)
|
||||
}
|
||||
|
||||
// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
|
||||
CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)
|
||||
}
|
||||
|
||||
// Uint8 defines a uint8 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a uint8 variable that stores the value of the flag.
|
||||
func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {
|
||||
p := new(uint8)
|
||||
f.Uint8VarP(p, name, "", value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
|
||||
func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
|
||||
p := new(uint8)
|
||||
f.Uint8VarP(p, name, shorthand, value, usage)
|
||||
return p
|
||||
}
|
||||
|
||||
// Uint8 defines a uint8 flag with specified name, default value, and usage string.
|
||||
// The return value is the address of a uint8 variable that stores the value of the flag.
|
||||
func Uint8(name string, value uint8, usage string) *uint8 {
|
||||
return CommandLine.Uint8P(name, "", value, usage)
|
||||
}
|
||||
|
||||
// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
|
||||
func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
|
||||
return CommandLine.Uint8P(name, shorthand, value, usage)
|
||||
}
|
188
vendor/gopkg.in/yaml.v2/LICENSE
generated
vendored
Normal file
188
vendor/gopkg.in/yaml.v2/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
|
||||
Copyright (c) 2011-2014 - Canonical Inc.
|
||||
|
||||
This software is licensed under the LGPLv3, included below.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
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.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
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.
|
||||
|
||||
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".
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
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:
|
||||
|
||||
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.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
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:
|
||||
|
||||
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.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
31
vendor/gopkg.in/yaml.v2/LICENSE.libyaml
generated
vendored
Normal file
31
vendor/gopkg.in/yaml.v2/LICENSE.libyaml
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
The following files were ported to Go from C files of libyaml, and thus
|
||||
are still covered by their original copyright and license:
|
||||
|
||||
apic.go
|
||||
emitterc.go
|
||||
parserc.go
|
||||
readerc.go
|
||||
scannerc.go
|
||||
writerc.go
|
||||
yamlh.go
|
||||
yamlprivateh.go
|
||||
|
||||
Copyright (c) 2006 Kirill Simonov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue