diff --git a/Gopkg.lock b/Gopkg.lock
index e043ed3..b408b4c 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -35,36 +35,17 @@
revision = "22d885f9ecc78bf4ee5d72b937e4bbcdc58e8cae"
[[projects]]
- digest = "1:d5083934eb25e45d17f72ffa86cae3814f4a9d6c073c4f16b64147169b245606"
+ digest = "1:d8bd2a337f6ff2188e08f72c614f2f3f0fd48e6a7b37a071b197e427d77d3a47"
name = "github.com/gin-gonic/gin"
packages = [
".",
"binding",
- "json",
+ "internal/json",
"render",
]
pruneopts = "UT"
- revision = "b869fe1415e4b9eb52f247441830d502aece2d4d"
- version = "v1.3.0"
-
-[[projects]]
- digest = "1:e1ff887e232b2d8f4f7c7db15a5fac7be418025afc4dda53c59c765dbb5aa6b4"
- name = "github.com/go-playground/locales"
- packages = [
- ".",
- "currency",
- ]
- pruneopts = "UT"
- revision = "f63010822830b6fe52288ee52d5a1151088ce039"
- version = "v0.12.1"
-
-[[projects]]
- digest = "1:e022cf244bcac1b6ef933f1a2e0adcf6a6dfd7b872d8d41e4d4179bb09a87cbc"
- name = "github.com/go-playground/universal-translator"
- packages = ["."]
- pruneopts = "UT"
- revision = "b32fa301c9fe55953584134cb6853a13c87ec0a1"
- version = "v0.16.0"
+ revision = "b75d67cd51eb53c3c3a2fc406524c940021ffbda"
+ version = "v1.4.0"
[[projects]]
digest = "1:b7a8552c62868d867795b63eaf4f45d3e92d36db82b428e680b9c95a8c33e5b1"
@@ -162,6 +143,14 @@
revision = "9316a62528ac99aaecb4e47eadd6dc8aa6533d58"
version = "v0.3.5"
+[[projects]]
+ digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
+ name = "github.com/inconshreveable/mousetrap"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
+ version = "v1.0"
+
[[projects]]
digest = "1:eaefc85d32c03e5f0c2b88ea2f79fce3d993e2c78316d21319575dd4ea9153ca"
name = "github.com/json-iterator/go"
@@ -178,14 +167,6 @@
revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e"
version = "v1.0.2"
-[[projects]]
- digest = "1:6782ffc812e8e700e6952ede1e60487ff1fd9da489eff762985be662a7cfc431"
- name = "github.com/leodido/go-urn"
- packages = ["."]
- pruneopts = "UT"
- revision = "70078a794e8ea4b497ba7c19a78cd60f90ccf0f4"
- version = "v1.1.0"
-
[[projects]]
branch = "master"
digest = "1:f7d8e8432e355163397d2da1e17d0fb616d611db1360c43b1ac73e56f87038e2"
@@ -308,6 +289,14 @@
revision = "8c9545af88b134710ab1cd196795e7f2388358d7"
version = "v1.3.0"
+[[projects]]
+ digest = "1:22799aea8fe96dd5693abdd1eaa14b1b29e3eafbdc7733fa155b3cb556c8a7ae"
+ name = "github.com/spf13/cobra"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "67fc4837d267bc9bfd6e47f77783fcc3dffc68de"
+ version = "v0.0.4"
+
[[projects]]
digest = "1:1b753ec16506f5864d26a28b43703c58831255059644351bbcb019b843950900"
name = "github.com/spf13/jwalterweatherman"
@@ -325,12 +314,12 @@
version = "v1.0.3"
[[projects]]
- digest = "1:1b773526998f3dbde3a51a4a5881680c4d237d3600f570d900f97ac93c7ba0a8"
+ digest = "1:11118bd196646c6515fea3d6c43f66162833c6ae4939bfb229b9956d91c6cf17"
name = "github.com/spf13/viper"
packages = ["."]
pruneopts = "UT"
- revision = "9e56dacc08fbbf8c9ee2dbc717553c758ce42bc9"
- version = "v1.3.2"
+ revision = "b5bf975e5823809fb22c7644d008757f78a4259e"
+ version = "v1.4.0"
[[projects]]
digest = "1:c268acaa4a4d94a467980e5e91452eb61c460145765293dc0aed48e5e9919cc6"
@@ -436,14 +425,6 @@
revision = "5f57d2222ad794d0dffb07e664ea05e2ee07d60c"
version = "v8.18.1"
-[[projects]]
- digest = "1:7bb1ad654b21fb8f44c77c07840007d6796f70d42d1b470600f943a508ff8a72"
- name = "gopkg.in/go-playground/validator.v9"
- packages = ["."]
- pruneopts = "UT"
- revision = "46b4b1e301c24cac870ffcb4ba5c8a703d1ef475"
- version = "v9.28.0"
-
[[projects]]
digest = "1:ef72505cf098abdd34efeea032103377bec06abb61d8a06f002d5d296a4b1185"
name = "gopkg.in/inf.v0"
@@ -642,8 +623,8 @@
"github.com/pkg/errors",
"github.com/rifflock/lfshook",
"github.com/sirupsen/logrus",
+ "github.com/spf13/cobra",
"github.com/spf13/viper",
- "gopkg.in/go-playground/validator.v9",
"k8s.io/api/core/v1",
"k8s.io/apimachinery/pkg/util/json",
"k8s.io/client-go/kubernetes",
diff --git a/pkg/api/auth.go b/pkg/api/auth.go
index dd1a725..52c8e29 100644
--- a/pkg/api/auth.go
+++ b/pkg/api/auth.go
@@ -1,7 +1,6 @@
package api
import (
- "fmt"
"github.com/gin-gonic/gin"
"k8s-webshell/pkg/e"
"k8s-webshell/pkg/setting"
@@ -33,12 +32,12 @@ func GetAuth(c *gin.Context) {
})
return
}
- fmt.Println(">>>", apiAuth.SecretKey,
- apiAuth.SecretKey,
- apiAuth.PaasUser,
- apiAuth.PodNs,
- apiAuth.PodName,
- apiAuth.ContainerName)
+ //fmt.Println(">>>", apiAuth.SecretKey,
+ // apiAuth.SecretKey,
+ // apiAuth.PaasUser,
+ // apiAuth.PodNs,
+ // apiAuth.PodName,
+ // apiAuth.ContainerName)
if apiAuth.SecretKey == setting.SecretKey {
token, err := utils.GenerateToken(
diff --git a/vendor/github.com/gin-gonic/gin/.gitignore b/vendor/github.com/gin-gonic/gin/.gitignore
index 14dc8f2..bdd50c9 100644
--- a/vendor/github.com/gin-gonic/gin/.gitignore
+++ b/vendor/github.com/gin-gonic/gin/.gitignore
@@ -3,3 +3,5 @@ vendor/*
coverage.out
count.out
test
+profile.out
+tmp.out
diff --git a/vendor/github.com/gin-gonic/gin/.travis.yml b/vendor/github.com/gin-gonic/gin/.travis.yml
index e910156..f6ec8a8 100644
--- a/vendor/github.com/gin-gonic/gin/.travis.yml
+++ b/vendor/github.com/gin-gonic/gin/.travis.yml
@@ -1,25 +1,34 @@
language: go
-sudo: false
-go:
- - 1.6.x
- - 1.7.x
- - 1.8.x
- - 1.9.x
- - 1.10.x
- - master
+
+matrix:
+ fast_finish: true
+ include:
+ - go: 1.8.x
+ - go: 1.9.x
+ - go: 1.10.x
+ - go: 1.11.x
+ env: GO111MODULE=on
+ - go: 1.12.x
+ env: GO111MODULE=on
+ - go: master
+ env: GO111MODULE=on
git:
depth: 10
+before_install:
+ - if [[ "${GO111MODULE}" = "on" ]]; then mkdir "${HOME}/go"; export GOPATH="${HOME}/go"; fi
+
install:
- - make install
+ - if [[ "${GO111MODULE}" = "on" ]]; then go mod download; else make install; fi
+ - if [[ "${GO111MODULE}" = "on" ]]; then export PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}"; fi
+ - if [[ "${GO111MODULE}" = "on" ]]; then make tools; fi
go_import_path: github.com/gin-gonic/gin
script:
- make vet
- make fmt-check
- - make embedmd
- make misspell-check
- make test
diff --git a/vendor/github.com/gin-gonic/gin/CHANGELOG.md b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
index e6a108c..8ea2495 100644
--- a/vendor/github.com/gin-gonic/gin/CHANGELOG.md
+++ b/vendor/github.com/gin-gonic/gin/CHANGELOG.md
@@ -1,4 +1,60 @@
-# CHANGELOG
+
+### Gin 1.4.0
+
+- [NEW] Support for [Go Modules](https://github.com/golang/go/wiki/Modules) [#1569](https://github.com/gin-gonic/gin/pull/1569)
+- [NEW] Refactor of form mapping multipart requesta [#1829](https://github.com/gin-gonic/gin/pull/1829)
+- [FIX] Truncate Latency precision in long running request [#1830](https://github.com/gin-gonic/gin/pull/1830)
+- [FIX] IsTerm flag should not be affected by DisableConsoleColor method. [#1802](https://github.com/gin-gonic/gin/pull/1802)
+- [NEW] Supporting file binding [#1264](https://github.com/gin-gonic/gin/pull/1264)
+- [NEW] Add support for mapping arrays [#1797](https://github.com/gin-gonic/gin/pull/1797)
+- [FIX] Readme updates [#1793](https://github.com/gin-gonic/gin/pull/1793) [#1788](https://github.com/gin-gonic/gin/pull/1788) [1789](https://github.com/gin-gonic/gin/pull/1789)
+- [FIX] StaticFS: Fixed Logging two log lines on 404. [#1805](https://github.com/gin-gonic/gin/pull/1805), [#1804](https://github.com/gin-gonic/gin/pull/1804)
+- [NEW] Make context.Keys available as LogFormatterParams [#1779](https://github.com/gin-gonic/gin/pull/1779)
+- [NEW] Use internal/json for Marshal/Unmarshal [#1791](https://github.com/gin-gonic/gin/pull/1791)
+- [NEW] Support mapping time.Duration [#1794](https://github.com/gin-gonic/gin/pull/1794)
+- [NEW] Refactor form mappings [#1749](https://github.com/gin-gonic/gin/pull/1749)
+- [NEW] Added flag to context.Stream indicates if client disconnected in middle of stream [#1252](https://github.com/gin-gonic/gin/pull/1252)
+- [FIX] Moved [examples](https://github.com/gin-gonic/examples) to stand alone Repo [#1775](https://github.com/gin-gonic/gin/pull/1775)
+- [NEW] Extend context.File to allow for the content-dispositon attachments via a new method context.Attachment [#1260](https://github.com/gin-gonic/gin/pull/1260)
+- [FIX] Support HTTP content negotiation wildcards [#1112](https://github.com/gin-gonic/gin/pull/1112)
+- [NEW] Add prefix from X-Forwarded-Prefix in redirectTrailingSlash [#1238](https://github.com/gin-gonic/gin/pull/1238)
+- [FIX] context.Copy() race condition [#1020](https://github.com/gin-gonic/gin/pull/1020)
+- [NEW] Add context.HandlerNames() [#1729](https://github.com/gin-gonic/gin/pull/1729)
+- [FIX] Change color methods to public in the defaultLogger. [#1771](https://github.com/gin-gonic/gin/pull/1771)
+- [FIX] Update writeHeaders method to use http.Header.Set [#1722](https://github.com/gin-gonic/gin/pull/1722)
+- [NEW] Add response size to LogFormatterParams [#1752](https://github.com/gin-gonic/gin/pull/1752)
+- [NEW] Allow ignoring field on form mapping [#1733](https://github.com/gin-gonic/gin/pull/1733)
+- [NEW] Add a function to force color in console output. [#1724](https://github.com/gin-gonic/gin/pull/1724)
+- [FIX] Context.Next() - recheck len of handlers on every iteration. [#1745](https://github.com/gin-gonic/gin/pull/1745)
+- [FIX] Fix all errcheck warnings [#1739](https://github.com/gin-gonic/gin/pull/1739) [#1653](https://github.com/gin-gonic/gin/pull/1653)
+- [NEW] context: inherits context cancellation and deadline from http.Request context for Go>=1.7 [#1690](https://github.com/gin-gonic/gin/pull/1690)
+- [NEW] Binding for URL Params [#1694](https://github.com/gin-gonic/gin/pull/1694)
+- [NEW] Add LoggerWithFormatter method [#1677](https://github.com/gin-gonic/gin/pull/1677)
+- [FIX] CI testing updates [#1671](https://github.com/gin-gonic/gin/pull/1671) [#1670](https://github.com/gin-gonic/gin/pull/1670) [#1682](https://github.com/gin-gonic/gin/pull/1682) [#1669](https://github.com/gin-gonic/gin/pull/1669)
+- [FIX] StaticFS(): Send 404 when path does not exist [#1663](https://github.com/gin-gonic/gin/pull/1663)
+- [FIX] Handle nil body for JSON binding [#1638](https://github.com/gin-gonic/gin/pull/1638)
+- [FIX] Support bind uri param [#1612](https://github.com/gin-gonic/gin/pull/1612)
+- [FIX] recovery: fix issue with syscall import on google app engine [#1640](https://github.com/gin-gonic/gin/pull/1640)
+- [FIX] Make sure the debug log contains line breaks [#1650](https://github.com/gin-gonic/gin/pull/1650)
+- [FIX] Panic stack trace being printed during recovery of broken pipe [#1089](https://github.com/gin-gonic/gin/pull/1089) [#1259](https://github.com/gin-gonic/gin/pull/1259)
+- [NEW] RunFd method to run http.Server through a file descriptor [#1609](https://github.com/gin-gonic/gin/pull/1609)
+- [NEW] Yaml binding support [#1618](https://github.com/gin-gonic/gin/pull/1618)
+- [FIX] Pass MaxMultipartMemory when FormFile is called [#1600](https://github.com/gin-gonic/gin/pull/1600)
+- [FIX] LoadHTML* tests [#1559](https://github.com/gin-gonic/gin/pull/1559)
+- [FIX] Removed use of sync.pool from HandleContext [#1565](https://github.com/gin-gonic/gin/pull/1565)
+- [FIX] Format output log to os.Stderr [#1571](https://github.com/gin-gonic/gin/pull/1571)
+- [FIX] Make logger use a yellow background and a darkgray text for legibility [#1570](https://github.com/gin-gonic/gin/pull/1570)
+- [FIX] Remove sensitive request information from panic log. [#1370](https://github.com/gin-gonic/gin/pull/1370)
+- [FIX] log.Println() does not print timestamp [#829](https://github.com/gin-gonic/gin/pull/829) [#1560](https://github.com/gin-gonic/gin/pull/1560)
+- [NEW] Add PureJSON renderer [#694](https://github.com/gin-gonic/gin/pull/694)
+- [FIX] Add missing copyright and update if/else [#1497](https://github.com/gin-gonic/gin/pull/1497)
+- [FIX] Update msgpack usage [#1498](https://github.com/gin-gonic/gin/pull/1498)
+- [FIX] Use protobuf on render [#1496](https://github.com/gin-gonic/gin/pull/1496)
+- [FIX] Add support for Protobuf format response [#1479](https://github.com/gin-gonic/gin/pull/1479)
+- [NEW] Set default time format in form binding [#1487](https://github.com/gin-gonic/gin/pull/1487)
+- [FIX] Add BindXML and ShouldBindXML [#1485](https://github.com/gin-gonic/gin/pull/1485)
+- [NEW] Upgrade dependency libraries [#1491](https://github.com/gin-gonic/gin/pull/1491)
+
### Gin 1.3.0
diff --git a/vendor/github.com/gin-gonic/gin/Makefile b/vendor/github.com/gin-gonic/gin/Makefile
index 51b9969..51a6b91 100644
--- a/vendor/github.com/gin-gonic/gin/Makefile
+++ b/vendor/github.com/gin-gonic/gin/Makefile
@@ -1,7 +1,9 @@
+GO ?= go
GOFMT ?= gofmt "-s"
-PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
-VETPACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /examples/)
+PACKAGES ?= $(shell $(GO) list ./... | grep -v /vendor/)
+VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /vendor/ | grep -v /examples/)
GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
+TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
all: install
@@ -10,7 +12,25 @@ install: deps
.PHONY: test
test:
- sh coverage.sh
+ echo "mode: count" > coverage.out
+ for d in $(TESTFOLDER); do \
+ $(GO) test -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
+ cat tmp.out; \
+ if grep -q "^--- FAIL" tmp.out; then \
+ rm tmp.out; \
+ exit 1; \
+ elif grep -q "build failed" tmp.out; then \
+ rm tmp.out; \
+ exit 1; \
+ elif grep -q "setup failed" tmp.out; then \
+ rm tmp.out; \
+ exit 1; \
+ fi; \
+ if [ -f profile.out ]; then \
+ cat profile.out | grep -v "mode:" >> coverage.out; \
+ rm profile.out; \
+ fi; \
+ done
.PHONY: fmt
fmt:
@@ -18,7 +38,6 @@ fmt:
.PHONY: fmt-check
fmt-check:
- # get all go files and run go fmt on them
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
@@ -27,36 +46,35 @@ fmt-check:
fi;
vet:
- go vet $(VETPACKAGES)
+ $(GO) vet $(VETPACKAGES)
deps:
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/kardianos/govendor; \
+ $(GO) get -u github.com/kardianos/govendor; \
fi
- @hash embedmd > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/campoy/embedmd; \
- fi
-
-embedmd:
- embedmd -d *.md
.PHONY: lint
lint:
@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/golang/lint/golint; \
+ $(GO) get -u golang.org/x/lint/golint; \
fi
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
.PHONY: misspell-check
misspell-check:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/client9/misspell/cmd/misspell; \
+ $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
misspell -error $(GOFILES)
.PHONY: misspell
misspell:
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
- go get -u github.com/client9/misspell/cmd/misspell; \
+ $(GO) get -u github.com/client9/misspell/cmd/misspell; \
fi
misspell -w $(GOFILES)
+
+.PHONY: tools
+tools:
+ go install golang.org/x/lint/golint; \
+ go install github.com/client9/misspell/cmd/misspell;
diff --git a/vendor/github.com/gin-gonic/gin/README.md b/vendor/github.com/gin-gonic/gin/README.md
index 28598ba..3e817a7 100644
--- a/vendor/github.com/gin-gonic/gin/README.md
+++ b/vendor/github.com/gin-gonic/gin/README.md
@@ -9,10 +9,10 @@
[![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Sourcegraph](https://sourcegraph.com/github.com/gin-gonic/gin/-/badge.svg)](https://sourcegraph.com/github.com/gin-gonic/gin?badge)
[![Open Source Helpers](https://www.codetriage.com/gin-gonic/gin/badges/users.svg)](https://www.codetriage.com/gin-gonic/gin)
+[![Release](https://img.shields.io/github/release/gin-gonic/gin.svg?style=flat-square)](https://github.com/gin-gonic/gin/releases)
Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
-![Gin console logger](https://gin-gonic.github.io/gin/other/console.png)
## Contents
@@ -34,13 +34,15 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
- [Blank Gin without middleware by default](#blank-gin-without-middleware-by-default)
- [Using middleware](#using-middleware)
- [How to write log file](#how-to-write-log-file)
+ - [Custom Log Format](#custom-log-format)
- [Model binding and validation](#model-binding-and-validation)
- [Custom Validators](#custom-validators)
- [Only Bind Query String](#only-bind-query-string)
- [Bind Query String or Post Data](#bind-query-string-or-post-data)
+ - [Bind Uri](#bind-uri)
- [Bind HTML checkboxes](#bind-html-checkboxes)
- [Multipart/Urlencoded binding](#multiparturlencoded-binding)
- - [XML, JSON and YAML rendering](#xml-json-and-yaml-rendering)
+ - [XML, JSON, YAML and ProtoBuf rendering](#xml-json-yaml-and-protobuf-rendering)
- [JSONP rendering](#jsonp)
- [Serving static files](#serving-static-files)
- [Serving data from reader](#serving-data-from-reader)
@@ -58,14 +60,16 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
- [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)
- [Try to bind body into different structs](#try-to-bind-body-into-different-structs)
- [http2 server push](#http2-server-push)
+ - [Define format for the log of routes](#define-format-for-the-log-of-routes)
+ - [Set and get a cookie](#set-and-get-a-cookie)
- [Testing](#testing)
-- [Users](#users--)
+- [Users](#users)
## Installation
To install Gin package, you need to install Go and set your Go workspace first.
-1. Download and install it:
+1. The first need [Go](https://golang.org/) installed (**version 1.8+ is required**), then you can use the below Go command to install Gin.
```sh
$ go get -u github.com/gin-gonic/gin
@@ -100,13 +104,13 @@ $ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
```sh
$ govendor init
-$ govendor fetch github.com/gin-gonic/gin@v1.2
+$ govendor fetch github.com/gin-gonic/gin@v1.3
```
4. Copy a starting template inside your project
```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go > main.go
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
```
5. Run your project
@@ -198,7 +202,7 @@ BenchmarkVulcan_GithubAll | 5000 | 394253 | 19894
## Build with [jsoniter](https://github.com/json-iterator/go)
-Gin use `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
+Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
```sh
$ go build -tags=jsoniter .
@@ -206,13 +210,12 @@ $ go build -tags=jsoniter .
## API Examples
+You can find a number of ready-to-run examples at [Gin examples repository](https://github.com/gin-gonic/examples).
+
### Using GET, POST, PUT, PATCH, DELETE and OPTIONS
```go
func main() {
- // Disable Console Color
- // gin.DisableConsoleColor()
-
// Creates a gin router with default middleware:
// logger and recovery (crash-free) middleware
router := gin.Default()
@@ -357,7 +360,11 @@ ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
#### Single file
-References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single).
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
```go
func main() {
@@ -388,7 +395,7 @@ curl -X POST http://localhost:8080/upload \
#### Multiple files
-See the detail [example code](examples/upload-file/multiple).
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
```go
func main() {
@@ -524,9 +531,88 @@ func main() {
}
```
+### Custom Log Format
+```go
+func main() {
+ router := gin.New()
+
+ // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
+ // By default gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+**Sample Output**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
+
+### Controlling Log output coloring
+
+By default, logs output on console should be colorized depending on the detected TTY.
+
+Never colorize logs:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Always colorize logs:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
### Model binding and validation
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz).
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
Gin uses [**go-playground/validator.v8**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags).
@@ -534,10 +620,10 @@ Note that you need to set the corresponding binding tag on all fields you want t
Also, Gin provides two sets of methods for binding:
- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindQuery`
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindQuery`
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
@@ -547,8 +633,8 @@ You can also specify that specific fields are required. If a field is decorated
```go
// Binding from JSON
type Login struct {
- User string `form:"user" json:"user" binding:"required"`
- Password string `form:"password" json:"password" binding:"required"`
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
func main() {
@@ -557,30 +643,55 @@ func main() {
// Example for binding JSON ({"user": "manu", "password": "123"})
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
- if err := c.ShouldBindJSON(&json); err == nil {
- if json.User == "manu" && json.Password == "123" {
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- }
- } else {
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //
+ // user
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
}
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// Example for binding a HTML form (user=manu&password=123)
router.POST("/loginForm", func(c *gin.Context) {
var form Login
// This will infer what binder to use depending on the content-type header.
- if err := c.ShouldBind(&form); err == nil {
- if form.User == "manu" && form.Password == "123" {
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- }
- } else {
+ if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
}
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// Listen and serve on 0.0.0.0:8080
@@ -616,9 +727,8 @@ When running the above example using the above the `curl` command, it returns er
### Custom Validators
-It is also possible to register custom validators. See the [example code](examples/custom-validation/server.go).
+It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/custom-validation/server.go).
-[embedmd]:# (examples/custom-validation/server.go go)
```go
package main
@@ -632,6 +742,7 @@ import (
"gopkg.in/go-playground/validator.v8"
)
+// Booking contains binded and validated data.
type Booking struct {
CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
@@ -679,8 +790,8 @@ $ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
```
-[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registed this way.
-See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
+See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
### Only Bind Query String
@@ -725,9 +836,12 @@ See the [detail information](https://github.com/gin-gonic/gin/issues/742#issueco
```go
package main
-import "log"
-import "github.com/gin-gonic/gin"
-import "time"
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
type Person struct {
Name string `form:"name"`
@@ -761,6 +875,40 @@ Test it with:
$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
```
+### Bind Uri
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Test it with:
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
+
### Bind HTML checkboxes
See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
@@ -792,12 +940,12 @@ form.html
```
@@ -846,7 +994,7 @@ Test it with:
$ curl -v --form user=user --form password=password http://localhost:8080/login
```
-### XML, JSON and YAML rendering
+### XML, JSON, YAML and ProtoBuf rendering
```go
func main() {
@@ -880,6 +1028,19 @@ func main() {
c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // The specific definition of protobuf is written in the testdata/protoexample file.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Note that data becomes binary data in the response
+ // Will output protoexample.Test protobuf serialized data
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
// Listen and serve on 0.0.0.0:8080
r.Run(":8080")
}
@@ -953,6 +1114,34 @@ func main() {
}
```
+#### PureJSON
+
+Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
+This feature is unavailable in Go 1.6 and lower.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Serves unicode entities
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Serves literal characters
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
### Serving static files
```go
@@ -1087,12 +1276,12 @@ You may use custom delims
```go
r := gin.Default()
r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates"))
+ r.LoadHTMLGlob("/path/to/templates")
```
#### Custom Template Funcs
-See the detail [example code](examples/template).
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
main.go
@@ -1312,7 +1501,6 @@ func main() {
example for 1-line LetsEncrypt HTTPS servers.
-[embedmd]:# (examples/auto-tls/example1/main.go go)
```go
package main
@@ -1337,7 +1525,6 @@ func main() {
example for custom autocert manager.
-[embedmd]:# (examples/auto-tls/example2/main.go go)
```go
package main
@@ -1371,7 +1558,6 @@ func main() {
See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
-[embedmd]:# (examples/multiple-service/main.go go)
```go
package main
@@ -1469,9 +1655,8 @@ An alternative to endless:
* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](./examples/graceful-shutdown) example with gin.
+If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
-[embedmd]:# (examples/graceful-shutdown/graceful-shutdown/server.go go)
```go
// +build go1.8
@@ -1483,6 +1668,7 @@ import (
"net/http"
"os"
"os/signal"
+ "syscall"
"time"
"github.com/gin-gonic/gin"
@@ -1510,7 +1696,10 @@ func main() {
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
quit := make(chan os.Signal)
- signal.Notify(quit, os.Interrupt)
+ // kill (no param) default send syscall.SIGTERM
+ // kill -2 is syscall.SIGINT
+ // kill -9 is syscall.SIGKILL but can"t be catch, so don't need add it
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutdown Server ...")
@@ -1519,6 +1708,11 @@ func main() {
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
+ // catching ctx.Done(). timeout of 5 seconds.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
log.Println("Server exiting")
}
```
@@ -1565,7 +1759,7 @@ func loadTemplate() (*template.Template, error) {
}
```
-See a complete example in the `examples/assets-in-binary` directory.
+See a complete example in the `https://github.com/gin-gonic/examples/tree/master/assets-in-binary` directory.
### Bind form-data request with custom struct
@@ -1641,24 +1835,6 @@ $ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
{"d":"world","x":{"FieldX":"hello"}}
```
-**NOTE**: NOT support the follow style struct:
-
-```go
-type StructX struct {
- X struct {} `form:"name_x"` // HERE have form
-}
-
-type StructY struct {
- Y StructX `form:"name_y"` // HERE hava form
-}
-
-type StructZ struct {
- Z *StructZ `form:"name_z"` // HERE hava form
-}
-```
-
-In a word, only support nested custom struct which have no `form` now.
-
### Try to bind body into different structs
The normal methods for binding request body consumes `c.Request.Body` and they
@@ -1721,7 +1897,6 @@ performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
-[embedmd]:# (examples/http-pusher/main.go go)
```go
package main
@@ -1766,6 +1941,78 @@ func main() {
}
```
+### Define format for the log of routes
+
+The default log of routes is:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
+In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Listen and Server in http://0.0.0.0:8080
+ r.Run()
+}
+```
+
+### Set and get a cookie
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
+
+
## Testing
The `net/http/httptest` package is preferable way for HTTP testing.
@@ -1816,5 +2063,8 @@ func TestPingRoute(t *testing.T) {
Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework.
-* [drone](https://github.com/drone/drone): Drone is a Continuous Delivery platform built on Docker, written in Go
* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
+* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
+* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
+* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
+* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
diff --git a/vendor/github.com/gin-gonic/gin/binding/binding.go b/vendor/github.com/gin-gonic/gin/binding/binding.go
index 3a2aad9..520c510 100644
--- a/vendor/github.com/gin-gonic/gin/binding/binding.go
+++ b/vendor/github.com/gin-gonic/gin/binding/binding.go
@@ -18,6 +18,7 @@ const (
MIMEPROTOBUF = "application/x-protobuf"
MIMEMSGPACK = "application/x-msgpack"
MIMEMSGPACK2 = "application/msgpack"
+ MIMEYAML = "application/x-yaml"
)
// Binding describes the interface which needs to be implemented for binding the
@@ -35,9 +36,16 @@ type BindingBody interface {
BindBody([]byte, interface{}) error
}
+// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
+// but it read the Params.
+type BindingUri interface {
+ Name() string
+ BindUri(map[string][]string, interface{}) error
+}
+
// StructValidator is the minimal interface which needs to be implemented in
// order for it to be used as the validator engine for ensuring the correctness
-// of the reqest. Gin provides a default implementation for this using
+// of the request. Gin provides a default implementation for this using
// https://github.com/go-playground/validator/tree/v8.18.2.
type StructValidator interface {
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
@@ -68,6 +76,8 @@ var (
FormMultipart = formMultipartBinding{}
ProtoBuf = protobufBinding{}
MsgPack = msgpackBinding{}
+ YAML = yamlBinding{}
+ Uri = uriBinding{}
)
// Default returns the appropriate Binding instance based on the HTTP method
@@ -86,7 +96,11 @@ func Default(method, contentType string) Binding {
return ProtoBuf
case MIMEMSGPACK, MIMEMSGPACK2:
return MsgPack
- default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
+ case MIMEYAML:
+ return YAML
+ case MIMEMultipartPOSTForm:
+ return FormMultipart
+ default: // case MIMEPOSTForm:
return Form
}
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/form.go b/vendor/github.com/gin-gonic/gin/binding/form.go
index 0be5966..0b28aa8 100644
--- a/vendor/github.com/gin-gonic/gin/binding/form.go
+++ b/vendor/github.com/gin-gonic/gin/binding/form.go
@@ -4,7 +4,11 @@
package binding
-import "net/http"
+import (
+ "mime/multipart"
+ "net/http"
+ "reflect"
+)
const defaultMemory = 32 * 1024 * 1024
@@ -20,7 +24,11 @@ func (formBinding) Bind(req *http.Request, obj interface{}) error {
if err := req.ParseForm(); err != nil {
return err
}
- req.ParseMultipartForm(defaultMemory)
+ if err := req.ParseMultipartForm(defaultMemory); err != nil {
+ if err != http.ErrNotMultipart {
+ return err
+ }
+ }
if err := mapForm(obj, req.Form); err != nil {
return err
}
@@ -49,8 +57,33 @@ func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
if err := req.ParseMultipartForm(defaultMemory); err != nil {
return err
}
- if err := mapForm(obj, req.MultipartForm.Value); err != nil {
+ if err := mappingByPtr(obj, (*multipartRequest)(req), "form"); err != nil {
return err
}
+
return validate(obj)
}
+
+type multipartRequest http.Request
+
+var _ setter = (*multipartRequest)(nil)
+
+var (
+ multipartFileHeaderStructType = reflect.TypeOf(multipart.FileHeader{})
+)
+
+// TrySet tries to set a value by the multipart request with the binding a form file
+func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error) {
+ if value.Type() == multipartFileHeaderStructType {
+ _, file, err := (*http.Request)(r).FormFile(key)
+ if err != nil {
+ return false, err
+ }
+ if file != nil {
+ value.Set(reflect.ValueOf(*file))
+ return true, nil
+ }
+ }
+
+ return setByForm(value, field, r.MultipartForm.Value, key, opt)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
index 3f6b9bf..aaacf6c 100644
--- a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
+++ b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go
@@ -6,127 +6,211 @@ package binding
import (
"errors"
+ "fmt"
"reflect"
"strconv"
"strings"
"time"
+
+ "github.com/gin-gonic/gin/internal/json"
)
+var errUnknownType = errors.New("Unknown type")
+
+func mapUri(ptr interface{}, m map[string][]string) error {
+ return mapFormByTag(ptr, m, "uri")
+}
+
func mapForm(ptr interface{}, form map[string][]string) error {
- typ := reflect.TypeOf(ptr).Elem()
- val := reflect.ValueOf(ptr).Elem()
- for i := 0; i < typ.NumField(); i++ {
- typeField := typ.Field(i)
- structField := val.Field(i)
- if !structField.CanSet() {
- continue
- }
+ return mapFormByTag(ptr, form, "form")
+}
- structFieldKind := structField.Kind()
- inputFieldName := typeField.Tag.Get("form")
- inputFieldNameList := strings.Split(inputFieldName, ",")
- inputFieldName = inputFieldNameList[0]
- var defaultValue string
- if len(inputFieldNameList) > 1 {
- defaultList := strings.SplitN(inputFieldNameList[1], "=", 2)
- if defaultList[0] == "default" {
- defaultValue = defaultList[1]
- }
+var emptyField = reflect.StructField{}
+
+func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
+ return mappingByPtr(ptr, formSource(form), tag)
+}
+
+// setter tries to set value on a walking by fields of a struct
+type setter interface {
+ TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error)
+}
+
+type formSource map[string][]string
+
+var _ setter = formSource(nil)
+
+// TrySet tries to set a value by request's form source (like map[string][]string)
+func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSetted bool, err error) {
+ return setByForm(value, field, form, tagValue, opt)
+}
+
+func mappingByPtr(ptr interface{}, setter setter, tag string) error {
+ _, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag)
+ return err
+}
+
+func mapping(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) {
+ var vKind = value.Kind()
+
+ if vKind == reflect.Ptr {
+ var isNew bool
+ vPtr := value
+ if value.IsNil() {
+ isNew = true
+ vPtr = reflect.New(value.Type().Elem())
}
- if inputFieldName == "" {
- inputFieldName = typeField.Name
-
- // if "form" tag is nil, we inspect if the field is a struct or struct pointer.
- // this would not make sense for JSON parsing but it does for a form
- // since data is flatten
- if structFieldKind == reflect.Ptr {
- if !structField.Elem().IsValid() {
- structField.Set(reflect.New(structField.Type().Elem()))
- }
- structField = structField.Elem()
- structFieldKind = structField.Kind()
- }
- if structFieldKind == reflect.Struct {
- err := mapForm(structField.Addr().Interface(), form)
- if err != nil {
- return err
- }
- continue
- }
+ isSetted, err := mapping(vPtr.Elem(), field, setter, tag)
+ if err != nil {
+ return false, err
}
- inputValue, exists := form[inputFieldName]
-
- if !exists {
- if defaultValue == "" {
- continue
- }
- inputValue = make([]string, 1)
- inputValue[0] = defaultValue
+ if isNew && isSetted {
+ value.Set(vPtr)
}
+ return isSetted, nil
+ }
- numElems := len(inputValue)
- if structFieldKind == reflect.Slice && numElems > 0 {
- sliceOf := structField.Type().Elem().Kind()
- slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
- for i := 0; i < numElems; i++ {
- if err := setWithProperType(sliceOf, inputValue[i], slice.Index(i)); err != nil {
- return err
- }
- }
- val.Field(i).Set(slice)
- } else {
- if _, isTime := structField.Interface().(time.Time); isTime {
- if err := setTimeField(inputValue[0], typeField, structField); err != nil {
- return err
- }
+ ok, err := tryToSetValue(value, field, setter, tag)
+ if err != nil {
+ return false, err
+ }
+ if ok {
+ return true, nil
+ }
+
+ if vKind == reflect.Struct {
+ tValue := value.Type()
+
+ var isSetted bool
+ for i := 0; i < value.NumField(); i++ {
+ if !value.Field(i).CanSet() {
continue
}
- if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
- return err
+ ok, err := mapping(value.Field(i), tValue.Field(i), setter, tag)
+ if err != nil {
+ return false, err
}
+ isSetted = isSetted || ok
}
+ return isSetted, nil
}
- return nil
+ return false, nil
+}
+
+type setOptions struct {
+ isDefaultExists bool
+ defaultValue string
+}
+
+func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter, tag string) (bool, error) {
+ var tagValue string
+ var setOpt setOptions
+
+ tagValue = field.Tag.Get(tag)
+ tagValue, opts := head(tagValue, ",")
+
+ if tagValue == "-" { // just ignoring this field
+ return false, nil
+ }
+ if tagValue == "" { // default value is FieldName
+ tagValue = field.Name
+ }
+ if tagValue == "" { // when field is "emptyField" variable
+ return false, nil
+ }
+
+ var opt string
+ for len(opts) > 0 {
+ opt, opts = head(opts, ",")
+
+ k, v := head(opt, "=")
+ switch k {
+ case "default":
+ setOpt.isDefaultExists = true
+ setOpt.defaultValue = v
+ }
+ }
+
+ return setter.TrySet(value, field, tagValue, setOpt)
}
-func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value) error {
- switch valueKind {
+func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSetted bool, err error) {
+ vs, ok := form[tagValue]
+ if !ok && !opt.isDefaultExists {
+ return false, nil
+ }
+
+ switch value.Kind() {
+ case reflect.Slice:
+ if !ok {
+ vs = []string{opt.defaultValue}
+ }
+ return true, setSlice(vs, value, field)
+ case reflect.Array:
+ if !ok {
+ vs = []string{opt.defaultValue}
+ }
+ if len(vs) != value.Len() {
+ return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
+ }
+ return true, setArray(vs, value, field)
+ default:
+ var val string
+ if !ok {
+ val = opt.defaultValue
+ }
+
+ if len(vs) > 0 {
+ val = vs[0]
+ }
+ return true, setWithProperType(val, value, field)
+ }
+}
+
+func setWithProperType(val string, value reflect.Value, field reflect.StructField) error {
+ switch value.Kind() {
case reflect.Int:
- return setIntField(val, 0, structField)
+ return setIntField(val, 0, value)
case reflect.Int8:
- return setIntField(val, 8, structField)
+ return setIntField(val, 8, value)
case reflect.Int16:
- return setIntField(val, 16, structField)
+ return setIntField(val, 16, value)
case reflect.Int32:
- return setIntField(val, 32, structField)
+ return setIntField(val, 32, value)
case reflect.Int64:
- return setIntField(val, 64, structField)
+ switch value.Interface().(type) {
+ case time.Duration:
+ return setTimeDuration(val, value, field)
+ }
+ return setIntField(val, 64, value)
case reflect.Uint:
- return setUintField(val, 0, structField)
+ return setUintField(val, 0, value)
case reflect.Uint8:
- return setUintField(val, 8, structField)
+ return setUintField(val, 8, value)
case reflect.Uint16:
- return setUintField(val, 16, structField)
+ return setUintField(val, 16, value)
case reflect.Uint32:
- return setUintField(val, 32, structField)
+ return setUintField(val, 32, value)
case reflect.Uint64:
- return setUintField(val, 64, structField)
+ return setUintField(val, 64, value)
case reflect.Bool:
- return setBoolField(val, structField)
+ return setBoolField(val, value)
case reflect.Float32:
- return setFloatField(val, 32, structField)
+ return setFloatField(val, 32, value)
case reflect.Float64:
- return setFloatField(val, 64, structField)
+ return setFloatField(val, 64, value)
case reflect.String:
- structField.SetString(val)
- case reflect.Ptr:
- if !structField.Elem().IsValid() {
- structField.Set(reflect.New(structField.Type().Elem()))
+ value.SetString(val)
+ case reflect.Struct:
+ switch value.Interface().(type) {
+ case time.Time:
+ return setTimeField(val, field, value)
}
- structFieldElem := structField.Elem()
- return setWithProperType(structFieldElem.Kind(), val, structFieldElem)
+ return json.Unmarshal([]byte(val), value.Addr().Interface())
+ case reflect.Map:
+ return json.Unmarshal([]byte(val), value.Addr().Interface())
default:
- return errors.New("Unknown type")
+ return errUnknownType
}
return nil
}
@@ -178,7 +262,7 @@ func setFloatField(val string, bitSize int, field reflect.Value) error {
func setTimeField(val string, structField reflect.StructField, value reflect.Value) error {
timeFormat := structField.Tag.Get("time_format")
if timeFormat == "" {
- return errors.New("Blank time format")
+ timeFormat = time.RFC3339
}
if val == "" {
@@ -207,3 +291,40 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
value.Set(reflect.ValueOf(t))
return nil
}
+
+func setArray(vals []string, value reflect.Value, field reflect.StructField) error {
+ for i, s := range vals {
+ err := setWithProperType(s, value.Index(i), field)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func setSlice(vals []string, value reflect.Value, field reflect.StructField) error {
+ slice := reflect.MakeSlice(value.Type(), len(vals), len(vals))
+ err := setArray(vals, slice, field)
+ if err != nil {
+ return err
+ }
+ value.Set(slice)
+ return nil
+}
+
+func setTimeDuration(val string, value reflect.Value, field reflect.StructField) error {
+ d, err := time.ParseDuration(val)
+ if err != nil {
+ return err
+ }
+ value.Set(reflect.ValueOf(d))
+ return nil
+}
+
+func head(str, sep string) (head string, tail string) {
+ idx := strings.Index(str, sep)
+ if idx < 0 {
+ return str, ""
+ }
+ return str[:idx], str[idx+len(sep):]
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/json.go b/vendor/github.com/gin-gonic/gin/binding/json.go
index fea17bb..f968161 100644
--- a/vendor/github.com/gin-gonic/gin/binding/json.go
+++ b/vendor/github.com/gin-gonic/gin/binding/json.go
@@ -6,10 +6,11 @@ package binding
import (
"bytes"
+ "fmt"
"io"
"net/http"
- "github.com/gin-gonic/gin/json"
+ "github.com/gin-gonic/gin/internal/json"
)
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
@@ -24,6 +25,9 @@ func (jsonBinding) Name() string {
}
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
+ if req == nil || req.Body == nil {
+ return fmt.Errorf("invalid request")
+ }
return decodeJSON(req.Body, obj)
}
diff --git a/vendor/github.com/gin-gonic/gin/binding/protobuf.go b/vendor/github.com/gin-gonic/gin/binding/protobuf.go
index 540e9c1..f9ece92 100644
--- a/vendor/github.com/gin-gonic/gin/binding/protobuf.go
+++ b/vendor/github.com/gin-gonic/gin/binding/protobuf.go
@@ -29,7 +29,7 @@ func (protobufBinding) BindBody(body []byte, obj interface{}) error {
if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil {
return err
}
- // Here it's same to return validate(obj), but util now we cann't add
+ // Here it's same to return validate(obj), but util now we can't add
// `binding:""` to the struct which automatically generate by gen-proto
return nil
// return validate(obj)
diff --git a/vendor/github.com/gin-gonic/gin/binding/uri.go b/vendor/github.com/gin-gonic/gin/binding/uri.go
new file mode 100644
index 0000000..f91ec38
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/uri.go
@@ -0,0 +1,18 @@
+// Copyright 2018 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+type uriBinding struct{}
+
+func (uriBinding) Name() string {
+ return "uri"
+}
+
+func (uriBinding) BindUri(m map[string][]string, obj interface{}) error {
+ if err := mapUri(obj, m); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/binding/yaml.go b/vendor/github.com/gin-gonic/gin/binding/yaml.go
new file mode 100644
index 0000000..a2d36d6
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/binding/yaml.go
@@ -0,0 +1,35 @@
+// Copyright 2018 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package binding
+
+import (
+ "bytes"
+ "io"
+ "net/http"
+
+ "gopkg.in/yaml.v2"
+)
+
+type yamlBinding struct{}
+
+func (yamlBinding) Name() string {
+ return "yaml"
+}
+
+func (yamlBinding) Bind(req *http.Request, obj interface{}) error {
+ return decodeYAML(req.Body, obj)
+}
+
+func (yamlBinding) BindBody(body []byte, obj interface{}) error {
+ return decodeYAML(bytes.NewReader(body), obj)
+}
+
+func decodeYAML(r io.Reader, obj interface{}) error {
+ decoder := yaml.NewDecoder(r)
+ if err := decoder.Decode(obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
diff --git a/vendor/github.com/gin-gonic/gin/context.go b/vendor/github.com/gin-gonic/gin/context.go
index 724ded7..af747a1 100644
--- a/vendor/github.com/gin-gonic/gin/context.go
+++ b/vendor/github.com/gin-gonic/gin/context.go
@@ -6,6 +6,7 @@ package gin
import (
"errors"
+ "fmt"
"io"
"io/ioutil"
"math"
@@ -31,6 +32,7 @@ const (
MIMEPlain = binding.MIMEPlain
MIMEPOSTForm = binding.MIMEPOSTForm
MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
+ MIMEYAML = binding.MIMEYAML
BodyBytesKey = "_gin-gonic/gin/bodybyteskey"
)
@@ -81,6 +83,10 @@ func (c *Context) Copy() *Context {
cp.Writer = &cp.writermem
cp.index = abortIndex
cp.handlers = nil
+ cp.Keys = map[string]interface{}{}
+ for k, v := range c.Keys {
+ cp.Keys[k] = v
+ }
return &cp
}
@@ -90,6 +96,16 @@ func (c *Context) HandlerName() string {
return nameOfFunction(c.handlers.Last())
}
+// HandlerNames returns a list of all registered handlers for this context in descending order,
+// following the semantics of HandlerName()
+func (c *Context) HandlerNames() []string {
+ hn := make([]string, 0, len(c.handlers))
+ for _, val := range c.handlers {
+ hn = append(hn, nameOfFunction(val))
+ }
+ return hn
+}
+
// Handler returns the main handler.
func (c *Context) Handler() HandlerFunc {
return c.handlers.Last()
@@ -104,8 +120,9 @@ func (c *Context) Handler() HandlerFunc {
// See example in GitHub.
func (c *Context) Next() {
c.index++
- for s := int8(len(c.handlers)); c.index < s; c.index++ {
+ for c.index < int8(len(c.handlers)) {
c.handlers[c.index](c)
+ c.index++
}
}
@@ -414,16 +431,14 @@ func (c *Context) PostFormArray(key string) []string {
// a boolean value whether at least one value exists for the given key.
func (c *Context) GetPostFormArray(key string) ([]string, bool) {
req := c.Request
- req.ParseForm()
- req.ParseMultipartForm(c.engine.MaxMultipartMemory)
+ if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
+ if err != http.ErrNotMultipart {
+ debugPrint("error on parse multipart form array: %v", err)
+ }
+ }
if values := req.PostForm[key]; len(values) > 0 {
return values, true
}
- if req.MultipartForm != nil && req.MultipartForm.File != nil {
- if values := req.MultipartForm.Value[key]; len(values) > 0 {
- return values, true
- }
- }
return []string{}, false
}
@@ -437,15 +452,12 @@ func (c *Context) PostFormMap(key string) map[string]string {
// whether at least one value exists for the given key.
func (c *Context) GetPostFormMap(key string) (map[string]string, bool) {
req := c.Request
- req.ParseForm()
- req.ParseMultipartForm(c.engine.MaxMultipartMemory)
- dicts, exist := c.get(req.PostForm, key)
-
- if !exist && req.MultipartForm != nil && req.MultipartForm.File != nil {
- dicts, exist = c.get(req.MultipartForm.Value, key)
+ if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
+ if err != http.ErrNotMultipart {
+ debugPrint("error on parse multipart form map: %v", err)
+ }
}
-
- return dicts, exist
+ return c.get(req.PostForm, key)
}
// get is an internal method and returns a map which satisfy conditions.
@@ -465,6 +477,11 @@ func (c *Context) get(m map[string][]string, key string) (map[string]string, boo
// FormFile returns the first file for the provided form key.
func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
+ if c.Request.MultipartForm == nil {
+ if err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
+ return nil, err
+ }
+ }
_, fh, err := c.Request.FormFile(name)
return fh, err
}
@@ -489,8 +506,8 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error
}
defer out.Close()
- io.Copy(out, src)
- return nil
+ _, err = io.Copy(out, src)
+ return err
}
// Bind checks the Content-Type to select a binding engine automatically,
@@ -511,20 +528,40 @@ func (c *Context) BindJSON(obj interface{}) error {
return c.MustBindWith(obj, binding.JSON)
}
+// BindXML is a shortcut for c.MustBindWith(obj, binding.BindXML).
+func (c *Context) BindXML(obj interface{}) error {
+ return c.MustBindWith(obj, binding.XML)
+}
+
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
func (c *Context) BindQuery(obj interface{}) error {
return c.MustBindWith(obj, binding.Query)
}
+// BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML).
+func (c *Context) BindYAML(obj interface{}) error {
+ return c.MustBindWith(obj, binding.YAML)
+}
+
+// BindUri binds the passed struct pointer using binding.Uri.
+// It will abort the request with HTTP 400 if any error occurs.
+func (c *Context) BindUri(obj interface{}) error {
+ if err := c.ShouldBindUri(obj); err != nil {
+ c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
+ return err
+ }
+ return nil
+}
+
// MustBindWith binds the passed struct pointer using the specified binding engine.
-// It will abort the request with HTTP 400 if any error ocurrs.
+// It will abort the request with HTTP 400 if any error occurs.
// See the binding package.
-func (c *Context) MustBindWith(obj interface{}, b binding.Binding) (err error) {
- if err = c.ShouldBindWith(obj, b); err != nil {
- c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind)
+func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
+ if err := c.ShouldBindWith(obj, b); err != nil {
+ c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
+ return err
}
-
- return
+ return nil
}
// ShouldBind checks the Content-Type to select a binding engine automatically,
@@ -545,11 +582,30 @@ func (c *Context) ShouldBindJSON(obj interface{}) error {
return c.ShouldBindWith(obj, binding.JSON)
}
+// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
+func (c *Context) ShouldBindXML(obj interface{}) error {
+ return c.ShouldBindWith(obj, binding.XML)
+}
+
// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
func (c *Context) ShouldBindQuery(obj interface{}) error {
return c.ShouldBindWith(obj, binding.Query)
}
+// ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML).
+func (c *Context) ShouldBindYAML(obj interface{}) error {
+ return c.ShouldBindWith(obj, binding.YAML)
+}
+
+// ShouldBindUri binds the passed struct pointer using the specified binding engine.
+func (c *Context) ShouldBindUri(obj interface{}) error {
+ m := make(map[string][]string)
+ for _, v := range c.Params {
+ m[v.Key] = []string{v.Value}
+ }
+ return binding.Uri.BindUri(m, obj)
+}
+
// ShouldBindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
@@ -561,9 +617,7 @@ func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
//
// NOTE: This method reads the body before binding. So you should use
// ShouldBindWith for better performance if you need to call only once.
-func (c *Context) ShouldBindBodyWith(
- obj interface{}, bb binding.BindingBody,
-) (err error) {
+func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) {
var body []byte
if cb, ok := c.Get(BodyBytesKey); ok {
if cbb, ok := cb.([]byte); ok {
@@ -655,9 +709,9 @@ func (c *Context) Status(code int) {
func (c *Context) Header(key, value string) {
if value == "" {
c.Writer.Header().Del(key)
- } else {
- c.Writer.Header().Set(key, value)
+ return
}
+ c.Writer.Header().Set(key, value)
}
// GetHeader returns value from request headers.
@@ -701,6 +755,7 @@ func (c *Context) Cookie(name string) (string, error) {
return val, nil
}
+// Render writes the response headers and calls render.Render to render data.
func (c *Context) Render(code int, r render.Render) {
c.Status(code)
@@ -745,9 +800,9 @@ func (c *Context) JSONP(code int, obj interface{}) {
callback := c.DefaultQuery("callback", "")
if callback == "" {
c.Render(code, render.JSON{Data: obj})
- } else {
- c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
+ return
}
+ c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
}
// JSON serializes the given struct as JSON into the response body.
@@ -762,6 +817,12 @@ func (c *Context) AsciiJSON(code int, obj interface{}) {
c.Render(code, render.AsciiJSON{Data: obj})
}
+// PureJSON serializes the given struct as JSON into the response body.
+// PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
+func (c *Context) PureJSON(code int, obj interface{}) {
+ c.Render(code, render.PureJSON{Data: obj})
+}
+
// XML serializes the given struct as XML into the response body.
// It also sets the Content-Type as "application/xml".
func (c *Context) XML(code int, obj interface{}) {
@@ -773,6 +834,11 @@ func (c *Context) YAML(code int, obj interface{}) {
c.Render(code, render.YAML{Data: obj})
}
+// ProtoBuf serializes the given struct as ProtoBuf into the response body.
+func (c *Context) ProtoBuf(code int, obj interface{}) {
+ c.Render(code, render.ProtoBuf{Data: obj})
+}
+
// String writes the given string into the response body.
func (c *Context) String(code int, format string, values ...interface{}) {
c.Render(code, render.String{Format: format, Data: values})
@@ -810,6 +876,13 @@ func (c *Context) File(filepath string) {
http.ServeFile(c.Writer, c.Request, filepath)
}
+// FileAttachment writes the specified file into the body stream in an efficient way
+// On the client side, the file will typically be downloaded with the given filename
+func (c *Context) FileAttachment(filepath, filename string) {
+ c.Writer.Header().Set("content-disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
+ http.ServeFile(c.Writer, c.Request, filepath)
+}
+
// SSEvent writes a Server-Sent Event into the body stream.
func (c *Context) SSEvent(name string, message interface{}) {
c.Render(-1, sse.Event{
@@ -818,18 +891,20 @@ func (c *Context) SSEvent(name string, message interface{}) {
})
}
-func (c *Context) Stream(step func(w io.Writer) bool) {
+// Stream sends a streaming response and returns a boolean
+// indicates "Is client disconnected in middle of stream"
+func (c *Context) Stream(step func(w io.Writer) bool) bool {
w := c.Writer
clientGone := w.CloseNotify()
for {
select {
case <-clientGone:
- return
+ return true
default:
keepOpen := step(w)
w.Flush()
if !keepOpen {
- return
+ return false
}
}
}
@@ -839,6 +914,7 @@ func (c *Context) Stream(step func(w io.Writer) bool) {
/******** CONTENT NEGOTIATION *******/
/************************************/
+// Negotiate contains all negotiations data.
type Negotiate struct {
Offered []string
HTMLName string
@@ -848,6 +924,7 @@ type Negotiate struct {
Data interface{}
}
+// Negotiate calls different Render according acceptable Accept format.
func (c *Context) Negotiate(code int, config Negotiate) {
switch c.NegotiateFormat(config.Offered...) {
case binding.MIMEJSON:
@@ -863,10 +940,11 @@ func (c *Context) Negotiate(code int, config Negotiate) {
c.XML(code, data)
default:
- c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server"))
+ c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) // nolint: errcheck
}
}
+// NegotiateFormat returns an acceptable Accept format.
func (c *Context) NegotiateFormat(offered ...string) string {
assert1(len(offered) > 0, "you must provide at least one offer")
@@ -878,7 +956,18 @@ func (c *Context) NegotiateFormat(offered ...string) string {
}
for _, accepted := range c.Accepted {
for _, offert := range offered {
- if accepted == offert {
+ // According to RFC 2616 and RFC 2396, non-ASCII characters are not allowed in headers,
+ // therefore we can just iterate over the string without casting it into []rune
+ i := 0
+ for ; i < len(accepted); i++ {
+ if accepted[i] == '*' || offert[i] == '*' {
+ return offert
+ }
+ if accepted[i] != offert[i] {
+ break
+ }
+ }
+ if i == len(accepted) {
return offert
}
}
@@ -886,6 +975,7 @@ func (c *Context) NegotiateFormat(offered ...string) string {
return ""
}
+// SetAccepted sets Accept header data.
func (c *Context) SetAccepted(formats ...string) {
c.Accepted = formats
}
diff --git a/vendor/github.com/gin-gonic/gin/coverage.sh b/vendor/github.com/gin-gonic/gin/coverage.sh
deleted file mode 100644
index 4d1ee03..0000000
--- a/vendor/github.com/gin-gonic/gin/coverage.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-echo "mode: count" > coverage.out
-
-for d in $(go list ./... | grep -E 'gin$|binding$|render$' | grep -v 'examples'); do
- go test -v -covermode=count -coverprofile=profile.out $d
- if [ -f profile.out ]; then
- cat profile.out | grep -v "mode:" >> coverage.out
- rm profile.out
- fi
-done
diff --git a/vendor/github.com/gin-gonic/gin/debug.go b/vendor/github.com/gin-gonic/gin/debug.go
index f11156b..6d40a5d 100644
--- a/vendor/github.com/gin-gonic/gin/debug.go
+++ b/vendor/github.com/gin-gonic/gin/debug.go
@@ -6,13 +6,15 @@ package gin
import (
"bytes"
+ "fmt"
"html/template"
- "log"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
)
-func init() {
- log.SetFlags(0)
-}
+const ginSupportMinGoVer = 8
// IsDebugging returns true if the framework is running in debug mode.
// Use SetMode(gin.ReleaseMode) to disable debug mode.
@@ -20,11 +22,18 @@ func IsDebugging() bool {
return ginMode == debugCode
}
+// DebugPrintRouteFunc indicates debug log output format.
+var DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string, nuHandlers int)
+
func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
if IsDebugging() {
nuHandlers := len(handlers)
handlerName := nameOfFunction(handlers.Last())
- debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ if DebugPrintRouteFunc == nil {
+ debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ } else {
+ DebugPrintRouteFunc(httpMethod, absolutePath, handlerName, nuHandlers)
+ }
}
}
@@ -42,14 +51,28 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
func debugPrint(format string, values ...interface{}) {
if IsDebugging() {
- log.Printf("[GIN-debug] "+format, values...)
+ if !strings.HasSuffix(format, "\n") {
+ format += "\n"
+ }
+ fmt.Fprintf(os.Stderr, "[GIN-debug] "+format, values...)
}
}
+func getMinVer(v string) (uint64, error) {
+ first := strings.IndexByte(v, '.')
+ last := strings.LastIndexByte(v, '.')
+ if first == last {
+ return strconv.ParseUint(v[first+1:], 10, 64)
+ }
+ return strconv.ParseUint(v[first+1:last], 10, 64)
+}
+
func debugPrintWARNINGDefault() {
- debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
+ if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
+ debugPrint(`[WARNING] Now Gin requires Go 1.8 or later and Go 1.9 will be required soon.
`)
+ }
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
`)
diff --git a/vendor/github.com/gin-gonic/gin/doc.go b/vendor/github.com/gin-gonic/gin/doc.go
index 01ac4a9..1bd0386 100644
--- a/vendor/github.com/gin-gonic/gin/doc.go
+++ b/vendor/github.com/gin-gonic/gin/doc.go
@@ -1,6 +1,6 @@
/*
Package gin implements a HTTP web framework called gin.
-See https://gin-gonic.github.io/gin/ for more information about gin.
+See https://gin-gonic.com/ for more information about gin.
*/
package gin // import "github.com/gin-gonic/gin"
diff --git a/vendor/github.com/gin-gonic/gin/errors.go b/vendor/github.com/gin-gonic/gin/errors.go
index dbfccd8..6070ff5 100644
--- a/vendor/github.com/gin-gonic/gin/errors.go
+++ b/vendor/github.com/gin-gonic/gin/errors.go
@@ -9,21 +9,28 @@ import (
"fmt"
"reflect"
- "github.com/gin-gonic/gin/json"
+ "github.com/gin-gonic/gin/internal/json"
)
+// ErrorType is an unsigned 64-bit error code as defined in the gin spec.
type ErrorType uint64
const (
- ErrorTypeBind ErrorType = 1 << 63 // used when c.Bind() fails
- ErrorTypeRender ErrorType = 1 << 62 // used when c.Render() fails
+ // ErrorTypeBind is used when Context.Bind() fails.
+ ErrorTypeBind ErrorType = 1 << 63
+ // ErrorTypeRender is used when Context.Render() fails.
+ ErrorTypeRender ErrorType = 1 << 62
+ // ErrorTypePrivate indicates a private error.
ErrorTypePrivate ErrorType = 1 << 0
- ErrorTypePublic ErrorType = 1 << 1
-
+ // ErrorTypePublic indicates a public error.
+ ErrorTypePublic ErrorType = 1 << 1
+ // ErrorTypeAny indicates any other error.
ErrorTypeAny ErrorType = 1<<64 - 1
- ErrorTypeNu = 2
+ // ErrorTypeNu indicates any other error.
+ ErrorTypeNu = 2
)
+// Error represents a error's specification.
type Error struct {
Err error
Type ErrorType
@@ -34,16 +41,19 @@ type errorMsgs []*Error
var _ error = &Error{}
+// SetType sets the error's type.
func (msg *Error) SetType(flags ErrorType) *Error {
msg.Type = flags
return msg
}
+// SetMeta sets the error's meta data.
func (msg *Error) SetMeta(data interface{}) *Error {
msg.Meta = data
return msg
}
+// JSON creates a properly formatted JSON
func (msg *Error) JSON() interface{} {
json := H{}
if msg.Meta != nil {
@@ -70,11 +80,12 @@ func (msg *Error) MarshalJSON() ([]byte, error) {
return json.Marshal(msg.JSON())
}
-// Error implements the error interface
+// Error implements the error interface.
func (msg Error) Error() string {
return msg.Err.Error()
}
+// IsType judges one error.
func (msg *Error) IsType(flags ErrorType) bool {
return (msg.Type & flags) > 0
}
@@ -138,6 +149,7 @@ func (a errorMsgs) JSON() interface{} {
}
}
+// MarshalJSON implements the json.Marshaller interface.
func (a errorMsgs) MarshalJSON() ([]byte, error) {
return json.Marshal(a.JSON())
}
diff --git a/vendor/github.com/gin-gonic/gin/gin.go b/vendor/github.com/gin-gonic/gin/gin.go
index aa62e01..4dbe983 100644
--- a/vendor/github.com/gin-gonic/gin/gin.go
+++ b/vendor/github.com/gin-gonic/gin/gin.go
@@ -5,20 +5,18 @@
package gin
import (
+ "fmt"
"html/template"
"net"
"net/http"
"os"
+ "path"
"sync"
"github.com/gin-gonic/gin/render"
)
-const (
- // Version is Framework's version.
- Version = "v1.3.0"
- defaultMultipartMemory = 32 << 20 // 32 MB
-)
+const defaultMultipartMemory = 32 << 20 // 32 MB
var (
default404Body = []byte("404 page not found")
@@ -26,7 +24,10 @@ var (
defaultAppEngine bool
)
+// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
+
+// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc
// Last returns the last handler in the chain. ie. the last handler is the main own.
@@ -37,12 +38,15 @@ func (c HandlersChain) Last() HandlerFunc {
return nil
}
+// RouteInfo represents a request route's specification which contains method and path and its handler.
type RouteInfo struct {
- Method string
- Path string
- Handler string
+ Method string
+ Path string
+ Handler string
+ HandlerFunc HandlerFunc
}
+// RoutesInfo defines a RouteInfo array.
type RoutesInfo []RouteInfo
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
@@ -155,6 +159,7 @@ func (engine *Engine) allocateContext() *Context {
return &Context{engine: engine}
}
+// Delims sets template left and right delims and returns a Engine instance.
func (engine *Engine) Delims(left, right string) *Engine {
engine.delims = render.Delims{Left: left, Right: right}
return engine
@@ -220,7 +225,7 @@ func (engine *Engine) NoMethod(handlers ...HandlerFunc) {
engine.rebuild405Handlers()
}
-// Use attachs a global middleware to the router. ie. the middleware attached though Use() will be
+// Use attaches a global middleware to the router. ie. the middleware attached though Use() will be
// included in the handlers chain for every single request. Even 404, 405, static files...
// For example, this is the right place for a logger or error management middleware.
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
@@ -264,10 +269,12 @@ func (engine *Engine) Routes() (routes RoutesInfo) {
func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
path += root.path
if len(root.handlers) > 0 {
+ handlerFunc := root.handlers.Last()
routes = append(routes, RouteInfo{
- Method: method,
- Path: path,
- Handler: nameOfFunction(root.handlers.Last()),
+ Method: method,
+ Path: path,
+ Handler: nameOfFunction(handlerFunc),
+ HandlerFunc: handlerFunc,
})
}
for _, child := range root.children {
@@ -312,6 +319,24 @@ func (engine *Engine) RunUnix(file string) (err error) {
return
}
defer listener.Close()
+ os.Chmod(file, 0777)
+ err = http.Serve(listener, engine)
+ return
+}
+
+// RunFd attaches the router to a http.Server and starts listening and serving HTTP requests
+// through the specified file descriptor.
+// Note: this method will block the calling goroutine indefinitely unless an error happens.
+func (engine *Engine) RunFd(fd int) (err error) {
+ debugPrint("Listening and serving HTTP on fd@%d", fd)
+ defer func() { debugPrintError(err) }()
+
+ f := os.NewFile(uintptr(fd), fmt.Sprintf("fd@%d", fd))
+ listener, err := net.FileListener(f)
+ if err != nil {
+ return
+ }
+ defer listener.Close()
err = http.Serve(listener, engine)
return
}
@@ -332,19 +357,22 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// This can be done by setting c.Request.URL.Path to your new target.
// Disclaimer: You can loop yourself to death with this, use wisely.
func (engine *Engine) HandleContext(c *Context) {
+ oldIndexValue := c.index
c.reset()
engine.handleHTTPRequest(c)
- engine.pool.Put(c)
+
+ c.index = oldIndexValue
}
func (engine *Engine) handleHTTPRequest(c *Context) {
httpMethod := c.Request.Method
- path := c.Request.URL.Path
+ rPath := c.Request.URL.Path
unescape := false
if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
- path = c.Request.URL.RawPath
+ rPath = c.Request.URL.RawPath
unescape = engine.UnescapePathValues
}
+ rPath = cleanPath(rPath)
// Find root of the tree for the given HTTP method
t := engine.trees
@@ -354,7 +382,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
}
root := t[i].root
// Find route in tree
- handlers, params, tsr := root.getValue(path, c.Params, unescape)
+ handlers, params, tsr := root.getValue(rPath, c.Params, unescape)
if handlers != nil {
c.handlers = handlers
c.Params = params
@@ -362,7 +390,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
c.writermem.WriteHeaderNow()
return
}
- if httpMethod != "CONNECT" && path != "/" {
+ if httpMethod != "CONNECT" && rPath != "/" {
if tsr && engine.RedirectTrailingSlash {
redirectTrailingSlash(c)
return
@@ -379,7 +407,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
if tree.method == httpMethod {
continue
}
- if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil {
+ if handlers, _, _ := tree.root.getValue(rPath, nil, unescape); handlers != nil {
c.handlers = engine.allNoMethod
serveError(c, http.StatusMethodNotAllowed, default405Body)
return
@@ -400,7 +428,10 @@ func serveError(c *Context, code int, defaultMessage []byte) {
}
if c.writermem.Status() == code {
c.writermem.Header()["Content-Type"] = mimePlain
- c.Writer.Write(defaultMessage)
+ _, err := c.Writer.Write(defaultMessage)
+ if err != nil {
+ debugPrint("cannot write message to writer during serve error: %v", err)
+ }
return
}
c.writermem.WriteHeaderNow()
@@ -409,32 +440,35 @@ func serveError(c *Context, code int, defaultMessage []byte) {
func redirectTrailingSlash(c *Context) {
req := c.Request
- path := req.URL.Path
+ p := req.URL.Path
+ if prefix := path.Clean(c.Request.Header.Get("X-Forwarded-Prefix")); prefix != "." {
+ p = prefix + "/" + req.URL.Path
+ }
code := http.StatusMovedPermanently // Permanent redirect, request with GET method
if req.Method != "GET" {
code = http.StatusTemporaryRedirect
}
- req.URL.Path = path + "/"
- if length := len(path); length > 1 && path[length-1] == '/' {
- req.URL.Path = path[:length-1]
+ req.URL.Path = p + "/"
+ if length := len(p); length > 1 && p[length-1] == '/' {
+ req.URL.Path = p[:length-1]
}
- debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
+ debugPrint("redirecting request %d: %s --> %s", code, p, req.URL.String())
http.Redirect(c.Writer, req, req.URL.String(), code)
c.writermem.WriteHeaderNow()
}
func redirectFixedPath(c *Context, root *node, trailingSlash bool) bool {
req := c.Request
- path := req.URL.Path
+ rPath := req.URL.Path
- if fixedPath, ok := root.findCaseInsensitivePath(cleanPath(path), trailingSlash); ok {
+ if fixedPath, ok := root.findCaseInsensitivePath(cleanPath(rPath), trailingSlash); ok {
code := http.StatusMovedPermanently // Permanent redirect, request with GET method
if req.Method != "GET" {
code = http.StatusTemporaryRedirect
}
req.URL.Path = string(fixedPath)
- debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String())
+ debugPrint("redirecting request %d: %s --> %s", code, rPath, req.URL.String())
http.Redirect(c.Writer, req, req.URL.String(), code)
c.writermem.WriteHeaderNow()
return true
diff --git a/vendor/github.com/gin-gonic/gin/go.mod b/vendor/github.com/gin-gonic/gin/go.mod
new file mode 100644
index 0000000..1c5e995
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/go.mod
@@ -0,0 +1,18 @@
+module github.com/gin-gonic/gin
+
+go 1.12
+
+require (
+ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
+ github.com/golang/protobuf v1.3.1
+ github.com/json-iterator/go v1.1.6
+ github.com/mattn/go-isatty v0.0.7
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.1 // indirect
+ github.com/stretchr/testify v1.3.0
+ github.com/ugorji/go v1.1.4
+ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c
+ gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
+ gopkg.in/go-playground/validator.v8 v8.18.2
+ gopkg.in/yaml.v2 v2.2.2
+)
diff --git a/vendor/github.com/gin-gonic/gin/go.sum b/vendor/github.com/gin-gonic/gin/go.sum
new file mode 100644
index 0000000..5810468
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/go.sum
@@ -0,0 +1,36 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
+github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
+github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
+gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
+gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
+gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/gin-gonic/gin/internal/json/json.go b/vendor/github.com/gin-gonic/gin/internal/json/json.go
new file mode 100644
index 0000000..480e8bf
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/internal/json/json.go
@@ -0,0 +1,22 @@
+// Copyright 2017 Bo-Yi Wu. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// +build !jsoniter
+
+package json
+
+import "encoding/json"
+
+var (
+ // Marshal is exported by gin/json package.
+ Marshal = json.Marshal
+ // Unmarshal is exported by gin/json package.
+ Unmarshal = json.Unmarshal
+ // MarshalIndent is exported by gin/json package.
+ MarshalIndent = json.MarshalIndent
+ // NewDecoder is exported by gin/json package.
+ NewDecoder = json.NewDecoder
+ // NewEncoder is exported by gin/json package.
+ NewEncoder = json.NewEncoder
+)
diff --git a/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go b/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go
new file mode 100644
index 0000000..fabd7b8
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/internal/json/jsoniter.go
@@ -0,0 +1,23 @@
+// Copyright 2017 Bo-Yi Wu. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// +build jsoniter
+
+package json
+
+import "github.com/json-iterator/go"
+
+var (
+ json = jsoniter.ConfigCompatibleWithStandardLibrary
+ // Marshal is exported by gin/json package.
+ Marshal = json.Marshal
+ // Unmarshal is exported by gin/json package.
+ Unmarshal = json.Unmarshal
+ // MarshalIndent is exported by gin/json package.
+ MarshalIndent = json.MarshalIndent
+ // NewDecoder is exported by gin/json package.
+ NewDecoder = json.NewDecoder
+ // NewEncoder is exported by gin/json package.
+ NewEncoder = json.NewEncoder
+)
diff --git a/vendor/github.com/gin-gonic/gin/json/json.go b/vendor/github.com/gin-gonic/gin/json/json.go
deleted file mode 100644
index aa76aa3..0000000
--- a/vendor/github.com/gin-gonic/gin/json/json.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 Bo-Yi Wu. All rights reserved.
-// Use of this source code is governed by a MIT style
-// license that can be found in the LICENSE file.
-
-// +build !jsoniter
-
-package json
-
-import "encoding/json"
-
-var (
- Marshal = json.Marshal
- MarshalIndent = json.MarshalIndent
- NewDecoder = json.NewDecoder
-)
diff --git a/vendor/github.com/gin-gonic/gin/json/jsoniter.go b/vendor/github.com/gin-gonic/gin/json/jsoniter.go
deleted file mode 100644
index ffe1424..0000000
--- a/vendor/github.com/gin-gonic/gin/json/jsoniter.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 Bo-Yi Wu. All rights reserved.
-// Use of this source code is governed by a MIT style
-// license that can be found in the LICENSE file.
-
-// +build jsoniter
-
-package json
-
-import "github.com/json-iterator/go"
-
-var (
- json = jsoniter.ConfigCompatibleWithStandardLibrary
- Marshal = json.Marshal
- MarshalIndent = json.MarshalIndent
- NewDecoder = json.NewDecoder
-)
diff --git a/vendor/github.com/gin-gonic/gin/logger.go b/vendor/github.com/gin-gonic/gin/logger.go
index 1a8df60..5ab4639 100644
--- a/vendor/github.com/gin-gonic/gin/logger.go
+++ b/vendor/github.com/gin-gonic/gin/logger.go
@@ -14,21 +14,151 @@ import (
"github.com/mattn/go-isatty"
)
+type consoleColorModeValue int
+
+const (
+ autoColor consoleColorModeValue = iota
+ disableColor
+ forceColor
+)
+
var (
- green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
- white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
- yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
- red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
- blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
- magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
- cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
- reset = string([]byte{27, 91, 48, 109})
- disableColor = false
+ green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
+ white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
+ yellow = string([]byte{27, 91, 57, 48, 59, 52, 51, 109})
+ red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
+ blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
+ magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
+ cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
+ reset = string([]byte{27, 91, 48, 109})
+ consoleColorMode = autoColor
)
+// LoggerConfig defines the config for Logger middleware.
+type LoggerConfig struct {
+ // Optional. Default value is gin.defaultLogFormatter
+ Formatter LogFormatter
+
+ // Output is a writer where logs are written.
+ // Optional. Default value is gin.DefaultWriter.
+ Output io.Writer
+
+ // SkipPaths is a url path array which logs are not written.
+ // Optional.
+ SkipPaths []string
+}
+
+// LogFormatter gives the signature of the formatter function passed to LoggerWithFormatter
+type LogFormatter func(params LogFormatterParams) string
+
+// LogFormatterParams is the structure any formatter will be handed when time to log comes
+type LogFormatterParams struct {
+ Request *http.Request
+
+ // TimeStamp shows the time after the server returns a response.
+ TimeStamp time.Time
+ // StatusCode is HTTP response code.
+ StatusCode int
+ // Latency is how much time the server cost to process a certain request.
+ Latency time.Duration
+ // ClientIP equals Context's ClientIP method.
+ ClientIP string
+ // Method is the HTTP method given to the request.
+ Method string
+ // Path is a path the client requests.
+ Path string
+ // ErrorMessage is set if error has occurred in processing the request.
+ ErrorMessage string
+ // isTerm shows whether does gin's output descriptor refers to a terminal.
+ isTerm bool
+ // BodySize is the size of the Response Body
+ BodySize int
+ // Keys are the keys set on the request's context.
+ Keys map[string]interface{}
+}
+
+// StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal.
+func (p *LogFormatterParams) StatusCodeColor() string {
+ code := p.StatusCode
+
+ switch {
+ case code >= http.StatusOK && code < http.StatusMultipleChoices:
+ return green
+ case code >= http.StatusMultipleChoices && code < http.StatusBadRequest:
+ return white
+ case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
+ return yellow
+ default:
+ return red
+ }
+}
+
+// MethodColor is the ANSI color for appropriately logging http method to a terminal.
+func (p *LogFormatterParams) MethodColor() string {
+ method := p.Method
+
+ switch method {
+ case "GET":
+ return blue
+ case "POST":
+ return cyan
+ case "PUT":
+ return yellow
+ case "DELETE":
+ return red
+ case "PATCH":
+ return green
+ case "HEAD":
+ return magenta
+ case "OPTIONS":
+ return white
+ default:
+ return reset
+ }
+}
+
+// ResetColor resets all escape attributes.
+func (p *LogFormatterParams) ResetColor() string {
+ return reset
+}
+
+// IsOutputColor indicates whether can colors be outputted to the log.
+func (p *LogFormatterParams) IsOutputColor() bool {
+ return consoleColorMode == forceColor || (consoleColorMode == autoColor && p.isTerm)
+}
+
+// defaultLogFormatter is the default log format function Logger middleware uses.
+var defaultLogFormatter = func(param LogFormatterParams) string {
+ var statusColor, methodColor, resetColor string
+ if param.IsOutputColor() {
+ statusColor = param.StatusCodeColor()
+ methodColor = param.MethodColor()
+ resetColor = param.ResetColor()
+ }
+
+ if param.Latency > time.Minute {
+ // Truncate in a golang < 1.8 safe way
+ param.Latency = param.Latency - param.Latency%time.Second
+ }
+ return fmt.Sprintf("[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
+ param.TimeStamp.Format("2006/01/02 - 15:04:05"),
+ statusColor, param.StatusCode, resetColor,
+ param.Latency,
+ param.ClientIP,
+ methodColor, param.Method, resetColor,
+ param.Path,
+ param.ErrorMessage,
+ )
+}
+
// DisableConsoleColor disables color output in the console.
func DisableConsoleColor() {
- disableColor = true
+ consoleColorMode = disableColor
+}
+
+// ForceConsoleColor force color output in the console.
+func ForceConsoleColor() {
+ consoleColorMode = forceColor
}
// ErrorLogger returns a handlerfunc for any error type.
@@ -50,17 +180,43 @@ func ErrorLoggerT(typ ErrorType) HandlerFunc {
// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
// By default gin.DefaultWriter = os.Stdout.
func Logger() HandlerFunc {
- return LoggerWithWriter(DefaultWriter)
+ return LoggerWithConfig(LoggerConfig{})
}
-// LoggerWithWriter instance a Logger middleware with the specified writter buffer.
+// LoggerWithFormatter instance a Logger middleware with the specified log format function.
+func LoggerWithFormatter(f LogFormatter) HandlerFunc {
+ return LoggerWithConfig(LoggerConfig{
+ Formatter: f,
+ })
+}
+
+// LoggerWithWriter instance a Logger middleware with the specified writer buffer.
// Example: os.Stdout, a file opened in write mode, a socket...
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
+ return LoggerWithConfig(LoggerConfig{
+ Output: out,
+ SkipPaths: notlogged,
+ })
+}
+
+// LoggerWithConfig instance a Logger middleware with config.
+func LoggerWithConfig(conf LoggerConfig) HandlerFunc {
+ formatter := conf.Formatter
+ if formatter == nil {
+ formatter = defaultLogFormatter
+ }
+
+ out := conf.Output
+ if out == nil {
+ out = DefaultWriter
+ }
+
+ notlogged := conf.SkipPaths
+
isTerm := true
- if w, ok := out.(*os.File); !ok ||
- (os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd()))) ||
- disableColor {
+ if w, ok := out.(*os.File); !ok || os.Getenv("TERM") == "dumb" ||
+ (!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd())) {
isTerm = false
}
@@ -85,68 +241,30 @@ func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
// Log only when path is not being skipped
if _, ok := skip[path]; !ok {
- // Stop timer
- end := time.Now()
- latency := end.Sub(start)
-
- clientIP := c.ClientIP()
- method := c.Request.Method
- statusCode := c.Writer.Status()
- var statusColor, methodColor, resetColor string
- if isTerm {
- statusColor = colorForStatus(statusCode)
- methodColor = colorForMethod(method)
- resetColor = reset
+ param := LogFormatterParams{
+ Request: c.Request,
+ isTerm: isTerm,
+ Keys: c.Keys,
}
- comment := c.Errors.ByType(ErrorTypePrivate).String()
+
+ // Stop timer
+ param.TimeStamp = time.Now()
+ param.Latency = param.TimeStamp.Sub(start)
+
+ param.ClientIP = c.ClientIP()
+ param.Method = c.Request.Method
+ param.StatusCode = c.Writer.Status()
+ param.ErrorMessage = c.Errors.ByType(ErrorTypePrivate).String()
+
+ param.BodySize = c.Writer.Size()
if raw != "" {
path = path + "?" + raw
}
- fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
- end.Format("2006/01/02 - 15:04:05"),
- statusColor, statusCode, resetColor,
- latency,
- clientIP,
- methodColor, method, resetColor,
- path,
- comment,
- )
- }
- }
-}
+ param.Path = path
-func colorForStatus(code int) string {
- switch {
- case code >= http.StatusOK && code < http.StatusMultipleChoices:
- return green
- case code >= http.StatusMultipleChoices && code < http.StatusBadRequest:
- return white
- case code >= http.StatusBadRequest && code < http.StatusInternalServerError:
- return yellow
- default:
- return red
- }
-}
-
-func colorForMethod(method string) string {
- switch method {
- case "GET":
- return blue
- case "POST":
- return cyan
- case "PUT":
- return yellow
- case "DELETE":
- return red
- case "PATCH":
- return green
- case "HEAD":
- return magenta
- case "OPTIONS":
- return white
- default:
- return reset
+ fmt.Fprint(out, formatter(param))
+ }
}
}
diff --git a/vendor/github.com/gin-gonic/gin/mode.go b/vendor/github.com/gin-gonic/gin/mode.go
index 9df4e45..8aa84aa 100644
--- a/vendor/github.com/gin-gonic/gin/mode.go
+++ b/vendor/github.com/gin-gonic/gin/mode.go
@@ -11,12 +11,16 @@ import (
"github.com/gin-gonic/gin/binding"
)
-const ENV_GIN_MODE = "GIN_MODE"
+// EnvGinMode indicates environment name for gin mode.
+const EnvGinMode = "GIN_MODE"
const (
- DebugMode = "debug"
+ // DebugMode indicates gin mode is debug.
+ DebugMode = "debug"
+ // ReleaseMode indicates gin mode is release.
ReleaseMode = "release"
- TestMode = "test"
+ // TestMode indicates gin mode is test.
+ TestMode = "test"
)
const (
debugCode = iota
@@ -24,7 +28,7 @@ const (
testCode
)
-// DefaultWriter is the default io.Writer used the Gin for debug output and
+// DefaultWriter is the default io.Writer used by Gin for debug output and
// middleware output like Logger() or Recovery().
// Note that both Logger and Recovery provides custom ways to configure their
// output io.Writer.
@@ -32,16 +36,19 @@ const (
// import "github.com/mattn/go-colorable"
// gin.DefaultWriter = colorable.NewColorableStdout()
var DefaultWriter io.Writer = os.Stdout
+
+// DefaultErrorWriter is the default io.Writer used by Gin to debug errors
var DefaultErrorWriter io.Writer = os.Stderr
var ginMode = debugCode
var modeName = DebugMode
func init() {
- mode := os.Getenv(ENV_GIN_MODE)
+ mode := os.Getenv(EnvGinMode)
SetMode(mode)
}
+// SetMode sets gin mode according to input string.
func SetMode(value string) {
switch value {
case DebugMode, "":
@@ -59,14 +66,18 @@ func SetMode(value string) {
modeName = value
}
+// DisableBindValidation closes the default validator.
func DisableBindValidation() {
binding.Validator = nil
}
+// EnableJsonDecoderUseNumber sets true for binding.EnableDecoderUseNumberto to
+// call the UseNumber method on the JSON Decoder instance.
func EnableJsonDecoderUseNumber() {
binding.EnableDecoderUseNumber = true
}
+// Mode returns currently gin mode.
func Mode() string {
return modeName
}
diff --git a/vendor/github.com/gin-gonic/gin/recovery.go b/vendor/github.com/gin-gonic/gin/recovery.go
index 61c5bd5..bc946c0 100644
--- a/vendor/github.com/gin-gonic/gin/recovery.go
+++ b/vendor/github.com/gin-gonic/gin/recovery.go
@@ -10,9 +10,12 @@ import (
"io"
"io/ioutil"
"log"
+ "net"
"net/http"
"net/http/httputil"
+ "os"
"runtime"
+ "strings"
"time"
)
@@ -37,12 +40,44 @@ func RecoveryWithWriter(out io.Writer) HandlerFunc {
return func(c *Context) {
defer func() {
if err := recover(); err != nil {
+ // Check for a broken connection, as it is not really a
+ // condition that warrants a panic stack trace.
+ var brokenPipe bool
+ if ne, ok := err.(*net.OpError); ok {
+ if se, ok := ne.Err.(*os.SyscallError); ok {
+ if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
+ brokenPipe = true
+ }
+ }
+ }
if logger != nil {
stack := stack(3)
- httprequest, _ := httputil.DumpRequest(c.Request, false)
- logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s", timeFormat(time.Now()), string(httprequest), err, stack, reset)
+ httpRequest, _ := httputil.DumpRequest(c.Request, false)
+ headers := strings.Split(string(httpRequest), "\r\n")
+ for idx, header := range headers {
+ current := strings.Split(header, ":")
+ if current[0] == "Authorization" {
+ headers[idx] = current[0] + ": *"
+ }
+ }
+ if brokenPipe {
+ logger.Printf("%s\n%s%s", err, string(httpRequest), reset)
+ } else if IsDebugging() {
+ logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s",
+ timeFormat(time.Now()), strings.Join(headers, "\r\n"), err, stack, reset)
+ } else {
+ logger.Printf("[Recovery] %s panic recovered:\n%s\n%s%s",
+ timeFormat(time.Now()), err, stack, reset)
+ }
+ }
+
+ // If the connection is dead, we can't write a status to it.
+ if brokenPipe {
+ c.Error(err.(error)) // nolint: errcheck
+ c.Abort()
+ } else {
+ c.AbortWithStatus(http.StatusInternalServerError)
}
- c.AbortWithStatus(http.StatusInternalServerError)
}
}()
c.Next()
@@ -100,8 +135,8 @@ func function(pc uintptr) []byte {
// *T.ptrmethod
// Also the package path might contains dot (e.g. code.google.com/...),
// so first eliminate the path prefix
- if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
- name = name[lastslash+1:]
+ if lastSlash := bytes.LastIndex(name, slash); lastSlash >= 0 {
+ name = name[lastSlash+1:]
}
if period := bytes.Index(name, dot); period >= 0 {
name = name[period+1:]
diff --git a/vendor/github.com/gin-gonic/gin/render/data.go b/vendor/github.com/gin-gonic/gin/render/data.go
index 3319491..6ba657b 100644
--- a/vendor/github.com/gin-gonic/gin/render/data.go
+++ b/vendor/github.com/gin-gonic/gin/render/data.go
@@ -6,6 +6,7 @@ package render
import "net/http"
+// Data contains ContentType and bytes data.
type Data struct {
ContentType string
Data []byte
@@ -18,6 +19,7 @@ func (r Data) Render(w http.ResponseWriter) (err error) {
return
}
+// WriteContentType (Data) writes custom ContentType.
func (r Data) WriteContentType(w http.ResponseWriter) {
writeContentType(w, []string{r.ContentType})
}
diff --git a/vendor/github.com/gin-gonic/gin/render/html.go b/vendor/github.com/gin-gonic/gin/render/html.go
index 1e3be65..6696ece 100644
--- a/vendor/github.com/gin-gonic/gin/render/html.go
+++ b/vendor/github.com/gin-gonic/gin/render/html.go
@@ -9,20 +9,27 @@ import (
"net/http"
)
+// Delims represents a set of Left and Right delimiters for HTML template rendering.
type Delims struct {
- Left string
+ // Left delimiter, defaults to {{.
+ Left string
+ // Right delimiter, defaults to }}.
Right string
}
+// HTMLRender interface is to be implemented by HTMLProduction and HTMLDebug.
type HTMLRender interface {
+ // Instance returns an HTML instance.
Instance(string, interface{}) Render
}
+// HTMLProduction contains template reference and its delims.
type HTMLProduction struct {
Template *template.Template
Delims Delims
}
+// HTMLDebug contains template delims and pattern and function with file list.
type HTMLDebug struct {
Files []string
Glob string
@@ -30,6 +37,7 @@ type HTMLDebug struct {
FuncMap template.FuncMap
}
+// HTML contains template reference and its name with given interface object.
type HTML struct {
Template *template.Template
Name string
@@ -38,6 +46,7 @@ type HTML struct {
var htmlContentType = []string{"text/html; charset=utf-8"}
+// Instance (HTMLProduction) returns an HTML instance which it realizes Render interface.
func (r HTMLProduction) Instance(name string, data interface{}) Render {
return HTML{
Template: r.Template,
@@ -46,6 +55,7 @@ func (r HTMLProduction) Instance(name string, data interface{}) Render {
}
}
+// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface.
func (r HTMLDebug) Instance(name string, data interface{}) Render {
return HTML{
Template: r.loadTemplate(),
@@ -66,6 +76,7 @@ func (r HTMLDebug) loadTemplate() *template.Template {
panic("the HTML debug render was created without files or glob pattern")
}
+// Render (HTML) executes template and writes its result with custom ContentType for response.
func (r HTML) Render(w http.ResponseWriter) error {
r.WriteContentType(w)
@@ -75,6 +86,7 @@ func (r HTML) Render(w http.ResponseWriter) error {
return r.Template.ExecuteTemplate(w, r.Name, r.Data)
}
+// WriteContentType (HTML) writes HTML ContentType.
func (r HTML) WriteContentType(w http.ResponseWriter) {
writeContentType(w, htmlContentType)
}
diff --git a/vendor/github.com/gin-gonic/gin/render/json.go b/vendor/github.com/gin-gonic/gin/render/json.go
old mode 100755
new mode 100644
index 6e5089a..18f27fa
--- a/vendor/github.com/gin-gonic/gin/render/json.go
+++ b/vendor/github.com/gin-gonic/gin/render/json.go
@@ -10,37 +10,49 @@ import (
"html/template"
"net/http"
- "github.com/gin-gonic/gin/json"
+ "github.com/gin-gonic/gin/internal/json"
)
+// JSON contains the given interface object.
type JSON struct {
Data interface{}
}
+// IndentedJSON contains the given interface object.
type IndentedJSON struct {
Data interface{}
}
+// SecureJSON contains the given interface object and its prefix.
type SecureJSON struct {
Prefix string
Data interface{}
}
+// JsonpJSON contains the given interface object its callback.
type JsonpJSON struct {
Callback string
Data interface{}
}
+// AsciiJSON contains the given interface object.
type AsciiJSON struct {
Data interface{}
}
+// SecureJSONPrefix is a string which represents SecureJSON prefix.
type SecureJSONPrefix string
+// PureJSON contains the given interface object.
+type PureJSON struct {
+ Data interface{}
+}
+
var jsonContentType = []string{"application/json; charset=utf-8"}
var jsonpContentType = []string{"application/javascript; charset=utf-8"}
var jsonAsciiContentType = []string{"application/json"}
+// Render (JSON) writes data with custom ContentType.
func (r JSON) Render(w http.ResponseWriter) (err error) {
if err = WriteJSON(w, r.Data); err != nil {
panic(err)
@@ -48,34 +60,39 @@ func (r JSON) Render(w http.ResponseWriter) (err error) {
return
}
+// WriteContentType (JSON) writes JSON ContentType.
func (r JSON) WriteContentType(w http.ResponseWriter) {
writeContentType(w, jsonContentType)
}
+// WriteJSON marshals the given interface object and writes it with custom ContentType.
func WriteJSON(w http.ResponseWriter, obj interface{}) error {
writeContentType(w, jsonContentType)
jsonBytes, err := json.Marshal(obj)
if err != nil {
return err
}
- w.Write(jsonBytes)
- return nil
+ _, err = w.Write(jsonBytes)
+ return err
}
+// Render (IndentedJSON) marshals the given interface object and writes it with custom ContentType.
func (r IndentedJSON) Render(w http.ResponseWriter) error {
r.WriteContentType(w)
jsonBytes, err := json.MarshalIndent(r.Data, "", " ")
if err != nil {
return err
}
- w.Write(jsonBytes)
- return nil
+ _, err = w.Write(jsonBytes)
+ return err
}
+// WriteContentType (IndentedJSON) writes JSON ContentType.
func (r IndentedJSON) WriteContentType(w http.ResponseWriter) {
writeContentType(w, jsonContentType)
}
+// Render (SecureJSON) marshals the given interface object and writes it with custom ContentType.
func (r SecureJSON) Render(w http.ResponseWriter) error {
r.WriteContentType(w)
jsonBytes, err := json.Marshal(r.Data)
@@ -84,16 +101,21 @@ func (r SecureJSON) Render(w http.ResponseWriter) error {
}
// if the jsonBytes is array values
if bytes.HasPrefix(jsonBytes, []byte("[")) && bytes.HasSuffix(jsonBytes, []byte("]")) {
- w.Write([]byte(r.Prefix))
+ _, err = w.Write([]byte(r.Prefix))
+ if err != nil {
+ return err
+ }
}
- w.Write(jsonBytes)
- return nil
+ _, err = w.Write(jsonBytes)
+ return err
}
+// WriteContentType (SecureJSON) writes JSON ContentType.
func (r SecureJSON) WriteContentType(w http.ResponseWriter) {
writeContentType(w, jsonContentType)
}
+// Render (JsonpJSON) marshals the given interface object and writes it and its callback with custom ContentType.
func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
r.WriteContentType(w)
ret, err := json.Marshal(r.Data)
@@ -102,23 +124,37 @@ func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
}
if r.Callback == "" {
- w.Write(ret)
- return nil
+ _, err = w.Write(ret)
+ return err
}
callback := template.JSEscapeString(r.Callback)
- w.Write([]byte(callback))
- w.Write([]byte("("))
- w.Write(ret)
- w.Write([]byte(")"))
+ _, err = w.Write([]byte(callback))
+ if err != nil {
+ return err
+ }
+ _, err = w.Write([]byte("("))
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(ret)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write([]byte(")"))
+ if err != nil {
+ return err
+ }
return nil
}
+// WriteContentType (JsonpJSON) writes Javascript ContentType.
func (r JsonpJSON) WriteContentType(w http.ResponseWriter) {
writeContentType(w, jsonpContentType)
}
+// Render (AsciiJSON) marshals the given interface object and writes it with custom ContentType.
func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
r.WriteContentType(w)
ret, err := json.Marshal(r.Data)
@@ -128,19 +164,31 @@ func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
var buffer bytes.Buffer
for _, r := range string(ret) {
- cvt := ""
- if r < 128 {
- cvt = string(r)
- } else {
+ cvt := string(r)
+ if r >= 128 {
cvt = fmt.Sprintf("\\u%04x", int64(r))
}
buffer.WriteString(cvt)
}
- w.Write(buffer.Bytes())
- return nil
+ _, err = w.Write(buffer.Bytes())
+ return err
}
+// WriteContentType (AsciiJSON) writes JSON ContentType.
func (r AsciiJSON) WriteContentType(w http.ResponseWriter) {
writeContentType(w, jsonAsciiContentType)
}
+
+// Render (PureJSON) writes custom ContentType and encodes the given interface object.
+func (r PureJSON) Render(w http.ResponseWriter) error {
+ r.WriteContentType(w)
+ encoder := json.NewEncoder(w)
+ encoder.SetEscapeHTML(false)
+ return encoder.Encode(r.Data)
+}
+
+// WriteContentType (PureJSON) writes custom ContentType.
+func (r PureJSON) WriteContentType(w http.ResponseWriter) {
+ writeContentType(w, jsonContentType)
+}
diff --git a/vendor/github.com/gin-gonic/gin/render/msgpack.go b/vendor/github.com/gin-gonic/gin/render/msgpack.go
index e6c13e5..dc681fc 100644
--- a/vendor/github.com/gin-gonic/gin/render/msgpack.go
+++ b/vendor/github.com/gin-gonic/gin/render/msgpack.go
@@ -10,22 +10,26 @@ import (
"github.com/ugorji/go/codec"
)
+// MsgPack contains the given interface object.
type MsgPack struct {
Data interface{}
}
var msgpackContentType = []string{"application/msgpack; charset=utf-8"}
+// WriteContentType (MsgPack) writes MsgPack ContentType.
func (r MsgPack) WriteContentType(w http.ResponseWriter) {
writeContentType(w, msgpackContentType)
}
+// Render (MsgPack) encodes the given interface object and writes data with custom ContentType.
func (r MsgPack) Render(w http.ResponseWriter) error {
return WriteMsgPack(w, r.Data)
}
+// WriteMsgPack writes MsgPack ContentType and encodes the given interface object.
func WriteMsgPack(w http.ResponseWriter, obj interface{}) error {
writeContentType(w, msgpackContentType)
- var h codec.Handle = new(codec.MsgpackHandle)
- return codec.NewEncoder(w, h).Encode(obj)
+ var mh codec.MsgpackHandle
+ return codec.NewEncoder(w, &mh).Encode(obj)
}
diff --git a/vendor/github.com/gin-gonic/gin/render/protobuf.go b/vendor/github.com/gin-gonic/gin/render/protobuf.go
new file mode 100644
index 0000000..15aca99
--- /dev/null
+++ b/vendor/github.com/gin-gonic/gin/render/protobuf.go
@@ -0,0 +1,36 @@
+// Copyright 2018 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package render
+
+import (
+ "net/http"
+
+ "github.com/golang/protobuf/proto"
+)
+
+// ProtoBuf contains the given interface object.
+type ProtoBuf struct {
+ Data interface{}
+}
+
+var protobufContentType = []string{"application/x-protobuf"}
+
+// Render (ProtoBuf) marshals the given interface object and writes data with custom ContentType.
+func (r ProtoBuf) Render(w http.ResponseWriter) error {
+ r.WriteContentType(w)
+
+ bytes, err := proto.Marshal(r.Data.(proto.Message))
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(bytes)
+ return err
+}
+
+// WriteContentType (ProtoBuf) writes ProtoBuf ContentType.
+func (r ProtoBuf) WriteContentType(w http.ResponseWriter) {
+ writeContentType(w, protobufContentType)
+}
diff --git a/vendor/github.com/gin-gonic/gin/render/reader.go b/vendor/github.com/gin-gonic/gin/render/reader.go
index be2132c..312af74 100644
--- a/vendor/github.com/gin-gonic/gin/render/reader.go
+++ b/vendor/github.com/gin-gonic/gin/render/reader.go
@@ -1,3 +1,7 @@
+// Copyright 2018 Gin Core Team. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
package render
import (
@@ -6,6 +10,7 @@ import (
"strconv"
)
+// Reader contains the IO reader and its length, and custom ContentType and other headers.
type Reader struct {
ContentType string
ContentLength int64
@@ -22,15 +27,17 @@ func (r Reader) Render(w http.ResponseWriter) (err error) {
return
}
+// WriteContentType (Reader) writes custom ContentType.
func (r Reader) WriteContentType(w http.ResponseWriter) {
writeContentType(w, []string{r.ContentType})
}
+// writeHeaders writes custom Header.
func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) {
header := w.Header()
for k, v := range headers {
- if val := header[k]; len(val) == 0 {
- header[k] = []string{v}
+ if header.Get(k) == "" {
+ header.Set(k, v)
}
}
}
diff --git a/vendor/github.com/gin-gonic/gin/render/redirect.go b/vendor/github.com/gin-gonic/gin/render/redirect.go
index a0634f5..c006691 100644
--- a/vendor/github.com/gin-gonic/gin/render/redirect.go
+++ b/vendor/github.com/gin-gonic/gin/render/redirect.go
@@ -9,20 +9,21 @@ import (
"net/http"
)
+// Redirect contains the http request reference and redirects status code and location.
type Redirect struct {
Code int
Request *http.Request
Location string
}
+// Render (Redirect) redirects the http request to new location and writes redirect response.
func (r Redirect) Render(w http.ResponseWriter) error {
- // todo(thinkerou): go1.6 not support StatusPermanentRedirect(308)
- // when we upgrade go version we can use http.StatusPermanentRedirect
- if (r.Code < 300 || r.Code > 308) && r.Code != 201 {
+ if (r.Code < http.StatusMultipleChoices || r.Code > http.StatusPermanentRedirect) && r.Code != http.StatusCreated {
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
}
http.Redirect(w, r.Request, r.Location, r.Code)
return nil
}
+// WriteContentType (Redirect) don't write any ContentType.
func (r Redirect) WriteContentType(http.ResponseWriter) {}
diff --git a/vendor/github.com/gin-gonic/gin/render/render.go b/vendor/github.com/gin-gonic/gin/render/render.go
old mode 100755
new mode 100644
index 4ff1c7b..abfc79f
--- a/vendor/github.com/gin-gonic/gin/render/render.go
+++ b/vendor/github.com/gin-gonic/gin/render/render.go
@@ -6,8 +6,11 @@ package render
import "net/http"
+// Render interface is to be implemented by JSON, XML, HTML, YAML and so on.
type Render interface {
+ // Render writes data with custom ContentType.
Render(http.ResponseWriter) error
+ // WriteContentType writes custom ContentType.
WriteContentType(w http.ResponseWriter)
}
@@ -27,6 +30,7 @@ var (
_ Render = MsgPack{}
_ Render = Reader{}
_ Render = AsciiJSON{}
+ _ Render = ProtoBuf{}
)
func writeContentType(w http.ResponseWriter, value []string) {
diff --git a/vendor/github.com/gin-gonic/gin/render/text.go b/vendor/github.com/gin-gonic/gin/render/text.go
index 74cd26b..4e52d4c 100644
--- a/vendor/github.com/gin-gonic/gin/render/text.go
+++ b/vendor/github.com/gin-gonic/gin/render/text.go
@@ -10,6 +10,7 @@ import (
"net/http"
)
+// String contains the given interface object slice and its format.
type String struct {
Format string
Data []interface{}
@@ -17,20 +18,23 @@ type String struct {
var plainContentType = []string{"text/plain; charset=utf-8"}
+// Render (String) writes data with custom ContentType.
func (r String) Render(w http.ResponseWriter) error {
- WriteString(w, r.Format, r.Data)
- return nil
+ return WriteString(w, r.Format, r.Data)
}
+// WriteContentType (String) writes Plain ContentType.
func (r String) WriteContentType(w http.ResponseWriter) {
writeContentType(w, plainContentType)
}
-func WriteString(w http.ResponseWriter, format string, data []interface{}) {
+// WriteString writes data according to its format and write custom ContentType.
+func WriteString(w http.ResponseWriter, format string, data []interface{}) (err error) {
writeContentType(w, plainContentType)
if len(data) > 0 {
- fmt.Fprintf(w, format, data...)
- } else {
- io.WriteString(w, format)
+ _, err = fmt.Fprintf(w, format, data...)
+ return
}
+ _, err = io.WriteString(w, format)
+ return
}
diff --git a/vendor/github.com/gin-gonic/gin/render/xml.go b/vendor/github.com/gin-gonic/gin/render/xml.go
index cff1ac3..cc5390a 100644
--- a/vendor/github.com/gin-gonic/gin/render/xml.go
+++ b/vendor/github.com/gin-gonic/gin/render/xml.go
@@ -9,17 +9,20 @@ import (
"net/http"
)
+// XML contains the given interface object.
type XML struct {
Data interface{}
}
var xmlContentType = []string{"application/xml; charset=utf-8"}
+// Render (XML) encodes the given interface object and writes data with custom ContentType.
func (r XML) Render(w http.ResponseWriter) error {
r.WriteContentType(w)
return xml.NewEncoder(w).Encode(r.Data)
}
+// WriteContentType (XML) writes XML ContentType for response.
func (r XML) WriteContentType(w http.ResponseWriter) {
writeContentType(w, xmlContentType)
}
diff --git a/vendor/github.com/gin-gonic/gin/render/yaml.go b/vendor/github.com/gin-gonic/gin/render/yaml.go
index 25d0ebd..0df7836 100644
--- a/vendor/github.com/gin-gonic/gin/render/yaml.go
+++ b/vendor/github.com/gin-gonic/gin/render/yaml.go
@@ -10,12 +10,14 @@ import (
"gopkg.in/yaml.v2"
)
+// YAML contains the given interface object.
type YAML struct {
Data interface{}
}
var yamlContentType = []string{"application/x-yaml; charset=utf-8"}
+// Render (YAML) marshals the given interface object and writes data with custom ContentType.
func (r YAML) Render(w http.ResponseWriter) error {
r.WriteContentType(w)
@@ -24,10 +26,11 @@ func (r YAML) Render(w http.ResponseWriter) error {
return err
}
- w.Write(bytes)
- return nil
+ _, err = w.Write(bytes)
+ return err
}
+// WriteContentType (YAML) writes YAML ContentType for response.
func (r YAML) WriteContentType(w http.ResponseWriter) {
writeContentType(w, yamlContentType)
}
diff --git a/vendor/github.com/gin-gonic/gin/response_writer.go b/vendor/github.com/gin-gonic/gin/response_writer.go
index 923b53f..2682668 100644
--- a/vendor/github.com/gin-gonic/gin/response_writer.go
+++ b/vendor/github.com/gin-gonic/gin/response_writer.go
@@ -16,7 +16,8 @@ const (
defaultStatus = http.StatusOK
)
-type responseWriterBase interface {
+// ResponseWriter ...
+type ResponseWriter interface {
http.ResponseWriter
http.Hijacker
http.Flusher
@@ -37,6 +38,9 @@ type responseWriterBase interface {
// Forces to write the http header (status code + headers).
WriteHeaderNow()
+
+ // get the http.Pusher for server push
+ Pusher() http.Pusher
}
type responseWriter struct {
@@ -113,3 +117,10 @@ func (w *responseWriter) Flush() {
w.WriteHeaderNow()
w.ResponseWriter.(http.Flusher).Flush()
}
+
+func (w *responseWriter) Pusher() (pusher http.Pusher) {
+ if pusher, ok := w.ResponseWriter.(http.Pusher); ok {
+ return pusher
+ }
+ return nil
+}
diff --git a/vendor/github.com/gin-gonic/gin/response_writer_1.8.go b/vendor/github.com/gin-gonic/gin/response_writer_1.8.go
deleted file mode 100644
index 527c003..0000000
--- a/vendor/github.com/gin-gonic/gin/response_writer_1.8.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// +build go1.8
-
-// Copyright 2018 Gin Core Team. All rights reserved.
-// Use of this source code is governed by a MIT style
-// license that can be found in the LICENSE file.
-
-package gin
-
-import (
- "net/http"
-)
-
-// ResponseWriter ...
-type ResponseWriter interface {
- responseWriterBase
- // get the http.Pusher for server push
- Pusher() http.Pusher
-}
-
-func (w *responseWriter) Pusher() (pusher http.Pusher) {
- if pusher, ok := w.ResponseWriter.(http.Pusher); ok {
- return pusher
- }
- return nil
-}
diff --git a/vendor/github.com/gin-gonic/gin/routergroup.go b/vendor/github.com/gin-gonic/gin/routergroup.go
index 876a61b..a1e6c92 100644
--- a/vendor/github.com/gin-gonic/gin/routergroup.go
+++ b/vendor/github.com/gin-gonic/gin/routergroup.go
@@ -11,11 +11,13 @@ import (
"strings"
)
+// IRouter defines all router handle interface includes single and group router.
type IRouter interface {
IRoutes
Group(string, ...HandlerFunc) *RouterGroup
}
+// IRoutes defines all router handle interface.
type IRoutes interface {
Use(...HandlerFunc) IRoutes
@@ -34,8 +36,8 @@ type IRoutes interface {
StaticFS(string, http.FileSystem) IRoutes
}
-// RouterGroup is used internally to configure router, a RouterGroup is associated with a prefix
-// and an array of handlers (middleware).
+// RouterGroup is used internally to configure router, a RouterGroup is associated with
+// a prefix and an array of handlers (middleware).
type RouterGroup struct {
Handlers HandlersChain
basePath string
@@ -45,14 +47,14 @@ type RouterGroup struct {
var _ IRouter = &RouterGroup{}
-// Use adds middleware to the group, see example code in github.
+// Use adds middleware to the group, see example code in GitHub.
func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {
group.Handlers = append(group.Handlers, middleware...)
return group.returnObj()
}
-// Group creates a new router group. You should add all the routes that have common middlwares or the same path prefix.
-// For example, all the routes that use a common middlware for authorization could be grouped.
+// Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix.
+// For example, all the routes that use a common middleware for authorization could be grouped.
func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
return &RouterGroup{
Handlers: group.combineHandlers(handlers),
@@ -61,6 +63,8 @@ func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *R
}
}
+// BasePath returns the base path of router group.
+// For example, if v := router.Group("/rest/n/v1/api"), v.BasePath() is "/rest/n/v1/api".
func (group *RouterGroup) BasePath() string {
return group.basePath
}
@@ -74,7 +78,7 @@ func (group *RouterGroup) handle(httpMethod, relativePath string, handlers Handl
// Handle registers a new request handle and middleware with the given path and method.
// The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes.
-// See the example code in github.
+// See the example code in GitHub.
//
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
// functions can be used.
@@ -181,11 +185,22 @@ func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRou
func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc {
absolutePath := group.calculateAbsolutePath(relativePath)
fileServer := http.StripPrefix(absolutePath, http.FileServer(fs))
- _, nolisting := fs.(*onlyfilesFS)
+
return func(c *Context) {
- if nolisting {
+ if _, nolisting := fs.(*onlyfilesFS); nolisting {
c.Writer.WriteHeader(http.StatusNotFound)
}
+
+ file := c.Param("filepath")
+ // Check if file exists and/or if we have permission to access it
+ if _, err := fs.Open(file); err != nil {
+ c.Writer.WriteHeader(http.StatusNotFound)
+ c.handlers = group.engine.noRoute
+ // Reset index
+ c.index = -1
+ return
+ }
+
fileServer.ServeHTTP(c.Writer, c.Request)
}
}
diff --git a/vendor/github.com/gin-gonic/gin/tree.go b/vendor/github.com/gin-gonic/gin/tree.go
index b653066..ada62ce 100644
--- a/vendor/github.com/gin-gonic/gin/tree.go
+++ b/vendor/github.com/gin-gonic/gin/tree.go
@@ -193,9 +193,16 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
}
}
- panic("path segment '" + path +
+ pathSeg := path
+ if n.nType != catchAll {
+ pathSeg = strings.SplitN(path, "/", 2)[0]
+ }
+ prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path
+ panic("'" + pathSeg +
+ "' in new path '" + fullPath +
"' conflicts with existing wildcard '" + n.path +
- "' in path '" + fullPath + "'")
+ "' in existing prefix '" + prefix +
+ "'")
}
c := path[0]
diff --git a/vendor/github.com/gin-gonic/gin/utils.go b/vendor/github.com/gin-gonic/gin/utils.go
index bf32c77..f4532d5 100644
--- a/vendor/github.com/gin-gonic/gin/utils.go
+++ b/vendor/github.com/gin-gonic/gin/utils.go
@@ -14,8 +14,10 @@ import (
"strings"
)
+// BindKey indicates a default bind key.
const BindKey = "_gin-gonic/gin/bindkey"
+// Bind is a helper function for given interface object and returns a Gin middleware.
func Bind(val interface{}) HandlerFunc {
value := reflect.ValueOf(val)
if value.Kind() == reflect.Ptr {
@@ -33,16 +35,14 @@ func Bind(val interface{}) HandlerFunc {
}
}
-// WrapF is a helper function for wrapping http.HandlerFunc
-// Returns a Gin middleware
+// WrapF is a helper function for wrapping http.HandlerFunc and returns a Gin middleware.
func WrapF(f http.HandlerFunc) HandlerFunc {
return func(c *Context) {
f(c.Writer, c.Request)
}
}
-// WrapH is a helper function for wrapping http.Handler
-// Returns a Gin middleware
+// WrapH is a helper function for wrapping http.Handler and returns a Gin middleware.
func WrapH(h http.Handler) HandlerFunc {
return func(c *Context) {
h.ServeHTTP(c.Writer, c.Request)
diff --git a/vendor/github.com/gin-gonic/gin/response_writer_1.7.go b/vendor/github.com/gin-gonic/gin/version.go
similarity index 64%
rename from vendor/github.com/gin-gonic/gin/response_writer_1.7.go
rename to vendor/github.com/gin-gonic/gin/version.go
index 801d196..07e7859 100644
--- a/vendor/github.com/gin-gonic/gin/response_writer_1.7.go
+++ b/vendor/github.com/gin-gonic/gin/version.go
@@ -1,12 +1,8 @@
-// +build !go1.8
-
// Copyright 2018 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package gin
-// ResponseWriter ...
-type ResponseWriter interface {
- responseWriterBase
-}
+// Version is the current gin framework's version.
+const Version = "v1.4.0"
diff --git a/vendor/github.com/gin-gonic/gin/wercker.yml b/vendor/github.com/gin-gonic/gin/wercker.yml
deleted file mode 100644
index 3ab8084..0000000
--- a/vendor/github.com/gin-gonic/gin/wercker.yml
+++ /dev/null
@@ -1 +0,0 @@
-box: wercker/default
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/locales/.gitignore b/vendor/github.com/go-playground/locales/.gitignore
deleted file mode 100644
index daf913b..0000000
--- a/vendor/github.com/go-playground/locales/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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
-*.prof
diff --git a/vendor/github.com/go-playground/locales/LICENSE b/vendor/github.com/go-playground/locales/LICENSE
deleted file mode 100644
index 75854ac..0000000
--- a/vendor/github.com/go-playground/locales/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Go Playground
-
-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.
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/locales/README.md b/vendor/github.com/go-playground/locales/README.md
deleted file mode 100644
index 43329f8..0000000
--- a/vendor/github.com/go-playground/locales/README.md
+++ /dev/null
@@ -1,172 +0,0 @@
-## locales
-![Project status](https://img.shields.io/badge/version-0.12.1-green.svg)
-[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/locales/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/locales)
-[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/locales)](https://goreportcard.com/report/github.com/go-playground/locales)
-[![GoDoc](https://godoc.org/github.com/go-playground/locales?status.svg)](https://godoc.org/github.com/go-playground/locales)
-![License](https://img.shields.io/dub/l/vibe-d.svg)
-[![Gitter](https://badges.gitter.im/go-playground/locales.svg)](https://gitter.im/go-playground/locales?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
-
-Locales is a set of locales generated from the [Unicode CLDR Project](http://cldr.unicode.org/) which can be used independently or within
-an i18n package; these were built for use with, but not exclusive to, [Universal Translator](https://github.com/go-playground/universal-translator).
-
-Features
---------
-- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v31.0.1
-- [x] Contains Cardinal, Ordinal and Range Plural Rules
-- [x] Contains Month, Weekday and Timezone translations built in
-- [x] Contains Date & Time formatting functions
-- [x] Contains Number, Currency, Accounting and Percent formatting functions
-- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
-
-Full Tests
---------------------
-I could sure use your help adding tests for every locale, it is a huge undertaking and I just don't have the free time to do it all at the moment;
-any help would be **greatly appreciated!!!!** please see [issue](https://github.com/go-playground/locales/issues/1) for details.
-
-Installation
------------
-
-Use go get
-
-```shell
-go get github.com/go-playground/locales
-```
-
-NOTES
---------
-You'll notice most return types are []byte, this is because most of the time the results will be concatenated with a larger body
-of text and can avoid some allocations if already appending to a byte array, otherwise just cast as string.
-
-Usage
--------
-```go
-package main
-
-import (
- "fmt"
- "time"
-
- "github.com/go-playground/locales/currency"
- "github.com/go-playground/locales/en_CA"
-)
-
-func main() {
-
- loc, _ := time.LoadLocation("America/Toronto")
- datetime := time.Date(2016, 02, 03, 9, 0, 1, 0, loc)
-
- l := en_CA.New()
-
- // Dates
- fmt.Println(l.FmtDateFull(datetime))
- fmt.Println(l.FmtDateLong(datetime))
- fmt.Println(l.FmtDateMedium(datetime))
- fmt.Println(l.FmtDateShort(datetime))
-
- // Times
- fmt.Println(l.FmtTimeFull(datetime))
- fmt.Println(l.FmtTimeLong(datetime))
- fmt.Println(l.FmtTimeMedium(datetime))
- fmt.Println(l.FmtTimeShort(datetime))
-
- // Months Wide
- fmt.Println(l.MonthWide(time.January))
- fmt.Println(l.MonthWide(time.February))
- fmt.Println(l.MonthWide(time.March))
- // ...
-
- // Months Abbreviated
- fmt.Println(l.MonthAbbreviated(time.January))
- fmt.Println(l.MonthAbbreviated(time.February))
- fmt.Println(l.MonthAbbreviated(time.March))
- // ...
-
- // Months Narrow
- fmt.Println(l.MonthNarrow(time.January))
- fmt.Println(l.MonthNarrow(time.February))
- fmt.Println(l.MonthNarrow(time.March))
- // ...
-
- // Weekdays Wide
- fmt.Println(l.WeekdayWide(time.Sunday))
- fmt.Println(l.WeekdayWide(time.Monday))
- fmt.Println(l.WeekdayWide(time.Tuesday))
- // ...
-
- // Weekdays Abbreviated
- fmt.Println(l.WeekdayAbbreviated(time.Sunday))
- fmt.Println(l.WeekdayAbbreviated(time.Monday))
- fmt.Println(l.WeekdayAbbreviated(time.Tuesday))
- // ...
-
- // Weekdays Short
- fmt.Println(l.WeekdayShort(time.Sunday))
- fmt.Println(l.WeekdayShort(time.Monday))
- fmt.Println(l.WeekdayShort(time.Tuesday))
- // ...
-
- // Weekdays Narrow
- fmt.Println(l.WeekdayNarrow(time.Sunday))
- fmt.Println(l.WeekdayNarrow(time.Monday))
- fmt.Println(l.WeekdayNarrow(time.Tuesday))
- // ...
-
- var f64 float64
-
- f64 = -10356.4523
-
- // Number
- fmt.Println(l.FmtNumber(f64, 2))
-
- // Currency
- fmt.Println(l.FmtCurrency(f64, 2, currency.CAD))
- fmt.Println(l.FmtCurrency(f64, 2, currency.USD))
-
- // Accounting
- fmt.Println(l.FmtAccounting(f64, 2, currency.CAD))
- fmt.Println(l.FmtAccounting(f64, 2, currency.USD))
-
- f64 = 78.12
-
- // Percent
- fmt.Println(l.FmtPercent(f64, 0))
-
- // Plural Rules for locale, so you know what rules you must cover
- fmt.Println(l.PluralsCardinal())
- fmt.Println(l.PluralsOrdinal())
-
- // Cardinal Plural Rules
- fmt.Println(l.CardinalPluralRule(1, 0))
- fmt.Println(l.CardinalPluralRule(1.0, 0))
- fmt.Println(l.CardinalPluralRule(1.0, 1))
- fmt.Println(l.CardinalPluralRule(3, 0))
-
- // Ordinal Plural Rules
- fmt.Println(l.OrdinalPluralRule(21, 0)) // 21st
- fmt.Println(l.OrdinalPluralRule(22, 0)) // 22nd
- fmt.Println(l.OrdinalPluralRule(33, 0)) // 33rd
- fmt.Println(l.OrdinalPluralRule(34, 0)) // 34th
-
- // Range Plural Rules
- fmt.Println(l.RangePluralRule(1, 0, 1, 0)) // 1-1
- fmt.Println(l.RangePluralRule(1, 0, 2, 0)) // 1-2
- fmt.Println(l.RangePluralRule(5, 0, 8, 0)) // 5-8
-}
-```
-
-NOTES:
--------
-These rules were generated from the [Unicode CLDR Project](http://cldr.unicode.org/), if you encounter any issues
-I strongly encourage contributing to the CLDR project to get the locale information corrected and the next time
-these locales are regenerated the fix will come with.
-
-I do however realize that time constraints are often important and so there are two options:
-
-1. Create your own locale, copy, paste and modify, and ensure it complies with the `Translator` interface.
-2. Add an exception in the locale generation code directly and once regenerated, fix will be in place.
-
-Please to not make fixes inside the locale files, they WILL get overwritten when the locales are regenerated.
-
-License
-------
-Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/github.com/go-playground/locales/currency/currency.go b/vendor/github.com/go-playground/locales/currency/currency.go
deleted file mode 100644
index cdaba59..0000000
--- a/vendor/github.com/go-playground/locales/currency/currency.go
+++ /dev/null
@@ -1,308 +0,0 @@
-package currency
-
-// Type is the currency type associated with the locales currency enum
-type Type int
-
-// locale currencies
-const (
- ADP Type = iota
- AED
- AFA
- AFN
- ALK
- ALL
- AMD
- ANG
- AOA
- AOK
- AON
- AOR
- ARA
- ARL
- ARM
- ARP
- ARS
- ATS
- AUD
- AWG
- AZM
- AZN
- BAD
- BAM
- BAN
- BBD
- BDT
- BEC
- BEF
- BEL
- BGL
- BGM
- BGN
- BGO
- BHD
- BIF
- BMD
- BND
- BOB
- BOL
- BOP
- BOV
- BRB
- BRC
- BRE
- BRL
- BRN
- BRR
- BRZ
- BSD
- BTN
- BUK
- BWP
- BYB
- BYN
- BYR
- BZD
- CAD
- CDF
- CHE
- CHF
- CHW
- CLE
- CLF
- CLP
- CNH
- CNX
- CNY
- COP
- COU
- CRC
- CSD
- CSK
- CUC
- CUP
- CVE
- CYP
- CZK
- DDM
- DEM
- DJF
- DKK
- DOP
- DZD
- ECS
- ECV
- EEK
- EGP
- ERN
- ESA
- ESB
- ESP
- ETB
- EUR
- FIM
- FJD
- FKP
- FRF
- GBP
- GEK
- GEL
- GHC
- GHS
- GIP
- GMD
- GNF
- GNS
- GQE
- GRD
- GTQ
- GWE
- GWP
- GYD
- HKD
- HNL
- HRD
- HRK
- HTG
- HUF
- IDR
- IEP
- ILP
- ILR
- ILS
- INR
- IQD
- IRR
- ISJ
- ISK
- ITL
- JMD
- JOD
- JPY
- KES
- KGS
- KHR
- KMF
- KPW
- KRH
- KRO
- KRW
- KWD
- KYD
- KZT
- LAK
- LBP
- LKR
- LRD
- LSL
- LTL
- LTT
- LUC
- LUF
- LUL
- LVL
- LVR
- LYD
- MAD
- MAF
- MCF
- MDC
- MDL
- MGA
- MGF
- MKD
- MKN
- MLF
- MMK
- MNT
- MOP
- MRO
- MTL
- MTP
- MUR
- MVP
- MVR
- MWK
- MXN
- MXP
- MXV
- MYR
- MZE
- MZM
- MZN
- NAD
- NGN
- NIC
- NIO
- NLG
- NOK
- NPR
- NZD
- OMR
- PAB
- PEI
- PEN
- PES
- PGK
- PHP
- PKR
- PLN
- PLZ
- PTE
- PYG
- QAR
- RHD
- ROL
- RON
- RSD
- RUB
- RUR
- RWF
- SAR
- SBD
- SCR
- SDD
- SDG
- SDP
- SEK
- SGD
- SHP
- SIT
- SKK
- SLL
- SOS
- SRD
- SRG
- SSP
- STD
- STN
- SUR
- SVC
- SYP
- SZL
- THB
- TJR
- TJS
- TMM
- TMT
- TND
- TOP
- TPE
- TRL
- TRY
- TTD
- TWD
- TZS
- UAH
- UAK
- UGS
- UGX
- USD
- USN
- USS
- UYI
- UYP
- UYU
- UZS
- VEB
- VEF
- VND
- VNN
- VUV
- WST
- XAF
- XAG
- XAU
- XBA
- XBB
- XBC
- XBD
- XCD
- XDR
- XEU
- XFO
- XFU
- XOF
- XPD
- XPF
- XPT
- XRE
- XSU
- XTS
- XUA
- XXX
- YDD
- YER
- YUD
- YUM
- YUN
- YUR
- ZAL
- ZAR
- ZMK
- ZMW
- ZRN
- ZRZ
- ZWD
- ZWL
- ZWR
-)
diff --git a/vendor/github.com/go-playground/locales/logo.png b/vendor/github.com/go-playground/locales/logo.png
deleted file mode 100644
index 3038276..0000000
Binary files a/vendor/github.com/go-playground/locales/logo.png and /dev/null differ
diff --git a/vendor/github.com/go-playground/locales/rules.go b/vendor/github.com/go-playground/locales/rules.go
deleted file mode 100644
index 9202900..0000000
--- a/vendor/github.com/go-playground/locales/rules.go
+++ /dev/null
@@ -1,293 +0,0 @@
-package locales
-
-import (
- "strconv"
- "time"
-
- "github.com/go-playground/locales/currency"
-)
-
-// // ErrBadNumberValue is returned when the number passed for
-// // plural rule determination cannot be parsed
-// type ErrBadNumberValue struct {
-// NumberValue string
-// InnerError error
-// }
-
-// // Error returns ErrBadNumberValue error string
-// func (e *ErrBadNumberValue) Error() string {
-// return fmt.Sprintf("Invalid Number Value '%s' %s", e.NumberValue, e.InnerError)
-// }
-
-// var _ error = new(ErrBadNumberValue)
-
-// PluralRule denotes the type of plural rules
-type PluralRule int
-
-// PluralRule's
-const (
- PluralRuleUnknown PluralRule = iota
- PluralRuleZero // zero
- PluralRuleOne // one - singular
- PluralRuleTwo // two - dual
- PluralRuleFew // few - paucal
- PluralRuleMany // many - also used for fractions if they have a separate class
- PluralRuleOther // other - required—general plural form—also used if the language only has a single form
-)
-
-const (
- pluralsString = "UnknownZeroOneTwoFewManyOther"
-)
-
-// Translator encapsulates an instance of a locale
-// NOTE: some values are returned as a []byte just in case the caller
-// wishes to add more and can help avoid allocations; otherwise just cast as string
-type Translator interface {
-
- // The following Functions are for overriding, debugging or developing
- // with a Translator Locale
-
- // Locale returns the string value of the translator
- Locale() string
-
- // returns an array of cardinal plural rules associated
- // with this translator
- PluralsCardinal() []PluralRule
-
- // returns an array of ordinal plural rules associated
- // with this translator
- PluralsOrdinal() []PluralRule
-
- // returns an array of range plural rules associated
- // with this translator
- PluralsRange() []PluralRule
-
- // returns the cardinal PluralRule given 'num' and digits/precision of 'v' for locale
- CardinalPluralRule(num float64, v uint64) PluralRule
-
- // returns the ordinal PluralRule given 'num' and digits/precision of 'v' for locale
- OrdinalPluralRule(num float64, v uint64) PluralRule
-
- // returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for locale
- RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) PluralRule
-
- // returns the locales abbreviated month given the 'month' provided
- MonthAbbreviated(month time.Month) string
-
- // returns the locales abbreviated months
- MonthsAbbreviated() []string
-
- // returns the locales narrow month given the 'month' provided
- MonthNarrow(month time.Month) string
-
- // returns the locales narrow months
- MonthsNarrow() []string
-
- // returns the locales wide month given the 'month' provided
- MonthWide(month time.Month) string
-
- // returns the locales wide months
- MonthsWide() []string
-
- // returns the locales abbreviated weekday given the 'weekday' provided
- WeekdayAbbreviated(weekday time.Weekday) string
-
- // returns the locales abbreviated weekdays
- WeekdaysAbbreviated() []string
-
- // returns the locales narrow weekday given the 'weekday' provided
- WeekdayNarrow(weekday time.Weekday) string
-
- // WeekdaysNarrowreturns the locales narrow weekdays
- WeekdaysNarrow() []string
-
- // returns the locales short weekday given the 'weekday' provided
- WeekdayShort(weekday time.Weekday) string
-
- // returns the locales short weekdays
- WeekdaysShort() []string
-
- // returns the locales wide weekday given the 'weekday' provided
- WeekdayWide(weekday time.Weekday) string
-
- // returns the locales wide weekdays
- WeekdaysWide() []string
-
- // The following Functions are common Formatting functionsfor the Translator's Locale
-
- // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
- FmtNumber(num float64, v uint64) string
-
- // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
- // NOTE: 'num' passed into FmtPercent is assumed to be in percent already
- FmtPercent(num float64, v uint64) string
-
- // returns the currency representation of 'num' with digits/precision of 'v' for locale
- FmtCurrency(num float64, v uint64, currency currency.Type) string
-
- // returns the currency representation of 'num' with digits/precision of 'v' for locale
- // in accounting notation.
- FmtAccounting(num float64, v uint64, currency currency.Type) string
-
- // returns the short date representation of 't' for locale
- FmtDateShort(t time.Time) string
-
- // returns the medium date representation of 't' for locale
- FmtDateMedium(t time.Time) string
-
- // returns the long date representation of 't' for locale
- FmtDateLong(t time.Time) string
-
- // returns the full date representation of 't' for locale
- FmtDateFull(t time.Time) string
-
- // returns the short time representation of 't' for locale
- FmtTimeShort(t time.Time) string
-
- // returns the medium time representation of 't' for locale
- FmtTimeMedium(t time.Time) string
-
- // returns the long time representation of 't' for locale
- FmtTimeLong(t time.Time) string
-
- // returns the full time representation of 't' for locale
- FmtTimeFull(t time.Time) string
-}
-
-// String returns the string value of PluralRule
-func (p PluralRule) String() string {
-
- switch p {
- case PluralRuleZero:
- return pluralsString[7:11]
- case PluralRuleOne:
- return pluralsString[11:14]
- case PluralRuleTwo:
- return pluralsString[14:17]
- case PluralRuleFew:
- return pluralsString[17:20]
- case PluralRuleMany:
- return pluralsString[20:24]
- case PluralRuleOther:
- return pluralsString[24:]
- default:
- return pluralsString[:7]
- }
-}
-
-//
-// Precision Notes:
-//
-// must specify a precision >= 0, and here is why https://play.golang.org/p/LyL90U0Vyh
-//
-// v := float64(3.141)
-// i := float64(int64(v))
-//
-// fmt.Println(v - i)
-//
-// or
-//
-// s := strconv.FormatFloat(v-i, 'f', -1, 64)
-// fmt.Println(s)
-//
-// these will not print what you'd expect: 0.14100000000000001
-// and so this library requires a precision to be specified, or
-// inaccurate plural rules could be applied.
-//
-//
-//
-// n - absolute value of the source number (integer and decimals).
-// i - integer digits of n.
-// v - number of visible fraction digits in n, with trailing zeros.
-// w - number of visible fraction digits in n, without trailing zeros.
-// f - visible fractional digits in n, with trailing zeros.
-// t - visible fractional digits in n, without trailing zeros.
-//
-//
-// Func(num float64, v uint64) // v = digits/precision and prevents -1 as a special case as this can lead to very unexpected behaviour, see precision note's above.
-//
-// n := math.Abs(num)
-// i := int64(n)
-// v := v
-//
-//
-// w := strconv.FormatFloat(num-float64(i), 'f', int(v), 64) // then parse backwards on string until no more zero's....
-// f := strconv.FormatFloat(n, 'f', int(v), 64) // then turn everything after decimal into an int64
-// t := strconv.FormatFloat(n, 'f', int(v), 64) // then parse backwards on string until no more zero's....
-//
-//
-//
-// General Inclusion Rules
-// - v will always be available inherently
-// - all require n
-// - w requires i
-//
-
-// W returns the number of visible fraction digits in N, without trailing zeros.
-func W(n float64, v uint64) (w int64) {
-
- s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
-
- // with either be '0' or '0.xxxx', so if 1 then w will be zero
- // otherwise need to parse
- if len(s) != 1 {
-
- s = s[2:]
- end := len(s) + 1
-
- for i := end; i >= 0; i-- {
- if s[i] != '0' {
- end = i + 1
- break
- }
- }
-
- w = int64(len(s[:end]))
- }
-
- return
-}
-
-// F returns the visible fractional digits in N, with trailing zeros.
-func F(n float64, v uint64) (f int64) {
-
- s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
-
- // with either be '0' or '0.xxxx', so if 1 then f will be zero
- // otherwise need to parse
- if len(s) != 1 {
-
- // ignoring error, because it can't fail as we generated
- // the string internally from a real number
- f, _ = strconv.ParseInt(s[2:], 10, 64)
- }
-
- return
-}
-
-// T returns the visible fractional digits in N, without trailing zeros.
-func T(n float64, v uint64) (t int64) {
-
- s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
-
- // with either be '0' or '0.xxxx', so if 1 then t will be zero
- // otherwise need to parse
- if len(s) != 1 {
-
- s = s[2:]
- end := len(s) + 1
-
- for i := end; i >= 0; i-- {
- if s[i] != '0' {
- end = i + 1
- break
- }
- }
-
- // ignoring error, because it can't fail as we generated
- // the string internally from a real number
- t, _ = strconv.ParseInt(s[:end], 10, 64)
- }
-
- return
-}
diff --git a/vendor/github.com/go-playground/universal-translator/LICENSE b/vendor/github.com/go-playground/universal-translator/LICENSE
deleted file mode 100644
index 8d8aba1..0000000
--- a/vendor/github.com/go-playground/universal-translator/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Go Playground
-
-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.
diff --git a/vendor/github.com/go-playground/universal-translator/README.md b/vendor/github.com/go-playground/universal-translator/README.md
deleted file mode 100644
index 24aef15..0000000
--- a/vendor/github.com/go-playground/universal-translator/README.md
+++ /dev/null
@@ -1,90 +0,0 @@
-## universal-translator
-
-![Project status](https://img.shields.io/badge/version-0.16.0-green.svg)
-[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/universal-translator/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/universal-translator)
-[![Coverage Status](https://coveralls.io/repos/github/go-playground/universal-translator/badge.svg)](https://coveralls.io/github/go-playground/universal-translator)
-[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/universal-translator)](https://goreportcard.com/report/github.com/go-playground/universal-translator)
-[![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator)
-![License](https://img.shields.io/dub/l/vibe-d.svg)
-[![Gitter](https://badges.gitter.im/go-playground/universal-translator.svg)](https://gitter.im/go-playground/universal-translator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
-
-Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules
-
-Why another i18n library?
---------------------------
-Because none of the plural rules seem to be correct out there, including the previous implementation of this package,
-so I took it upon myself to create [locales](https://github.com/go-playground/locales) for everyone to use; this package
-is a thin wrapper around [locales](https://github.com/go-playground/locales) in order to store and translate text for
-use in your applications.
-
-Features
---------
-- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v30.0.3
-- [x] Contains Cardinal, Ordinal and Range Plural Rules
-- [x] Contains Month, Weekday and Timezone translations built in
-- [x] Contains Date & Time formatting functions
-- [x] Contains Number, Currency, Accounting and Percent formatting functions
-- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
-- [x] Support loading translations from files
-- [x] Exporting translations to file(s), mainly for getting them professionally translated
-- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated
-- [ ] Tests for all languages, I need help with this, please see [here](https://github.com/go-playground/locales/issues/1)
-
-Installation
------------
-
-Use go get
-
-```shell
-go get github.com/go-playground/universal-translator
-```
-
-Usage & Documentation
--------
-
-Please see https://godoc.org/github.com/go-playground/universal-translator for usage docs
-
-##### Examples:
-
-- [Basic](https://github.com/go-playground/universal-translator/tree/master/examples/basic)
-- [Full - no files](https://github.com/go-playground/universal-translator/tree/master/examples/full-no-files)
-- [Full - with files](https://github.com/go-playground/universal-translator/tree/master/examples/full-with-files)
-
-File formatting
---------------
-All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained withing the same file(s);
-they are only separated for easy viewing.
-
-##### Examples:
-
-- [Formats](https://github.com/go-playground/universal-translator/tree/master/examples/file-formats)
-
-##### Basic Makeup
-NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/examples/file-formats)
-```json
-{
- "locale": "en",
- "key": "days-left",
- "trans": "You have {0} day left.",
- "type": "Cardinal",
- "rule": "One",
- "override": false
-}
-```
-|Field|Description|
-|---|---|
-|locale|The locale for which the translation is for.|
-|key|The translation key that will be used to store and lookup each translation; normally it is a string or integer.|
-|trans|The actual translation text.|
-|type|The type of translation Cardinal, Ordinal, Range or "" for a plain substitution(not required to be defined if plain used)|
-|rule|The plural rule for which the translation is for eg. One, Two, Few, Many or Other.(not required to be defined if plain used)|
-|override|If you wish to override an existing translation that has already been registered, set this to 'true'. 99% of the time there is no need to define it.|
-
-Help With Tests
----------------
-To anyone interesting in helping or contributing, I sure could use some help creating tests for each language.
-Please see issue [here](https://github.com/go-playground/locales/issues/1) for details.
-
-License
-------
-Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/github.com/go-playground/universal-translator/errors.go b/vendor/github.com/go-playground/universal-translator/errors.go
deleted file mode 100644
index 38b163b..0000000
--- a/vendor/github.com/go-playground/universal-translator/errors.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package ut
-
-import (
- "errors"
- "fmt"
-
- "github.com/go-playground/locales"
-)
-
-var (
- // ErrUnknowTranslation indicates the translation could not be found
- ErrUnknowTranslation = errors.New("Unknown Translation")
-)
-
-var _ error = new(ErrConflictingTranslation)
-var _ error = new(ErrRangeTranslation)
-var _ error = new(ErrOrdinalTranslation)
-var _ error = new(ErrCardinalTranslation)
-var _ error = new(ErrMissingPluralTranslation)
-var _ error = new(ErrExistingTranslator)
-
-// ErrExistingTranslator is the error representing a conflicting translator
-type ErrExistingTranslator struct {
- locale string
-}
-
-// Error returns ErrExistingTranslator's internal error text
-func (e *ErrExistingTranslator) Error() string {
- return fmt.Sprintf("error: conflicting translator for locale '%s'", e.locale)
-}
-
-// ErrConflictingTranslation is the error representing a conflicting translation
-type ErrConflictingTranslation struct {
- locale string
- key interface{}
- rule locales.PluralRule
- text string
-}
-
-// Error returns ErrConflictingTranslation's internal error text
-func (e *ErrConflictingTranslation) Error() string {
-
- if _, ok := e.key.(string); !ok {
- return fmt.Sprintf("error: conflicting key '%#v' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale)
- }
-
- return fmt.Sprintf("error: conflicting key '%s' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale)
-}
-
-// ErrRangeTranslation is the error representing a range translation error
-type ErrRangeTranslation struct {
- text string
-}
-
-// Error returns ErrRangeTranslation's internal error text
-func (e *ErrRangeTranslation) Error() string {
- return e.text
-}
-
-// ErrOrdinalTranslation is the error representing an ordinal translation error
-type ErrOrdinalTranslation struct {
- text string
-}
-
-// Error returns ErrOrdinalTranslation's internal error text
-func (e *ErrOrdinalTranslation) Error() string {
- return e.text
-}
-
-// ErrCardinalTranslation is the error representing a cardinal translation error
-type ErrCardinalTranslation struct {
- text string
-}
-
-// Error returns ErrCardinalTranslation's internal error text
-func (e *ErrCardinalTranslation) Error() string {
- return e.text
-}
-
-// ErrMissingPluralTranslation is the error signifying a missing translation given
-// the locales plural rules.
-type ErrMissingPluralTranslation struct {
- locale string
- key interface{}
- rule locales.PluralRule
- translationType string
-}
-
-// Error returns ErrMissingPluralTranslation's internal error text
-func (e *ErrMissingPluralTranslation) Error() string {
-
- if _, ok := e.key.(string); !ok {
- return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%#v' and locale '%s'", e.translationType, e.rule, e.key, e.locale)
- }
-
- return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%s' and locale '%s'", e.translationType, e.rule, e.key, e.locale)
-}
-
-// ErrMissingBracket is the error representing a missing bracket in a translation
-// eg. This is a {0 <-- missing ending '}'
-type ErrMissingBracket struct {
- locale string
- key interface{}
- text string
-}
-
-// Error returns ErrMissingBracket error message
-func (e *ErrMissingBracket) Error() string {
- return fmt.Sprintf("error: missing bracket '{}', in translation. locale: '%s' key: '%v' text: '%s'", e.locale, e.key, e.text)
-}
-
-// ErrBadParamSyntax is the error representing a bad parameter definition in a translation
-// eg. This is a {must-be-int}
-type ErrBadParamSyntax struct {
- locale string
- param string
- key interface{}
- text string
-}
-
-// Error returns ErrBadParamSyntax error message
-func (e *ErrBadParamSyntax) Error() string {
- return fmt.Sprintf("error: bad parameter syntax, missing parameter '%s' in translation. locale: '%s' key: '%v' text: '%s'", e.param, e.locale, e.key, e.text)
-}
-
-// import/export errors
-
-// ErrMissingLocale is the error representing an expected locale that could
-// not be found aka locale not registered with the UniversalTranslator Instance
-type ErrMissingLocale struct {
- locale string
-}
-
-// Error returns ErrMissingLocale's internal error text
-func (e *ErrMissingLocale) Error() string {
- return fmt.Sprintf("error: locale '%s' not registered.", e.locale)
-}
-
-// ErrBadPluralDefinition is the error representing an incorrect plural definition
-// usually found within translations defined within files during the import process.
-type ErrBadPluralDefinition struct {
- tl translation
-}
-
-// Error returns ErrBadPluralDefinition's internal error text
-func (e *ErrBadPluralDefinition) Error() string {
- return fmt.Sprintf("error: bad plural definition '%#v'", e.tl)
-}
diff --git a/vendor/github.com/go-playground/universal-translator/import_export.go b/vendor/github.com/go-playground/universal-translator/import_export.go
deleted file mode 100644
index 7bd76f2..0000000
--- a/vendor/github.com/go-playground/universal-translator/import_export.go
+++ /dev/null
@@ -1,274 +0,0 @@
-package ut
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
-
- "io"
-
- "github.com/go-playground/locales"
-)
-
-type translation struct {
- Locale string `json:"locale"`
- Key interface{} `json:"key"` // either string or integer
- Translation string `json:"trans"`
- PluralType string `json:"type,omitempty"`
- PluralRule string `json:"rule,omitempty"`
- OverrideExisting bool `json:"override,omitempty"`
-}
-
-const (
- cardinalType = "Cardinal"
- ordinalType = "Ordinal"
- rangeType = "Range"
-)
-
-// ImportExportFormat is the format of the file import or export
-type ImportExportFormat uint8
-
-// supported Export Formats
-const (
- FormatJSON ImportExportFormat = iota
-)
-
-// Export writes the translations out to a file on disk.
-//
-// NOTE: this currently only works with string or int translations keys.
-func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string) error {
-
- _, err := os.Stat(dirname)
- fmt.Println(dirname, err, os.IsNotExist(err))
- if err != nil {
-
- if !os.IsNotExist(err) {
- return err
- }
-
- if err = os.MkdirAll(dirname, 0744); err != nil {
- return err
- }
- }
-
- // build up translations
- var trans []translation
- var b []byte
- var ext string
-
- for _, locale := range t.translators {
-
- for k, v := range locale.(*translator).translations {
- trans = append(trans, translation{
- Locale: locale.Locale(),
- Key: k,
- Translation: v.text,
- })
- }
-
- for k, pluralTrans := range locale.(*translator).cardinalTanslations {
-
- for i, plural := range pluralTrans {
-
- // leave enough for all plural rules
- // but not all are set for all languages.
- if plural == nil {
- continue
- }
-
- trans = append(trans, translation{
- Locale: locale.Locale(),
- Key: k.(string),
- Translation: plural.text,
- PluralType: cardinalType,
- PluralRule: locales.PluralRule(i).String(),
- })
- }
- }
-
- for k, pluralTrans := range locale.(*translator).ordinalTanslations {
-
- for i, plural := range pluralTrans {
-
- // leave enough for all plural rules
- // but not all are set for all languages.
- if plural == nil {
- continue
- }
-
- trans = append(trans, translation{
- Locale: locale.Locale(),
- Key: k.(string),
- Translation: plural.text,
- PluralType: ordinalType,
- PluralRule: locales.PluralRule(i).String(),
- })
- }
- }
-
- for k, pluralTrans := range locale.(*translator).rangeTanslations {
-
- for i, plural := range pluralTrans {
-
- // leave enough for all plural rules
- // but not all are set for all languages.
- if plural == nil {
- continue
- }
-
- trans = append(trans, translation{
- Locale: locale.Locale(),
- Key: k.(string),
- Translation: plural.text,
- PluralType: rangeType,
- PluralRule: locales.PluralRule(i).String(),
- })
- }
- }
-
- switch format {
- case FormatJSON:
- b, err = json.MarshalIndent(trans, "", " ")
- ext = ".json"
- }
-
- if err != nil {
- return err
- }
-
- err = ioutil.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644)
- if err != nil {
- return err
- }
-
- trans = trans[0:0]
- }
-
- return nil
-}
-
-// Import reads the translations out of a file or directory on disk.
-//
-// NOTE: this currently only works with string or int translations keys.
-func (t *UniversalTranslator) Import(format ImportExportFormat, dirnameOrFilename string) error {
-
- fi, err := os.Stat(dirnameOrFilename)
- if err != nil {
- return err
- }
-
- processFn := func(filename string) error {
-
- f, err := os.Open(filename)
- if err != nil {
- return err
- }
- defer f.Close()
-
- return t.ImportByReader(format, f)
- }
-
- if !fi.IsDir() {
- return processFn(dirnameOrFilename)
- }
-
- // recursively go through directory
- walker := func(path string, info os.FileInfo, err error) error {
-
- if info.IsDir() {
- return nil
- }
-
- switch format {
- case FormatJSON:
- // skip non JSON files
- if filepath.Ext(info.Name()) != ".json" {
- return nil
- }
- }
-
- return processFn(path)
- }
-
- return filepath.Walk(dirnameOrFilename, walker)
-}
-
-// ImportByReader imports the the translations found within the contents read from the supplied reader.
-//
-// NOTE: generally used when assets have been embedded into the binary and are already in memory.
-func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader io.Reader) error {
-
- b, err := ioutil.ReadAll(reader)
- if err != nil {
- return err
- }
-
- var trans []translation
-
- switch format {
- case FormatJSON:
- err = json.Unmarshal(b, &trans)
- }
-
- if err != nil {
- return err
- }
-
- for _, tl := range trans {
-
- locale, found := t.FindTranslator(tl.Locale)
- if !found {
- return &ErrMissingLocale{locale: tl.Locale}
- }
-
- pr := stringToPR(tl.PluralRule)
-
- if pr == locales.PluralRuleUnknown {
-
- err = locale.Add(tl.Key, tl.Translation, tl.OverrideExisting)
- if err != nil {
- return err
- }
-
- continue
- }
-
- switch tl.PluralType {
- case cardinalType:
- err = locale.AddCardinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
- case ordinalType:
- err = locale.AddOrdinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
- case rangeType:
- err = locale.AddRange(tl.Key, tl.Translation, pr, tl.OverrideExisting)
- default:
- return &ErrBadPluralDefinition{tl: tl}
- }
-
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func stringToPR(s string) locales.PluralRule {
-
- switch s {
- case "One":
- return locales.PluralRuleOne
- case "Two":
- return locales.PluralRuleTwo
- case "Few":
- return locales.PluralRuleFew
- case "Many":
- return locales.PluralRuleMany
- case "Other":
- return locales.PluralRuleOther
- default:
- return locales.PluralRuleUnknown
- }
-
-}
diff --git a/vendor/github.com/go-playground/universal-translator/logo.png b/vendor/github.com/go-playground/universal-translator/logo.png
deleted file mode 100644
index a37aa8c..0000000
Binary files a/vendor/github.com/go-playground/universal-translator/logo.png and /dev/null differ
diff --git a/vendor/github.com/go-playground/universal-translator/translator.go b/vendor/github.com/go-playground/universal-translator/translator.go
deleted file mode 100644
index cfafce8..0000000
--- a/vendor/github.com/go-playground/universal-translator/translator.go
+++ /dev/null
@@ -1,420 +0,0 @@
-package ut
-
-import (
- "fmt"
- "strconv"
- "strings"
-
- "github.com/go-playground/locales"
-)
-
-const (
- paramZero = "{0}"
- paramOne = "{1}"
- unknownTranslation = ""
-)
-
-// Translator is universal translators
-// translator instance which is a thin wrapper
-// around locales.Translator instance providing
-// some extra functionality
-type Translator interface {
- locales.Translator
-
- // adds a normal translation for a particular language/locale
- // {#} is the only replacement type accepted and are ad infinitum
- // eg. one: '{0} day left' other: '{0} days left'
- Add(key interface{}, text string, override bool) error
-
- // adds a cardinal plural translation for a particular language/locale
- // {0} is the only replacement type accepted and only one variable is accepted as
- // multiple cannot be used for a plural rule determination, unless it is a range;
- // see AddRange below.
- // eg. in locale 'en' one: '{0} day left' other: '{0} days left'
- AddCardinal(key interface{}, text string, rule locales.PluralRule, override bool) error
-
- // adds an ordinal plural translation for a particular language/locale
- // {0} is the only replacement type accepted and only one variable is accepted as
- // multiple cannot be used for a plural rule determination, unless it is a range;
- // see AddRange below.
- // eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring'
- // - 1st, 2nd, 3rd...
- AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error
-
- // adds a range plural translation for a particular language/locale
- // {0} and {1} are the only replacement types accepted and only these are accepted.
- // eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left'
- AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error
-
- // creates the translation for the locale given the 'key' and params passed in
- T(key interface{}, params ...string) (string, error)
-
- // creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments
- // and param passed in
- C(key interface{}, num float64, digits uint64, param string) (string, error)
-
- // creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments
- // and param passed in
- O(key interface{}, num float64, digits uint64, param string) (string, error)
-
- // creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and
- // 'digit2' arguments and 'param1' and 'param2' passed in
- R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error)
-
- // VerifyTranslations checks to ensures that no plural rules have been
- // missed within the translations.
- VerifyTranslations() error
-}
-
-var _ Translator = new(translator)
-var _ locales.Translator = new(translator)
-
-type translator struct {
- locales.Translator
- translations map[interface{}]*transText
- cardinalTanslations map[interface{}][]*transText // array index is mapped to locales.PluralRule index + the locales.PluralRuleUnknown
- ordinalTanslations map[interface{}][]*transText
- rangeTanslations map[interface{}][]*transText
-}
-
-type transText struct {
- text string
- indexes []int
-}
-
-func newTranslator(trans locales.Translator) Translator {
- return &translator{
- Translator: trans,
- translations: make(map[interface{}]*transText), // translation text broken up by byte index
- cardinalTanslations: make(map[interface{}][]*transText),
- ordinalTanslations: make(map[interface{}][]*transText),
- rangeTanslations: make(map[interface{}][]*transText),
- }
-}
-
-// Add adds a normal translation for a particular language/locale
-// {#} is the only replacement type accepted and are ad infinitum
-// eg. one: '{0} day left' other: '{0} days left'
-func (t *translator) Add(key interface{}, text string, override bool) error {
-
- if _, ok := t.translations[key]; ok && !override {
- return &ErrConflictingTranslation{locale: t.Locale(), key: key, text: text}
- }
-
- lb := strings.Count(text, "{")
- rb := strings.Count(text, "}")
-
- if lb != rb {
- return &ErrMissingBracket{locale: t.Locale(), key: key, text: text}
- }
-
- trans := &transText{
- text: text,
- }
-
- var idx int
-
- for i := 0; i < lb; i++ {
- s := "{" + strconv.Itoa(i) + "}"
- idx = strings.Index(text, s)
- if idx == -1 {
- return &ErrBadParamSyntax{locale: t.Locale(), param: s, key: key, text: text}
- }
-
- trans.indexes = append(trans.indexes, idx)
- trans.indexes = append(trans.indexes, idx+len(s))
- }
-
- t.translations[key] = trans
-
- return nil
-}
-
-// AddCardinal adds a cardinal plural translation for a particular language/locale
-// {0} is the only replacement type accepted and only one variable is accepted as
-// multiple cannot be used for a plural rule determination, unless it is a range;
-// see AddRange below.
-// eg. in locale 'en' one: '{0} day left' other: '{0} days left'
-func (t *translator) AddCardinal(key interface{}, text string, rule locales.PluralRule, override bool) error {
-
- var verified bool
-
- // verify plural rule exists for locale
- for _, pr := range t.PluralsCardinal() {
- if pr == rule {
- verified = true
- break
- }
- }
-
- if !verified {
- return &ErrCardinalTranslation{text: fmt.Sprintf("error: cardinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
- }
-
- tarr, ok := t.cardinalTanslations[key]
- if ok {
- // verify not adding a conflicting record
- if len(tarr) > 0 && tarr[rule] != nil && !override {
- return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
- }
-
- } else {
- tarr = make([]*transText, 7, 7)
- t.cardinalTanslations[key] = tarr
- }
-
- trans := &transText{
- text: text,
- indexes: make([]int, 2, 2),
- }
-
- tarr[rule] = trans
-
- idx := strings.Index(text, paramZero)
- if idx == -1 {
- tarr[rule] = nil
- return &ErrCardinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddCardinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
- }
-
- trans.indexes[0] = idx
- trans.indexes[1] = idx + len(paramZero)
-
- return nil
-}
-
-// AddOrdinal adds an ordinal plural translation for a particular language/locale
-// {0} is the only replacement type accepted and only one variable is accepted as
-// multiple cannot be used for a plural rule determination, unless it is a range;
-// see AddRange below.
-// eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring' - 1st, 2nd, 3rd...
-func (t *translator) AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error {
-
- var verified bool
-
- // verify plural rule exists for locale
- for _, pr := range t.PluralsOrdinal() {
- if pr == rule {
- verified = true
- break
- }
- }
-
- if !verified {
- return &ErrOrdinalTranslation{text: fmt.Sprintf("error: ordinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
- }
-
- tarr, ok := t.ordinalTanslations[key]
- if ok {
- // verify not adding a conflicting record
- if len(tarr) > 0 && tarr[rule] != nil && !override {
- return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
- }
-
- } else {
- tarr = make([]*transText, 7, 7)
- t.ordinalTanslations[key] = tarr
- }
-
- trans := &transText{
- text: text,
- indexes: make([]int, 2, 2),
- }
-
- tarr[rule] = trans
-
- idx := strings.Index(text, paramZero)
- if idx == -1 {
- tarr[rule] = nil
- return &ErrOrdinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddOrdinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
- }
-
- trans.indexes[0] = idx
- trans.indexes[1] = idx + len(paramZero)
-
- return nil
-}
-
-// AddRange adds a range plural translation for a particular language/locale
-// {0} and {1} are the only replacement types accepted and only these are accepted.
-// eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left'
-func (t *translator) AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error {
-
- var verified bool
-
- // verify plural rule exists for locale
- for _, pr := range t.PluralsRange() {
- if pr == rule {
- verified = true
- break
- }
- }
-
- if !verified {
- return &ErrRangeTranslation{text: fmt.Sprintf("error: range plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
- }
-
- tarr, ok := t.rangeTanslations[key]
- if ok {
- // verify not adding a conflicting record
- if len(tarr) > 0 && tarr[rule] != nil && !override {
- return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
- }
-
- } else {
- tarr = make([]*transText, 7, 7)
- t.rangeTanslations[key] = tarr
- }
-
- trans := &transText{
- text: text,
- indexes: make([]int, 4, 4),
- }
-
- tarr[rule] = trans
-
- idx := strings.Index(text, paramZero)
- if idx == -1 {
- tarr[rule] = nil
- return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, are you sure you're adding a Range Translation? locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
- }
-
- trans.indexes[0] = idx
- trans.indexes[1] = idx + len(paramZero)
-
- idx = strings.Index(text, paramOne)
- if idx == -1 {
- tarr[rule] = nil
- return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, a Range Translation requires two parameters. locale: '%s' key: '%v' text: '%s'", paramOne, t.Locale(), key, text)}
- }
-
- trans.indexes[2] = idx
- trans.indexes[3] = idx + len(paramOne)
-
- return nil
-}
-
-// T creates the translation for the locale given the 'key' and params passed in
-func (t *translator) T(key interface{}, params ...string) (string, error) {
-
- trans, ok := t.translations[key]
- if !ok {
- return unknownTranslation, ErrUnknowTranslation
- }
-
- b := make([]byte, 0, 64)
-
- var start, end, count int
-
- for i := 0; i < len(trans.indexes); i++ {
- end = trans.indexes[i]
- b = append(b, trans.text[start:end]...)
- b = append(b, params[count]...)
- i++
- start = trans.indexes[i]
- count++
- }
-
- b = append(b, trans.text[start:]...)
-
- return string(b), nil
-}
-
-// C creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in
-func (t *translator) C(key interface{}, num float64, digits uint64, param string) (string, error) {
-
- tarr, ok := t.cardinalTanslations[key]
- if !ok {
- return unknownTranslation, ErrUnknowTranslation
- }
-
- rule := t.CardinalPluralRule(num, digits)
-
- trans := tarr[rule]
-
- b := make([]byte, 0, 64)
- b = append(b, trans.text[:trans.indexes[0]]...)
- b = append(b, param...)
- b = append(b, trans.text[trans.indexes[1]:]...)
-
- return string(b), nil
-}
-
-// O creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in
-func (t *translator) O(key interface{}, num float64, digits uint64, param string) (string, error) {
-
- tarr, ok := t.ordinalTanslations[key]
- if !ok {
- return unknownTranslation, ErrUnknowTranslation
- }
-
- rule := t.OrdinalPluralRule(num, digits)
-
- trans := tarr[rule]
-
- b := make([]byte, 0, 64)
- b = append(b, trans.text[:trans.indexes[0]]...)
- b = append(b, param...)
- b = append(b, trans.text[trans.indexes[1]:]...)
-
- return string(b), nil
-}
-
-// R creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and 'digit2' arguments
-// and 'param1' and 'param2' passed in
-func (t *translator) R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error) {
-
- tarr, ok := t.rangeTanslations[key]
- if !ok {
- return unknownTranslation, ErrUnknowTranslation
- }
-
- rule := t.RangePluralRule(num1, digits1, num2, digits2)
-
- trans := tarr[rule]
-
- b := make([]byte, 0, 64)
- b = append(b, trans.text[:trans.indexes[0]]...)
- b = append(b, param1...)
- b = append(b, trans.text[trans.indexes[1]:trans.indexes[2]]...)
- b = append(b, param2...)
- b = append(b, trans.text[trans.indexes[3]:]...)
-
- return string(b), nil
-}
-
-// VerifyTranslations checks to ensures that no plural rules have been
-// missed within the translations.
-func (t *translator) VerifyTranslations() error {
-
- for k, v := range t.cardinalTanslations {
-
- for _, rule := range t.PluralsCardinal() {
-
- if v[rule] == nil {
- return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "plural", rule: rule, key: k}
- }
- }
- }
-
- for k, v := range t.ordinalTanslations {
-
- for _, rule := range t.PluralsOrdinal() {
-
- if v[rule] == nil {
- return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "ordinal", rule: rule, key: k}
- }
- }
- }
-
- for k, v := range t.rangeTanslations {
-
- for _, rule := range t.PluralsRange() {
-
- if v[rule] == nil {
- return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "range", rule: rule, key: k}
- }
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/go-playground/universal-translator/universal_translator.go b/vendor/github.com/go-playground/universal-translator/universal_translator.go
deleted file mode 100644
index dbf707f..0000000
--- a/vendor/github.com/go-playground/universal-translator/universal_translator.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package ut
-
-import (
- "strings"
-
- "github.com/go-playground/locales"
-)
-
-// UniversalTranslator holds all locale & translation data
-type UniversalTranslator struct {
- translators map[string]Translator
- fallback Translator
-}
-
-// New returns a new UniversalTranslator instance set with
-// the fallback locale and locales it should support
-func New(fallback locales.Translator, supportedLocales ...locales.Translator) *UniversalTranslator {
-
- t := &UniversalTranslator{
- translators: make(map[string]Translator),
- }
-
- for _, v := range supportedLocales {
-
- trans := newTranslator(v)
- t.translators[strings.ToLower(trans.Locale())] = trans
-
- if fallback.Locale() == v.Locale() {
- t.fallback = trans
- }
- }
-
- if t.fallback == nil && fallback != nil {
- t.fallback = newTranslator(fallback)
- }
-
- return t
-}
-
-// FindTranslator trys to find a Translator based on an array of locales
-// and returns the first one it can find, otherwise returns the
-// fallback translator.
-func (t *UniversalTranslator) FindTranslator(locales ...string) (trans Translator, found bool) {
-
- for _, locale := range locales {
-
- if trans, found = t.translators[strings.ToLower(locale)]; found {
- return
- }
- }
-
- return t.fallback, false
-}
-
-// GetTranslator returns the specified translator for the given locale,
-// or fallback if not found
-func (t *UniversalTranslator) GetTranslator(locale string) (trans Translator, found bool) {
-
- if trans, found = t.translators[strings.ToLower(locale)]; found {
- return
- }
-
- return t.fallback, false
-}
-
-// GetFallback returns the fallback locale
-func (t *UniversalTranslator) GetFallback() Translator {
- return t.fallback
-}
-
-// AddTranslator adds the supplied translator, if it already exists the override param
-// will be checked and if false an error will be returned, otherwise the translator will be
-// overridden; if the fallback matches the supplied translator it will be overridden as well
-// NOTE: this is normally only used when translator is embedded within a library
-func (t *UniversalTranslator) AddTranslator(translator locales.Translator, override bool) error {
-
- lc := strings.ToLower(translator.Locale())
- _, ok := t.translators[lc]
- if ok && !override {
- return &ErrExistingTranslator{locale: translator.Locale()}
- }
-
- trans := newTranslator(translator)
-
- if t.fallback.Locale() == translator.Locale() {
-
- // because it's optional to have a fallback, I don't impose that limitation
- // don't know why you wouldn't but...
- if !override {
- return &ErrExistingTranslator{locale: translator.Locale()}
- }
-
- t.fallback = trans
- }
-
- t.translators[lc] = trans
-
- return nil
-}
-
-// VerifyTranslations runs through all locales and identifies any issues
-// eg. missing plural rules for a locale
-func (t *UniversalTranslator) VerifyTranslations() (err error) {
-
- for _, trans := range t.translators {
- err = trans.VerifyTranslations()
- if err != nil {
- return
- }
- }
-
- return
-}
diff --git a/vendor/github.com/inconshreveable/mousetrap/LICENSE b/vendor/github.com/inconshreveable/mousetrap/LICENSE
new file mode 100644
index 0000000..5f0d1fb
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 Alan Shreve
+
+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.
diff --git a/vendor/github.com/inconshreveable/mousetrap/README.md b/vendor/github.com/inconshreveable/mousetrap/README.md
new file mode 100644
index 0000000..7a950d1
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/README.md
@@ -0,0 +1,23 @@
+# mousetrap
+
+mousetrap is a tiny library that answers a single question.
+
+On a Windows machine, was the process invoked by someone double clicking on
+the executable file while browsing in explorer?
+
+### Motivation
+
+Windows developers unfamiliar with command line tools will often "double-click"
+the executable for a tool. Because most CLI tools print the help and then exit
+when invoked without arguments, this is often very frustrating for those users.
+
+mousetrap provides a way to detect these invocations so that you can provide
+more helpful behavior and instructions on how to run the CLI tool. To see what
+this looks like, both from an organizational and a technical perspective, see
+https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/
+
+### The interface
+
+The library exposes a single interface:
+
+ func StartedByExplorer() (bool)
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
new file mode 100644
index 0000000..9d2d8a4
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_others.go
@@ -0,0 +1,15 @@
+// +build !windows
+
+package mousetrap
+
+// StartedByExplorer returns true if the program was invoked by the user
+// double-clicking on the executable from explorer.exe
+//
+// It is conservative and returns false if any of the internal calls fail.
+// It does not guarantee that the program was run from a terminal. It only can tell you
+// whether it was launched from explorer.exe
+//
+// On non-Windows platforms, it always returns false.
+func StartedByExplorer() bool {
+ return false
+}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
new file mode 100644
index 0000000..336142a
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go
@@ -0,0 +1,98 @@
+// +build windows
+// +build !go1.4
+
+package mousetrap
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ // defined by the Win32 API
+ th32cs_snapprocess uintptr = 0x2
+)
+
+var (
+ kernel = syscall.MustLoadDLL("kernel32.dll")
+ CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot")
+ Process32First = kernel.MustFindProc("Process32FirstW")
+ Process32Next = kernel.MustFindProc("Process32NextW")
+)
+
+// ProcessEntry32 structure defined by the Win32 API
+type processEntry32 struct {
+ dwSize uint32
+ cntUsage uint32
+ th32ProcessID uint32
+ th32DefaultHeapID int
+ th32ModuleID uint32
+ cntThreads uint32
+ th32ParentProcessID uint32
+ pcPriClassBase int32
+ dwFlags uint32
+ szExeFile [syscall.MAX_PATH]uint16
+}
+
+func getProcessEntry(pid int) (pe *processEntry32, err error) {
+ snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0))
+ if snapshot == uintptr(syscall.InvalidHandle) {
+ err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1)
+ return
+ }
+ defer syscall.CloseHandle(syscall.Handle(snapshot))
+
+ var processEntry processEntry32
+ processEntry.dwSize = uint32(unsafe.Sizeof(processEntry))
+ ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
+ if ok == 0 {
+ err = fmt.Errorf("Process32First: %v", e1)
+ return
+ }
+
+ for {
+ if processEntry.th32ProcessID == uint32(pid) {
+ pe = &processEntry
+ return
+ }
+
+ ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry)))
+ if ok == 0 {
+ err = fmt.Errorf("Process32Next: %v", e1)
+ return
+ }
+ }
+}
+
+func getppid() (pid int, err error) {
+ pe, err := getProcessEntry(os.Getpid())
+ if err != nil {
+ return
+ }
+
+ pid = int(pe.th32ParentProcessID)
+ return
+}
+
+// StartedByExplorer returns true if the program was invoked by the user double-clicking
+// on the executable from explorer.exe
+//
+// It is conservative and returns false if any of the internal calls fail.
+// It does not guarantee that the program was run from a terminal. It only can tell you
+// whether it was launched from explorer.exe
+func StartedByExplorer() bool {
+ ppid, err := getppid()
+ if err != nil {
+ return false
+ }
+
+ pe, err := getProcessEntry(ppid)
+ if err != nil {
+ return false
+ }
+
+ name := syscall.UTF16ToString(pe.szExeFile[:])
+ return name == "explorer.exe"
+}
diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
new file mode 100644
index 0000000..9a28e57
--- /dev/null
+++ b/vendor/github.com/inconshreveable/mousetrap/trap_windows_1.4.go
@@ -0,0 +1,46 @@
+// +build windows
+// +build go1.4
+
+package mousetrap
+
+import (
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
+ snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CloseHandle(snapshot)
+ var procEntry syscall.ProcessEntry32
+ procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+ if err = syscall.Process32First(snapshot, &procEntry); err != nil {
+ return nil, err
+ }
+ for {
+ if procEntry.ProcessID == uint32(pid) {
+ return &procEntry, nil
+ }
+ err = syscall.Process32Next(snapshot, &procEntry)
+ if err != nil {
+ return nil, err
+ }
+ }
+}
+
+// StartedByExplorer returns true if the program was invoked by the user double-clicking
+// on the executable from explorer.exe
+//
+// It is conservative and returns false if any of the internal calls fail.
+// It does not guarantee that the program was run from a terminal. It only can tell you
+// whether it was launched from explorer.exe
+func StartedByExplorer() bool {
+ pe, err := getProcessEntry(os.Getppid())
+ if err != nil {
+ return false
+ }
+ return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
+}
diff --git a/vendor/github.com/leodido/go-urn/.gitignore b/vendor/github.com/leodido/go-urn/.gitignore
deleted file mode 100644
index a30b5ab..0000000
--- a/vendor/github.com/leodido/go-urn/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-*.exe
-*.dll
-*.so
-*.dylib
-
-*.test
-
-*.out
-*.txt
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/.travis.yml b/vendor/github.com/leodido/go-urn/.travis.yml
deleted file mode 100644
index 913b641..0000000
--- a/vendor/github.com/leodido/go-urn/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-language: go
-
-go:
- - 1.9.x
- - 1.10.x
- - tip
-
-before_install:
- - go get -t -v ./...
-
-script:
- - go test -race -coverprofile=coverage.txt -covermode=atomic
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/README.md b/vendor/github.com/leodido/go-urn/README.md
deleted file mode 100644
index cc902ec..0000000
--- a/vendor/github.com/leodido/go-urn/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-[![Build](https://img.shields.io/travis/leodido/go-urn/master.svg?style=for-the-badge)](https://travis-ci.org/leodido/go-urn) [![Coverage](https://img.shields.io/codecov/c/github/leodido/go-urn.svg?style=for-the-badge)](https://codecov.io/gh/leodido/go-urn) [![Documentation](https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge)](https://godoc.org/github.com/leodido/go-urn)
-
-**A parser for URNs**.
-
-> As seen on [RFC 2141](https://tools.ietf.org/html/rfc2141#ref-1).
-
-[API documentation](https://godoc.org/github.com/leodido/go-urn).
-
-## Installation
-
-```
-go get github.com/leodido/go-urn
-```
-
-## Performances
-
-This implementation results to be really fast.
-
-Usually below ½ microsecond on my machine[1](#mymachine).
-
-Notice it also performs, while parsing:
-
-1. fine-grained and informative erroring
-2. specific-string normalization
-
-```
-ok/00/urn:a:b______________________________________/-4 20000000 265 ns/op 182 B/op 6 allocs/op
-ok/01/URN:foo:a123,456_____________________________/-4 30000000 296 ns/op 200 B/op 6 allocs/op
-ok/02/urn:foo:a123%2c456___________________________/-4 20000000 331 ns/op 208 B/op 6 allocs/op
-ok/03/urn:ietf:params:scim:schemas:core:2.0:User___/-4 20000000 430 ns/op 280 B/op 6 allocs/op
-ok/04/urn:ietf:params:scim:schemas:extension:enterp/-4 20000000 411 ns/op 312 B/op 6 allocs/op
-ok/05/urn:ietf:params:scim:schemas:extension:enterp/-4 20000000 472 ns/op 344 B/op 6 allocs/op
-ok/06/urn:burnout:nss______________________________/-4 30000000 257 ns/op 192 B/op 6 allocs/op
-ok/07/urn:abcdefghilmnopqrstuvzabcdefghilm:x_______/-4 20000000 375 ns/op 213 B/op 6 allocs/op
-ok/08/urn:urnurnurn:urn____________________________/-4 30000000 265 ns/op 197 B/op 6 allocs/op
-ok/09/urn:ciao:@!=%2c(xyz)+a,b.*@g=$_'_____________/-4 20000000 307 ns/op 248 B/op 6 allocs/op
-ok/10/URN:x:abc%1dz%2f%3az_________________________/-4 30000000 259 ns/op 212 B/op 6 allocs/op
-no/11/URN:-xxx:x___________________________________/-4 20000000 445 ns/op 320 B/op 6 allocs/op
-no/12/urn::colon:nss_______________________________/-4 20000000 461 ns/op 320 B/op 6 allocs/op
-no/13/urn:abcdefghilmnopqrstuvzabcdefghilmn:specifi/-4 10000000 660 ns/op 320 B/op 6 allocs/op
-no/14/URN:a!?:x____________________________________/-4 20000000 507 ns/op 320 B/op 6 allocs/op
-no/15/urn:urn:NSS__________________________________/-4 20000000 429 ns/op 288 B/op 6 allocs/op
-no/16/urn:white_space:NSS__________________________/-4 20000000 482 ns/op 320 B/op 6 allocs/op
-no/17/urn:concat:no_spaces_________________________/-4 20000000 539 ns/op 328 B/op 7 allocs/op
-no/18/urn:a:/______________________________________/-4 20000000 470 ns/op 320 B/op 7 allocs/op
-no/19/urn:UrN:NSS__________________________________/-4 20000000 399 ns/op 288 B/op 6 allocs/op
-```
-
----
-
-* [1]: Intel Core i7-7600U CPU @ 2.80GHz
-
----
-
-[![Analytics](https://ga-beacon.appspot.com/UA-49657176-1/go-urn?flat)](https://github.com/igrigorik/ga-beacon)
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/machine.go b/vendor/github.com/leodido/go-urn/machine.go
deleted file mode 100644
index d621ea6..0000000
--- a/vendor/github.com/leodido/go-urn/machine.go
+++ /dev/null
@@ -1,1670 +0,0 @@
-package urn
-
-import (
- "fmt"
-)
-
-var (
- errPrefix = "expecting the prefix to be the \"urn\" string (whatever case) [col %d]"
- errIdentifier = "expecting the identifier to be string (1..31 alnum chars, also containing dashes but not at its start) [col %d]"
- errSpecificString = "expecting the specific string to be a string containing alnum, hex, or others ([()+,-.:=@;$_!*']) chars [col %d]"
- errNoUrnWithinID = "expecting the identifier to not contain the \"urn\" reserved string [col %d]"
- errHex = "expecting the specific string hex chars to be well-formed (%%alnum{2}) [col %d]"
- errParse = "parsing error [col %d]"
-)
-
-
-const start int = 1
-const first_final int = 44
-
-const en_fail int = 46
-const en_main int = 1
-
-
-// Machine is the interface representing the FSM
-type Machine interface {
- Error() error
- Parse(input []byte) (*URN, error)
-}
-
-type machine struct {
- data []byte
- cs int
- p, pe, eof, pb int
- err error
- tolower []int
-}
-
-// NewMachine creates a new FSM able to parse RFC 2141 strings.
-func NewMachine() Machine {
- m := &machine{}
-
- return m
-}
-
-// Err returns the error that occurred on the last call to Parse.
-//
-// If the result is nil, then the line was parsed successfully.
-func (m *machine) Error() error {
- return m.err
-}
-
-func (m *machine) text() []byte {
- return m.data[m.pb:m.p]
-}
-
-// Parse parses the input byte array as a RFC 2141 string.
-func (m *machine) Parse(input []byte) (*URN, error) {
- m.data = input
- m.p = 0
- m.pb = 0
- m.pe = len(input)
- m.eof = len(input)
- m.err = nil
- m.tolower = []int{}
- output := &URN{}
-
- {
- m.cs = start
- }
-
-
- {
- if (m.p) == (m.pe) {
- goto _test_eof
- }
- switch m.cs {
- case 1:
- goto st_case_1
- case 0:
- goto st_case_0
- case 2:
- goto st_case_2
- case 3:
- goto st_case_3
- case 4:
- goto st_case_4
- case 5:
- goto st_case_5
- case 6:
- goto st_case_6
- case 7:
- goto st_case_7
- case 8:
- goto st_case_8
- case 9:
- goto st_case_9
- case 10:
- goto st_case_10
- case 11:
- goto st_case_11
- case 12:
- goto st_case_12
- case 13:
- goto st_case_13
- case 14:
- goto st_case_14
- case 15:
- goto st_case_15
- case 16:
- goto st_case_16
- case 17:
- goto st_case_17
- case 18:
- goto st_case_18
- case 19:
- goto st_case_19
- case 20:
- goto st_case_20
- case 21:
- goto st_case_21
- case 22:
- goto st_case_22
- case 23:
- goto st_case_23
- case 24:
- goto st_case_24
- case 25:
- goto st_case_25
- case 26:
- goto st_case_26
- case 27:
- goto st_case_27
- case 28:
- goto st_case_28
- case 29:
- goto st_case_29
- case 30:
- goto st_case_30
- case 31:
- goto st_case_31
- case 32:
- goto st_case_32
- case 33:
- goto st_case_33
- case 34:
- goto st_case_34
- case 35:
- goto st_case_35
- case 36:
- goto st_case_36
- case 37:
- goto st_case_37
- case 38:
- goto st_case_38
- case 44:
- goto st_case_44
- case 39:
- goto st_case_39
- case 40:
- goto st_case_40
- case 45:
- goto st_case_45
- case 41:
- goto st_case_41
- case 42:
- goto st_case_42
- case 43:
- goto st_case_43
- case 46:
- goto st_case_46
- }
- goto st_out
- st_case_1:
- switch (m.data)[(m.p)] {
- case 85:
- goto tr1
- case 117:
- goto tr1
- }
- goto tr0
- tr0:
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- tr3:
- m.err = fmt.Errorf(errPrefix, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- tr6:
- m.err = fmt.Errorf(errIdentifier, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- tr41:
- m.err = fmt.Errorf(errSpecificString, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- tr44:
- m.err = fmt.Errorf(errHex, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errSpecificString, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- tr50:
- m.err = fmt.Errorf(errPrefix, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errIdentifier, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- tr52:
- m.err = fmt.Errorf(errNoUrnWithinID, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errIdentifier, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- goto st0
- st_case_0:
- st0:
- m.cs = 0
- goto _out
- tr1:
- m.pb = m.p
-
- goto st2
- st2:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof2
- }
- st_case_2:
- switch (m.data)[(m.p)] {
- case 82:
- goto st3
- case 114:
- goto st3
- }
- goto tr0
- st3:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof3
- }
- st_case_3:
- switch (m.data)[(m.p)] {
- case 78:
- goto st4
- case 110:
- goto st4
- }
- goto tr3
- st4:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof4
- }
- st_case_4:
- if (m.data)[(m.p)] == 58 {
- goto tr5
- }
- goto tr0
- tr5:
- output.prefix = string(m.text())
-
- goto st5
- st5:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof5
- }
- st_case_5:
- switch (m.data)[(m.p)] {
- case 85:
- goto tr8
- case 117:
- goto tr8
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto tr7
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto tr7
- }
- default:
- goto tr7
- }
- goto tr6
- tr7:
- m.pb = m.p
-
- goto st6
- st6:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof6
- }
- st_case_6:
- switch (m.data)[(m.p)] {
- case 45:
- goto st7
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st7
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st7
- }
- default:
- goto st7
- }
- goto tr6
- st7:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof7
- }
- st_case_7:
- switch (m.data)[(m.p)] {
- case 45:
- goto st8
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st8
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st8
- }
- default:
- goto st8
- }
- goto tr6
- st8:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof8
- }
- st_case_8:
- switch (m.data)[(m.p)] {
- case 45:
- goto st9
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st9
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st9
- }
- default:
- goto st9
- }
- goto tr6
- st9:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof9
- }
- st_case_9:
- switch (m.data)[(m.p)] {
- case 45:
- goto st10
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st10
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st10
- }
- default:
- goto st10
- }
- goto tr6
- st10:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof10
- }
- st_case_10:
- switch (m.data)[(m.p)] {
- case 45:
- goto st11
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st11
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st11
- }
- default:
- goto st11
- }
- goto tr6
- st11:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof11
- }
- st_case_11:
- switch (m.data)[(m.p)] {
- case 45:
- goto st12
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st12
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st12
- }
- default:
- goto st12
- }
- goto tr6
- st12:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof12
- }
- st_case_12:
- switch (m.data)[(m.p)] {
- case 45:
- goto st13
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st13
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st13
- }
- default:
- goto st13
- }
- goto tr6
- st13:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof13
- }
- st_case_13:
- switch (m.data)[(m.p)] {
- case 45:
- goto st14
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st14
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st14
- }
- default:
- goto st14
- }
- goto tr6
- st14:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof14
- }
- st_case_14:
- switch (m.data)[(m.p)] {
- case 45:
- goto st15
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st15
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st15
- }
- default:
- goto st15
- }
- goto tr6
- st15:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof15
- }
- st_case_15:
- switch (m.data)[(m.p)] {
- case 45:
- goto st16
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st16
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st16
- }
- default:
- goto st16
- }
- goto tr6
- st16:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof16
- }
- st_case_16:
- switch (m.data)[(m.p)] {
- case 45:
- goto st17
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st17
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st17
- }
- default:
- goto st17
- }
- goto tr6
- st17:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof17
- }
- st_case_17:
- switch (m.data)[(m.p)] {
- case 45:
- goto st18
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st18
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st18
- }
- default:
- goto st18
- }
- goto tr6
- st18:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof18
- }
- st_case_18:
- switch (m.data)[(m.p)] {
- case 45:
- goto st19
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st19
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st19
- }
- default:
- goto st19
- }
- goto tr6
- st19:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof19
- }
- st_case_19:
- switch (m.data)[(m.p)] {
- case 45:
- goto st20
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st20
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st20
- }
- default:
- goto st20
- }
- goto tr6
- st20:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof20
- }
- st_case_20:
- switch (m.data)[(m.p)] {
- case 45:
- goto st21
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st21
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st21
- }
- default:
- goto st21
- }
- goto tr6
- st21:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof21
- }
- st_case_21:
- switch (m.data)[(m.p)] {
- case 45:
- goto st22
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st22
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st22
- }
- default:
- goto st22
- }
- goto tr6
- st22:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof22
- }
- st_case_22:
- switch (m.data)[(m.p)] {
- case 45:
- goto st23
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st23
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st23
- }
- default:
- goto st23
- }
- goto tr6
- st23:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof23
- }
- st_case_23:
- switch (m.data)[(m.p)] {
- case 45:
- goto st24
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st24
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st24
- }
- default:
- goto st24
- }
- goto tr6
- st24:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof24
- }
- st_case_24:
- switch (m.data)[(m.p)] {
- case 45:
- goto st25
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st25
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st25
- }
- default:
- goto st25
- }
- goto tr6
- st25:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof25
- }
- st_case_25:
- switch (m.data)[(m.p)] {
- case 45:
- goto st26
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st26
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st26
- }
- default:
- goto st26
- }
- goto tr6
- st26:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof26
- }
- st_case_26:
- switch (m.data)[(m.p)] {
- case 45:
- goto st27
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st27
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st27
- }
- default:
- goto st27
- }
- goto tr6
- st27:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof27
- }
- st_case_27:
- switch (m.data)[(m.p)] {
- case 45:
- goto st28
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st28
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st28
- }
- default:
- goto st28
- }
- goto tr6
- st28:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof28
- }
- st_case_28:
- switch (m.data)[(m.p)] {
- case 45:
- goto st29
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st29
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st29
- }
- default:
- goto st29
- }
- goto tr6
- st29:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof29
- }
- st_case_29:
- switch (m.data)[(m.p)] {
- case 45:
- goto st30
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st30
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st30
- }
- default:
- goto st30
- }
- goto tr6
- st30:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof30
- }
- st_case_30:
- switch (m.data)[(m.p)] {
- case 45:
- goto st31
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st31
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st31
- }
- default:
- goto st31
- }
- goto tr6
- st31:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof31
- }
- st_case_31:
- switch (m.data)[(m.p)] {
- case 45:
- goto st32
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st32
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st32
- }
- default:
- goto st32
- }
- goto tr6
- st32:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof32
- }
- st_case_32:
- switch (m.data)[(m.p)] {
- case 45:
- goto st33
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st33
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st33
- }
- default:
- goto st33
- }
- goto tr6
- st33:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof33
- }
- st_case_33:
- switch (m.data)[(m.p)] {
- case 45:
- goto st34
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st34
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st34
- }
- default:
- goto st34
- }
- goto tr6
- st34:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof34
- }
- st_case_34:
- switch (m.data)[(m.p)] {
- case 45:
- goto st35
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st35
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st35
- }
- default:
- goto st35
- }
- goto tr6
- st35:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof35
- }
- st_case_35:
- switch (m.data)[(m.p)] {
- case 45:
- goto st36
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st36
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st36
- }
- default:
- goto st36
- }
- goto tr6
- st36:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof36
- }
- st_case_36:
- switch (m.data)[(m.p)] {
- case 45:
- goto st37
- case 58:
- goto tr10
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st37
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st37
- }
- default:
- goto st37
- }
- goto tr6
- st37:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof37
- }
- st_case_37:
- if (m.data)[(m.p)] == 58 {
- goto tr10
- }
- goto tr6
- tr10:
- output.ID = string(m.text())
-
- goto st38
- st38:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof38
- }
- st_case_38:
- switch (m.data)[(m.p)] {
- case 33:
- goto tr42
- case 36:
- goto tr42
- case 37:
- goto tr43
- case 61:
- goto tr42
- case 95:
- goto tr42
- }
- switch {
- case (m.data)[(m.p)] < 48:
- if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
- goto tr42
- }
- case (m.data)[(m.p)] > 59:
- switch {
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto tr42
- }
- case (m.data)[(m.p)] >= 64:
- goto tr42
- }
- default:
- goto tr42
- }
- goto tr41
- tr42:
- m.pb = m.p
-
- goto st44
- st44:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof44
- }
- st_case_44:
- switch (m.data)[(m.p)] {
- case 33:
- goto st44
- case 36:
- goto st44
- case 37:
- goto st39
- case 61:
- goto st44
- case 95:
- goto st44
- }
- switch {
- case (m.data)[(m.p)] < 48:
- if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
- goto st44
- }
- case (m.data)[(m.p)] > 59:
- switch {
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st44
- }
- case (m.data)[(m.p)] >= 64:
- goto st44
- }
- default:
- goto st44
- }
- goto tr41
- tr43:
- m.pb = m.p
-
- goto st39
- st39:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof39
- }
- st_case_39:
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st40
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st40
- }
- default:
- goto tr46
- }
- goto tr44
- tr46:
- m.tolower = append(m.tolower, m.p-m.pb)
-
- goto st40
- st40:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof40
- }
- st_case_40:
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st45
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st45
- }
- default:
- goto tr48
- }
- goto tr44
- tr48:
- m.tolower = append(m.tolower, m.p-m.pb)
-
- goto st45
- st45:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof45
- }
- st_case_45:
- switch (m.data)[(m.p)] {
- case 33:
- goto st44
- case 36:
- goto st44
- case 37:
- goto st39
- case 61:
- goto st44
- case 95:
- goto st44
- }
- switch {
- case (m.data)[(m.p)] < 48:
- if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
- goto st44
- }
- case (m.data)[(m.p)] > 59:
- switch {
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st44
- }
- case (m.data)[(m.p)] >= 64:
- goto st44
- }
- default:
- goto st44
- }
- goto tr44
- tr8:
- m.pb = m.p
-
- goto st41
- st41:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof41
- }
- st_case_41:
- switch (m.data)[(m.p)] {
- case 45:
- goto st7
- case 58:
- goto tr10
- case 82:
- goto st42
- case 114:
- goto st42
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st7
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st7
- }
- default:
- goto st7
- }
- goto tr6
- st42:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof42
- }
- st_case_42:
- switch (m.data)[(m.p)] {
- case 45:
- goto st8
- case 58:
- goto tr10
- case 78:
- goto st43
- case 110:
- goto st43
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st8
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st8
- }
- default:
- goto st8
- }
- goto tr50
- st43:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof43
- }
- st_case_43:
- if (m.data)[(m.p)] == 45 {
- goto st9
- }
- switch {
- case (m.data)[(m.p)] < 65:
- if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
- goto st9
- }
- case (m.data)[(m.p)] > 90:
- if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
- goto st9
- }
- default:
- goto st9
- }
- goto tr52
- st46:
- if (m.p)++; (m.p) == (m.pe) {
- goto _test_eof46
- }
- st_case_46:
- switch (m.data)[(m.p)] {
- case 10:
- goto st0
- case 13:
- goto st0
- }
- goto st46
- st_out:
- _test_eof2:
- m.cs = 2
- goto _test_eof
- _test_eof3:
- m.cs = 3
- goto _test_eof
- _test_eof4:
- m.cs = 4
- goto _test_eof
- _test_eof5:
- m.cs = 5
- goto _test_eof
- _test_eof6:
- m.cs = 6
- goto _test_eof
- _test_eof7:
- m.cs = 7
- goto _test_eof
- _test_eof8:
- m.cs = 8
- goto _test_eof
- _test_eof9:
- m.cs = 9
- goto _test_eof
- _test_eof10:
- m.cs = 10
- goto _test_eof
- _test_eof11:
- m.cs = 11
- goto _test_eof
- _test_eof12:
- m.cs = 12
- goto _test_eof
- _test_eof13:
- m.cs = 13
- goto _test_eof
- _test_eof14:
- m.cs = 14
- goto _test_eof
- _test_eof15:
- m.cs = 15
- goto _test_eof
- _test_eof16:
- m.cs = 16
- goto _test_eof
- _test_eof17:
- m.cs = 17
- goto _test_eof
- _test_eof18:
- m.cs = 18
- goto _test_eof
- _test_eof19:
- m.cs = 19
- goto _test_eof
- _test_eof20:
- m.cs = 20
- goto _test_eof
- _test_eof21:
- m.cs = 21
- goto _test_eof
- _test_eof22:
- m.cs = 22
- goto _test_eof
- _test_eof23:
- m.cs = 23
- goto _test_eof
- _test_eof24:
- m.cs = 24
- goto _test_eof
- _test_eof25:
- m.cs = 25
- goto _test_eof
- _test_eof26:
- m.cs = 26
- goto _test_eof
- _test_eof27:
- m.cs = 27
- goto _test_eof
- _test_eof28:
- m.cs = 28
- goto _test_eof
- _test_eof29:
- m.cs = 29
- goto _test_eof
- _test_eof30:
- m.cs = 30
- goto _test_eof
- _test_eof31:
- m.cs = 31
- goto _test_eof
- _test_eof32:
- m.cs = 32
- goto _test_eof
- _test_eof33:
- m.cs = 33
- goto _test_eof
- _test_eof34:
- m.cs = 34
- goto _test_eof
- _test_eof35:
- m.cs = 35
- goto _test_eof
- _test_eof36:
- m.cs = 36
- goto _test_eof
- _test_eof37:
- m.cs = 37
- goto _test_eof
- _test_eof38:
- m.cs = 38
- goto _test_eof
- _test_eof44:
- m.cs = 44
- goto _test_eof
- _test_eof39:
- m.cs = 39
- goto _test_eof
- _test_eof40:
- m.cs = 40
- goto _test_eof
- _test_eof45:
- m.cs = 45
- goto _test_eof
- _test_eof41:
- m.cs = 41
- goto _test_eof
- _test_eof42:
- m.cs = 42
- goto _test_eof
- _test_eof43:
- m.cs = 43
- goto _test_eof
- _test_eof46:
- m.cs = 46
- goto _test_eof
-
- _test_eof:
- {
- }
- if (m.p) == (m.eof) {
- switch m.cs {
- case 44, 45:
- raw := m.text()
- output.SS = string(raw)
- // Iterate upper letters lowering them
- for _, i := range m.tolower {
- raw[i] = raw[i] + 32
- }
- output.norm = string(raw)
-
- case 1, 2, 4:
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- case 3:
- m.err = fmt.Errorf(errPrefix, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- case 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 41:
- m.err = fmt.Errorf(errIdentifier, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- case 38:
- m.err = fmt.Errorf(errSpecificString, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- case 42:
- m.err = fmt.Errorf(errPrefix, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errIdentifier, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- case 43:
- m.err = fmt.Errorf(errNoUrnWithinID, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errIdentifier, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- case 39, 40:
- m.err = fmt.Errorf(errHex, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errSpecificString, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- m.err = fmt.Errorf(errParse, m.p)
- (m.p)--
-
- {
- goto st46
- }
-
- }
- }
-
- _out:
- {
- }
- }
-
- if m.cs < first_final || m.cs == en_fail {
- return nil, m.err
- }
-
- return output, nil
-}
diff --git a/vendor/github.com/leodido/go-urn/machine.go.rl b/vendor/github.com/leodido/go-urn/machine.go.rl
deleted file mode 100644
index 3bc05a6..0000000
--- a/vendor/github.com/leodido/go-urn/machine.go.rl
+++ /dev/null
@@ -1,159 +0,0 @@
-package urn
-
-import (
- "fmt"
-)
-
-var (
- errPrefix = "expecting the prefix to be the \"urn\" string (whatever case) [col %d]"
- errIdentifier = "expecting the identifier to be string (1..31 alnum chars, also containing dashes but not at its start) [col %d]"
- errSpecificString = "expecting the specific string to be a string containing alnum, hex, or others ([()+,-.:=@;$_!*']) chars [col %d]"
- errNoUrnWithinID = "expecting the identifier to not contain the \"urn\" reserved string [col %d]"
- errHex = "expecting the specific string hex chars to be well-formed (%%alnum{2}) [col %d]"
- errParse = "parsing error [col %d]"
-)
-
-%%{
-machine urn;
-
-# unsigned alphabet
-alphtype uint8;
-
-action mark {
- m.pb = m.p
-}
-
-action tolower {
- m.tolower = append(m.tolower, m.p - m.pb)
-}
-
-action set_pre {
- output.prefix = string(m.text())
-}
-
-action set_nid {
- output.ID = string(m.text())
-}
-
-action set_nss {
- raw := m.text()
- output.SS = string(raw)
- // Iterate upper letters lowering them
- for _, i := range m.tolower {
- raw[i] = raw[i] + 32
- }
- output.norm = string(raw)
-}
-
-action err_pre {
- m.err = fmt.Errorf(errPrefix, m.p)
- fhold;
- fgoto fail;
-}
-
-action err_nid {
- m.err = fmt.Errorf(errIdentifier, m.p)
- fhold;
- fgoto fail;
-}
-
-action err_nss {
- m.err = fmt.Errorf(errSpecificString, m.p)
- fhold;
- fgoto fail;
-}
-
-action err_urn {
- m.err = fmt.Errorf(errNoUrnWithinID, m.p)
- fhold;
- fgoto fail;
-}
-
-action err_hex {
- m.err = fmt.Errorf(errHex, m.p)
- fhold;
- fgoto fail;
-}
-
-action err_parse {
- m.err = fmt.Errorf(errParse, m.p)
- fhold;
- fgoto fail;
-}
-
-pre = ([uU][rR][nN] @err(err_pre)) >mark %set_pre;
-
-nid = (alnum >mark (alnum | '-'){0,31}) %set_nid;
-
-hex = '%' (digit | lower | upper >tolower){2} $err(err_hex);
-
-sss = (alnum | [()+,\-.:=@;$_!*']);
-
-nss = (sss | hex)+ $err(err_nss);
-
-fail := (any - [\n\r])* @err{ fgoto main; };
-
-main := (pre ':' (nid - pre %err(err_urn)) $err(err_nid) ':' nss >mark %set_nss) $err(err_parse);
-
-}%%
-
-%% write data noerror noprefix;
-
-// Machine is the interface representing the FSM
-type Machine interface {
- Error() error
- Parse(input []byte) (*URN, error)
-}
-
-type machine struct {
- data []byte
- cs int
- p, pe, eof, pb int
- err error
- tolower []int
-}
-
-// NewMachine creates a new FSM able to parse RFC 2141 strings.
-func NewMachine() Machine {
- m := &machine{}
-
- %% access m.;
- %% variable p m.p;
- %% variable pe m.pe;
- %% variable eof m.eof;
- %% variable data m.data;
-
- return m
-}
-
-// Err returns the error that occurred on the last call to Parse.
-//
-// If the result is nil, then the line was parsed successfully.
-func (m *machine) Error() error {
- return m.err
-}
-
-func (m *machine) text() []byte {
- return m.data[m.pb:m.p]
-}
-
-// Parse parses the input byte array as a RFC 2141 string.
-func (m *machine) Parse(input []byte) (*URN, error) {
- m.data = input
- m.p = 0
- m.pb = 0
- m.pe = len(input)
- m.eof = len(input)
- m.err = nil
- m.tolower = []int{}
- output := &URN{}
-
- %% write init;
- %% write exec;
-
- if m.cs < first_final || m.cs == en_fail {
- return nil, m.err
- }
-
- return output, nil
-}
diff --git a/vendor/github.com/leodido/go-urn/makefile b/vendor/github.com/leodido/go-urn/makefile
deleted file mode 100644
index 362137a..0000000
--- a/vendor/github.com/leodido/go-urn/makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-SHELL := /bin/bash
-
-machine.go: machine.go.rl
- ragel -Z -G2 -e -o $@ $<
- @gofmt -w -s $@
- @sed -i '/^\/\/line/d' $@
-
-.PHONY: build
-build: machine.go
-
-.PHONY: bench
-bench: *_test.go machine.go
- go test -bench=. -benchmem -benchtime=5s ./...
-
-.PHONY: tests
-tests: *_test.go machine.go
- go test -race -timeout 10s -coverprofile=coverage.out -covermode=atomic -v ./...
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/urn.go b/vendor/github.com/leodido/go-urn/urn.go
deleted file mode 100644
index b903b7b..0000000
--- a/vendor/github.com/leodido/go-urn/urn.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package urn
-
-import (
- "strings"
-)
-
-// URN represents an Uniform Resource Name.
-//
-// The general form represented is:
-//
-// urn::
-//
-// Details at https://tools.ietf.org/html/rfc2141.
-type URN struct {
- prefix string // Static prefix. Equal to "urn" when empty.
- ID string // Namespace identifier
- SS string // Namespace specific string
- norm string // Normalized namespace specific string
-}
-
-// Normalize turns the receiving URN into its norm version.
-//
-// Which means: lowercase prefix, lowercase namespace identifier, and immutate namespace specific string chars (except tokens which are lowercased).
-func (u *URN) Normalize() *URN {
- return &URN{
- prefix: "urn",
- ID: strings.ToLower(u.ID),
- SS: u.norm,
- }
-}
-
-// Equal checks the lexical equivalence of the current URN with another one.
-func (u *URN) Equal(x *URN) bool {
- return *u.Normalize() == *x.Normalize()
-}
-
-// String reassembles the URN into a valid URN string.
-//
-// This requires both ID and SS fields to be non-empty.
-// Otherwise it returns an empty string.
-//
-// Default URN prefix is "urn".
-func (u *URN) String() string {
- var res string
- if u.ID != "" && u.SS != "" {
- if u.prefix == "" {
- res += "urn"
- }
- res += u.prefix + ":" + u.ID + ":" + u.SS
- }
-
- return res
-}
-
-// Parse is responsible to create an URN instance from a byte array matching the correct URN syntax.
-func Parse(u []byte) (*URN, bool) {
- urn, err := NewMachine().Parse(u)
- if err != nil {
- return nil, false
- }
-
- return urn, true
-}
diff --git a/vendor/github.com/go-playground/universal-translator/.gitignore b/vendor/github.com/spf13/cobra/.gitignore
similarity index 53%
rename from vendor/github.com/go-playground/universal-translator/.gitignore
rename to vendor/github.com/spf13/cobra/.gitignore
index 2661785..1b8c7c2 100644
--- a/vendor/github.com/go-playground/universal-translator/.gitignore
+++ b/vendor/github.com/spf13/cobra/.gitignore
@@ -19,6 +19,18 @@ _cgo_export.*
_testmain.go
+# Vim files https://github.com/github/gitignore/blob/master/Global/Vim.gitignore
+# swap
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+# session
+Session.vim
+# temporary
+.netrwhist
+*~
+# auto-generated tag files
+tags
+
*.exe
-*.test
-*.prof
\ No newline at end of file
+
+cobra.test
diff --git a/vendor/github.com/spf13/cobra/.mailmap b/vendor/github.com/spf13/cobra/.mailmap
new file mode 100644
index 0000000..94ec530
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/.mailmap
@@ -0,0 +1,3 @@
+Steve Francia
+Bjørn Erik Pedersen
+Fabiano Franz
diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml
new file mode 100644
index 0000000..38b85f4
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/.travis.yml
@@ -0,0 +1,31 @@
+language: go
+
+stages:
+ - diff
+ - test
+
+go:
+ - 1.10.x
+ - 1.11.x
+ - 1.12.x
+ - tip
+
+matrix:
+ allow_failures:
+ - go: tip
+ include:
+ - stage: diff
+ go: 1.12.x
+ script: diff -u <(echo -n) <(gofmt -d -s .)
+
+before_install:
+ - mkdir -p bin
+ - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.6.0/shellcheck
+ - chmod +x bin/shellcheck
+ - go get -u github.com/kyoh86/richgo
+script:
+ - PATH=$PATH:$PWD/bin richgo test -v ./...
+ - go build
+ - if [ -z $NOVET ]; then
+ diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
+ fi
diff --git a/vendor/github.com/spf13/cobra/LICENSE.txt b/vendor/github.com/spf13/cobra/LICENSE.txt
new file mode 100644
index 0000000..298f0e2
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/LICENSE.txt
@@ -0,0 +1,174 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md
new file mode 100644
index 0000000..ff16e3f
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/README.md
@@ -0,0 +1,734 @@
+![cobra logo](https://cloud.githubusercontent.com/assets/173412/10886352/ad566232-814f-11e5-9cd0-aa101788c117.png)
+
+Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files.
+
+Many of the most widely used Go projects are built using Cobra, such as:
+[Kubernetes](http://kubernetes.io/),
+[Hugo](http://gohugo.io),
+[rkt](https://github.com/coreos/rkt),
+[etcd](https://github.com/coreos/etcd),
+[Moby (former Docker)](https://github.com/moby/moby),
+[Docker (distribution)](https://github.com/docker/distribution),
+[OpenShift](https://www.openshift.com/),
+[Delve](https://github.com/derekparker/delve),
+[GopherJS](http://www.gopherjs.org/),
+[CockroachDB](http://www.cockroachlabs.com/),
+[Bleve](http://www.blevesearch.com/),
+[ProjectAtomic (enterprise)](http://www.projectatomic.io/),
+[Giant Swarm's gsctl](https://github.com/giantswarm/gsctl),
+[Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack),
+[rclone](http://rclone.org/),
+[nehm](https://github.com/bogem/nehm),
+[Pouch](https://github.com/alibaba/pouch),
+[Istio](https://istio.io),
+[Prototool](https://github.com/uber/prototool),
+[mattermost-server](https://github.com/mattermost/mattermost-server),
+etc.
+
+[![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra)
+[![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra)
+[![GoDoc](https://godoc.org/github.com/spf13/cobra?status.svg)](https://godoc.org/github.com/spf13/cobra)
+
+# Table of Contents
+
+- [Overview](#overview)
+- [Concepts](#concepts)
+ * [Commands](#commands)
+ * [Flags](#flags)
+- [Installing](#installing)
+- [Getting Started](#getting-started)
+ * [Using the Cobra Generator](#using-the-cobra-generator)
+ * [Using the Cobra Library](#using-the-cobra-library)
+ * [Working with Flags](#working-with-flags)
+ * [Positional and Custom Arguments](#positional-and-custom-arguments)
+ * [Example](#example)
+ * [Help Command](#help-command)
+ * [Usage Message](#usage-message)
+ * [PreRun and PostRun Hooks](#prerun-and-postrun-hooks)
+ * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
+ * [Generating documentation for your command](#generating-documentation-for-your-command)
+ * [Generating bash completions](#generating-bash-completions)
+- [Contributing](#contributing)
+- [License](#license)
+
+# Overview
+
+Cobra is a library providing a simple interface to create powerful modern CLI
+interfaces similar to git & go tools.
+
+Cobra is also an application that will generate your application scaffolding to rapidly
+develop a Cobra-based application.
+
+Cobra provides:
+* Easy subcommand-based CLIs: `app server`, `app fetch`, etc.
+* Fully POSIX-compliant flags (including short & long versions)
+* Nested subcommands
+* Global, local and cascading flags
+* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
+* Intelligent suggestions (`app srver`... did you mean `app server`?)
+* Automatic help generation for commands and flags
+* Automatic help flag recognition of `-h`, `--help`, etc.
+* Automatically generated bash autocomplete for your application
+* Automatically generated man pages for your application
+* Command aliases so you can change things without breaking them
+* The flexibility to define your own help, usage, etc.
+* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
+
+# Concepts
+
+Cobra is built on a structure of commands, arguments & flags.
+
+**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions.
+
+The best applications will read like sentences when used. Users will know how
+to use the application because they will natively understand how to use it.
+
+The pattern to follow is
+`APPNAME VERB NOUN --ADJECTIVE.`
+ or
+`APPNAME COMMAND ARG --FLAG`
+
+A few good real world examples may better illustrate this point.
+
+In the following example, 'server' is a command, and 'port' is a flag:
+
+ hugo server --port=1313
+
+In this command we are telling Git to clone the url bare.
+
+ git clone URL --bare
+
+## Commands
+
+Command is the central point of the application. Each interaction that
+the application supports will be contained in a Command. A command can
+have children commands and optionally run an action.
+
+In the example above, 'server' is the command.
+
+[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
+
+## Flags
+
+A flag is a way to modify the behavior of a command. Cobra supports
+fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
+A Cobra command can define flags that persist through to children commands
+and flags that are only available to that command.
+
+In the example above, 'port' is the flag.
+
+Flag functionality is provided by the [pflag
+library](https://github.com/spf13/pflag), a fork of the flag standard library
+which maintains the same interface while adding POSIX compliance.
+
+# Installing
+Using Cobra is easy. First, use `go get` to install the latest version
+of the library. This command will install the `cobra` generator executable
+along with the library and its dependencies:
+
+ go get -u github.com/spf13/cobra/cobra
+
+Next, include Cobra in your application:
+
+```go
+import "github.com/spf13/cobra"
+```
+
+# Getting Started
+
+While you are welcome to provide your own organization, typically a Cobra-based
+application will follow the following organizational structure:
+
+```
+ ▾ appName/
+ ▾ cmd/
+ add.go
+ your.go
+ commands.go
+ here.go
+ main.go
+```
+
+In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra.
+
+```go
+package main
+
+import (
+ "{pathToYourApp}/cmd"
+)
+
+func main() {
+ cmd.Execute()
+}
+```
+
+## Using the Cobra Generator
+
+Cobra provides its own program that will create your application and add any
+commands you want. It's the easiest way to incorporate Cobra into your application.
+
+[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it.
+
+## Using the Cobra Library
+
+To manually implement Cobra you need to create a bare main.go file and a rootCmd file.
+You will optionally provide additional commands as you see fit.
+
+### Create rootCmd
+
+Cobra doesn't require any special constructors. Simply create your commands.
+
+Ideally you place this in app/cmd/root.go:
+
+```go
+var rootCmd = &cobra.Command{
+ Use: "hugo",
+ Short: "Hugo is a very fast static site generator",
+ Long: `A Fast and Flexible Static Site Generator built with
+ love by spf13 and friends in Go.
+ Complete documentation is available at http://hugo.spf13.com`,
+ Run: func(cmd *cobra.Command, args []string) {
+ // Do Stuff Here
+ },
+}
+
+func Execute() {
+ if err := rootCmd.Execute(); err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+```
+
+You will additionally define flags and handle configuration in your init() function.
+
+For example cmd/root.go:
+
+```go
+import (
+ "fmt"
+ "os"
+
+ homedir "github.com/mitchellh/go-homedir"
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
+)
+
+func init() {
+ cobra.OnInitialize(initConfig)
+ rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
+ rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/")
+ rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
+ rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
+ rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
+ viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
+ viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase"))
+ viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
+ viper.SetDefault("author", "NAME HERE ")
+ viper.SetDefault("license", "apache")
+}
+
+func initConfig() {
+ // Don't forget to read config either from cfgFile or from home directory!
+ if cfgFile != "" {
+ // Use config file from the flag.
+ viper.SetConfigFile(cfgFile)
+ } else {
+ // Find home directory.
+ home, err := homedir.Dir()
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ // Search config in home directory with name ".cobra" (without extension).
+ viper.AddConfigPath(home)
+ viper.SetConfigName(".cobra")
+ }
+
+ if err := viper.ReadInConfig(); err != nil {
+ fmt.Println("Can't read config:", err)
+ os.Exit(1)
+ }
+}
+```
+
+### Create your main.go
+
+With the root command you need to have your main function execute it.
+Execute should be run on the root for clarity, though it can be called on any command.
+
+In a Cobra app, typically the main.go file is very bare. It serves, one purpose, to initialize Cobra.
+
+```go
+package main
+
+import (
+ "{pathToYourApp}/cmd"
+)
+
+func main() {
+ cmd.Execute()
+}
+```
+
+### Create additional commands
+
+Additional commands can be defined and typically are each given their own file
+inside of the cmd/ directory.
+
+If you wanted to create a version command you would create cmd/version.go and
+populate it with the following:
+
+```go
+package cmd
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+func init() {
+ rootCmd.AddCommand(versionCmd)
+}
+
+var versionCmd = &cobra.Command{
+ Use: "version",
+ Short: "Print the version number of Hugo",
+ Long: `All software has versions. This is Hugo's`,
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
+ },
+}
+```
+
+## Working with Flags
+
+Flags provide modifiers to control how the action command operates.
+
+### Assign flags to a command
+
+Since the flags are defined and used in different locations, we need to
+define a variable outside with the correct scope to assign the flag to
+work with.
+
+```go
+var Verbose bool
+var Source string
+```
+
+There are two different approaches to assign a flag.
+
+### Persistent Flags
+
+A flag can be 'persistent' meaning that this flag will be available to the
+command it's assigned to as well as every command under that command. For
+global flags, assign a flag as a persistent flag on the root.
+
+```go
+rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
+```
+
+### Local Flags
+
+A flag can also be assigned locally which will only apply to that specific command.
+
+```go
+rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
+```
+
+### Local Flag on Parent Commands
+
+By default Cobra only parses local flags on the target command, any local flags on
+parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
+parse local flags on each command before executing the target command.
+
+```go
+command := cobra.Command{
+ Use: "print [OPTIONS] [COMMANDS]",
+ TraverseChildren: true,
+}
+```
+
+### Bind Flags with Config
+
+You can also bind your flags with [viper](https://github.com/spf13/viper):
+```go
+var author string
+
+func init() {
+ rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
+ viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
+}
+```
+
+In this example the persistent flag `author` is bound with `viper`.
+**Note**, that the variable `author` will not be set to the value from config,
+when the `--author` flag is not provided by user.
+
+More in [viper documentation](https://github.com/spf13/viper#working-with-flags).
+
+### Required flags
+
+Flags are optional by default. If instead you wish your command to report an error
+when a flag has not been set, mark it as required:
+```go
+rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
+rootCmd.MarkFlagRequired("region")
+```
+
+## Positional and Custom Arguments
+
+Validation of positional arguments can be specified using the `Args` field
+of `Command`.
+
+The following validators are built in:
+
+- `NoArgs` - the command will report an error if there are any positional args.
+- `ArbitraryArgs` - the command will accept any args.
+- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`.
+- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
+- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
+- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
+- `ExactValidArgs(int)` - the command will report an error if there are not exactly N positional args OR if there are any positional args that are not in the `ValidArgs` field of `Command`
+- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
+
+An example of setting the custom validator:
+
+```go
+var cmd = &cobra.Command{
+ Short: "hello",
+ Args: func(cmd *cobra.Command, args []string) error {
+ if len(args) < 1 {
+ return errors.New("requires a color argument")
+ }
+ if myapp.IsValidColor(args[0]) {
+ return nil
+ }
+ return fmt.Errorf("invalid color specified: %s", args[0])
+ },
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Println("Hello, World!")
+ },
+}
+```
+
+## Example
+
+In the example below, we have defined three commands. Two are at the top level
+and one (cmdTimes) is a child of one of the top commands. In this case the root
+is not executable meaning that a subcommand is required. This is accomplished
+by not providing a 'Run' for the 'rootCmd'.
+
+We have only defined one flag for a single command.
+
+More documentation about flags is available at https://github.com/spf13/pflag
+
+```go
+package main
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/spf13/cobra"
+)
+
+func main() {
+ var echoTimes int
+
+ var cmdPrint = &cobra.Command{
+ Use: "print [string to print]",
+ Short: "Print anything to the screen",
+ Long: `print is for printing anything back to the screen.
+For many years people have printed back to the screen.`,
+ Args: cobra.MinimumNArgs(1),
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Println("Print: " + strings.Join(args, " "))
+ },
+ }
+
+ var cmdEcho = &cobra.Command{
+ Use: "echo [string to echo]",
+ Short: "Echo anything to the screen",
+ Long: `echo is for echoing anything back.
+Echo works a lot like print, except it has a child command.`,
+ Args: cobra.MinimumNArgs(1),
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Println("Print: " + strings.Join(args, " "))
+ },
+ }
+
+ var cmdTimes = &cobra.Command{
+ Use: "times [string to echo]",
+ Short: "Echo anything to the screen more times",
+ Long: `echo things multiple times back to the user by providing
+a count and a string.`,
+ Args: cobra.MinimumNArgs(1),
+ Run: func(cmd *cobra.Command, args []string) {
+ for i := 0; i < echoTimes; i++ {
+ fmt.Println("Echo: " + strings.Join(args, " "))
+ }
+ },
+ }
+
+ cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
+
+ var rootCmd = &cobra.Command{Use: "app"}
+ rootCmd.AddCommand(cmdPrint, cmdEcho)
+ cmdEcho.AddCommand(cmdTimes)
+ rootCmd.Execute()
+}
+```
+
+For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
+
+## Help Command
+
+Cobra automatically adds a help command to your application when you have subcommands.
+This will be called when a user runs 'app help'. Additionally, help will also
+support all other commands as input. Say, for instance, you have a command called
+'create' without any additional configuration; Cobra will work when 'app help
+create' is called. Every command will automatically have the '--help' flag added.
+
+### Example
+
+The following output is automatically generated by Cobra. Nothing beyond the
+command and flag definitions are needed.
+
+ $ cobra help
+
+ Cobra is a CLI library for Go that empowers applications.
+ This application is a tool to generate the needed files
+ to quickly create a Cobra application.
+
+ Usage:
+ cobra [command]
+
+ Available Commands:
+ add Add a command to a Cobra Application
+ help Help about any command
+ init Initialize a Cobra Application
+
+ Flags:
+ -a, --author string author name for copyright attribution (default "YOUR NAME")
+ --config string config file (default is $HOME/.cobra.yaml)
+ -h, --help help for cobra
+ -l, --license string name of license for the project
+ --viper use Viper for configuration (default true)
+
+ Use "cobra [command] --help" for more information about a command.
+
+
+Help is just a command like any other. There is no special logic or behavior
+around it. In fact, you can provide your own if you want.
+
+### Defining your own help
+
+You can provide your own Help command or your own template for the default command to use
+with following functions:
+
+```go
+cmd.SetHelpCommand(cmd *Command)
+cmd.SetHelpFunc(f func(*Command, []string))
+cmd.SetHelpTemplate(s string)
+```
+
+The latter two will also apply to any children commands.
+
+## Usage Message
+
+When the user provides an invalid flag or invalid command, Cobra responds by
+showing the user the 'usage'.
+
+### Example
+You may recognize this from the help above. That's because the default help
+embeds the usage as part of its output.
+
+ $ cobra --invalid
+ Error: unknown flag: --invalid
+ Usage:
+ cobra [command]
+
+ Available Commands:
+ add Add a command to a Cobra Application
+ help Help about any command
+ init Initialize a Cobra Application
+
+ Flags:
+ -a, --author string author name for copyright attribution (default "YOUR NAME")
+ --config string config file (default is $HOME/.cobra.yaml)
+ -h, --help help for cobra
+ -l, --license string name of license for the project
+ --viper use Viper for configuration (default true)
+
+ Use "cobra [command] --help" for more information about a command.
+
+### Defining your own usage
+You can provide your own usage function or template for Cobra to use.
+Like help, the function and template are overridable through public methods:
+
+```go
+cmd.SetUsageFunc(f func(*Command) error)
+cmd.SetUsageTemplate(s string)
+```
+
+## Version Flag
+
+Cobra adds a top-level '--version' flag if the Version field is set on the root command.
+Running an application with the '--version' flag will print the version to stdout using
+the version template. The template can be customized using the
+`cmd.SetVersionTemplate(s string)` function.
+
+## PreRun and PostRun Hooks
+
+It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherited by children if they do not declare their own. These functions are run in the following order:
+
+- `PersistentPreRun`
+- `PreRun`
+- `Run`
+- `PostRun`
+- `PersistentPostRun`
+
+An example of two commands which use all of these features is below. When the subcommand is executed, it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun`:
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+func main() {
+
+ var rootCmd = &cobra.Command{
+ Use: "root [sub]",
+ Short: "My root command",
+ PersistentPreRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
+ },
+ PreRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
+ },
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside rootCmd Run with args: %v\n", args)
+ },
+ PostRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
+ },
+ PersistentPostRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
+ },
+ }
+
+ var subCmd = &cobra.Command{
+ Use: "sub [no options!]",
+ Short: "My subcommand",
+ PreRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
+ },
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside subCmd Run with args: %v\n", args)
+ },
+ PostRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
+ },
+ PersistentPostRun: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
+ },
+ }
+
+ rootCmd.AddCommand(subCmd)
+
+ rootCmd.SetArgs([]string{""})
+ rootCmd.Execute()
+ fmt.Println()
+ rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
+ rootCmd.Execute()
+}
+```
+
+Output:
+```
+Inside rootCmd PersistentPreRun with args: []
+Inside rootCmd PreRun with args: []
+Inside rootCmd Run with args: []
+Inside rootCmd PostRun with args: []
+Inside rootCmd PersistentPostRun with args: []
+
+Inside rootCmd PersistentPreRun with args: [arg1 arg2]
+Inside subCmd PreRun with args: [arg1 arg2]
+Inside subCmd Run with args: [arg1 arg2]
+Inside subCmd PostRun with args: [arg1 arg2]
+Inside subCmd PersistentPostRun with args: [arg1 arg2]
+```
+
+## Suggestions when "unknown command" happens
+
+Cobra will print automatic suggestions when "unknown command" errors happen. This allows Cobra to behave similarly to the `git` command when a typo happens. For example:
+
+```
+$ hugo srever
+Error: unknown command "srever" for "hugo"
+
+Did you mean this?
+ server
+
+Run 'hugo --help' for usage.
+```
+
+Suggestions are automatic based on every subcommand registered and use an implementation of [Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion.
+
+If you need to disable suggestions or tweak the string distance in your command, use:
+
+```go
+command.DisableSuggestions = true
+```
+
+or
+
+```go
+command.SuggestionsMinimumDistance = 1
+```
+
+You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but makes sense in your set of commands and for some which you don't want aliases. Example:
+
+```
+$ kubectl remove
+Error: unknown command "remove" for "kubectl"
+
+Did you mean this?
+ delete
+
+Run 'kubectl help' for usage.
+```
+
+## Generating documentation for your command
+
+Cobra can generate documentation based on subcommands, flags, etc. in the following formats:
+
+- [Markdown](doc/md_docs.md)
+- [ReStructured Text](doc/rest_docs.md)
+- [Man Page](doc/man_docs.md)
+
+## Generating bash completions
+
+Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md).
+
+# Contributing
+
+1. Fork it
+2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
+3. Create your feature branch (`git checkout -b my-new-feature`)
+4. Make changes and add them (`git add .`)
+5. Commit your changes (`git commit -m 'Add some feature'`)
+6. Push to the branch (`git push origin my-new-feature`)
+7. Create new pull request
+
+# License
+
+Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go
new file mode 100644
index 0000000..c4d820b
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/args.go
@@ -0,0 +1,101 @@
+package cobra
+
+import (
+ "fmt"
+)
+
+type PositionalArgs func(cmd *Command, args []string) error
+
+// Legacy arg validation has the following behaviour:
+// - root commands with no subcommands can take arbitrary arguments
+// - root commands with subcommands will do subcommand validity checking
+// - subcommands will always accept arbitrary arguments
+func legacyArgs(cmd *Command, args []string) error {
+ // no subcommand, always take args
+ if !cmd.HasSubCommands() {
+ return nil
+ }
+
+ // root command with subcommands, do subcommand checking.
+ if !cmd.HasParent() && len(args) > 0 {
+ return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
+ }
+ return nil
+}
+
+// NoArgs returns an error if any args are included.
+func NoArgs(cmd *Command, args []string) error {
+ if len(args) > 0 {
+ return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
+ }
+ return nil
+}
+
+// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
+func OnlyValidArgs(cmd *Command, args []string) error {
+ if len(cmd.ValidArgs) > 0 {
+ for _, v := range args {
+ if !stringInSlice(v, cmd.ValidArgs) {
+ return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
+ }
+ }
+ }
+ return nil
+}
+
+// ArbitraryArgs never returns an error.
+func ArbitraryArgs(cmd *Command, args []string) error {
+ return nil
+}
+
+// MinimumNArgs returns an error if there is not at least N args.
+func MinimumNArgs(n int) PositionalArgs {
+ return func(cmd *Command, args []string) error {
+ if len(args) < n {
+ return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))
+ }
+ return nil
+ }
+}
+
+// MaximumNArgs returns an error if there are more than N args.
+func MaximumNArgs(n int) PositionalArgs {
+ return func(cmd *Command, args []string) error {
+ if len(args) > n {
+ return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))
+ }
+ return nil
+ }
+}
+
+// ExactArgs returns an error if there are not exactly n args.
+func ExactArgs(n int) PositionalArgs {
+ return func(cmd *Command, args []string) error {
+ if len(args) != n {
+ return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))
+ }
+ return nil
+ }
+}
+
+// ExactValidArgs returns an error if
+// there are not exactly N positional args OR
+// there are any positional args that are not in the `ValidArgs` field of `Command`
+func ExactValidArgs(n int) PositionalArgs {
+ return func(cmd *Command, args []string) error {
+ if err := ExactArgs(n)(cmd, args); err != nil {
+ return err
+ }
+ return OnlyValidArgs(cmd, args)
+ }
+}
+
+// RangeArgs returns an error if the number of args is not within the expected range.
+func RangeArgs(min int, max int) PositionalArgs {
+ return func(cmd *Command, args []string) error {
+ if len(args) < min || len(args) > max {
+ return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))
+ }
+ return nil
+ }
+}
diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go
new file mode 100644
index 0000000..c3c1e50
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/bash_completions.go
@@ -0,0 +1,595 @@
+package cobra
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "sort"
+ "strings"
+
+ "github.com/spf13/pflag"
+)
+
+// Annotations for Bash completion.
+const (
+ BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions"
+ BashCompCustom = "cobra_annotation_bash_completion_custom"
+ BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
+ BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
+)
+
+func writePreamble(buf *bytes.Buffer, name string) {
+ buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
+ buf.WriteString(fmt.Sprintf(`
+__%[1]s_debug()
+{
+ if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
+ echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
+ fi
+}
+
+# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
+# _init_completion. This is a very minimal version of that function.
+__%[1]s_init_completion()
+{
+ COMPREPLY=()
+ _get_comp_words_by_ref "$@" cur prev words cword
+}
+
+__%[1]s_index_of_word()
+{
+ local w word=$1
+ shift
+ index=0
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ index=$((index+1))
+ done
+ index=-1
+}
+
+__%[1]s_contains_word()
+{
+ local w word=$1; shift
+ for w in "$@"; do
+ [[ $w = "$word" ]] && return
+ done
+ return 1
+}
+
+__%[1]s_handle_reply()
+{
+ __%[1]s_debug "${FUNCNAME[0]}"
+ case $cur in
+ -*)
+ if [[ $(type -t compopt) = "builtin" ]]; then
+ compopt -o nospace
+ fi
+ local allflags
+ if [ ${#must_have_one_flag[@]} -ne 0 ]; then
+ allflags=("${must_have_one_flag[@]}")
+ else
+ allflags=("${flags[*]} ${two_word_flags[*]}")
+ fi
+ COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
+ if [[ $(type -t compopt) = "builtin" ]]; then
+ [[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
+ fi
+
+ # complete after --flag=abc
+ if [[ $cur == *=* ]]; then
+ if [[ $(type -t compopt) = "builtin" ]]; then
+ compopt +o nospace
+ fi
+
+ local index flag
+ flag="${cur%%=*}"
+ __%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}"
+ COMPREPLY=()
+ if [[ ${index} -ge 0 ]]; then
+ PREFIX=""
+ cur="${cur#*=}"
+ ${flags_completion[${index}]}
+ if [ -n "${ZSH_VERSION}" ]; then
+ # zsh completion needs --flag= prefix
+ eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
+ fi
+ fi
+ fi
+ return 0;
+ ;;
+ esac
+
+ # check if we are handling a flag with special work handling
+ local index
+ __%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}"
+ if [[ ${index} -ge 0 ]]; then
+ ${flags_completion[${index}]}
+ return
+ fi
+
+ # we are parsing a flag and don't have a special handler, no completion
+ if [[ ${cur} != "${words[cword]}" ]]; then
+ return
+ fi
+
+ local completions
+ completions=("${commands[@]}")
+ if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
+ completions=("${must_have_one_noun[@]}")
+ fi
+ if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
+ completions+=("${must_have_one_flag[@]}")
+ fi
+ COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
+
+ if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
+ COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
+ fi
+
+ if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
+ if declare -F __%[1]s_custom_func >/dev/null; then
+ # try command name qualified custom func
+ __%[1]s_custom_func
+ else
+ # otherwise fall back to unqualified for compatibility
+ declare -F __custom_func >/dev/null && __custom_func
+ fi
+ fi
+
+ # available in bash-completion >= 2, not always present on macOS
+ if declare -F __ltrim_colon_completions >/dev/null; then
+ __ltrim_colon_completions "$cur"
+ fi
+
+ # If there is only 1 completion and it is a flag with an = it will be completed
+ # but we don't want a space after the =
+ if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
+ compopt -o nospace
+ fi
+}
+
+# The arguments should be in the form "ext1|ext2|extn"
+__%[1]s_handle_filename_extension_flag()
+{
+ local ext="$1"
+ _filedir "@(${ext})"
+}
+
+__%[1]s_handle_subdirs_in_dir_flag()
+{
+ local dir="$1"
+ pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
+}
+
+__%[1]s_handle_flag()
+{
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+
+ # if a command required a flag, and we found it, unset must_have_one_flag()
+ local flagname=${words[c]}
+ local flagvalue
+ # if the word contained an =
+ if [[ ${words[c]} == *"="* ]]; then
+ flagvalue=${flagname#*=} # take in as flagvalue after the =
+ flagname=${flagname%%=*} # strip everything after the =
+ flagname="${flagname}=" # but put the = back
+ fi
+ __%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}"
+ if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
+ must_have_one_flag=()
+ fi
+
+ # if you set a flag which only applies to this command, don't show subcommands
+ if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
+ commands=()
+ fi
+
+ # keep flag value with flagname as flaghash
+ # flaghash variable is an associative array which is only supported in bash > 3.
+ if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
+ if [ -n "${flagvalue}" ] ; then
+ flaghash[${flagname}]=${flagvalue}
+ elif [ -n "${words[ $((c+1)) ]}" ] ; then
+ flaghash[${flagname}]=${words[ $((c+1)) ]}
+ else
+ flaghash[${flagname}]="true" # pad "true" for bool flag
+ fi
+ fi
+
+ # skip the argument to a two word flag
+ if [[ ${words[c]} != *"="* ]] && __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
+ __%[1]s_debug "${FUNCNAME[0]}: found a flag ${words[c]}, skip the next argument"
+ c=$((c+1))
+ # if we are looking for a flags value, don't show commands
+ if [[ $c -eq $cword ]]; then
+ commands=()
+ fi
+ fi
+
+ c=$((c+1))
+
+}
+
+__%[1]s_handle_noun()
+{
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+
+ if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
+ must_have_one_noun=()
+ elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then
+ must_have_one_noun=()
+ fi
+
+ nouns+=("${words[c]}")
+ c=$((c+1))
+}
+
+__%[1]s_handle_command()
+{
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+
+ local next_command
+ if [[ -n ${last_command} ]]; then
+ next_command="_${last_command}_${words[c]//:/__}"
+ else
+ if [[ $c -eq 0 ]]; then
+ next_command="_%[1]s_root_command"
+ else
+ next_command="_${words[c]//:/__}"
+ fi
+ fi
+ c=$((c+1))
+ __%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}"
+ declare -F "$next_command" >/dev/null && $next_command
+}
+
+__%[1]s_handle_word()
+{
+ if [[ $c -ge $cword ]]; then
+ __%[1]s_handle_reply
+ return
+ fi
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+ if [[ "${words[c]}" == -* ]]; then
+ __%[1]s_handle_flag
+ elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then
+ __%[1]s_handle_command
+ elif [[ $c -eq 0 ]]; then
+ __%[1]s_handle_command
+ elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then
+ # aliashash variable is an associative array which is only supported in bash > 3.
+ if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
+ words[c]=${aliashash[${words[c]}]}
+ __%[1]s_handle_command
+ else
+ __%[1]s_handle_noun
+ fi
+ else
+ __%[1]s_handle_noun
+ fi
+ __%[1]s_handle_word
+}
+
+`, name))
+}
+
+func writePostscript(buf *bytes.Buffer, name string) {
+ name = strings.Replace(name, ":", "__", -1)
+ buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
+ buf.WriteString(fmt.Sprintf(`{
+ local cur prev words cword
+ declare -A flaghash 2>/dev/null || :
+ declare -A aliashash 2>/dev/null || :
+ if declare -F _init_completion >/dev/null 2>&1; then
+ _init_completion -s || return
+ else
+ __%[1]s_init_completion -n "=" || return
+ fi
+
+ local c=0
+ local flags=()
+ local two_word_flags=()
+ local local_nonpersistent_flags=()
+ local flags_with_completion=()
+ local flags_completion=()
+ local commands=("%[1]s")
+ local must_have_one_flag=()
+ local must_have_one_noun=()
+ local last_command
+ local nouns=()
+
+ __%[1]s_handle_word
+}
+
+`, name))
+ buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
+ complete -o default -F __start_%s %s
+else
+ complete -o default -o nospace -F __start_%s %s
+fi
+
+`, name, name, name, name))
+ buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
+}
+
+func writeCommands(buf *bytes.Buffer, cmd *Command) {
+ buf.WriteString(" commands=()\n")
+ for _, c := range cmd.Commands() {
+ if !c.IsAvailableCommand() || c == cmd.helpCommand {
+ continue
+ }
+ buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
+ writeCmdAliases(buf, c)
+ }
+ buf.WriteString("\n")
+}
+
+func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
+ for key, value := range annotations {
+ switch key {
+ case BashCompFilenameExt:
+ buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
+
+ var ext string
+ if len(value) > 0 {
+ ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
+ } else {
+ ext = "_filedir"
+ }
+ buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
+ case BashCompCustom:
+ buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
+ if len(value) > 0 {
+ handlers := strings.Join(value, "; ")
+ buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
+ } else {
+ buf.WriteString(" flags_completion+=(:)\n")
+ }
+ case BashCompSubdirsInDir:
+ buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
+
+ var ext string
+ if len(value) == 1 {
+ ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
+ } else {
+ ext = "_filedir -d"
+ }
+ buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
+ }
+ }
+}
+
+func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
+ name := flag.Shorthand
+ format := " "
+ if len(flag.NoOptDefVal) == 0 {
+ format += "two_word_"
+ }
+ format += "flags+=(\"-%s\")\n"
+ buf.WriteString(fmt.Sprintf(format, name))
+ writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
+}
+
+func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
+ name := flag.Name
+ format := " flags+=(\"--%s"
+ if len(flag.NoOptDefVal) == 0 {
+ format += "="
+ }
+ format += "\")\n"
+ buf.WriteString(fmt.Sprintf(format, name))
+ if len(flag.NoOptDefVal) == 0 {
+ format = " two_word_flags+=(\"--%s\")\n"
+ buf.WriteString(fmt.Sprintf(format, name))
+ }
+ writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
+}
+
+func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
+ name := flag.Name
+ format := " local_nonpersistent_flags+=(\"--%s"
+ if len(flag.NoOptDefVal) == 0 {
+ format += "="
+ }
+ format += "\")\n"
+ buf.WriteString(fmt.Sprintf(format, name))
+}
+
+func writeFlags(buf *bytes.Buffer, cmd *Command) {
+ buf.WriteString(` flags=()
+ two_word_flags=()
+ local_nonpersistent_flags=()
+ flags_with_completion=()
+ flags_completion=()
+
+`)
+ localNonPersistentFlags := cmd.LocalNonPersistentFlags()
+ cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
+ if nonCompletableFlag(flag) {
+ return
+ }
+ writeFlag(buf, flag, cmd)
+ if len(flag.Shorthand) > 0 {
+ writeShortFlag(buf, flag, cmd)
+ }
+ if localNonPersistentFlags.Lookup(flag.Name) != nil {
+ writeLocalNonPersistentFlag(buf, flag)
+ }
+ })
+ cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
+ if nonCompletableFlag(flag) {
+ return
+ }
+ writeFlag(buf, flag, cmd)
+ if len(flag.Shorthand) > 0 {
+ writeShortFlag(buf, flag, cmd)
+ }
+ })
+
+ buf.WriteString("\n")
+}
+
+func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
+ buf.WriteString(" must_have_one_flag=()\n")
+ flags := cmd.NonInheritedFlags()
+ flags.VisitAll(func(flag *pflag.Flag) {
+ if nonCompletableFlag(flag) {
+ return
+ }
+ for key := range flag.Annotations {
+ switch key {
+ case BashCompOneRequiredFlag:
+ format := " must_have_one_flag+=(\"--%s"
+ if flag.Value.Type() != "bool" {
+ format += "="
+ }
+ format += "\")\n"
+ buf.WriteString(fmt.Sprintf(format, flag.Name))
+
+ if len(flag.Shorthand) > 0 {
+ buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
+ }
+ }
+ }
+ })
+}
+
+func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
+ buf.WriteString(" must_have_one_noun=()\n")
+ sort.Sort(sort.StringSlice(cmd.ValidArgs))
+ for _, value := range cmd.ValidArgs {
+ buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
+ }
+}
+
+func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
+ if len(cmd.Aliases) == 0 {
+ return
+ }
+
+ sort.Sort(sort.StringSlice(cmd.Aliases))
+
+ buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
+ for _, value := range cmd.Aliases {
+ buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value))
+ buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
+ }
+ buf.WriteString(` fi`)
+ buf.WriteString("\n")
+}
+func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
+ buf.WriteString(" noun_aliases=()\n")
+ sort.Sort(sort.StringSlice(cmd.ArgAliases))
+ for _, value := range cmd.ArgAliases {
+ buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
+ }
+}
+
+func gen(buf *bytes.Buffer, cmd *Command) {
+ for _, c := range cmd.Commands() {
+ if !c.IsAvailableCommand() || c == cmd.helpCommand {
+ continue
+ }
+ gen(buf, c)
+ }
+ commandName := cmd.CommandPath()
+ commandName = strings.Replace(commandName, " ", "_", -1)
+ commandName = strings.Replace(commandName, ":", "__", -1)
+
+ if cmd.Root() == cmd {
+ buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
+ } else {
+ buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
+ }
+
+ buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
+ buf.WriteString("\n")
+ buf.WriteString(" command_aliases=()\n")
+ buf.WriteString("\n")
+
+ writeCommands(buf, cmd)
+ writeFlags(buf, cmd)
+ writeRequiredFlag(buf, cmd)
+ writeRequiredNouns(buf, cmd)
+ writeArgAliases(buf, cmd)
+ buf.WriteString("}\n\n")
+}
+
+// GenBashCompletion generates bash completion file and writes to the passed writer.
+func (c *Command) GenBashCompletion(w io.Writer) error {
+ buf := new(bytes.Buffer)
+ writePreamble(buf, c.Name())
+ if len(c.BashCompletionFunction) > 0 {
+ buf.WriteString(c.BashCompletionFunction + "\n")
+ }
+ gen(buf, c)
+ writePostscript(buf, c.Name())
+
+ _, err := buf.WriteTo(w)
+ return err
+}
+
+func nonCompletableFlag(flag *pflag.Flag) bool {
+ return flag.Hidden || len(flag.Deprecated) > 0
+}
+
+// GenBashCompletionFile generates bash completion file.
+func (c *Command) GenBashCompletionFile(filename string) error {
+ outFile, err := os.Create(filename)
+ if err != nil {
+ return err
+ }
+ defer outFile.Close()
+
+ return c.GenBashCompletion(outFile)
+}
+
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
+// and causes your command to report an error if invoked without the flag.
+func (c *Command) MarkFlagRequired(name string) error {
+ return MarkFlagRequired(c.Flags(), name)
+}
+
+// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
+// and causes your command to report an error if invoked without the flag.
+func (c *Command) MarkPersistentFlagRequired(name string) error {
+ return MarkFlagRequired(c.PersistentFlags(), name)
+}
+
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
+// and causes your command to report an error if invoked without the flag.
+func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
+ return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
+}
+
+// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
+// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
+func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
+ return MarkFlagFilename(c.Flags(), name, extensions...)
+}
+
+// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
+// Generated bash autocompletion will call the bash function f for the flag.
+func (c *Command) MarkFlagCustom(name string, f string) error {
+ return MarkFlagCustom(c.Flags(), name, f)
+}
+
+// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
+// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
+func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
+ return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
+}
+
+// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
+// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
+func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {
+ return flags.SetAnnotation(name, BashCompFilenameExt, extensions)
+}
+
+// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists.
+// Generated bash autocompletion will call the bash function f for the flag.
+func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {
+ return flags.SetAnnotation(name, BashCompCustom, []string{f})
+}
diff --git a/vendor/github.com/spf13/cobra/bash_completions.md b/vendor/github.com/spf13/cobra/bash_completions.md
new file mode 100644
index 0000000..4ac61ee
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/bash_completions.md
@@ -0,0 +1,256 @@
+# Generating Bash Completions For Your Own cobra.Command
+
+If you are using the generator you can create a completion command by running
+
+```bash
+cobra add completion
+```
+
+Update the help text show how to install the bash_completion Linux show here [Kubectl docs show mac options](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion)
+
+Writing the shell script to stdout allows the most flexible use.
+
+```go
+// completionCmd represents the completion command
+var completionCmd = &cobra.Command{
+ Use: "completion",
+ Short: "Generates bash completion scripts",
+ Long: `To load completion run
+
+. <(bitbucket completion)
+
+To configure your bash shell to load completions for each session add to your bashrc
+
+# ~/.bashrc or ~/.profile
+. <(bitbucket completion)
+`,
+ Run: func(cmd *cobra.Command, args []string) {
+ rootCmd.GenBashCompletion(os.Stdout);
+ },
+}
+```
+
+**Note:** The cobra generator may include messages printed to stdout for example if the config file is loaded, this will break the auto complete script
+
+
+## Example from kubectl
+
+Generating bash completions from a cobra command is incredibly easy. An actual program which does so for the kubernetes kubectl binary is as follows:
+
+```go
+package main
+
+import (
+ "io/ioutil"
+ "os"
+
+ "k8s.io/kubernetes/pkg/kubectl/cmd"
+ "k8s.io/kubernetes/pkg/kubectl/cmd/util"
+)
+
+func main() {
+ kubectl := cmd.NewKubectlCommand(util.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
+ kubectl.GenBashCompletionFile("out.sh")
+}
+```
+
+`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
+
+## Creating your own custom functions
+
+Some more actual code that works in kubernetes:
+
+```bash
+const (
+ bash_completion_func = `__kubectl_parse_get()
+{
+ local kubectl_output out
+ if kubectl_output=$(kubectl get --no-headers "$1" 2>/dev/null); then
+ out=($(echo "${kubectl_output}" | awk '{print $1}'))
+ COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) )
+ fi
+}
+
+__kubectl_get_resource()
+{
+ if [[ ${#nouns[@]} -eq 0 ]]; then
+ return 1
+ fi
+ __kubectl_parse_get ${nouns[${#nouns[@]} -1]}
+ if [[ $? -eq 0 ]]; then
+ return 0
+ fi
+}
+
+__kubectl_custom_func() {
+ case ${last_command} in
+ kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop)
+ __kubectl_get_resource
+ return
+ ;;
+ *)
+ ;;
+ esac
+}
+`)
+```
+
+And then I set that in my command definition:
+
+```go
+cmds := &cobra.Command{
+ Use: "kubectl",
+ Short: "kubectl controls the Kubernetes cluster manager",
+ Long: `kubectl controls the Kubernetes cluster manager.
+
+Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
+ Run: runHelp,
+ BashCompletionFunction: bash_completion_func,
+}
+```
+
+The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__kubectl_custom_func()` (`___custom_func()`) to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__kubectl_customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__kubectl_custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods!
+
+## Have the completions code complete your 'nouns'
+
+In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like:
+
+```go
+validArgs []string = { "pod", "node", "service", "replicationcontroller" }
+
+cmd := &cobra.Command{
+ Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",
+ Short: "Display one or many resources",
+ Long: get_long,
+ Example: get_example,
+ Run: func(cmd *cobra.Command, args []string) {
+ err := RunGet(f, out, cmd, args)
+ util.CheckErr(err)
+ },
+ ValidArgs: validArgs,
+}
+```
+
+Notice we put the "ValidArgs" on the "get" subcommand. Doing so will give results like
+
+```bash
+# kubectl get [tab][tab]
+node pod replicationcontroller service
+```
+
+## Plural form and shortcuts for nouns
+
+If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
+
+```go
+argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
+
+cmd := &cobra.Command{
+ ...
+ ValidArgs: validArgs,
+ ArgAliases: argAliases
+}
+```
+
+The aliases are not shown to the user on tab completion, but they are accepted as valid nouns by
+the completion algorithm if entered manually, e.g. in:
+
+```bash
+# kubectl get rc [tab][tab]
+backend frontend database
+```
+
+Note that without declaring `rc` as an alias, the completion algorithm would show the list of nouns
+in this example again instead of the replication controllers.
+
+## Mark flags as required
+
+Most of the time completions will only show subcommands. But if a flag is required to make a subcommand work, you probably want it to show up when the user types [tab][tab]. Marking a flag as 'Required' is incredibly easy.
+
+```go
+cmd.MarkFlagRequired("pod")
+cmd.MarkFlagRequired("container")
+```
+
+and you'll get something like
+
+```bash
+# kubectl exec [tab][tab][tab]
+-c --container= -p --pod=
+```
+
+# Specify valid filename extensions for flags that take a filename
+
+In this example we use --filename= and expect to get a json or yaml file as the argument. To make this easier we annotate the --filename flag with valid filename extensions.
+
+```go
+ annotations := []string{"json", "yaml", "yml"}
+ annotation := make(map[string][]string)
+ annotation[cobra.BashCompFilenameExt] = annotations
+
+ flag := &pflag.Flag{
+ Name: "filename",
+ Shorthand: "f",
+ Usage: usage,
+ Value: value,
+ DefValue: value.String(),
+ Annotations: annotation,
+ }
+ cmd.Flags().AddFlag(flag)
+```
+
+Now when you run a command with this filename flag you'll get something like
+
+```bash
+# kubectl create -f
+test/ example/ rpmbuild/
+hello.yml test.json
+```
+
+So while there are many other files in the CWD it only shows me subdirs and those with valid extensions.
+
+# Specify custom flag completion
+
+Similar to the filename completion and filtering using cobra.BashCompFilenameExt, you can specify
+a custom flag completion function with cobra.BashCompCustom:
+
+```go
+ annotation := make(map[string][]string)
+ annotation[cobra.BashCompCustom] = []string{"__kubectl_get_namespaces"}
+
+ flag := &pflag.Flag{
+ Name: "namespace",
+ Usage: usage,
+ Annotations: annotation,
+ }
+ cmd.Flags().AddFlag(flag)
+```
+
+In addition add the `__handle_namespace_flag` implementation in the `BashCompletionFunction`
+value, e.g.:
+
+```bash
+__kubectl_get_namespaces()
+{
+ local template
+ template="{{ range .items }}{{ .metadata.name }} {{ end }}"
+ local kubectl_out
+ if kubectl_out=$(kubectl get -o template --template="${template}" namespace 2>/dev/null); then
+ COMPREPLY=( $( compgen -W "${kubectl_out}[*]" -- "$cur" ) )
+ fi
+}
+```
+# Using bash aliases for commands
+
+You can also configure the `bash aliases` for the commands and they will also support completions.
+
+```bash
+alias aliasname=origcommand
+complete -o default -F __start_origcommand aliasname
+
+# and now when you run `aliasname` completion will make
+# suggestions as it did for `origcommand`.
+
+$) aliasname
+completion firstcommand secondcommand
+```
diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go
new file mode 100644
index 0000000..6505c07
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/cobra.go
@@ -0,0 +1,207 @@
+// Copyright © 2013 Steve Francia .
+//
+// 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.
+
+// Commands similar to git, go tools and other modern CLI tools
+// inspired by go, go-Commander, gh and subcommand
+
+package cobra
+
+import (
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "strings"
+ "text/template"
+ "time"
+ "unicode"
+)
+
+var templateFuncs = template.FuncMap{
+ "trim": strings.TrimSpace,
+ "trimRightSpace": trimRightSpace,
+ "trimTrailingWhitespaces": trimRightSpace,
+ "appendIfNotPresent": appendIfNotPresent,
+ "rpad": rpad,
+ "gt": Gt,
+ "eq": Eq,
+}
+
+var initializers []func()
+
+// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
+// to automatically enable in CLI tools.
+// Set this to true to enable it.
+var EnablePrefixMatching = false
+
+// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
+// To disable sorting, set it to false.
+var EnableCommandSorting = true
+
+// MousetrapHelpText enables an information splash screen on Windows
+// if the CLI is started from explorer.exe.
+// To disable the mousetrap, just set this variable to blank string ("").
+// Works only on Microsoft Windows.
+var MousetrapHelpText string = `This is a command line tool.
+
+You need to open cmd.exe and run it from there.
+`
+
+// MousetrapDisplayDuration controls how long the MousetrapHelpText message is displayed on Windows
+// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed.
+// To disable the mousetrap, just set MousetrapHelpText to blank string ("").
+// Works only on Microsoft Windows.
+var MousetrapDisplayDuration time.Duration = 5 * time.Second
+
+// AddTemplateFunc adds a template function that's available to Usage and Help
+// template generation.
+func AddTemplateFunc(name string, tmplFunc interface{}) {
+ templateFuncs[name] = tmplFunc
+}
+
+// AddTemplateFuncs adds multiple template functions that are available to Usage and
+// Help template generation.
+func AddTemplateFuncs(tmplFuncs template.FuncMap) {
+ for k, v := range tmplFuncs {
+ templateFuncs[k] = v
+ }
+}
+
+// OnInitialize sets the passed functions to be run when each command's
+// Execute method is called.
+func OnInitialize(y ...func()) {
+ initializers = append(initializers, y...)
+}
+
+// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
+
+// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
+// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
+// ints and then compared.
+func Gt(a interface{}, b interface{}) bool {
+ var left, right int64
+ av := reflect.ValueOf(a)
+
+ switch av.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+ left = int64(av.Len())
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ left = av.Int()
+ case reflect.String:
+ left, _ = strconv.ParseInt(av.String(), 10, 64)
+ }
+
+ bv := reflect.ValueOf(b)
+
+ switch bv.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+ right = int64(bv.Len())
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ right = bv.Int()
+ case reflect.String:
+ right, _ = strconv.ParseInt(bv.String(), 10, 64)
+ }
+
+ return left > right
+}
+
+// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
+
+// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
+func Eq(a interface{}, b interface{}) bool {
+ av := reflect.ValueOf(a)
+ bv := reflect.ValueOf(b)
+
+ switch av.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+ panic("Eq called on unsupported type")
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return av.Int() == bv.Int()
+ case reflect.String:
+ return av.String() == bv.String()
+ }
+ return false
+}
+
+func trimRightSpace(s string) string {
+ return strings.TrimRightFunc(s, unicode.IsSpace)
+}
+
+// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
+
+// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
+func appendIfNotPresent(s, stringToAppend string) string {
+ if strings.Contains(s, stringToAppend) {
+ return s
+ }
+ return s + " " + stringToAppend
+}
+
+// rpad adds padding to the right of a string.
+func rpad(s string, padding int) string {
+ template := fmt.Sprintf("%%-%ds", padding)
+ return fmt.Sprintf(template, s)
+}
+
+// tmpl executes the given template text on data, writing the result to w.
+func tmpl(w io.Writer, text string, data interface{}) error {
+ t := template.New("top")
+ t.Funcs(templateFuncs)
+ template.Must(t.Parse(text))
+ return t.Execute(w, data)
+}
+
+// ld compares two strings and returns the levenshtein distance between them.
+func ld(s, t string, ignoreCase bool) int {
+ if ignoreCase {
+ s = strings.ToLower(s)
+ t = strings.ToLower(t)
+ }
+ d := make([][]int, len(s)+1)
+ for i := range d {
+ d[i] = make([]int, len(t)+1)
+ }
+ for i := range d {
+ d[i][0] = i
+ }
+ for j := range d[0] {
+ d[0][j] = j
+ }
+ for j := 1; j <= len(t); j++ {
+ for i := 1; i <= len(s); i++ {
+ if s[i-1] == t[j-1] {
+ d[i][j] = d[i-1][j-1]
+ } else {
+ min := d[i-1][j]
+ if d[i][j-1] < min {
+ min = d[i][j-1]
+ }
+ if d[i-1][j-1] < min {
+ min = d[i-1][j-1]
+ }
+ d[i][j] = min + 1
+ }
+ }
+
+ }
+ return d[len(s)][len(t)]
+}
+
+func stringInSlice(a string, list []string) bool {
+ for _, b := range list {
+ if b == a {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go
new file mode 100644
index 0000000..b257f91
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/command.go
@@ -0,0 +1,1515 @@
+// Copyright © 2013 Steve Francia .
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.
+// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.
+package cobra
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ flag "github.com/spf13/pflag"
+)
+
+// FParseErrWhitelist configures Flag parse errors to be ignored
+type FParseErrWhitelist flag.ParseErrorsWhitelist
+
+// Command is just that, a command for your application.
+// E.g. 'go run ...' - 'run' is the command. Cobra requires
+// you to define the usage and description as part of your command
+// definition to ensure usability.
+type Command struct {
+ // Use is the one-line usage message.
+ Use string
+
+ // Aliases is an array of aliases that can be used instead of the first word in Use.
+ Aliases []string
+
+ // SuggestFor is an array of command names for which this command will be suggested -
+ // similar to aliases but only suggests.
+ SuggestFor []string
+
+ // Short is the short description shown in the 'help' output.
+ Short string
+
+ // Long is the long message shown in the 'help ' output.
+ Long string
+
+ // Example is examples of how to use the command.
+ Example string
+
+ // ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
+ ValidArgs []string
+
+ // Expected arguments
+ Args PositionalArgs
+
+ // ArgAliases is List of aliases for ValidArgs.
+ // These are not suggested to the user in the bash completion,
+ // but accepted if entered manually.
+ ArgAliases []string
+
+ // BashCompletionFunction is custom functions used by the bash autocompletion generator.
+ BashCompletionFunction string
+
+ // Deprecated defines, if this command is deprecated and should print this string when used.
+ Deprecated string
+
+ // Hidden defines, if this command is hidden and should NOT show up in the list of available commands.
+ Hidden bool
+
+ // Annotations are key/value pairs that can be used by applications to identify or
+ // group commands.
+ Annotations map[string]string
+
+ // Version defines the version for this command. If this value is non-empty and the command does not
+ // define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
+ // will print content of the "Version" variable.
+ Version string
+
+ // The *Run functions are executed in the following order:
+ // * PersistentPreRun()
+ // * PreRun()
+ // * Run()
+ // * PostRun()
+ // * PersistentPostRun()
+ // All functions get the same args, the arguments after the command name.
+ //
+ // PersistentPreRun: children of this command will inherit and execute.
+ PersistentPreRun func(cmd *Command, args []string)
+ // PersistentPreRunE: PersistentPreRun but returns an error.
+ PersistentPreRunE func(cmd *Command, args []string) error
+ // PreRun: children of this command will not inherit.
+ PreRun func(cmd *Command, args []string)
+ // PreRunE: PreRun but returns an error.
+ PreRunE func(cmd *Command, args []string) error
+ // Run: Typically the actual work function. Most commands will only implement this.
+ Run func(cmd *Command, args []string)
+ // RunE: Run but returns an error.
+ RunE func(cmd *Command, args []string) error
+ // PostRun: run after the Run command.
+ PostRun func(cmd *Command, args []string)
+ // PostRunE: PostRun but returns an error.
+ PostRunE func(cmd *Command, args []string) error
+ // PersistentPostRun: children of this command will inherit and execute after PostRun.
+ PersistentPostRun func(cmd *Command, args []string)
+ // PersistentPostRunE: PersistentPostRun but returns an error.
+ PersistentPostRunE func(cmd *Command, args []string) error
+
+ // SilenceErrors is an option to quiet errors down stream.
+ SilenceErrors bool
+
+ // SilenceUsage is an option to silence usage when an error occurs.
+ SilenceUsage bool
+
+ // DisableFlagParsing disables the flag parsing.
+ // If this is true all flags will be passed to the command as arguments.
+ DisableFlagParsing bool
+
+ // DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...")
+ // will be printed by generating docs for this command.
+ DisableAutoGenTag bool
+
+ // DisableFlagsInUseLine will disable the addition of [flags] to the usage
+ // line of a command when printing help or generating docs
+ DisableFlagsInUseLine bool
+
+ // DisableSuggestions disables the suggestions based on Levenshtein distance
+ // that go along with 'unknown command' messages.
+ DisableSuggestions bool
+ // SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.
+ // Must be > 0.
+ SuggestionsMinimumDistance int
+
+ // TraverseChildren parses flags on all parents before executing child command.
+ TraverseChildren bool
+
+ //FParseErrWhitelist flag parse errors to be ignored
+ FParseErrWhitelist FParseErrWhitelist
+
+ // commands is the list of commands supported by this program.
+ commands []*Command
+ // parent is a parent command for this command.
+ parent *Command
+ // Max lengths of commands' string lengths for use in padding.
+ commandsMaxUseLen int
+ commandsMaxCommandPathLen int
+ commandsMaxNameLen int
+ // commandsAreSorted defines, if command slice are sorted or not.
+ commandsAreSorted bool
+ // commandCalledAs is the name or alias value used to call this command.
+ commandCalledAs struct {
+ name string
+ called bool
+ }
+
+ // args is actual args parsed from flags.
+ args []string
+ // flagErrorBuf contains all error messages from pflag.
+ flagErrorBuf *bytes.Buffer
+ // flags is full set of flags.
+ flags *flag.FlagSet
+ // pflags contains persistent flags.
+ pflags *flag.FlagSet
+ // lflags contains local flags.
+ lflags *flag.FlagSet
+ // iflags contains inherited flags.
+ iflags *flag.FlagSet
+ // parentsPflags is all persistent flags of cmd's parents.
+ parentsPflags *flag.FlagSet
+ // globNormFunc is the global normalization function
+ // that we can use on every pflag set and children commands
+ globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName
+
+ // output is an output writer defined by user.
+ output io.Writer
+ // usageFunc is usage func defined by user.
+ usageFunc func(*Command) error
+ // usageTemplate is usage template defined by user.
+ usageTemplate string
+ // flagErrorFunc is func defined by user and it's called when the parsing of
+ // flags returns an error.
+ flagErrorFunc func(*Command, error) error
+ // helpTemplate is help template defined by user.
+ helpTemplate string
+ // helpFunc is help func defined by user.
+ helpFunc func(*Command, []string)
+ // helpCommand is command with usage 'help'. If it's not defined by user,
+ // cobra uses default help command.
+ helpCommand *Command
+ // versionTemplate is the version template defined by user.
+ versionTemplate string
+}
+
+// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
+// particularly useful when testing.
+func (c *Command) SetArgs(a []string) {
+ c.args = a
+}
+
+// SetOutput sets the destination for usage and error messages.
+// If output is nil, os.Stderr is used.
+func (c *Command) SetOutput(output io.Writer) {
+ c.output = output
+}
+
+// SetUsageFunc sets usage function. Usage can be defined by application.
+func (c *Command) SetUsageFunc(f func(*Command) error) {
+ c.usageFunc = f
+}
+
+// SetUsageTemplate sets usage template. Can be defined by Application.
+func (c *Command) SetUsageTemplate(s string) {
+ c.usageTemplate = s
+}
+
+// SetFlagErrorFunc sets a function to generate an error when flag parsing
+// fails.
+func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
+ c.flagErrorFunc = f
+}
+
+// SetHelpFunc sets help function. Can be defined by Application.
+func (c *Command) SetHelpFunc(f func(*Command, []string)) {
+ c.helpFunc = f
+}
+
+// SetHelpCommand sets help command.
+func (c *Command) SetHelpCommand(cmd *Command) {
+ c.helpCommand = cmd
+}
+
+// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
+func (c *Command) SetHelpTemplate(s string) {
+ c.helpTemplate = s
+}
+
+// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
+func (c *Command) SetVersionTemplate(s string) {
+ c.versionTemplate = s
+}
+
+// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
+// The user should not have a cyclic dependency on commands.
+func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
+ c.Flags().SetNormalizeFunc(n)
+ c.PersistentFlags().SetNormalizeFunc(n)
+ c.globNormFunc = n
+
+ for _, command := range c.commands {
+ command.SetGlobalNormalizationFunc(n)
+ }
+}
+
+// OutOrStdout returns output to stdout.
+func (c *Command) OutOrStdout() io.Writer {
+ return c.getOut(os.Stdout)
+}
+
+// OutOrStderr returns output to stderr
+func (c *Command) OutOrStderr() io.Writer {
+ return c.getOut(os.Stderr)
+}
+
+func (c *Command) getOut(def io.Writer) io.Writer {
+ if c.output != nil {
+ return c.output
+ }
+ if c.HasParent() {
+ return c.parent.getOut(def)
+ }
+ return def
+}
+
+// UsageFunc returns either the function set by SetUsageFunc for this command
+// or a parent, or it returns a default usage function.
+func (c *Command) UsageFunc() (f func(*Command) error) {
+ if c.usageFunc != nil {
+ return c.usageFunc
+ }
+ if c.HasParent() {
+ return c.Parent().UsageFunc()
+ }
+ return func(c *Command) error {
+ c.mergePersistentFlags()
+ err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)
+ if err != nil {
+ c.Println(err)
+ }
+ return err
+ }
+}
+
+// Usage puts out the usage for the command.
+// Used when a user provides invalid input.
+// Can be defined by user by overriding UsageFunc.
+func (c *Command) Usage() error {
+ return c.UsageFunc()(c)
+}
+
+// HelpFunc returns either the function set by SetHelpFunc for this command
+// or a parent, or it returns a function with default help behavior.
+func (c *Command) HelpFunc() func(*Command, []string) {
+ if c.helpFunc != nil {
+ return c.helpFunc
+ }
+ if c.HasParent() {
+ return c.Parent().HelpFunc()
+ }
+ return func(c *Command, a []string) {
+ c.mergePersistentFlags()
+ err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
+ if err != nil {
+ c.Println(err)
+ }
+ }
+}
+
+// Help puts out the help for the command.
+// Used when a user calls help [command].
+// Can be defined by user by overriding HelpFunc.
+func (c *Command) Help() error {
+ c.HelpFunc()(c, []string{})
+ return nil
+}
+
+// UsageString return usage string.
+func (c *Command) UsageString() string {
+ tmpOutput := c.output
+ bb := new(bytes.Buffer)
+ c.SetOutput(bb)
+ c.Usage()
+ c.output = tmpOutput
+ return bb.String()
+}
+
+// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
+// command or a parent, or it returns a function which returns the original
+// error.
+func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
+ if c.flagErrorFunc != nil {
+ return c.flagErrorFunc
+ }
+
+ if c.HasParent() {
+ return c.parent.FlagErrorFunc()
+ }
+ return func(c *Command, err error) error {
+ return err
+ }
+}
+
+var minUsagePadding = 25
+
+// UsagePadding return padding for the usage.
+func (c *Command) UsagePadding() int {
+ if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
+ return minUsagePadding
+ }
+ return c.parent.commandsMaxUseLen
+}
+
+var minCommandPathPadding = 11
+
+// CommandPathPadding return padding for the command path.
+func (c *Command) CommandPathPadding() int {
+ if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
+ return minCommandPathPadding
+ }
+ return c.parent.commandsMaxCommandPathLen
+}
+
+var minNamePadding = 11
+
+// NamePadding returns padding for the name.
+func (c *Command) NamePadding() int {
+ if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
+ return minNamePadding
+ }
+ return c.parent.commandsMaxNameLen
+}
+
+// UsageTemplate returns usage template for the command.
+func (c *Command) UsageTemplate() string {
+ if c.usageTemplate != "" {
+ return c.usageTemplate
+ }
+
+ if c.HasParent() {
+ return c.parent.UsageTemplate()
+ }
+ return `Usage:{{if .Runnable}}
+ {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
+ {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
+
+Aliases:
+ {{.NameAndAliases}}{{end}}{{if .HasExample}}
+
+Examples:
+{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
+
+Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
+
+Flags:
+{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
+
+Global Flags:
+{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
+
+Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
+ {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
+
+Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
+`
+}
+
+// HelpTemplate return help template for the command.
+func (c *Command) HelpTemplate() string {
+ if c.helpTemplate != "" {
+ return c.helpTemplate
+ }
+
+ if c.HasParent() {
+ return c.parent.HelpTemplate()
+ }
+ return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}
+
+{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
+}
+
+// VersionTemplate return version template for the command.
+func (c *Command) VersionTemplate() string {
+ if c.versionTemplate != "" {
+ return c.versionTemplate
+ }
+
+ if c.HasParent() {
+ return c.parent.VersionTemplate()
+ }
+ return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}}
+`
+}
+
+func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
+ flag := fs.Lookup(name)
+ if flag == nil {
+ return false
+ }
+ return flag.NoOptDefVal != ""
+}
+
+func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
+ if len(name) == 0 {
+ return false
+ }
+
+ flag := fs.ShorthandLookup(name[:1])
+ if flag == nil {
+ return false
+ }
+ return flag.NoOptDefVal != ""
+}
+
+func stripFlags(args []string, c *Command) []string {
+ if len(args) == 0 {
+ return args
+ }
+ c.mergePersistentFlags()
+
+ commands := []string{}
+ flags := c.Flags()
+
+Loop:
+ for len(args) > 0 {
+ s := args[0]
+ args = args[1:]
+ switch {
+ case s == "--":
+ // "--" terminates the flags
+ break Loop
+ case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
+ // If '--flag arg' then
+ // delete arg from args.
+ fallthrough // (do the same as below)
+ case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):
+ // If '-f arg' then
+ // delete 'arg' from args or break the loop if len(args) <= 1.
+ if len(args) <= 1 {
+ break Loop
+ } else {
+ args = args[1:]
+ continue
+ }
+ case s != "" && !strings.HasPrefix(s, "-"):
+ commands = append(commands, s)
+ }
+ }
+
+ return commands
+}
+
+// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like
+// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).
+func argsMinusFirstX(args []string, x string) []string {
+ for i, y := range args {
+ if x == y {
+ ret := []string{}
+ ret = append(ret, args[:i]...)
+ ret = append(ret, args[i+1:]...)
+ return ret
+ }
+ }
+ return args
+}
+
+func isFlagArg(arg string) bool {
+ return ((len(arg) >= 3 && arg[1] == '-') ||
+ (len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
+}
+
+// Find the target command given the args and command tree
+// Meant to be run on the highest node. Only searches down.
+func (c *Command) Find(args []string) (*Command, []string, error) {
+ var innerfind func(*Command, []string) (*Command, []string)
+
+ innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
+ argsWOflags := stripFlags(innerArgs, c)
+ if len(argsWOflags) == 0 {
+ return c, innerArgs
+ }
+ nextSubCmd := argsWOflags[0]
+
+ cmd := c.findNext(nextSubCmd)
+ if cmd != nil {
+ return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
+ }
+ return c, innerArgs
+ }
+
+ commandFound, a := innerfind(c, args)
+ if commandFound.Args == nil {
+ return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
+ }
+ return commandFound, a, nil
+}
+
+func (c *Command) findSuggestions(arg string) string {
+ if c.DisableSuggestions {
+ return ""
+ }
+ if c.SuggestionsMinimumDistance <= 0 {
+ c.SuggestionsMinimumDistance = 2
+ }
+ suggestionsString := ""
+ if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
+ suggestionsString += "\n\nDid you mean this?\n"
+ for _, s := range suggestions {
+ suggestionsString += fmt.Sprintf("\t%v\n", s)
+ }
+ }
+ return suggestionsString
+}
+
+func (c *Command) findNext(next string) *Command {
+ matches := make([]*Command, 0)
+ for _, cmd := range c.commands {
+ if cmd.Name() == next || cmd.HasAlias(next) {
+ cmd.commandCalledAs.name = next
+ return cmd
+ }
+ if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
+ matches = append(matches, cmd)
+ }
+ }
+
+ if len(matches) == 1 {
+ return matches[0]
+ }
+
+ return nil
+}
+
+// Traverse the command tree to find the command, and parse args for
+// each parent.
+func (c *Command) Traverse(args []string) (*Command, []string, error) {
+ flags := []string{}
+ inFlag := false
+
+ for i, arg := range args {
+ switch {
+ // A long flag with a space separated value
+ case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
+ // TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
+ inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
+ flags = append(flags, arg)
+ continue
+ // A short flag with a space separated value
+ case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
+ inFlag = true
+ flags = append(flags, arg)
+ continue
+ // The value for a flag
+ case inFlag:
+ inFlag = false
+ flags = append(flags, arg)
+ continue
+ // A flag without a value, or with an `=` separated value
+ case isFlagArg(arg):
+ flags = append(flags, arg)
+ continue
+ }
+
+ cmd := c.findNext(arg)
+ if cmd == nil {
+ return c, args, nil
+ }
+
+ if err := c.ParseFlags(flags); err != nil {
+ return nil, args, err
+ }
+ return cmd.Traverse(args[i+1:])
+ }
+ return c, args, nil
+}
+
+// SuggestionsFor provides suggestions for the typedName.
+func (c *Command) SuggestionsFor(typedName string) []string {
+ suggestions := []string{}
+ for _, cmd := range c.commands {
+ if cmd.IsAvailableCommand() {
+ levenshteinDistance := ld(typedName, cmd.Name(), true)
+ suggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance
+ suggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))
+ if suggestByLevenshtein || suggestByPrefix {
+ suggestions = append(suggestions, cmd.Name())
+ }
+ for _, explicitSuggestion := range cmd.SuggestFor {
+ if strings.EqualFold(typedName, explicitSuggestion) {
+ suggestions = append(suggestions, cmd.Name())
+ }
+ }
+ }
+ }
+ return suggestions
+}
+
+// VisitParents visits all parents of the command and invokes fn on each parent.
+func (c *Command) VisitParents(fn func(*Command)) {
+ if c.HasParent() {
+ fn(c.Parent())
+ c.Parent().VisitParents(fn)
+ }
+}
+
+// Root finds root command.
+func (c *Command) Root() *Command {
+ if c.HasParent() {
+ return c.Parent().Root()
+ }
+ return c
+}
+
+// ArgsLenAtDash will return the length of c.Flags().Args at the moment
+// when a -- was found during args parsing.
+func (c *Command) ArgsLenAtDash() int {
+ return c.Flags().ArgsLenAtDash()
+}
+
+func (c *Command) execute(a []string) (err error) {
+ if c == nil {
+ return fmt.Errorf("Called Execute() on a nil Command")
+ }
+
+ if len(c.Deprecated) > 0 {
+ c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
+ }
+
+ // initialize help and version flag at the last point possible to allow for user
+ // overriding
+ c.InitDefaultHelpFlag()
+ c.InitDefaultVersionFlag()
+
+ err = c.ParseFlags(a)
+ if err != nil {
+ return c.FlagErrorFunc()(c, err)
+ }
+
+ // If help is called, regardless of other flags, return we want help.
+ // Also say we need help if the command isn't runnable.
+ helpVal, err := c.Flags().GetBool("help")
+ if err != nil {
+ // should be impossible to get here as we always declare a help
+ // flag in InitDefaultHelpFlag()
+ c.Println("\"help\" flag declared as non-bool. Please correct your code")
+ return err
+ }
+
+ if helpVal {
+ return flag.ErrHelp
+ }
+
+ // for back-compat, only add version flag behavior if version is defined
+ if c.Version != "" {
+ versionVal, err := c.Flags().GetBool("version")
+ if err != nil {
+ c.Println("\"version\" flag declared as non-bool. Please correct your code")
+ return err
+ }
+ if versionVal {
+ err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)
+ if err != nil {
+ c.Println(err)
+ }
+ return err
+ }
+ }
+
+ if !c.Runnable() {
+ return flag.ErrHelp
+ }
+
+ c.preRun()
+
+ argWoFlags := c.Flags().Args()
+ if c.DisableFlagParsing {
+ argWoFlags = a
+ }
+
+ if err := c.ValidateArgs(argWoFlags); err != nil {
+ return err
+ }
+
+ for p := c; p != nil; p = p.Parent() {
+ if p.PersistentPreRunE != nil {
+ if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
+ return err
+ }
+ break
+ } else if p.PersistentPreRun != nil {
+ p.PersistentPreRun(c, argWoFlags)
+ break
+ }
+ }
+ if c.PreRunE != nil {
+ if err := c.PreRunE(c, argWoFlags); err != nil {
+ return err
+ }
+ } else if c.PreRun != nil {
+ c.PreRun(c, argWoFlags)
+ }
+
+ if err := c.validateRequiredFlags(); err != nil {
+ return err
+ }
+ if c.RunE != nil {
+ if err := c.RunE(c, argWoFlags); err != nil {
+ return err
+ }
+ } else {
+ c.Run(c, argWoFlags)
+ }
+ if c.PostRunE != nil {
+ if err := c.PostRunE(c, argWoFlags); err != nil {
+ return err
+ }
+ } else if c.PostRun != nil {
+ c.PostRun(c, argWoFlags)
+ }
+ for p := c; p != nil; p = p.Parent() {
+ if p.PersistentPostRunE != nil {
+ if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
+ return err
+ }
+ break
+ } else if p.PersistentPostRun != nil {
+ p.PersistentPostRun(c, argWoFlags)
+ break
+ }
+ }
+
+ return nil
+}
+
+func (c *Command) preRun() {
+ for _, x := range initializers {
+ x()
+ }
+}
+
+// Execute uses the args (os.Args[1:] by default)
+// and run through the command tree finding appropriate matches
+// for commands and then corresponding flags.
+func (c *Command) Execute() error {
+ _, err := c.ExecuteC()
+ return err
+}
+
+// ExecuteC executes the command.
+func (c *Command) ExecuteC() (cmd *Command, err error) {
+ // Regardless of what command execute is called on, run on Root only
+ if c.HasParent() {
+ return c.Root().ExecuteC()
+ }
+
+ // windows hook
+ if preExecHookFn != nil {
+ preExecHookFn(c)
+ }
+
+ // initialize help as the last point possible to allow for user
+ // overriding
+ c.InitDefaultHelpCmd()
+
+ args := c.args
+
+ // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
+ if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
+ args = os.Args[1:]
+ }
+
+ var flags []string
+ if c.TraverseChildren {
+ cmd, flags, err = c.Traverse(args)
+ } else {
+ cmd, flags, err = c.Find(args)
+ }
+ if err != nil {
+ // If found parse to a subcommand and then failed, talk about the subcommand
+ if cmd != nil {
+ c = cmd
+ }
+ if !c.SilenceErrors {
+ c.Println("Error:", err.Error())
+ c.Printf("Run '%v --help' for usage.\n", c.CommandPath())
+ }
+ return c, err
+ }
+
+ cmd.commandCalledAs.called = true
+ if cmd.commandCalledAs.name == "" {
+ cmd.commandCalledAs.name = cmd.Name()
+ }
+
+ err = cmd.execute(flags)
+ if err != nil {
+ // Always show help if requested, even if SilenceErrors is in
+ // effect
+ if err == flag.ErrHelp {
+ cmd.HelpFunc()(cmd, args)
+ return cmd, nil
+ }
+
+ // If root command has SilentErrors flagged,
+ // all subcommands should respect it
+ if !cmd.SilenceErrors && !c.SilenceErrors {
+ c.Println("Error:", err.Error())
+ }
+
+ // If root command has SilentUsage flagged,
+ // all subcommands should respect it
+ if !cmd.SilenceUsage && !c.SilenceUsage {
+ c.Println(cmd.UsageString())
+ }
+ }
+ return cmd, err
+}
+
+func (c *Command) ValidateArgs(args []string) error {
+ if c.Args == nil {
+ return nil
+ }
+ return c.Args(c, args)
+}
+
+func (c *Command) validateRequiredFlags() error {
+ flags := c.Flags()
+ missingFlagNames := []string{}
+ flags.VisitAll(func(pflag *flag.Flag) {
+ requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
+ if !found {
+ return
+ }
+ if (requiredAnnotation[0] == "true") && !pflag.Changed {
+ missingFlagNames = append(missingFlagNames, pflag.Name)
+ }
+ })
+
+ if len(missingFlagNames) > 0 {
+ return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`))
+ }
+ return nil
+}
+
+// InitDefaultHelpFlag adds default help flag to c.
+// It is called automatically by executing the c or by calling help and usage.
+// If c already has help flag, it will do nothing.
+func (c *Command) InitDefaultHelpFlag() {
+ c.mergePersistentFlags()
+ if c.Flags().Lookup("help") == nil {
+ usage := "help for "
+ if c.Name() == "" {
+ usage += "this command"
+ } else {
+ usage += c.Name()
+ }
+ c.Flags().BoolP("help", "h", false, usage)
+ }
+}
+
+// InitDefaultVersionFlag adds default version flag to c.
+// It is called automatically by executing the c.
+// If c already has a version flag, it will do nothing.
+// If c.Version is empty, it will do nothing.
+func (c *Command) InitDefaultVersionFlag() {
+ if c.Version == "" {
+ return
+ }
+
+ c.mergePersistentFlags()
+ if c.Flags().Lookup("version") == nil {
+ usage := "version for "
+ if c.Name() == "" {
+ usage += "this command"
+ } else {
+ usage += c.Name()
+ }
+ c.Flags().Bool("version", false, usage)
+ }
+}
+
+// InitDefaultHelpCmd adds default help command to c.
+// It is called automatically by executing the c or by calling help and usage.
+// If c already has help command or c has no subcommands, it will do nothing.
+func (c *Command) InitDefaultHelpCmd() {
+ if !c.HasSubCommands() {
+ return
+ }
+
+ if c.helpCommand == nil {
+ c.helpCommand = &Command{
+ Use: "help [command]",
+ Short: "Help about any command",
+ Long: `Help provides help for any command in the application.
+Simply type ` + c.Name() + ` help [path to command] for full details.`,
+
+ Run: func(c *Command, args []string) {
+ cmd, _, e := c.Root().Find(args)
+ if cmd == nil || e != nil {
+ c.Printf("Unknown help topic %#q\n", args)
+ c.Root().Usage()
+ } else {
+ cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
+ cmd.Help()
+ }
+ },
+ }
+ }
+ c.RemoveCommand(c.helpCommand)
+ c.AddCommand(c.helpCommand)
+}
+
+// ResetCommands delete parent, subcommand and help command from c.
+func (c *Command) ResetCommands() {
+ c.parent = nil
+ c.commands = nil
+ c.helpCommand = nil
+ c.parentsPflags = nil
+}
+
+// Sorts commands by their names.
+type commandSorterByName []*Command
+
+func (c commandSorterByName) Len() int { return len(c) }
+func (c commandSorterByName) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
+func (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }
+
+// Commands returns a sorted slice of child commands.
+func (c *Command) Commands() []*Command {
+ // do not sort commands if it already sorted or sorting was disabled
+ if EnableCommandSorting && !c.commandsAreSorted {
+ sort.Sort(commandSorterByName(c.commands))
+ c.commandsAreSorted = true
+ }
+ return c.commands
+}
+
+// AddCommand adds one or more commands to this parent command.
+func (c *Command) AddCommand(cmds ...*Command) {
+ for i, x := range cmds {
+ if cmds[i] == c {
+ panic("Command can't be a child of itself")
+ }
+ cmds[i].parent = c
+ // update max lengths
+ usageLen := len(x.Use)
+ if usageLen > c.commandsMaxUseLen {
+ c.commandsMaxUseLen = usageLen
+ }
+ commandPathLen := len(x.CommandPath())
+ if commandPathLen > c.commandsMaxCommandPathLen {
+ c.commandsMaxCommandPathLen = commandPathLen
+ }
+ nameLen := len(x.Name())
+ if nameLen > c.commandsMaxNameLen {
+ c.commandsMaxNameLen = nameLen
+ }
+ // If global normalization function exists, update all children
+ if c.globNormFunc != nil {
+ x.SetGlobalNormalizationFunc(c.globNormFunc)
+ }
+ c.commands = append(c.commands, x)
+ c.commandsAreSorted = false
+ }
+}
+
+// RemoveCommand removes one or more commands from a parent command.
+func (c *Command) RemoveCommand(cmds ...*Command) {
+ commands := []*Command{}
+main:
+ for _, command := range c.commands {
+ for _, cmd := range cmds {
+ if command == cmd {
+ command.parent = nil
+ continue main
+ }
+ }
+ commands = append(commands, command)
+ }
+ c.commands = commands
+ // recompute all lengths
+ c.commandsMaxUseLen = 0
+ c.commandsMaxCommandPathLen = 0
+ c.commandsMaxNameLen = 0
+ for _, command := range c.commands {
+ usageLen := len(command.Use)
+ if usageLen > c.commandsMaxUseLen {
+ c.commandsMaxUseLen = usageLen
+ }
+ commandPathLen := len(command.CommandPath())
+ if commandPathLen > c.commandsMaxCommandPathLen {
+ c.commandsMaxCommandPathLen = commandPathLen
+ }
+ nameLen := len(command.Name())
+ if nameLen > c.commandsMaxNameLen {
+ c.commandsMaxNameLen = nameLen
+ }
+ }
+}
+
+// Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
+func (c *Command) Print(i ...interface{}) {
+ fmt.Fprint(c.OutOrStderr(), i...)
+}
+
+// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
+func (c *Command) Println(i ...interface{}) {
+ c.Print(fmt.Sprintln(i...))
+}
+
+// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
+func (c *Command) Printf(format string, i ...interface{}) {
+ c.Print(fmt.Sprintf(format, i...))
+}
+
+// CommandPath returns the full path to this command.
+func (c *Command) CommandPath() string {
+ if c.HasParent() {
+ return c.Parent().CommandPath() + " " + c.Name()
+ }
+ return c.Name()
+}
+
+// UseLine puts out the full usage for a given command (including parents).
+func (c *Command) UseLine() string {
+ var useline string
+ if c.HasParent() {
+ useline = c.parent.CommandPath() + " " + c.Use
+ } else {
+ useline = c.Use
+ }
+ if c.DisableFlagsInUseLine {
+ return useline
+ }
+ if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
+ useline += " [flags]"
+ }
+ return useline
+}
+
+// DebugFlags used to determine which flags have been assigned to which commands
+// and which persist.
+func (c *Command) DebugFlags() {
+ c.Println("DebugFlags called on", c.Name())
+ var debugflags func(*Command)
+
+ debugflags = func(x *Command) {
+ if x.HasFlags() || x.HasPersistentFlags() {
+ c.Println(x.Name())
+ }
+ if x.HasFlags() {
+ x.flags.VisitAll(func(f *flag.Flag) {
+ if x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {
+ c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]")
+ } else {
+ c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
+ }
+ })
+ }
+ if x.HasPersistentFlags() {
+ x.pflags.VisitAll(func(f *flag.Flag) {
+ if x.HasFlags() {
+ if x.flags.Lookup(f.Name) == nil {
+ c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
+ }
+ } else {
+ c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
+ }
+ })
+ }
+ c.Println(x.flagErrorBuf)
+ if x.HasSubCommands() {
+ for _, y := range x.commands {
+ debugflags(y)
+ }
+ }
+ }
+
+ debugflags(c)
+}
+
+// Name returns the command's name: the first word in the use line.
+func (c *Command) Name() string {
+ name := c.Use
+ i := strings.Index(name, " ")
+ if i >= 0 {
+ name = name[:i]
+ }
+ return name
+}
+
+// HasAlias determines if a given string is an alias of the command.
+func (c *Command) HasAlias(s string) bool {
+ for _, a := range c.Aliases {
+ if a == s {
+ return true
+ }
+ }
+ return false
+}
+
+// CalledAs returns the command name or alias that was used to invoke
+// this command or an empty string if the command has not been called.
+func (c *Command) CalledAs() string {
+ if c.commandCalledAs.called {
+ return c.commandCalledAs.name
+ }
+ return ""
+}
+
+// hasNameOrAliasPrefix returns true if the Name or any of aliases start
+// with prefix
+func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
+ if strings.HasPrefix(c.Name(), prefix) {
+ c.commandCalledAs.name = c.Name()
+ return true
+ }
+ for _, alias := range c.Aliases {
+ if strings.HasPrefix(alias, prefix) {
+ c.commandCalledAs.name = alias
+ return true
+ }
+ }
+ return false
+}
+
+// NameAndAliases returns a list of the command name and all aliases
+func (c *Command) NameAndAliases() string {
+ return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
+}
+
+// HasExample determines if the command has example.
+func (c *Command) HasExample() bool {
+ return len(c.Example) > 0
+}
+
+// Runnable determines if the command is itself runnable.
+func (c *Command) Runnable() bool {
+ return c.Run != nil || c.RunE != nil
+}
+
+// HasSubCommands determines if the command has children commands.
+func (c *Command) HasSubCommands() bool {
+ return len(c.commands) > 0
+}
+
+// IsAvailableCommand determines if a command is available as a non-help command
+// (this includes all non deprecated/hidden commands).
+func (c *Command) IsAvailableCommand() bool {
+ if len(c.Deprecated) != 0 || c.Hidden {
+ return false
+ }
+
+ if c.HasParent() && c.Parent().helpCommand == c {
+ return false
+ }
+
+ if c.Runnable() || c.HasAvailableSubCommands() {
+ return true
+ }
+
+ return false
+}
+
+// IsAdditionalHelpTopicCommand determines if a command is an additional
+// help topic command; additional help topic command is determined by the
+// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that
+// are runnable/hidden/deprecated.
+// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.
+func (c *Command) IsAdditionalHelpTopicCommand() bool {
+ // if a command is runnable, deprecated, or hidden it is not a 'help' command
+ if c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {
+ return false
+ }
+
+ // if any non-help sub commands are found, the command is not a 'help' command
+ for _, sub := range c.commands {
+ if !sub.IsAdditionalHelpTopicCommand() {
+ return false
+ }
+ }
+
+ // the command either has no sub commands, or no non-help sub commands
+ return true
+}
+
+// HasHelpSubCommands determines if a command has any available 'help' sub commands
+// that need to be shown in the usage/help default template under 'additional help
+// topics'.
+func (c *Command) HasHelpSubCommands() bool {
+ // return true on the first found available 'help' sub command
+ for _, sub := range c.commands {
+ if sub.IsAdditionalHelpTopicCommand() {
+ return true
+ }
+ }
+
+ // the command either has no sub commands, or no available 'help' sub commands
+ return false
+}
+
+// HasAvailableSubCommands determines if a command has available sub commands that
+// need to be shown in the usage/help default template under 'available commands'.
+func (c *Command) HasAvailableSubCommands() bool {
+ // return true on the first found available (non deprecated/help/hidden)
+ // sub command
+ for _, sub := range c.commands {
+ if sub.IsAvailableCommand() {
+ return true
+ }
+ }
+
+ // the command either has no sub commands, or no available (non deprecated/help/hidden)
+ // sub commands
+ return false
+}
+
+// HasParent determines if the command is a child command.
+func (c *Command) HasParent() bool {
+ return c.parent != nil
+}
+
+// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.
+func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
+ return c.globNormFunc
+}
+
+// Flags returns the complete FlagSet that applies
+// to this command (local and persistent declared here and by all parents).
+func (c *Command) Flags() *flag.FlagSet {
+ if c.flags == nil {
+ c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ if c.flagErrorBuf == nil {
+ c.flagErrorBuf = new(bytes.Buffer)
+ }
+ c.flags.SetOutput(c.flagErrorBuf)
+ }
+
+ return c.flags
+}
+
+// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
+func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
+ persistentFlags := c.PersistentFlags()
+
+ out := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ c.LocalFlags().VisitAll(func(f *flag.Flag) {
+ if persistentFlags.Lookup(f.Name) == nil {
+ out.AddFlag(f)
+ }
+ })
+ return out
+}
+
+// LocalFlags returns the local FlagSet specifically set in the current command.
+func (c *Command) LocalFlags() *flag.FlagSet {
+ c.mergePersistentFlags()
+
+ if c.lflags == nil {
+ c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ if c.flagErrorBuf == nil {
+ c.flagErrorBuf = new(bytes.Buffer)
+ }
+ c.lflags.SetOutput(c.flagErrorBuf)
+ }
+ c.lflags.SortFlags = c.Flags().SortFlags
+ if c.globNormFunc != nil {
+ c.lflags.SetNormalizeFunc(c.globNormFunc)
+ }
+
+ addToLocal := func(f *flag.Flag) {
+ if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
+ c.lflags.AddFlag(f)
+ }
+ }
+ c.Flags().VisitAll(addToLocal)
+ c.PersistentFlags().VisitAll(addToLocal)
+ return c.lflags
+}
+
+// InheritedFlags returns all flags which were inherited from parent commands.
+func (c *Command) InheritedFlags() *flag.FlagSet {
+ c.mergePersistentFlags()
+
+ if c.iflags == nil {
+ c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ if c.flagErrorBuf == nil {
+ c.flagErrorBuf = new(bytes.Buffer)
+ }
+ c.iflags.SetOutput(c.flagErrorBuf)
+ }
+
+ local := c.LocalFlags()
+ if c.globNormFunc != nil {
+ c.iflags.SetNormalizeFunc(c.globNormFunc)
+ }
+
+ c.parentsPflags.VisitAll(func(f *flag.Flag) {
+ if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
+ c.iflags.AddFlag(f)
+ }
+ })
+ return c.iflags
+}
+
+// NonInheritedFlags returns all flags which were not inherited from parent commands.
+func (c *Command) NonInheritedFlags() *flag.FlagSet {
+ return c.LocalFlags()
+}
+
+// PersistentFlags returns the persistent FlagSet specifically set in the current command.
+func (c *Command) PersistentFlags() *flag.FlagSet {
+ if c.pflags == nil {
+ c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ if c.flagErrorBuf == nil {
+ c.flagErrorBuf = new(bytes.Buffer)
+ }
+ c.pflags.SetOutput(c.flagErrorBuf)
+ }
+ return c.pflags
+}
+
+// ResetFlags deletes all flags from command.
+func (c *Command) ResetFlags() {
+ c.flagErrorBuf = new(bytes.Buffer)
+ c.flagErrorBuf.Reset()
+ c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ c.flags.SetOutput(c.flagErrorBuf)
+ c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ c.pflags.SetOutput(c.flagErrorBuf)
+
+ c.lflags = nil
+ c.iflags = nil
+ c.parentsPflags = nil
+}
+
+// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
+func (c *Command) HasFlags() bool {
+ return c.Flags().HasFlags()
+}
+
+// HasPersistentFlags checks if the command contains persistent flags.
+func (c *Command) HasPersistentFlags() bool {
+ return c.PersistentFlags().HasFlags()
+}
+
+// HasLocalFlags checks if the command has flags specifically declared locally.
+func (c *Command) HasLocalFlags() bool {
+ return c.LocalFlags().HasFlags()
+}
+
+// HasInheritedFlags checks if the command has flags inherited from its parent command.
+func (c *Command) HasInheritedFlags() bool {
+ return c.InheritedFlags().HasFlags()
+}
+
+// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
+// structure) which are not hidden or deprecated.
+func (c *Command) HasAvailableFlags() bool {
+ return c.Flags().HasAvailableFlags()
+}
+
+// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
+func (c *Command) HasAvailablePersistentFlags() bool {
+ return c.PersistentFlags().HasAvailableFlags()
+}
+
+// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
+// or deprecated.
+func (c *Command) HasAvailableLocalFlags() bool {
+ return c.LocalFlags().HasAvailableFlags()
+}
+
+// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
+// not hidden or deprecated.
+func (c *Command) HasAvailableInheritedFlags() bool {
+ return c.InheritedFlags().HasAvailableFlags()
+}
+
+// Flag climbs up the command tree looking for matching flag.
+func (c *Command) Flag(name string) (flag *flag.Flag) {
+ flag = c.Flags().Lookup(name)
+
+ if flag == nil {
+ flag = c.persistentFlag(name)
+ }
+
+ return
+}
+
+// Recursively find matching persistent flag.
+func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
+ if c.HasPersistentFlags() {
+ flag = c.PersistentFlags().Lookup(name)
+ }
+
+ if flag == nil {
+ c.updateParentsPflags()
+ flag = c.parentsPflags.Lookup(name)
+ }
+ return
+}
+
+// ParseFlags parses persistent flag tree and local flags.
+func (c *Command) ParseFlags(args []string) error {
+ if c.DisableFlagParsing {
+ return nil
+ }
+
+ if c.flagErrorBuf == nil {
+ c.flagErrorBuf = new(bytes.Buffer)
+ }
+ beforeErrorBufLen := c.flagErrorBuf.Len()
+ c.mergePersistentFlags()
+
+ //do it here after merging all flags and just before parse
+ c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
+
+ err := c.Flags().Parse(args)
+ // Print warnings if they occurred (e.g. deprecated flag messages).
+ if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
+ c.Print(c.flagErrorBuf.String())
+ }
+
+ return err
+}
+
+// Parent returns a commands parent command.
+func (c *Command) Parent() *Command {
+ return c.parent
+}
+
+// mergePersistentFlags merges c.PersistentFlags() to c.Flags()
+// and adds missing persistent flags of all parents.
+func (c *Command) mergePersistentFlags() {
+ c.updateParentsPflags()
+ c.Flags().AddFlagSet(c.PersistentFlags())
+ c.Flags().AddFlagSet(c.parentsPflags)
+}
+
+// updateParentsPflags updates c.parentsPflags by adding
+// new persistent flags of all parents.
+// If c.parentsPflags == nil, it makes new.
+func (c *Command) updateParentsPflags() {
+ if c.parentsPflags == nil {
+ c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
+ c.parentsPflags.SetOutput(c.flagErrorBuf)
+ c.parentsPflags.SortFlags = false
+ }
+
+ if c.globNormFunc != nil {
+ c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
+ }
+
+ c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
+
+ c.VisitParents(func(parent *Command) {
+ c.parentsPflags.AddFlagSet(parent.PersistentFlags())
+ })
+}
diff --git a/vendor/github.com/spf13/cobra/command_notwin.go b/vendor/github.com/spf13/cobra/command_notwin.go
new file mode 100644
index 0000000..6159c1c
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/command_notwin.go
@@ -0,0 +1,5 @@
+// +build !windows
+
+package cobra
+
+var preExecHookFn func(*Command)
diff --git a/vendor/github.com/spf13/cobra/command_win.go b/vendor/github.com/spf13/cobra/command_win.go
new file mode 100644
index 0000000..8768b17
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/command_win.go
@@ -0,0 +1,26 @@
+// +build windows
+
+package cobra
+
+import (
+ "fmt"
+ "os"
+ "time"
+
+ "github.com/inconshreveable/mousetrap"
+)
+
+var preExecHookFn = preExecHook
+
+func preExecHook(c *Command) {
+ if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
+ c.Print(MousetrapHelpText)
+ if MousetrapDisplayDuration > 0 {
+ time.Sleep(MousetrapDisplayDuration)
+ } else {
+ c.Println("Press return to continue...")
+ fmt.Scanln()
+ }
+ os.Exit(1)
+ }
+}
diff --git a/vendor/github.com/spf13/cobra/go.mod b/vendor/github.com/spf13/cobra/go.mod
new file mode 100644
index 0000000..9a9eb65
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/go.mod
@@ -0,0 +1,13 @@
+module github.com/spf13/cobra
+
+go 1.12
+
+require (
+ github.com/BurntSushi/toml v0.3.1 // indirect
+ github.com/cpuguy83/go-md2man v1.0.10
+ github.com/inconshreveable/mousetrap v1.0.0
+ github.com/mitchellh/go-homedir v1.1.0
+ github.com/spf13/pflag v1.0.3
+ github.com/spf13/viper v1.3.2
+ gopkg.in/yaml.v2 v2.2.2
+)
diff --git a/vendor/github.com/spf13/cobra/go.sum b/vendor/github.com/spf13/cobra/go.sum
new file mode 100644
index 0000000..9761f4d
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/go.sum
@@ -0,0 +1,51 @@
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
+github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
+github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
+github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go
new file mode 100644
index 0000000..889c22e
--- /dev/null
+++ b/vendor/github.com/spf13/cobra/zsh_completions.go
@@ -0,0 +1,126 @@
+package cobra
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+)
+
+// GenZshCompletionFile generates zsh completion file.
+func (c *Command) GenZshCompletionFile(filename string) error {
+ outFile, err := os.Create(filename)
+ if err != nil {
+ return err
+ }
+ defer outFile.Close()
+
+ return c.GenZshCompletion(outFile)
+}
+
+// GenZshCompletion generates a zsh completion file and writes to the passed writer.
+func (c *Command) GenZshCompletion(w io.Writer) error {
+ buf := new(bytes.Buffer)
+
+ writeHeader(buf, c)
+ maxDepth := maxDepth(c)
+ writeLevelMapping(buf, maxDepth)
+ writeLevelCases(buf, maxDepth, c)
+
+ _, err := buf.WriteTo(w)
+ return err
+}
+
+func writeHeader(w io.Writer, cmd *Command) {
+ fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name())
+}
+
+func maxDepth(c *Command) int {
+ if len(c.Commands()) == 0 {
+ return 0
+ }
+ maxDepthSub := 0
+ for _, s := range c.Commands() {
+ subDepth := maxDepth(s)
+ if subDepth > maxDepthSub {
+ maxDepthSub = subDepth
+ }
+ }
+ return 1 + maxDepthSub
+}
+
+func writeLevelMapping(w io.Writer, numLevels int) {
+ fmt.Fprintln(w, `_arguments \`)
+ for i := 1; i <= numLevels; i++ {
+ fmt.Fprintf(w, ` '%d: :->level%d' \`, i, i)
+ fmt.Fprintln(w)
+ }
+ fmt.Fprintf(w, ` '%d: :%s'`, numLevels+1, "_files")
+ fmt.Fprintln(w)
+}
+
+func writeLevelCases(w io.Writer, maxDepth int, root *Command) {
+ fmt.Fprintln(w, "case $state in")
+ defer fmt.Fprintln(w, "esac")
+
+ for i := 1; i <= maxDepth; i++ {
+ fmt.Fprintf(w, " level%d)\n", i)
+ writeLevel(w, root, i)
+ fmt.Fprintln(w, " ;;")
+ }
+ fmt.Fprintln(w, " *)")
+ fmt.Fprintln(w, " _arguments '*: :_files'")
+ fmt.Fprintln(w, " ;;")
+}
+
+func writeLevel(w io.Writer, root *Command, i int) {
+ fmt.Fprintf(w, " case $words[%d] in\n", i)
+ defer fmt.Fprintln(w, " esac")
+
+ commands := filterByLevel(root, i)
+ byParent := groupByParent(commands)
+
+ for p, c := range byParent {
+ names := names(c)
+ fmt.Fprintf(w, " %s)\n", p)
+ fmt.Fprintf(w, " _arguments '%d: :(%s)'\n", i, strings.Join(names, " "))
+ fmt.Fprintln(w, " ;;")
+ }
+ fmt.Fprintln(w, " *)")
+ fmt.Fprintln(w, " _arguments '*: :_files'")
+ fmt.Fprintln(w, " ;;")
+
+}
+
+func filterByLevel(c *Command, l int) []*Command {
+ cs := make([]*Command, 0)
+ if l == 0 {
+ cs = append(cs, c)
+ return cs
+ }
+ for _, s := range c.Commands() {
+ cs = append(cs, filterByLevel(s, l-1)...)
+ }
+ return cs
+}
+
+func groupByParent(commands []*Command) map[string][]*Command {
+ m := make(map[string][]*Command)
+ for _, c := range commands {
+ parent := c.Parent()
+ if parent == nil {
+ continue
+ }
+ m[parent.Name()] = append(m[parent.Name()], c)
+ }
+ return m
+}
+
+func names(commands []*Command) []string {
+ ns := make([]string, len(commands))
+ for i, c := range commands {
+ ns[i] = c.Name()
+ }
+ return ns
+}
diff --git a/vendor/github.com/spf13/viper/go.mod b/vendor/github.com/spf13/viper/go.mod
index 86e801c..2794300 100644
--- a/vendor/github.com/spf13/viper/go.mod
+++ b/vendor/github.com/spf13/viper/go.mod
@@ -2,23 +2,42 @@ module github.com/spf13/viper
require (
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect
+ github.com/coreos/bbolt v1.3.2 // indirect
github.com/coreos/etcd v3.3.10+incompatible // indirect
- github.com/coreos/go-etcd v2.0.0+incompatible // indirect
github.com/coreos/go-semver v0.2.0 // indirect
+ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
+ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/fsnotify/fsnotify v1.4.7
+ github.com/gogo/protobuf v1.2.1 // indirect
+ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
+ github.com/google/btree v1.0.0 // indirect
+ github.com/gorilla/websocket v1.4.0 // indirect
+ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
+ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
+ github.com/grpc-ecosystem/grpc-gateway v1.9.0 // indirect
github.com/hashicorp/hcl v1.0.0
+ github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/magiconair/properties v1.8.0
github.com/mitchellh/mapstructure v1.1.2
github.com/pelletier/go-toml v1.2.0
+ github.com/prometheus/client_golang v0.9.3 // indirect
+ github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spf13/afero v1.1.2
github.com/spf13/cast v1.3.0
github.com/spf13/jwalterweatherman v1.0.0
github.com/spf13/pflag v1.0.3
github.com/stretchr/testify v1.2.2
- github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 // indirect
+ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
+ github.com/ugorji/go v1.1.4 // indirect
+ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77
- golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect
- golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a // indirect
- golang.org/x/text v0.3.0 // indirect
+ go.etcd.io/bbolt v1.3.2 // indirect
+ go.uber.org/atomic v1.4.0 // indirect
+ go.uber.org/multierr v1.1.0 // indirect
+ go.uber.org/zap v1.10.0 // indirect
+ golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect
+ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
+ google.golang.org/grpc v1.21.0 // indirect
gopkg.in/yaml.v2 v2.2.2
)
diff --git a/vendor/github.com/spf13/viper/go.sum b/vendor/github.com/spf13/viper/go.sum
index 5c9fb7d..97afaff 100644
--- a/vendor/github.com/spf13/viper/go.sum
+++ b/vendor/github.com/spf13/viper/go.sum
@@ -1,19 +1,109 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
@@ -22,14 +112,67 @@ github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go
index 7173c6e..a3d37f8 100644
--- a/vendor/github.com/spf13/viper/viper.go
+++ b/vendor/github.com/spf13/viper/viper.go
@@ -180,10 +180,11 @@ type Viper struct {
remoteProviders []*defaultRemoteProvider
// Name of file to look for inside the path
- configName string
- configFile string
- configType string
- envPrefix string
+ configName string
+ configFile string
+ configType string
+ configPermissions os.FileMode
+ envPrefix string
automaticEnvApplied bool
envKeyReplacer *strings.Replacer
@@ -210,6 +211,7 @@ func New() *Viper {
v := new(Viper)
v.keyDelim = "."
v.configName = "config"
+ v.configPermissions = os.FileMode(0644)
v.fs = afero.NewOsFs()
v.config = make(map[string]interface{})
v.override = make(map[string]interface{})
@@ -687,6 +689,12 @@ func (v *Viper) Get(key string) interface{} {
return cast.ToString(val)
case int32, int16, int8, int:
return cast.ToInt(val)
+ case uint:
+ return cast.ToUint(val)
+ case uint32:
+ return cast.ToUint32(val)
+ case uint64:
+ return cast.ToUint64(val)
case int64:
return cast.ToInt64(val)
case float64, float32:
@@ -750,6 +758,24 @@ func (v *Viper) GetInt64(key string) int64 {
return cast.ToInt64(v.Get(key))
}
+// GetUint returns the value associated with the key as an unsigned integer.
+func GetUint(key string) uint { return v.GetUint(key) }
+func (v *Viper) GetUint(key string) uint {
+ return cast.ToUint(v.Get(key))
+}
+
+// GetUint32 returns the value associated with the key as an unsigned integer.
+func GetUint32(key string) uint32 { return v.GetUint32(key) }
+func (v *Viper) GetUint32(key string) uint32 {
+ return cast.ToUint32(v.Get(key))
+}
+
+// GetUint64 returns the value associated with the key as an unsigned integer.
+func GetUint64(key string) uint64 { return v.GetUint64(key) }
+func (v *Viper) GetUint64(key string) uint64 {
+ return cast.ToUint64(v.Get(key))
+}
+
// GetFloat64 returns the value associated with the key as a float64.
func GetFloat64(key string) float64 { return v.GetFloat64(key) }
func (v *Viper) GetFloat64(key string) float64 {
@@ -1328,7 +1354,7 @@ func (v *Viper) writeConfig(filename string, force bool) error {
return fmt.Errorf("File: %s exists. Use WriteConfig to overwrite.", filename)
}
}
- f, err := v.fs.OpenFile(filename, flags, os.FileMode(0644))
+ f, err := v.fs.OpenFile(filename, flags, v.configPermissions)
if err != nil {
return err
}
@@ -1765,6 +1791,12 @@ func (v *Viper) SetConfigType(in string) {
}
}
+// SetConfigPermissions sets the permissions for the config file.
+func SetConfigPermissions(perm os.FileMode) { v.SetConfigPermissions(perm) }
+func (v *Viper) SetConfigPermissions(perm os.FileMode) {
+ v.configPermissions = perm.Perm()
+}
+
func (v *Viper) getConfigType() string {
if v.configType != "" {
return v.configType
diff --git a/vendor/gopkg.in/go-playground/validator.v9/.gitignore b/vendor/gopkg.in/go-playground/validator.v9/.gitignore
deleted file mode 100644
index 792ca00..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/.gitignore
+++ /dev/null
@@ -1,29 +0,0 @@
-# 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
-*.prof
-*.test
-*.out
-*.txt
-cover.html
-README.html
\ No newline at end of file
diff --git a/vendor/gopkg.in/go-playground/validator.v9/LICENSE b/vendor/gopkg.in/go-playground/validator.v9/LICENSE
deleted file mode 100644
index 6a2ae9a..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Dean Karn
-
-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.
-
diff --git a/vendor/gopkg.in/go-playground/validator.v9/Makefile b/vendor/gopkg.in/go-playground/validator.v9/Makefile
deleted file mode 100644
index aeeee9d..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-GOCMD=go
-
-linters-install:
- $(GOCMD) get -u github.com/alecthomas/gometalinter
- gometalinter --install
-
-lint: linters-install
- gometalinter --vendor --disable-all --enable=vet --enable=vetshadow --enable=golint --enable=maligned --enable=megacheck --enable=ineffassign --enable=misspell --enable=errcheck --enable=goconst ./...
-
-test:
- $(GOCMD) test -cover -race ./...
-
-bench:
- $(GOCMD) test -bench=. -benchmem ./...
-
-.PHONY: test lint linters-install
\ No newline at end of file
diff --git a/vendor/gopkg.in/go-playground/validator.v9/README.md b/vendor/gopkg.in/go-playground/validator.v9/README.md
deleted file mode 100644
index db03584..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/README.md
+++ /dev/null
@@ -1,153 +0,0 @@
-Package validator
-================
-[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-![Project status](https://img.shields.io/badge/version-9.28.0-green.svg)
-[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/validator/branches/v9/badge.svg)](https://semaphoreci.com/joeybloggs/validator)
-[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v9&service=github)](https://coveralls.io/github/go-playground/validator?branch=v9)
-[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
-[![GoDoc](https://godoc.org/gopkg.in/go-playground/validator.v9?status.svg)](https://godoc.org/gopkg.in/go-playground/validator.v9)
-![License](https://img.shields.io/dub/l/vibe-d.svg)
-
-Package validator implements value validations for structs and individual fields based on tags.
-
-It has the following **unique** features:
-
-- Cross Field and Cross Struct validations by using validation tags or custom validators.
-- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
-- Ability to dive into both map keys and values for validation
-- Handles type interface by determining it's underlying type prior to validation.
-- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29)
-- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
-- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
-- Customizable i18n aware error messages.
-- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
-
-Installation
-------------
-
-Use go get.
-
- go get gopkg.in/go-playground/validator.v9
-
-Then import the validator package into your own code.
-
- import "gopkg.in/go-playground/validator.v9"
-
-Error Return Value
--------
-
-Validation functions return type error
-
-They return type error to avoid the issue discussed in the following, where err is always != nil:
-
-* http://stackoverflow.com/a/29138676/3158232
-* https://github.com/go-playground/validator/issues/134
-
-Validator only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
-
-```go
-err := validate.Struct(mystruct)
-validationErrors := err.(validator.ValidationErrors)
- ```
-
-Usage and documentation
-------
-
-Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usage docs.
-
-##### Examples:
-
-- [Simple](https://github.com/go-playground/validator/blob/v9/_examples/simple/main.go)
-- [Custom Field Types](https://github.com/go-playground/validator/blob/v9/_examples/custom/main.go)
-- [Struct Level](https://github.com/go-playground/validator/blob/v9/_examples/struct-level/main.go)
-- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/v9/_examples/translations/main.go)
-- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
-- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash)
-
-Benchmarks
-------
-###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
-```go
-goos: darwin
-goarch: amd64
-pkg: github.com/go-playground/validator
-BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op
-BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op
-BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op
-BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op
-BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op
-BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op
-BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op
-BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op
-BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op
-BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op
-BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op
-BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op
-BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op
-BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op
-BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op
-BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op
-BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op
-BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op
-BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op
-BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op
-BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op
-BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op
-BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op
-BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op
-BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op
-BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op
-BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op
-BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op
-BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op
-BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op
-BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op
-BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op
-BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op
-BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op
-BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op
-BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op
-BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op
-BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op
-BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op
-BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op
-BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op
-BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op
-BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op
-BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op
-BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op
-BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op
-BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op
-BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op
-BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op
-BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op
-BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op
-BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op
-BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op
-BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op
-```
-
-Complementary Software
-----------------------
-
-Here is a list of software that complements using this library either pre or post validation.
-
-* [form](https://github.com/go-playground/form) - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
-* [mold](https://github.com/go-playground/mold) - A general library to help modify or set data within data structures and other objects
-
-How to Contribute
-------
-
-Make a pull request...
-
-License
-------
-Distributed under MIT License, please see license file within the code for more details.
diff --git a/vendor/gopkg.in/go-playground/validator.v9/baked_in.go b/vendor/gopkg.in/go-playground/validator.v9/baked_in.go
deleted file mode 100644
index 702e78d..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/baked_in.go
+++ /dev/null
@@ -1,1912 +0,0 @@
-package validator
-
-import (
- "bytes"
- "context"
- "crypto/sha256"
- "fmt"
- "net"
- "net/url"
- "os"
- "reflect"
- "strconv"
- "strings"
- "sync"
- "time"
- "unicode/utf8"
-
- urn "github.com/leodido/go-urn"
-)
-
-// Func accepts a FieldLevel interface for all validation needs. The return
-// value should be true when validation succeeds.
-type Func func(fl FieldLevel) bool
-
-// FuncCtx accepts a context.Context and FieldLevel interface for all
-// validation needs. The return value should be true when validation succeeds.
-type FuncCtx func(ctx context.Context, fl FieldLevel) bool
-
-// wrapFunc wraps noramal Func makes it compatible with FuncCtx
-func wrapFunc(fn Func) FuncCtx {
- if fn == nil {
- return nil // be sure not to wrap a bad function.
- }
- return func(ctx context.Context, fl FieldLevel) bool {
- return fn(fl)
- }
-}
-
-var (
- restrictedTags = map[string]struct{}{
- diveTag: {},
- keysTag: {},
- endKeysTag: {},
- structOnlyTag: {},
- omitempty: {},
- skipValidationTag: {},
- utf8HexComma: {},
- utf8Pipe: {},
- noStructLevelTag: {},
- requiredTag: {},
- isdefault: {},
- }
-
- // BakedInAliasValidators is a default mapping of a single validation tag that
- // defines a common or complex set of validation(s) to simplify
- // adding validation to structs.
- bakedInAliases = map[string]string{
- "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
- }
-
- // BakedInValidators is the default map of ValidationFunc
- // you can add, remove or even replace items to suite your needs,
- // or even disregard and use your own map if so desired.
- bakedInValidators = map[string]Func{
- "required": hasValue,
- "isdefault": isDefault,
- "len": hasLengthOf,
- "min": hasMinOf,
- "max": hasMaxOf,
- "eq": isEq,
- "ne": isNe,
- "lt": isLt,
- "lte": isLte,
- "gt": isGt,
- "gte": isGte,
- "eqfield": isEqField,
- "eqcsfield": isEqCrossStructField,
- "necsfield": isNeCrossStructField,
- "gtcsfield": isGtCrossStructField,
- "gtecsfield": isGteCrossStructField,
- "ltcsfield": isLtCrossStructField,
- "ltecsfield": isLteCrossStructField,
- "nefield": isNeField,
- "gtefield": isGteField,
- "gtfield": isGtField,
- "ltefield": isLteField,
- "ltfield": isLtField,
- "fieldcontains": fieldContains,
- "fieldexcludes": fieldExcludes,
- "alpha": isAlpha,
- "alphanum": isAlphanum,
- "alphaunicode": isAlphaUnicode,
- "alphanumunicode": isAlphanumUnicode,
- "numeric": isNumeric,
- "number": isNumber,
- "hexadecimal": isHexadecimal,
- "hexcolor": isHEXColor,
- "rgb": isRGB,
- "rgba": isRGBA,
- "hsl": isHSL,
- "hsla": isHSLA,
- "email": isEmail,
- "url": isURL,
- "uri": isURI,
- "urn_rfc2141": isUrnRFC2141, // RFC 2141
- "file": isFile,
- "base64": isBase64,
- "base64url": isBase64URL,
- "contains": contains,
- "containsany": containsAny,
- "containsrune": containsRune,
- "excludes": excludes,
- "excludesall": excludesAll,
- "excludesrune": excludesRune,
- "startswith": startsWith,
- "endswith": endsWith,
- "isbn": isISBN,
- "isbn10": isISBN10,
- "isbn13": isISBN13,
- "eth_addr": isEthereumAddress,
- "btc_addr": isBitcoinAddress,
- "btc_addr_bech32": isBitcoinBech32Address,
- "uuid": isUUID,
- "uuid3": isUUID3,
- "uuid4": isUUID4,
- "uuid5": isUUID5,
- "uuid_rfc4122": isUUIDRFC4122,
- "uuid3_rfc4122": isUUID3RFC4122,
- "uuid4_rfc4122": isUUID4RFC4122,
- "uuid5_rfc4122": isUUID5RFC4122,
- "ascii": isASCII,
- "printascii": isPrintableASCII,
- "multibyte": hasMultiByteCharacter,
- "datauri": isDataURI,
- "latitude": isLatitude,
- "longitude": isLongitude,
- "ssn": isSSN,
- "ipv4": isIPv4,
- "ipv6": isIPv6,
- "ip": isIP,
- "cidrv4": isCIDRv4,
- "cidrv6": isCIDRv6,
- "cidr": isCIDR,
- "tcp4_addr": isTCP4AddrResolvable,
- "tcp6_addr": isTCP6AddrResolvable,
- "tcp_addr": isTCPAddrResolvable,
- "udp4_addr": isUDP4AddrResolvable,
- "udp6_addr": isUDP6AddrResolvable,
- "udp_addr": isUDPAddrResolvable,
- "ip4_addr": isIP4AddrResolvable,
- "ip6_addr": isIP6AddrResolvable,
- "ip_addr": isIPAddrResolvable,
- "unix_addr": isUnixAddrResolvable,
- "mac": isMAC,
- "hostname": isHostnameRFC952, // RFC 952
- "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
- "fqdn": isFQDN,
- "unique": isUnique,
- "oneof": isOneOf,
- "html": isHTML,
- "html_encoded": isHTMLEncoded,
- "url_encoded": isURLEncoded,
- "dir": isDir,
- }
-)
-
-var oneofValsCache = map[string][]string{}
-var oneofValsCacheRWLock = sync.RWMutex{}
-
-func parseOneOfParam2(s string) []string {
- oneofValsCacheRWLock.RLock()
- vals, ok := oneofValsCache[s]
- oneofValsCacheRWLock.RUnlock()
- if !ok {
- oneofValsCacheRWLock.Lock()
- vals = strings.Fields(s)
- oneofValsCache[s] = vals
- oneofValsCacheRWLock.Unlock()
- }
- return vals
-}
-
-func isURLEncoded(fl FieldLevel) bool {
- return uRLEncodedRegex.MatchString(fl.Field().String())
-}
-
-func isHTMLEncoded(fl FieldLevel) bool {
- return hTMLEncodedRegex.MatchString(fl.Field().String())
-}
-
-func isHTML(fl FieldLevel) bool {
- return hTMLRegex.MatchString(fl.Field().String())
-}
-
-func isOneOf(fl FieldLevel) bool {
- vals := parseOneOfParam2(fl.Param())
-
- field := fl.Field()
-
- var v string
- switch field.Kind() {
- case reflect.String:
- v = field.String()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- v = strconv.FormatInt(field.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- v = strconv.FormatUint(field.Uint(), 10)
- default:
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
- }
- for i := 0; i < len(vals); i++ {
- if vals[i] == v {
- return true
- }
- }
- return false
-}
-
-// isUnique is the validation function for validating if each array|slice|map value is unique
-func isUnique(fl FieldLevel) bool {
-
- field := fl.Field()
- v := reflect.ValueOf(struct{}{})
-
- switch field.Kind() {
- case reflect.Slice, reflect.Array:
- m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
-
- for i := 0; i < field.Len(); i++ {
- m.SetMapIndex(field.Index(i), v)
- }
- return field.Len() == m.Len()
- case reflect.Map:
- m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
-
- for _, k := range field.MapKeys() {
- m.SetMapIndex(field.MapIndex(k), v)
- }
- return field.Len() == m.Len()
- default:
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
- }
-}
-
-// IsMAC is the validation function for validating if the field's value is a valid MAC address.
-func isMAC(fl FieldLevel) bool {
-
- _, err := net.ParseMAC(fl.Field().String())
-
- return err == nil
-}
-
-// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
-func isCIDRv4(fl FieldLevel) bool {
-
- ip, _, err := net.ParseCIDR(fl.Field().String())
-
- return err == nil && ip.To4() != nil
-}
-
-// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
-func isCIDRv6(fl FieldLevel) bool {
-
- ip, _, err := net.ParseCIDR(fl.Field().String())
-
- return err == nil && ip.To4() == nil
-}
-
-// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
-func isCIDR(fl FieldLevel) bool {
-
- _, _, err := net.ParseCIDR(fl.Field().String())
-
- return err == nil
-}
-
-// IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
-func isIPv4(fl FieldLevel) bool {
-
- ip := net.ParseIP(fl.Field().String())
-
- return ip != nil && ip.To4() != nil
-}
-
-// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
-func isIPv6(fl FieldLevel) bool {
-
- ip := net.ParseIP(fl.Field().String())
-
- return ip != nil && ip.To4() == nil
-}
-
-// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
-func isIP(fl FieldLevel) bool {
-
- ip := net.ParseIP(fl.Field().String())
-
- return ip != nil
-}
-
-// IsSSN is the validation function for validating if the field's value is a valid SSN.
-func isSSN(fl FieldLevel) bool {
-
- field := fl.Field()
-
- if field.Len() != 11 {
- return false
- }
-
- return sSNRegex.MatchString(field.String())
-}
-
-// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
-func isLongitude(fl FieldLevel) bool {
- field := fl.Field()
-
- var v string
- switch field.Kind() {
- case reflect.String:
- v = field.String()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- v = strconv.FormatInt(field.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- v = strconv.FormatUint(field.Uint(), 10)
- case reflect.Float32:
- v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
- case reflect.Float64:
- v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
- default:
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
- }
-
- return longitudeRegex.MatchString(v)
-}
-
-// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
-func isLatitude(fl FieldLevel) bool {
- field := fl.Field()
-
- var v string
- switch field.Kind() {
- case reflect.String:
- v = field.String()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- v = strconv.FormatInt(field.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- v = strconv.FormatUint(field.Uint(), 10)
- case reflect.Float32:
- v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
- case reflect.Float64:
- v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
- default:
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
- }
-
- return latitudeRegex.MatchString(v)
-}
-
-// IsDataURI is the validation function for validating if the field's value is a valid data URI.
-func isDataURI(fl FieldLevel) bool {
-
- uri := strings.SplitN(fl.Field().String(), ",", 2)
-
- if len(uri) != 2 {
- return false
- }
-
- if !dataURIRegex.MatchString(uri[0]) {
- return false
- }
-
- return base64Regex.MatchString(uri[1])
-}
-
-// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
-func hasMultiByteCharacter(fl FieldLevel) bool {
-
- field := fl.Field()
-
- if field.Len() == 0 {
- return true
- }
-
- return multibyteRegex.MatchString(field.String())
-}
-
-// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
-func isPrintableASCII(fl FieldLevel) bool {
- return printableASCIIRegex.MatchString(fl.Field().String())
-}
-
-// IsASCII is the validation function for validating if the field's value is a valid ASCII character.
-func isASCII(fl FieldLevel) bool {
- return aSCIIRegex.MatchString(fl.Field().String())
-}
-
-// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
-func isUUID5(fl FieldLevel) bool {
- return uUID5Regex.MatchString(fl.Field().String())
-}
-
-// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
-func isUUID4(fl FieldLevel) bool {
- return uUID4Regex.MatchString(fl.Field().String())
-}
-
-// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
-func isUUID3(fl FieldLevel) bool {
- return uUID3Regex.MatchString(fl.Field().String())
-}
-
-// IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
-func isUUID(fl FieldLevel) bool {
- return uUIDRegex.MatchString(fl.Field().String())
-}
-
-// IsUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
-func isUUID5RFC4122(fl FieldLevel) bool {
- return uUID5RFC4122Regex.MatchString(fl.Field().String())
-}
-
-// IsUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
-func isUUID4RFC4122(fl FieldLevel) bool {
- return uUID4RFC4122Regex.MatchString(fl.Field().String())
-}
-
-// IsUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
-func isUUID3RFC4122(fl FieldLevel) bool {
- return uUID3RFC4122Regex.MatchString(fl.Field().String())
-}
-
-// IsUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
-func isUUIDRFC4122(fl FieldLevel) bool {
- return uUIDRFC4122Regex.MatchString(fl.Field().String())
-}
-
-// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
-func isISBN(fl FieldLevel) bool {
- return isISBN10(fl) || isISBN13(fl)
-}
-
-// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
-func isISBN13(fl FieldLevel) bool {
-
- s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
-
- if !iSBN13Regex.MatchString(s) {
- return false
- }
-
- var checksum int32
- var i int32
-
- factor := []int32{1, 3}
-
- for i = 0; i < 12; i++ {
- checksum += factor[i%2] * int32(s[i]-'0')
- }
-
- return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
-}
-
-// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
-func isISBN10(fl FieldLevel) bool {
-
- s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
-
- if !iSBN10Regex.MatchString(s) {
- return false
- }
-
- var checksum int32
- var i int32
-
- for i = 0; i < 9; i++ {
- checksum += (i + 1) * int32(s[i]-'0')
- }
-
- if s[9] == 'X' {
- checksum += 10 * 10
- } else {
- checksum += 10 * int32(s[9]-'0')
- }
-
- return checksum%11 == 0
-}
-
-// IsEthereumAddress is the validation function for validating if the field's value is a valid ethereum address based currently only on the format
-func isEthereumAddress(fl FieldLevel) bool {
- address := fl.Field().String()
-
- if !ethAddressRegex.MatchString(address) {
- return false
- }
-
- if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
- return true
- }
-
- // checksum validation is blocked by https://github.com/golang/crypto/pull/28
-
- return true
-}
-
-// IsBitcoinAddress is the validation function for validating if the field's value is a valid btc address
-func isBitcoinAddress(fl FieldLevel) bool {
- address := fl.Field().String()
-
- if !btcAddressRegex.MatchString(address) {
- return false
- }
-
- alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
-
- decode := [25]byte{}
-
- for _, n := range []byte(address) {
- d := bytes.IndexByte(alphabet, n)
-
- for i := 24; i >= 0; i-- {
- d += 58 * int(decode[i])
- decode[i] = byte(d % 256)
- d /= 256
- }
- }
-
- h := sha256.New()
- _, _ = h.Write(decode[:21])
- d := h.Sum([]byte{})
- h = sha256.New()
- _, _ = h.Write(d)
-
- validchecksum := [4]byte{}
- computedchecksum := [4]byte{}
-
- copy(computedchecksum[:], h.Sum(d[:0]))
- copy(validchecksum[:], decode[21:])
-
- return validchecksum == computedchecksum
-}
-
-// IsBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
-func isBitcoinBech32Address(fl FieldLevel) bool {
- address := fl.Field().String()
-
- if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) {
- return false
- }
-
- am := len(address) % 8
-
- if am == 0 || am == 3 || am == 5 {
- return false
- }
-
- address = strings.ToLower(address)
-
- alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
-
- hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc
- addr := address[3:]
- dp := make([]int, 0, len(addr))
-
- for _, c := range addr {
- dp = append(dp, strings.IndexRune(alphabet, c))
- }
-
- ver := dp[0]
-
- if ver < 0 || ver > 16 {
- return false
- }
-
- if ver == 0 {
- if len(address) != 42 && len(address) != 62 {
- return false
- }
- }
-
- values := append(hr, dp...)
-
- GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
-
- p := 1
-
- for _, v := range values {
- b := p >> 25
- p = (p&0x1ffffff)<<5 ^ v
-
- for i := 0; i < 5; i++ {
- if (b>>uint(i))&1 == 1 {
- p ^= GEN[i]
- }
- }
- }
-
- if p != 1 {
- return false
- }
-
- b := uint(0)
- acc := 0
- mv := (1 << 5) - 1
- var sw []int
-
- for _, v := range dp[1 : len(dp)-6] {
- acc = (acc << 5) | v
- b += 5
- for b >= 8 {
- b -= 8
- sw = append(sw, (acc>>b)&mv)
- }
- }
-
- if len(sw) < 2 || len(sw) > 40 {
- return false
- }
-
- return true
-}
-
-// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
-func excludesRune(fl FieldLevel) bool {
- return !containsRune(fl)
-}
-
-// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
-func excludesAll(fl FieldLevel) bool {
- return !containsAny(fl)
-}
-
-// Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
-func excludes(fl FieldLevel) bool {
- return !contains(fl)
-}
-
-// ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
-func containsRune(fl FieldLevel) bool {
-
- r, _ := utf8.DecodeRuneInString(fl.Param())
-
- return strings.ContainsRune(fl.Field().String(), r)
-}
-
-// ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
-func containsAny(fl FieldLevel) bool {
- return strings.ContainsAny(fl.Field().String(), fl.Param())
-}
-
-// Contains is the validation function for validating that the field's value contains the text specified within the param.
-func contains(fl FieldLevel) bool {
- return strings.Contains(fl.Field().String(), fl.Param())
-}
-
-// StartsWith is the validation function for validating that the field's value starts with the text specified within the param.
-func startsWith(fl FieldLevel) bool {
- return strings.HasPrefix(fl.Field().String(), fl.Param())
-}
-
-// EndsWith is the validation function for validating that the field's value ends with the text specified within the param.
-func endsWith(fl FieldLevel) bool {
- return strings.HasSuffix(fl.Field().String(), fl.Param())
-}
-
-// FieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
-func fieldContains(fl FieldLevel) bool {
- field := fl.Field()
-
- currentField, _, ok := fl.GetStructFieldOK()
-
- if !ok {
- return false
- }
-
- return strings.Contains(field.String(), currentField.String())
-}
-
-// FieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
-func fieldExcludes(fl FieldLevel) bool {
- field := fl.Field()
-
- currentField, _, ok := fl.GetStructFieldOK()
- if !ok {
- return true
- }
-
- return !strings.Contains(field.String(), currentField.String())
-}
-
-// IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value.
-func isNeField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- currentField, currentKind, ok := fl.GetStructFieldOK()
-
- if !ok || currentKind != kind {
- return true
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() != currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() != currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() != currentField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) != int64(currentField.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return true
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return !fieldTime.Equal(t)
- }
-
- }
-
- // default reflect.String:
- return field.String() != currentField.String()
-}
-
-// IsNe is the validation function for validating that the field's value does not equal the provided param value.
-func isNe(fl FieldLevel) bool {
- return !isEq(fl)
-}
-
-// IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value.
-func isLteCrossStructField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- topField, topKind, ok := fl.GetStructFieldOK()
- if !ok || topKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() <= topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() <= topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() <= topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) <= int64(topField.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() <= topField.String()
-}
-
-// IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value.
-// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
-func isLtCrossStructField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- topField, topKind, ok := fl.GetStructFieldOK()
- if !ok || topKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() < topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() < topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() < topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) < int64(topField.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.Before(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() < topField.String()
-}
-
-// IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value.
-func isGteCrossStructField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- topField, topKind, ok := fl.GetStructFieldOK()
- if !ok || topKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() >= topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() >= topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() >= topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) >= int64(topField.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.After(topTime) || fieldTime.Equal(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() >= topField.String()
-}
-
-// IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value.
-func isGtCrossStructField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- topField, topKind, ok := fl.GetStructFieldOK()
- if !ok || topKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() > topField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() > topField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() > topField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) > int64(topField.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.After(topTime)
- }
- }
-
- // default reflect.String:
- return field.String() > topField.String()
-}
-
-// IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value.
-func isNeCrossStructField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- topField, currentKind, ok := fl.GetStructFieldOK()
- if !ok || currentKind != kind {
- return true
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return topField.Int() != field.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return topField.Uint() != field.Uint()
-
- case reflect.Float32, reflect.Float64:
- return topField.Float() != field.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(topField.Len()) != int64(field.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return true
- }
-
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
-
- return !fieldTime.Equal(t)
- }
- }
-
- // default reflect.String:
- return topField.String() != field.String()
-}
-
-// IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value.
-func isEqCrossStructField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- topField, topKind, ok := fl.GetStructFieldOK()
- if !ok || topKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return topField.Int() == field.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return topField.Uint() == field.Uint()
-
- case reflect.Float32, reflect.Float64:
- return topField.Float() == field.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(topField.Len()) == int64(field.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
-
- return fieldTime.Equal(t)
- }
- }
-
- // default reflect.String:
- return topField.String() == field.String()
-}
-
-// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
-func isEqField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- currentField, currentKind, ok := fl.GetStructFieldOK()
- if !ok || currentKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return field.Int() == currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return field.Uint() == currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
- return field.Float() == currentField.Float()
-
- case reflect.Slice, reflect.Map, reflect.Array:
- return int64(field.Len()) == int64(currentField.Len())
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Equal(t)
- }
-
- }
-
- // default reflect.String:
- return field.String() == currentField.String()
-}
-
-// IsEq is the validation function for validating if the current field's value is equal to the param's value.
-func isEq(fl FieldLevel) bool {
-
- field := fl.Field()
- param := fl.Param()
-
- switch field.Kind() {
-
- case reflect.String:
- return field.String() == param
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) == p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() == p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() == p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() == p
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsBase64 is the validation function for validating if the current field's value is a valid base 64.
-func isBase64(fl FieldLevel) bool {
- return base64Regex.MatchString(fl.Field().String())
-}
-
-// IsBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
-func isBase64URL(fl FieldLevel) bool {
- return base64URLRegex.MatchString(fl.Field().String())
-}
-
-// IsURI is the validation function for validating if the current field's value is a valid URI.
-func isURI(fl FieldLevel) bool {
-
- field := fl.Field()
-
- switch field.Kind() {
-
- case reflect.String:
-
- s := field.String()
-
- // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
- // emulate browser and strip the '#' suffix prior to validation. see issue-#237
- if i := strings.Index(s, "#"); i > -1 {
- s = s[:i]
- }
-
- if len(s) == 0 {
- return false
- }
-
- _, err := url.ParseRequestURI(s)
-
- return err == nil
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsURL is the validation function for validating if the current field's value is a valid URL.
-func isURL(fl FieldLevel) bool {
-
- field := fl.Field()
-
- switch field.Kind() {
-
- case reflect.String:
-
- var i int
- s := field.String()
-
- // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
- // emulate browser and strip the '#' suffix prior to validation. see issue-#237
- if i = strings.Index(s, "#"); i > -1 {
- s = s[:i]
- }
-
- if len(s) == 0 {
- return false
- }
-
- url, err := url.ParseRequestURI(s)
-
- if err != nil || url.Scheme == "" {
- return false
- }
-
- return err == nil
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
-func isUrnRFC2141(fl FieldLevel) bool {
- field := fl.Field()
-
- switch field.Kind() {
-
- case reflect.String:
-
- str := field.String()
-
- _, match := urn.Parse([]byte(str))
-
- return match
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsFile is the validation function for validating if the current field's value is a valid file path.
-func isFile(fl FieldLevel) bool {
- field := fl.Field()
-
- switch field.Kind() {
- case reflect.String:
- fileInfo, err := os.Stat(field.String())
- if err != nil {
- return false
- }
-
- return !fileInfo.IsDir()
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsEmail is the validation function for validating if the current field's value is a valid email address.
-func isEmail(fl FieldLevel) bool {
- return emailRegex.MatchString(fl.Field().String())
-}
-
-// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
-func isHSLA(fl FieldLevel) bool {
- return hslaRegex.MatchString(fl.Field().String())
-}
-
-// IsHSL is the validation function for validating if the current field's value is a valid HSL color.
-func isHSL(fl FieldLevel) bool {
- return hslRegex.MatchString(fl.Field().String())
-}
-
-// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
-func isRGBA(fl FieldLevel) bool {
- return rgbaRegex.MatchString(fl.Field().String())
-}
-
-// IsRGB is the validation function for validating if the current field's value is a valid RGB color.
-func isRGB(fl FieldLevel) bool {
- return rgbRegex.MatchString(fl.Field().String())
-}
-
-// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
-func isHEXColor(fl FieldLevel) bool {
- return hexcolorRegex.MatchString(fl.Field().String())
-}
-
-// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
-func isHexadecimal(fl FieldLevel) bool {
- return hexadecimalRegex.MatchString(fl.Field().String())
-}
-
-// IsNumber is the validation function for validating if the current field's value is a valid number.
-func isNumber(fl FieldLevel) bool {
- switch fl.Field().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
- return true
- default:
- return numberRegex.MatchString(fl.Field().String())
- }
-}
-
-// IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
-func isNumeric(fl FieldLevel) bool {
- switch fl.Field().Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
- return true
- default:
- return numericRegex.MatchString(fl.Field().String())
- }
-}
-
-// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
-func isAlphanum(fl FieldLevel) bool {
- return alphaNumericRegex.MatchString(fl.Field().String())
-}
-
-// IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
-func isAlpha(fl FieldLevel) bool {
- return alphaRegex.MatchString(fl.Field().String())
-}
-
-// IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
-func isAlphanumUnicode(fl FieldLevel) bool {
- return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
-}
-
-// IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
-func isAlphaUnicode(fl FieldLevel) bool {
- return alphaUnicodeRegex.MatchString(fl.Field().String())
-}
-
-// isDefault is the opposite of required aka hasValue
-func isDefault(fl FieldLevel) bool {
- return !hasValue(fl)
-}
-
-// HasValue is the validation function for validating if the current field's value is not the default static value.
-func hasValue(fl FieldLevel) bool {
-
- field := fl.Field()
-
- switch field.Kind() {
- case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
- return !field.IsNil()
- default:
-
- if fl.(*validate).fldIsPointer && field.Interface() != nil {
- return true
- }
-
- return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
- }
-}
-
-// IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
-func isGteField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- currentField, currentKind, ok := fl.GetStructFieldOK()
- if !ok || currentKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() >= currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() >= currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() >= currentField.Float()
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.After(t) || fieldTime.Equal(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) >= len(currentField.String())
-}
-
-// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
-func isGtField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- currentField, currentKind, ok := fl.GetStructFieldOK()
- if !ok || currentKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() > currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() > currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() > currentField.Float()
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.After(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) > len(currentField.String())
-}
-
-// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
-func isGte(fl FieldLevel) bool {
-
- field := fl.Field()
- param := fl.Param()
-
- switch field.Kind() {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) >= p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) >= p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() >= p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() >= p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() >= p
-
- case reflect.Struct:
-
- if field.Type() == timeType {
-
- now := time.Now().UTC()
- t := field.Interface().(time.Time)
-
- return t.After(now) || t.Equal(now)
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsGt is the validation function for validating if the current field's value is greater than the param's value.
-func isGt(fl FieldLevel) bool {
-
- field := fl.Field()
- param := fl.Param()
-
- switch field.Kind() {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) > p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) > p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() > p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() > p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() > p
- case reflect.Struct:
-
- if field.Type() == timeType {
-
- return field.Interface().(time.Time).After(time.Now().UTC())
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
-func hasLengthOf(fl FieldLevel) bool {
-
- field := fl.Field()
- param := fl.Param()
-
- switch field.Kind() {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) == p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) == p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() == p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() == p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() == p
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
-func hasMinOf(fl FieldLevel) bool {
- return isGte(fl)
-}
-
-// IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value.
-func isLteField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- currentField, currentKind, ok := fl.GetStructFieldOK()
- if !ok || currentKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() <= currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() <= currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() <= currentField.Float()
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Before(t) || fieldTime.Equal(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) <= len(currentField.String())
-}
-
-// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
-func isLtField(fl FieldLevel) bool {
-
- field := fl.Field()
- kind := field.Kind()
-
- currentField, currentKind, ok := fl.GetStructFieldOK()
- if !ok || currentKind != kind {
- return false
- }
-
- switch kind {
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-
- return field.Int() < currentField.Int()
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-
- return field.Uint() < currentField.Uint()
-
- case reflect.Float32, reflect.Float64:
-
- return field.Float() < currentField.Float()
-
- case reflect.Struct:
-
- fieldType := field.Type()
-
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Before(t)
- }
- }
-
- // default reflect.String
- return len(field.String()) < len(currentField.String())
-}
-
-// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
-func isLte(fl FieldLevel) bool {
-
- field := fl.Field()
- param := fl.Param()
-
- switch field.Kind() {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) <= p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) <= p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() <= p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() <= p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() <= p
-
- case reflect.Struct:
-
- if field.Type() == timeType {
-
- now := time.Now().UTC()
- t := field.Interface().(time.Time)
-
- return t.Before(now) || t.Equal(now)
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// IsLt is the validation function for validating if the current field's value is less than the param's value.
-func isLt(fl FieldLevel) bool {
-
- field := fl.Field()
- param := fl.Param()
-
- switch field.Kind() {
-
- case reflect.String:
- p := asInt(param)
-
- return int64(utf8.RuneCountInString(field.String())) < p
-
- case reflect.Slice, reflect.Map, reflect.Array:
- p := asInt(param)
-
- return int64(field.Len()) < p
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p := asInt(param)
-
- return field.Int() < p
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p := asUint(param)
-
- return field.Uint() < p
-
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
-
- return field.Float() < p
-
- case reflect.Struct:
-
- if field.Type() == timeType {
-
- return field.Interface().(time.Time).Before(time.Now().UTC())
- }
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
-
-// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
-func hasMaxOf(fl FieldLevel) bool {
- return isLte(fl)
-}
-
-// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
-func isTCP4AddrResolvable(fl FieldLevel) bool {
-
- if !isIP4Addr(fl) {
- return false
- }
-
- _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
- return err == nil
-}
-
-// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
-func isTCP6AddrResolvable(fl FieldLevel) bool {
-
- if !isIP6Addr(fl) {
- return false
- }
-
- _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
-
- return err == nil
-}
-
-// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
-func isTCPAddrResolvable(fl FieldLevel) bool {
-
- if !isIP4Addr(fl) && !isIP6Addr(fl) {
- return false
- }
-
- _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
-
- return err == nil
-}
-
-// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
-func isUDP4AddrResolvable(fl FieldLevel) bool {
-
- if !isIP4Addr(fl) {
- return false
- }
-
- _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
-
- return err == nil
-}
-
-// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
-func isUDP6AddrResolvable(fl FieldLevel) bool {
-
- if !isIP6Addr(fl) {
- return false
- }
-
- _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
-
- return err == nil
-}
-
-// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
-func isUDPAddrResolvable(fl FieldLevel) bool {
-
- if !isIP4Addr(fl) && !isIP6Addr(fl) {
- return false
- }
-
- _, err := net.ResolveUDPAddr("udp", fl.Field().String())
-
- return err == nil
-}
-
-// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
-func isIP4AddrResolvable(fl FieldLevel) bool {
-
- if !isIPv4(fl) {
- return false
- }
-
- _, err := net.ResolveIPAddr("ip4", fl.Field().String())
-
- return err == nil
-}
-
-// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
-func isIP6AddrResolvable(fl FieldLevel) bool {
-
- if !isIPv6(fl) {
- return false
- }
-
- _, err := net.ResolveIPAddr("ip6", fl.Field().String())
-
- return err == nil
-}
-
-// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
-func isIPAddrResolvable(fl FieldLevel) bool {
-
- if !isIP(fl) {
- return false
- }
-
- _, err := net.ResolveIPAddr("ip", fl.Field().String())
-
- return err == nil
-}
-
-// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
-func isUnixAddrResolvable(fl FieldLevel) bool {
-
- _, err := net.ResolveUnixAddr("unix", fl.Field().String())
-
- return err == nil
-}
-
-func isIP4Addr(fl FieldLevel) bool {
-
- val := fl.Field().String()
-
- if idx := strings.LastIndex(val, ":"); idx != -1 {
- val = val[0:idx]
- }
-
- ip := net.ParseIP(val)
-
- return ip != nil && ip.To4() != nil
-}
-
-func isIP6Addr(fl FieldLevel) bool {
-
- val := fl.Field().String()
-
- if idx := strings.LastIndex(val, ":"); idx != -1 {
- if idx != 0 && val[idx-1:idx] == "]" {
- val = val[1 : idx-1]
- }
- }
-
- ip := net.ParseIP(val)
-
- return ip != nil && ip.To4() == nil
-}
-
-func isHostnameRFC952(fl FieldLevel) bool {
- return hostnameRegexRFC952.MatchString(fl.Field().String())
-}
-
-func isHostnameRFC1123(fl FieldLevel) bool {
- return hostnameRegexRFC1123.MatchString(fl.Field().String())
-}
-
-func isFQDN(fl FieldLevel) bool {
- val := fl.Field().String()
-
- if val == "" {
- return false
- }
-
- if val[len(val)-1] == '.' {
- val = val[0 : len(val)-1]
- }
-
- return strings.ContainsAny(val, ".") &&
- hostnameRegexRFC952.MatchString(val)
-}
-
-// IsDir is the validation function for validating if the current field's value is a valid directory.
-func isDir(fl FieldLevel) bool {
- field := fl.Field()
-
- if field.Kind() == reflect.String {
- fileInfo, err := os.Stat(field.String())
- if err != nil {
- return false
- }
-
- return fileInfo.IsDir()
- }
-
- panic(fmt.Sprintf("Bad field type %T", field.Interface()))
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/cache.go b/vendor/gopkg.in/go-playground/validator.v9/cache.go
deleted file mode 100644
index a7a4202..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/cache.go
+++ /dev/null
@@ -1,337 +0,0 @@
-package validator
-
-import (
- "fmt"
- "reflect"
- "strings"
- "sync"
- "sync/atomic"
-)
-
-type tagType uint8
-
-const (
- typeDefault tagType = iota
- typeOmitEmpty
- typeIsDefault
- typeNoStructLevel
- typeStructOnly
- typeDive
- typeOr
- typeKeys
- typeEndKeys
-)
-
-const (
- invalidValidation = "Invalid validation tag on field '%s'"
- undefinedValidation = "Undefined validation function '%s' on field '%s'"
- keysTagNotDefined = "'" + endKeysTag + "' tag encountered without a corresponding '" + keysTag + "' tag"
-)
-
-type structCache struct {
- lock sync.Mutex
- m atomic.Value // map[reflect.Type]*cStruct
-}
-
-func (sc *structCache) Get(key reflect.Type) (c *cStruct, found bool) {
- c, found = sc.m.Load().(map[reflect.Type]*cStruct)[key]
- return
-}
-
-func (sc *structCache) Set(key reflect.Type, value *cStruct) {
-
- m := sc.m.Load().(map[reflect.Type]*cStruct)
-
- nm := make(map[reflect.Type]*cStruct, len(m)+1)
- for k, v := range m {
- nm[k] = v
- }
- nm[key] = value
- sc.m.Store(nm)
-}
-
-type tagCache struct {
- lock sync.Mutex
- m atomic.Value // map[string]*cTag
-}
-
-func (tc *tagCache) Get(key string) (c *cTag, found bool) {
- c, found = tc.m.Load().(map[string]*cTag)[key]
- return
-}
-
-func (tc *tagCache) Set(key string, value *cTag) {
-
- m := tc.m.Load().(map[string]*cTag)
-
- nm := make(map[string]*cTag, len(m)+1)
- for k, v := range m {
- nm[k] = v
- }
- nm[key] = value
- tc.m.Store(nm)
-}
-
-type cStruct struct {
- name string
- fields []*cField
- fn StructLevelFuncCtx
-}
-
-type cField struct {
- idx int
- name string
- altName string
- namesEqual bool
- cTags *cTag
-}
-
-type cTag struct {
- tag string
- aliasTag string
- actualAliasTag string
- param string
- keys *cTag // only populated when using tag's 'keys' and 'endkeys' for map key validation
- next *cTag
- fn FuncCtx
- typeof tagType
- hasTag bool
- hasAlias bool
- hasParam bool // true if parameter used eg. eq= where the equal sign has been set
- isBlockEnd bool // indicates the current tag represents the last validation in the block
-}
-
-func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStruct {
-
- v.structCache.lock.Lock()
- defer v.structCache.lock.Unlock() // leave as defer! because if inner panics, it will never get unlocked otherwise!
-
- typ := current.Type()
-
- // could have been multiple trying to access, but once first is done this ensures struct
- // isn't parsed again.
- cs, ok := v.structCache.Get(typ)
- if ok {
- return cs
- }
-
- cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]}
-
- numFields := current.NumField()
-
- var ctag *cTag
- var fld reflect.StructField
- var tag string
- var customName string
-
- for i := 0; i < numFields; i++ {
-
- fld = typ.Field(i)
-
- if !fld.Anonymous && len(fld.PkgPath) > 0 {
- continue
- }
-
- tag = fld.Tag.Get(v.tagName)
-
- if tag == skipValidationTag {
- continue
- }
-
- customName = fld.Name
-
- if v.hasTagNameFunc {
-
- name := v.tagNameFunc(fld)
-
- if len(name) > 0 {
- customName = name
- }
- }
-
- // NOTE: cannot use shared tag cache, because tags may be equal, but things like alias may be different
- // and so only struct level caching can be used instead of combined with Field tag caching
-
- if len(tag) > 0 {
- ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false)
- } else {
- // even if field doesn't have validations need cTag for traversing to potential inner/nested
- // elements of the field.
- ctag = new(cTag)
- }
-
- cs.fields = append(cs.fields, &cField{
- idx: i,
- name: fld.Name,
- altName: customName,
- cTags: ctag,
- namesEqual: fld.Name == customName,
- })
- }
-
- v.structCache.Set(typ, cs)
-
- return cs
-}
-
-func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias string, hasAlias bool) (firstCtag *cTag, current *cTag) {
-
- var t string
- var ok bool
- noAlias := len(alias) == 0
- tags := strings.Split(tag, tagSeparator)
-
- for i := 0; i < len(tags); i++ {
-
- t = tags[i]
-
- if noAlias {
- alias = t
- }
-
- // check map for alias and process new tags, otherwise process as usual
- if tagsVal, found := v.aliases[t]; found {
- if i == 0 {
- firstCtag, current = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true)
- } else {
- next, curr := v.parseFieldTagsRecursive(tagsVal, fieldName, t, true)
- current.next, current = next, curr
-
- }
-
- continue
- }
-
- var prevTag tagType
-
- if i == 0 {
- current = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true}
- firstCtag = current
- } else {
- prevTag = current.typeof
- current.next = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true}
- current = current.next
- }
-
- switch t {
-
- case diveTag:
- current.typeof = typeDive
- continue
-
- case keysTag:
- current.typeof = typeKeys
-
- if i == 0 || prevTag != typeDive {
- panic(fmt.Sprintf("'%s' tag must be immediately preceded by the '%s' tag", keysTag, diveTag))
- }
-
- current.typeof = typeKeys
-
- // need to pass along only keys tag
- // need to increment i to skip over the keys tags
- b := make([]byte, 0, 64)
-
- i++
-
- for ; i < len(tags); i++ {
-
- b = append(b, tags[i]...)
- b = append(b, ',')
-
- if tags[i] == endKeysTag {
- break
- }
- }
-
- current.keys, _ = v.parseFieldTagsRecursive(string(b[:len(b)-1]), fieldName, "", false)
- continue
-
- case endKeysTag:
- current.typeof = typeEndKeys
-
- // if there are more in tags then there was no keysTag defined
- // and an error should be thrown
- if i != len(tags)-1 {
- panic(keysTagNotDefined)
- }
- return
-
- case omitempty:
- current.typeof = typeOmitEmpty
- continue
-
- case structOnlyTag:
- current.typeof = typeStructOnly
- continue
-
- case noStructLevelTag:
- current.typeof = typeNoStructLevel
- continue
-
- default:
-
- if t == isdefault {
- current.typeof = typeIsDefault
- }
-
- // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C"
- orVals := strings.Split(t, orSeparator)
-
- for j := 0; j < len(orVals); j++ {
-
- vals := strings.SplitN(orVals[j], tagKeySeparator, 2)
-
- if noAlias {
- alias = vals[0]
- current.aliasTag = alias
- } else {
- current.actualAliasTag = t
- }
-
- if j > 0 {
- current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true}
- current = current.next
- }
- current.hasParam = len(vals) > 1
-
- current.tag = vals[0]
- if len(current.tag) == 0 {
- panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName)))
- }
-
- if current.fn, ok = v.validations[current.tag]; !ok {
- panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName)))
- }
-
- if len(orVals) > 1 {
- current.typeof = typeOr
- }
-
- if len(vals) > 1 {
- current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1)
- }
- }
- current.isBlockEnd = true
- }
- }
- return
-}
-
-func (v *Validate) fetchCacheTag(tag string) *cTag {
- // find cached tag
- ctag, found := v.tagCache.Get(tag)
- if !found {
- v.tagCache.lock.Lock()
- defer v.tagCache.lock.Unlock()
-
- // could have been multiple trying to access, but once first is done this ensures tag
- // isn't parsed again.
- ctag, found = v.tagCache.Get(tag)
- if !found {
- ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false)
- v.tagCache.Set(tag, ctag)
- }
- }
- return ctag
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/doc.go b/vendor/gopkg.in/go-playground/validator.v9/doc.go
deleted file mode 100644
index 40db7c4..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/doc.go
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
-Package validator implements value validations for structs and individual fields
-based on tags.
-
-It can also handle Cross-Field and Cross-Struct validation for nested structs
-and has the ability to dive into arrays and maps of any type.
-
-see more examples https://github.com/go-playground/validator/tree/v9/_examples
-
-Validation Functions Return Type error
-
-Doing things this way is actually the way the standard library does, see the
-file.Open method here:
-
- https://golang.org/pkg/os/#Open.
-
-The authors return type "error" to avoid the issue discussed in the following,
-where err is always != nil:
-
- http://stackoverflow.com/a/29138676/3158232
- https://github.com/go-playground/validator/issues/134
-
-Validator only InvalidValidationError for bad validation input, nil or
-ValidationErrors as type error; so, in your code all you need to do is check
-if the error returned is not nil, and if it's not check if error is
-InvalidValidationError ( if necessary, most of the time it isn't ) type cast
-it to type ValidationErrors like so err.(validator.ValidationErrors).
-
-Custom Validation Functions
-
-Custom Validation functions can be added. Example:
-
- // Structure
- func customFunc(fl validator.FieldLevel) bool {
-
- if fl.Field().String() == "invalid" {
- return false
- }
-
- return true
- }
-
- validate.RegisterValidation("custom tag name", customFunc)
- // NOTES: using the same tag name as an existing function
- // will overwrite the existing one
-
-Cross-Field Validation
-
-Cross-Field Validation can be done via the following tags:
- - eqfield
- - nefield
- - gtfield
- - gtefield
- - ltfield
- - ltefield
- - eqcsfield
- - necsfield
- - gtcsfield
- - gtecsfield
- - ltcsfield
- - ltecsfield
-
-If, however, some custom cross-field validation is required, it can be done
-using a custom validation.
-
-Why not just have cross-fields validation tags (i.e. only eqcsfield and not
-eqfield)?
-
-The reason is efficiency. If you want to check a field within the same struct
-"eqfield" only has to find the field on the same struct (1 level). But, if we
-used "eqcsfield" it could be multiple levels down. Example:
-
- type Inner struct {
- StartDate time.Time
- }
-
- type Outer struct {
- InnerStructField *Inner
- CreatedAt time.Time `validate:"ltecsfield=InnerStructField.StartDate"`
- }
-
- now := time.Now()
-
- inner := &Inner{
- StartDate: now,
- }
-
- outer := &Outer{
- InnerStructField: inner,
- CreatedAt: now,
- }
-
- errs := validate.Struct(outer)
-
- // NOTE: when calling validate.Struct(val) topStruct will be the top level struct passed
- // into the function
- // when calling validate.VarWithValue(val, field, tag) val will be
- // whatever you pass, struct, field...
- // when calling validate.Field(field, tag) val will be nil
-
-Multiple Validators
-
-Multiple validators on a field will process in the order defined. Example:
-
- type Test struct {
- Field `validate:"max=10,min=1"`
- }
-
- // max will be checked then min
-
-Bad Validator definitions are not handled by the library. Example:
-
- type Test struct {
- Field `validate:"min=10,max=0"`
- }
-
- // this definition of min max will never succeed
-
-Using Validator Tags
-
-Baked In Cross-Field validation only compares fields on the same struct.
-If Cross-Field + Cross-Struct validation is needed you should implement your
-own custom validator.
-
-Comma (",") is the default separator of validation tags. If you wish to
-have a comma included within the parameter (i.e. excludesall=,) you will need to
-use the UTF-8 hex representation 0x2C, which is replaced in the code as a comma,
-so the above will become excludesall=0x2C.
-
- type Test struct {
- Field `validate:"excludesall=,"` // BAD! Do not include a comma.
- Field `validate:"excludesall=0x2C"` // GOOD! Use the UTF-8 hex representation.
- }
-
-Pipe ("|") is the 'or' validation tags deparator. If you wish to
-have a pipe included within the parameter i.e. excludesall=| you will need to
-use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe,
-so the above will become excludesall=0x7C
-
- type Test struct {
- Field `validate:"excludesall=|"` // BAD! Do not include a a pipe!
- Field `validate:"excludesall=0x7C"` // GOOD! Use the UTF-8 hex representation.
- }
-
-
-Baked In Validators and Tags
-
-Here is a list of the current built in validators:
-
-
-Skip Field
-
-Tells the validation to skip this struct field; this is particularly
-handy in ignoring embedded structs from being validated. (Usage: -)
- Usage: -
-
-
-Or Operator
-
-This is the 'or' operator allowing multiple validators to be used and
-accepted. (Usage: rbg|rgba) <-- this would allow either rgb or rgba
-colors to be accepted. This can also be combined with 'and' for example
-( Usage: omitempty,rgb|rgba)
-
- Usage: |
-
-StructOnly
-
-When a field that is a nested struct is encountered, and contains this flag
-any validation on the nested struct will be run, but none of the nested
-struct fields will be validated. This is useful if inside of your program
-you know the struct will be valid, but need to verify it has been assigned.
-NOTE: only "required" and "omitempty" can be used on a struct itself.
-
- Usage: structonly
-
-NoStructLevel
-
-Same as structonly tag except that any struct level validations will not run.
-
- Usage: nostructlevel
-
-Omit Empty
-
-Allows conditional validation, for example if a field is not set with
-a value (Determined by the "required" validator) then other validation
-such as min or max won't run, but if a value is set validation will run.
-
- Usage: omitempty
-
-Dive
-
-This tells the validator to dive into a slice, array or map and validate that
-level of the slice, array or map with the validation tags that follow.
-Multidimensional nesting is also supported, each level you wish to dive will
-require another dive tag. dive has some sub-tags, 'keys' & 'endkeys', please see
-the Keys & EndKeys section just below.
-
- Usage: dive
-
-Example #1
-
- [][]string with validation tag "gt=0,dive,len=1,dive,required"
- // gt=0 will be applied to []
- // len=1 will be applied to []string
- // required will be applied to string
-
-Example #2
-
- [][]string with validation tag "gt=0,dive,dive,required"
- // gt=0 will be applied to []
- // []string will be spared validation
- // required will be applied to string
-
-Keys & EndKeys
-
-These are to be used together directly after the dive tag and tells the validator
-that anything between 'keys' and 'endkeys' applies to the keys of a map and not the
-values; think of it like the 'dive' tag, but for map keys instead of values.
-Multidimensional nesting is also supported, each level you wish to validate will
-require another 'keys' and 'endkeys' tag. These tags are only valid for maps.
-
- Usage: dive,keys,othertagvalidation(s),endkeys,valuevalidationtags
-
-Example #1
-
- map[string]string with validation tag "gt=0,dive,keys,eg=1|eq=2,endkeys,required"
- // gt=0 will be applied to the map itself
- // eg=1|eq=2 will be applied to the map keys
- // required will be applied to map values
-
-Example #2
-
- map[[2]string]string with validation tag "gt=0,dive,keys,dive,eq=1|eq=2,endkeys,required"
- // gt=0 will be applied to the map itself
- // eg=1|eq=2 will be applied to each array element in the the map keys
- // required will be applied to map values
-
-Required
-
-This validates that the value is not the data types default zero value.
-For numbers ensures value is not zero. For strings ensures value is
-not "". For slices, maps, pointers, interfaces, channels and functions
-ensures the value is not nil.
-
- Usage: required
-
-Is Default
-
-This validates that the value is the default value and is almost the
-opposite of required.
-
- Usage: isdefault
-
-Length
-
-For numbers, length will ensure that the value is
-equal to the parameter given. For strings, it checks that
-the string length is exactly that number of characters. For slices,
-arrays, and maps, validates the number of items.
-
- Usage: len=10
-
-Maximum
-
-For numbers, max will ensure that the value is
-less than or equal to the parameter given. For strings, it checks
-that the string length is at most that number of characters. For
-slices, arrays, and maps, validates the number of items.
-
- Usage: max=10
-
-Minimum
-
-For numbers, min will ensure that the value is
-greater or equal to the parameter given. For strings, it checks that
-the string length is at least that number of characters. For slices,
-arrays, and maps, validates the number of items.
-
- Usage: min=10
-
-Equals
-
-For strings & numbers, eq will ensure that the value is
-equal to the parameter given. For slices, arrays, and maps,
-validates the number of items.
-
- Usage: eq=10
-
-Not Equal
-
-For strings & numbers, ne will ensure that the value is not
-equal to the parameter given. For slices, arrays, and maps,
-validates the number of items.
-
- Usage: ne=10
-
-One Of
-
-For strings, ints, and uints, oneof will ensure that the value
-is one of the values in the parameter. The parameter should be
-a list of values separated by whitespace. Values may be
-strings or numbers.
-
- Usage: oneof=red green
- oneof=5 7 9
-
-Greater Than
-
-For numbers, this will ensure that the value is greater than the
-parameter given. For strings, it checks that the string length
-is greater than that number of characters. For slices, arrays
-and maps it validates the number of items.
-
-Example #1
-
- Usage: gt=10
-
-Example #2 (time.Time)
-
-For time.Time ensures the time value is greater than time.Now.UTC().
-
- Usage: gt
-
-Greater Than or Equal
-
-Same as 'min' above. Kept both to make terminology with 'len' easier.
-
-
-Example #1
-
- Usage: gte=10
-
-Example #2 (time.Time)
-
-For time.Time ensures the time value is greater than or equal to time.Now.UTC().
-
- Usage: gte
-
-Less Than
-
-For numbers, this will ensure that the value is less than the parameter given.
-For strings, it checks that the string length is less than that number of
-characters. For slices, arrays, and maps it validates the number of items.
-
-Example #1
-
- Usage: lt=10
-
-Example #2 (time.Time)
-For time.Time ensures the time value is less than time.Now.UTC().
-
- Usage: lt
-
-Less Than or Equal
-
-Same as 'max' above. Kept both to make terminology with 'len' easier.
-
-Example #1
-
- Usage: lte=10
-
-Example #2 (time.Time)
-
-For time.Time ensures the time value is less than or equal to time.Now.UTC().
-
- Usage: lte
-
-Field Equals Another Field
-
-This will validate the field value against another fields value either within
-a struct or passed in field.
-
-Example #1:
-
- // Validation on Password field using:
- Usage: eqfield=ConfirmPassword
-
-Example #2:
-
- // Validating by field:
- validate.VarWithValue(password, confirmpassword, "eqfield")
-
-Field Equals Another Field (relative)
-
-This does the same as eqfield except that it validates the field provided relative
-to the top level struct.
-
- Usage: eqcsfield=InnerStructField.Field)
-
-Field Does Not Equal Another Field
-
-This will validate the field value against another fields value either within
-a struct or passed in field.
-
-Examples:
-
- // Confirm two colors are not the same:
- //
- // Validation on Color field:
- Usage: nefield=Color2
-
- // Validating by field:
- validate.VarWithValue(color1, color2, "nefield")
-
-Field Does Not Equal Another Field (relative)
-
-This does the same as nefield except that it validates the field provided
-relative to the top level struct.
-
- Usage: necsfield=InnerStructField.Field
-
-Field Greater Than Another Field
-
-Only valid for Numbers and time.Time types, this will validate the field value
-against another fields value either within a struct or passed in field.
-usage examples are for validation of a Start and End date:
-
-Example #1:
-
- // Validation on End field using:
- validate.Struct Usage(gtfield=Start)
-
-Example #2:
-
- // Validating by field:
- validate.VarWithValue(start, end, "gtfield")
-
-
-Field Greater Than Another Relative Field
-
-This does the same as gtfield except that it validates the field provided
-relative to the top level struct.
-
- Usage: gtcsfield=InnerStructField.Field
-
-Field Greater Than or Equal To Another Field
-
-Only valid for Numbers and time.Time types, this will validate the field value
-against another fields value either within a struct or passed in field.
-usage examples are for validation of a Start and End date:
-
-Example #1:
-
- // Validation on End field using:
- validate.Struct Usage(gtefield=Start)
-
-Example #2:
-
- // Validating by field:
- validate.VarWithValue(start, end, "gtefield")
-
-Field Greater Than or Equal To Another Relative Field
-
-This does the same as gtefield except that it validates the field provided relative
-to the top level struct.
-
- Usage: gtecsfield=InnerStructField.Field
-
-Less Than Another Field
-
-Only valid for Numbers and time.Time types, this will validate the field value
-against another fields value either within a struct or passed in field.
-usage examples are for validation of a Start and End date:
-
-Example #1:
-
- // Validation on End field using:
- validate.Struct Usage(ltfield=Start)
-
-Example #2:
-
- // Validating by field:
- validate.VarWithValue(start, end, "ltfield")
-
-Less Than Another Relative Field
-
-This does the same as ltfield except that it validates the field provided relative
-to the top level struct.
-
- Usage: ltcsfield=InnerStructField.Field
-
-Less Than or Equal To Another Field
-
-Only valid for Numbers and time.Time types, this will validate the field value
-against another fields value either within a struct or passed in field.
-usage examples are for validation of a Start and End date:
-
-Example #1:
-
- // Validation on End field using:
- validate.Struct Usage(ltefield=Start)
-
-Example #2:
-
- // Validating by field:
- validate.VarWithValue(start, end, "ltefield")
-
-Less Than or Equal To Another Relative Field
-
-This does the same as ltefield except that it validates the field provided relative
-to the top level struct.
-
- Usage: ltecsfield=InnerStructField.Field
-
-Field Contains Another Field
-
-This does the same as contains except for struct fields. It should only be used
-with string types. See the behavior of reflect.Value.String() for behavior on
-other types.
-
- Usage: containsfield=InnerStructField.Field
-
-Field Excludes Another Field
-
-This does the same as excludes except for struct fields. It should only be used
-with string types. See the behavior of reflect.Value.String() for behavior on
-other types.
-
- Usage: excludesfield=InnerStructField.Field
-
-Unique
-
-For arrays & slices, unique will ensure that there are no duplicates.
-For maps, unique will ensure that there are no duplicate values.
-
- Usage: unique
-
-Alpha Only
-
-This validates that a string value contains ASCII alpha characters only
-
- Usage: alpha
-
-Alphanumeric
-
-This validates that a string value contains ASCII alphanumeric characters only
-
- Usage: alphanum
-
-Alpha Unicode
-
-This validates that a string value contains unicode alpha characters only
-
- Usage: alphaunicode
-
-Alphanumeric Unicode
-
-This validates that a string value contains unicode alphanumeric characters only
-
- Usage: alphanumunicode
-
-Numeric
-
-This validates that a string value contains a basic numeric value.
-basic excludes exponents etc...
-for integers or float it returns true.
-
- Usage: numeric
-
-Hexadecimal String
-
-This validates that a string value contains a valid hexadecimal.
-
- Usage: hexadecimal
-
-Hexcolor String
-
-This validates that a string value contains a valid hex color including
-hashtag (#)
-
- Usage: hexcolor
-
-RGB String
-
-This validates that a string value contains a valid rgb color
-
- Usage: rgb
-
-RGBA String
-
-This validates that a string value contains a valid rgba color
-
- Usage: rgba
-
-HSL String
-
-This validates that a string value contains a valid hsl color
-
- Usage: hsl
-
-HSLA String
-
-This validates that a string value contains a valid hsla color
-
- Usage: hsla
-
-E-mail String
-
-This validates that a string value contains a valid email
-This may not conform to all possibilities of any rfc standard, but neither
-does any email provider accept all possibilities.
-
- Usage: email
-
-File path
-
-This validates that a string value contains a valid file path and that
-the file exists on the machine.
-This is done using os.Stat, which is a platform independent function.
-
- Usage: file
-
-URL String
-
-This validates that a string value contains a valid url
-This will accept any url the golang request uri accepts but must contain
-a schema for example http:// or rtmp://
-
- Usage: url
-
-URI String
-
-This validates that a string value contains a valid uri
-This will accept any uri the golang request uri accepts
-
- Usage: uri
-
-Urn RFC 2141 String
-
-This validataes that a string value contains a valid URN
-according to the RFC 2141 spec.
-
- Usage: urn_rfc2141
-
-Base64 String
-
-This validates that a string value contains a valid base64 value.
-Although an empty string is valid base64 this will report an empty string
-as an error, if you wish to accept an empty string as valid you can use
-this with the omitempty tag.
-
- Usage: base64
-
-Base64URL String
-
-This validates that a string value contains a valid base64 URL safe value
-according the the RFC4648 spec.
-Although an empty string is a valid base64 URL safe value, this will report
-an empty string as an error, if you wish to accept an empty string as valid
-you can use this with the omitempty tag.
-
- Usage: base64url
-
-Bitcoin Address
-
-This validates that a string value contains a valid bitcoin address.
-The format of the string is checked to ensure it matches one of the three formats
-P2PKH, P2SH and performs checksum validation.
-
- Usage: btc_addr
-
-Bitcoin Bech32 Address (segwit)
-
-This validates that a string value contains a valid bitcoin Bech32 address as defined
-by bip-0173 (https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)
-Special thanks to Pieter Wuille for providng reference implementations.
-
- Usage: btc_addr_bech32
-
-Ethereum Address
-
-This validates that a string value contains a valid ethereum address.
-The format of the string is checked to ensure it matches the standard Ethereum address format
-Full validation is blocked by https://github.com/golang/crypto/pull/28
-
- Usage: eth_addr
-
-Contains
-
-This validates that a string value contains the substring value.
-
- Usage: contains=@
-
-Contains Any
-
-This validates that a string value contains any Unicode code points
-in the substring value.
-
- Usage: containsany=!@#?
-
-Contains Rune
-
-This validates that a string value contains the supplied rune value.
-
- Usage: containsrune=@
-
-Excludes
-
-This validates that a string value does not contain the substring value.
-
- Usage: excludes=@
-
-Excludes All
-
-This validates that a string value does not contain any Unicode code
-points in the substring value.
-
- Usage: excludesall=!@#?
-
-Excludes Rune
-
-This validates that a string value does not contain the supplied rune value.
-
- Usage: excludesrune=@
-
-Starts With
-
-This validates that a string value starts with the supplied string value
-
- Usage: startswith=hello
-
-Ends With
-
-This validates that a string value ends with the supplied string value
-
- Usage: endswith=goodbye
-
-International Standard Book Number
-
-This validates that a string value contains a valid isbn10 or isbn13 value.
-
- Usage: isbn
-
-International Standard Book Number 10
-
-This validates that a string value contains a valid isbn10 value.
-
- Usage: isbn10
-
-International Standard Book Number 13
-
-This validates that a string value contains a valid isbn13 value.
-
- Usage: isbn13
-
-Universally Unique Identifier UUID
-
-This validates that a string value contains a valid UUID. Uppercase UUID values will not pass - use `uuid_rfc4122` instead.
-
- Usage: uuid
-
-Universally Unique Identifier UUID v3
-
-This validates that a string value contains a valid version 3 UUID. Uppercase UUID values will not pass - use `uuid3_rfc4122` instead.
-
- Usage: uuid3
-
-Universally Unique Identifier UUID v4
-
-This validates that a string value contains a valid version 4 UUID. Uppercase UUID values will not pass - use `uuid4_rfc4122` instead.
-
- Usage: uuid4
-
-Universally Unique Identifier UUID v5
-
-This validates that a string value contains a valid version 5 UUID. Uppercase UUID values will not pass - use `uuid5_rfc4122` instead.
-
- Usage: uuid5
-
-ASCII
-
-This validates that a string value contains only ASCII characters.
-NOTE: if the string is blank, this validates as true.
-
- Usage: ascii
-
-Printable ASCII
-
-This validates that a string value contains only printable ASCII characters.
-NOTE: if the string is blank, this validates as true.
-
- Usage: printascii
-
-Multi-Byte Characters
-
-This validates that a string value contains one or more multibyte characters.
-NOTE: if the string is blank, this validates as true.
-
- Usage: multibyte
-
-Data URL
-
-This validates that a string value contains a valid DataURI.
-NOTE: this will also validate that the data portion is valid base64
-
- Usage: datauri
-
-Latitude
-
-This validates that a string value contains a valid latitude.
-
- Usage: latitude
-
-Longitude
-
-This validates that a string value contains a valid longitude.
-
- Usage: longitude
-
-Social Security Number SSN
-
-This validates that a string value contains a valid U.S. Social Security Number.
-
- Usage: ssn
-
-Internet Protocol Address IP
-
-This validates that a string value contains a valid IP Address.
-
- Usage: ip
-
-Internet Protocol Address IPv4
-
-This validates that a string value contains a valid v4 IP Address.
-
- Usage: ipv4
-
-Internet Protocol Address IPv6
-
-This validates that a string value contains a valid v6 IP Address.
-
- Usage: ipv6
-
-Classless Inter-Domain Routing CIDR
-
-This validates that a string value contains a valid CIDR Address.
-
- Usage: cidr
-
-Classless Inter-Domain Routing CIDRv4
-
-This validates that a string value contains a valid v4 CIDR Address.
-
- Usage: cidrv4
-
-Classless Inter-Domain Routing CIDRv6
-
-This validates that a string value contains a valid v6 CIDR Address.
-
- Usage: cidrv6
-
-Transmission Control Protocol Address TCP
-
-This validates that a string value contains a valid resolvable TCP Address.
-
- Usage: tcp_addr
-
-Transmission Control Protocol Address TCPv4
-
-This validates that a string value contains a valid resolvable v4 TCP Address.
-
- Usage: tcp4_addr
-
-Transmission Control Protocol Address TCPv6
-
-This validates that a string value contains a valid resolvable v6 TCP Address.
-
- Usage: tcp6_addr
-
-User Datagram Protocol Address UDP
-
-This validates that a string value contains a valid resolvable UDP Address.
-
- Usage: udp_addr
-
-User Datagram Protocol Address UDPv4
-
-This validates that a string value contains a valid resolvable v4 UDP Address.
-
- Usage: udp4_addr
-
-User Datagram Protocol Address UDPv6
-
-This validates that a string value contains a valid resolvable v6 UDP Address.
-
- Usage: udp6_addr
-
-Internet Protocol Address IP
-
-This validates that a string value contains a valid resolvable IP Address.
-
- Usage: ip_addr
-
-Internet Protocol Address IPv4
-
-This validates that a string value contains a valid resolvable v4 IP Address.
-
- Usage: ip4_addr
-
-Internet Protocol Address IPv6
-
-This validates that a string value contains a valid resolvable v6 IP Address.
-
- Usage: ip6_addr
-
-Unix domain socket end point Address
-
-This validates that a string value contains a valid Unix Address.
-
- Usage: unix_addr
-
-Media Access Control Address MAC
-
-This validates that a string value contains a valid MAC Address.
-
- Usage: mac
-
-Note: See Go's ParseMAC for accepted formats and types:
-
- http://golang.org/src/net/mac.go?s=866:918#L29
-
-Hostname RFC 952
-
-This validates that a string value is a valid Hostname according to RFC 952 https://tools.ietf.org/html/rfc952
-
- Usage: hostname
-
-Hostname RFC 1123
-
-This validates that a string value is a valid Hostname according to RFC 1123 https://tools.ietf.org/html/rfc1123
-
- Usage: hostname_rfc1123 or if you want to continue to use 'hostname' in your tags, create an alias.
-
-Full Qualified Domain Name (FQDN)
-
-This validates that a string value contains a valid FQDN.
-
- Usage: fqdn
-
-HTML Tags
-
-This validates that a string value appears to be an HTML element tag
-including those described at https://developer.mozilla.org/en-US/docs/Web/HTML/Element
-
- Usage: html
-
-HTML Encoded
-
-This validates that a string value is a proper character reference in decimal
-or hexadecimal format
-
- Usage: html_encoded
-
-URL Encoded
-
-This validates that a string value is percent-encoded (URL encoded) according
-to https://tools.ietf.org/html/rfc3986#section-2.1
-
- Usage: url_encoded
-
-Directory
-
-This validates that a string value contains a valid directory and that
-it exists on the machine.
-This is done using os.Stat, which is a platform independent function.
-
- Usage: dir
-
-Alias Validators and Tags
-
-NOTE: When returning an error, the tag returned in "FieldError" will be
-the alias tag unless the dive tag is part of the alias. Everything after the
-dive tag is not reported as the alias tag. Also, the "ActualTag" in the before
-case will be the actual tag within the alias that failed.
-
-Here is a list of the current built in alias tags:
-
- "iscolor"
- alias is "hexcolor|rgb|rgba|hsl|hsla" (Usage: iscolor)
-
-Validator notes:
-
- regex
- a regex validator won't be added because commas and = signs can be part
- of a regex which conflict with the validation definitions. Although
- workarounds can be made, they take away from using pure regex's.
- Furthermore it's quick and dirty but the regex's become harder to
- maintain and are not reusable, so it's as much a programming philosophy
- as anything.
-
- In place of this new validator functions should be created; a regex can
- be used within the validator function and even be precompiled for better
- efficiency within regexes.go.
-
- And the best reason, you can submit a pull request and we can keep on
- adding to the validation library of this package!
-
-Panics
-
-This package panics when bad input is provided, this is by design, bad code like
-that should not make it to production.
-
- type Test struct {
- TestField string `validate:"nonexistantfunction=1"`
- }
-
- t := &Test{
- TestField: "Test"
- }
-
- validate.Struct(t) // this will panic
-
-Non standard validators
-
-A collection of validation rules that are frequently needed but are more
-complex than the ones found in the baked in validators.
-A non standard validator must be registered manually using any tag you like.
-See below examples of registration and use.
-
- type Test struct {
- TestField string `validate:"yourtag"`
- }
-
- t := &Test{
- TestField: "Test"
- }
-
- validate := validator.New()
- validate.RegisterValidation("yourtag", validations.ValidatorName)
-
- NotBlank
- This validates that the value is not blank or with length zero.
- For strings ensures they do not contain only spaces. For channels, maps, slices and arrays
- ensures they don't have zero length. For others, a non empty value is required.
-
- Usage: notblank
-*/
-package validator
diff --git a/vendor/gopkg.in/go-playground/validator.v9/errors.go b/vendor/gopkg.in/go-playground/validator.v9/errors.go
deleted file mode 100644
index 7dc0a35..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/errors.go
+++ /dev/null
@@ -1,272 +0,0 @@
-package validator
-
-import (
- "bytes"
- "fmt"
- "reflect"
- "strings"
-
- ut "github.com/go-playground/universal-translator"
-)
-
-const (
- fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
-)
-
-// ValidationErrorsTranslations is the translation return type
-type ValidationErrorsTranslations map[string]string
-
-// InvalidValidationError describes an invalid argument passed to
-// `Struct`, `StructExcept`, StructPartial` or `Field`
-type InvalidValidationError struct {
- Type reflect.Type
-}
-
-// Error returns InvalidValidationError message
-func (e *InvalidValidationError) Error() string {
-
- if e.Type == nil {
- return "validator: (nil)"
- }
-
- return "validator: (nil " + e.Type.String() + ")"
-}
-
-// ValidationErrors is an array of FieldError's
-// for use in custom error messages post validation.
-type ValidationErrors []FieldError
-
-// Error is intended for use in development + debugging and not intended to be a production error message.
-// It allows ValidationErrors to subscribe to the Error interface.
-// All information to create an error message specific to your application is contained within
-// the FieldError found within the ValidationErrors array
-func (ve ValidationErrors) Error() string {
-
- buff := bytes.NewBufferString("")
-
- var fe *fieldError
-
- for i := 0; i < len(ve); i++ {
-
- fe = ve[i].(*fieldError)
- buff.WriteString(fe.Error())
- buff.WriteString("\n")
- }
-
- return strings.TrimSpace(buff.String())
-}
-
-// Translate translates all of the ValidationErrors
-func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations {
-
- trans := make(ValidationErrorsTranslations)
-
- var fe *fieldError
-
- for i := 0; i < len(ve); i++ {
- fe = ve[i].(*fieldError)
-
- // // in case an Anonymous struct was used, ensure that the key
- // // would be 'Username' instead of ".Username"
- // if len(fe.ns) > 0 && fe.ns[:1] == "." {
- // trans[fe.ns[1:]] = fe.Translate(ut)
- // continue
- // }
-
- trans[fe.ns] = fe.Translate(ut)
- }
-
- return trans
-}
-
-// FieldError contains all functions to get error details
-type FieldError interface {
-
- // returns the validation tag that failed. if the
- // validation was an alias, this will return the
- // alias name and not the underlying tag that failed.
- //
- // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
- // will return "iscolor"
- Tag() string
-
- // returns the validation tag that failed, even if an
- // alias the actual tag within the alias will be returned.
- // If an 'or' validation fails the entire or will be returned.
- //
- // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
- // will return "hexcolor|rgb|rgba|hsl|hsla"
- ActualTag() string
-
- // returns the namespace for the field error, with the tag
- // name taking precedence over the fields actual name.
- //
- // eg. JSON name "User.fname"
- //
- // See StructNamespace() for a version that returns actual names.
- //
- // NOTE: this field can be blank when validating a single primitive field
- // using validate.Field(...) as there is no way to extract it's name
- Namespace() string
-
- // returns the namespace for the field error, with the fields
- // actual name.
- //
- // eq. "User.FirstName" see Namespace for comparison
- //
- // NOTE: this field can be blank when validating a single primitive field
- // using validate.Field(...) as there is no way to extract it's name
- StructNamespace() string
-
- // returns the fields name with the tag name taking precedence over the
- // fields actual name.
- //
- // eq. JSON name "fname"
- // see StructField for comparison
- Field() string
-
- // returns the fields actual name from the struct, when able to determine.
- //
- // eq. "FirstName"
- // see Field for comparison
- StructField() string
-
- // returns the actual fields value in case needed for creating the error
- // message
- Value() interface{}
-
- // returns the param value, in string form for comparison; this will also
- // help with generating an error message
- Param() string
-
- // Kind returns the Field's reflect Kind
- //
- // eg. time.Time's kind is a struct
- Kind() reflect.Kind
-
- // Type returns the Field's reflect Type
- //
- // // eg. time.Time's type is time.Time
- Type() reflect.Type
-
- // returns the FieldError's translated error
- // from the provided 'ut.Translator' and registered 'TranslationFunc'
- //
- // NOTE: is not registered translation can be found it returns the same
- // as calling fe.Error()
- Translate(ut ut.Translator) string
-}
-
-// compile time interface checks
-var _ FieldError = new(fieldError)
-var _ error = new(fieldError)
-
-// fieldError contains a single field's validation error along
-// with other properties that may be needed for error message creation
-// it complies with the FieldError interface
-type fieldError struct {
- v *Validate
- tag string
- actualTag string
- ns string
- structNs string
- fieldLen uint8
- structfieldLen uint8
- value interface{}
- param string
- kind reflect.Kind
- typ reflect.Type
-}
-
-// Tag returns the validation tag that failed.
-func (fe *fieldError) Tag() string {
- return fe.tag
-}
-
-// ActualTag returns the validation tag that failed, even if an
-// alias the actual tag within the alias will be returned.
-func (fe *fieldError) ActualTag() string {
- return fe.actualTag
-}
-
-// Namespace returns the namespace for the field error, with the tag
-// name taking precedence over the fields actual name.
-func (fe *fieldError) Namespace() string {
- return fe.ns
-}
-
-// StructNamespace returns the namespace for the field error, with the fields
-// actual name.
-func (fe *fieldError) StructNamespace() string {
- return fe.structNs
-}
-
-// Field returns the fields name with the tag name taking precedence over the
-// fields actual name.
-func (fe *fieldError) Field() string {
-
- return fe.ns[len(fe.ns)-int(fe.fieldLen):]
- // // return fe.field
- // fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
-
- // log.Println("FLD:", fld)
-
- // if len(fld) > 0 && fld[:1] == "." {
- // return fld[1:]
- // }
-
- // return fld
-}
-
-// returns the fields actual name from the struct, when able to determine.
-func (fe *fieldError) StructField() string {
- // return fe.structField
- return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
-}
-
-// Value returns the actual fields value in case needed for creating the error
-// message
-func (fe *fieldError) Value() interface{} {
- return fe.value
-}
-
-// Param returns the param value, in string form for comparison; this will
-// also help with generating an error message
-func (fe *fieldError) Param() string {
- return fe.param
-}
-
-// Kind returns the Field's reflect Kind
-func (fe *fieldError) Kind() reflect.Kind {
- return fe.kind
-}
-
-// Type returns the Field's reflect Type
-func (fe *fieldError) Type() reflect.Type {
- return fe.typ
-}
-
-// Error returns the fieldError's error message
-func (fe *fieldError) Error() string {
- return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag)
-}
-
-// Translate returns the FieldError's translated error
-// from the provided 'ut.Translator' and registered 'TranslationFunc'
-//
-// NOTE: is not registered translation can be found it returns the same
-// as calling fe.Error()
-func (fe *fieldError) Translate(ut ut.Translator) string {
-
- m, ok := fe.v.transTagFunc[ut]
- if !ok {
- return fe.Error()
- }
-
- fn, ok := m[fe.tag]
- if !ok {
- return fe.Error()
- }
-
- return fn(ut, fe)
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/field_level.go b/vendor/gopkg.in/go-playground/validator.v9/field_level.go
deleted file mode 100644
index cbfbc15..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/field_level.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package validator
-
-import "reflect"
-
-// FieldLevel contains all the information and helper functions
-// to validate a field
-type FieldLevel interface {
-
- // returns the top level struct, if any
- Top() reflect.Value
-
- // returns the current fields parent struct, if any or
- // the comparison value if called 'VarWithValue'
- Parent() reflect.Value
-
- // returns current field for validation
- Field() reflect.Value
-
- // returns the field's name with the tag
- // name taking precedence over the fields actual name.
- FieldName() string
-
- // returns the struct field's name
- StructFieldName() string
-
- // returns param for validation against current field
- Param() string
-
- // ExtractType gets the actual underlying type of field value.
- // It will dive into pointers, customTypes and return you the
- // underlying value and it's kind.
- ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
-
- // traverses the parent struct to retrieve a specific field denoted by the provided namespace
- // in the param and returns the field, field kind and whether is was successful in retrieving
- // the field at all.
- //
- // NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
- // could not be retrieved because it didn't exist.
- GetStructFieldOK() (reflect.Value, reflect.Kind, bool)
-}
-
-var _ FieldLevel = new(validate)
-
-// Field returns current field for validation
-func (v *validate) Field() reflect.Value {
- return v.flField
-}
-
-// FieldName returns the field's name with the tag
-// name takeing precedence over the fields actual name.
-func (v *validate) FieldName() string {
- return v.cf.altName
-}
-
-// StructFieldName returns the struct field's name
-func (v *validate) StructFieldName() string {
- return v.cf.name
-}
-
-// Param returns param for validation against current field
-func (v *validate) Param() string {
- return v.ct.param
-}
-
-// GetStructFieldOK returns Param returns param for validation against current field
-func (v *validate) GetStructFieldOK() (reflect.Value, reflect.Kind, bool) {
- return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/logo.png b/vendor/gopkg.in/go-playground/validator.v9/logo.png
deleted file mode 100644
index 355000f..0000000
Binary files a/vendor/gopkg.in/go-playground/validator.v9/logo.png and /dev/null differ
diff --git a/vendor/gopkg.in/go-playground/validator.v9/regexes.go b/vendor/gopkg.in/go-playground/validator.v9/regexes.go
deleted file mode 100644
index 25e54d5..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/regexes.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package validator
-
-import "regexp"
-
-const (
- alphaRegexString = "^[a-zA-Z]+$"
- alphaNumericRegexString = "^[a-zA-Z0-9]+$"
- alphaUnicodeRegexString = "^[\\p{L}]+$"
- alphaUnicodeNumericRegexString = "^[\\p{L}\\p{N}]+$"
- numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
- numberRegexString = "^[0-9]+$"
- hexadecimalRegexString = "^[0-9a-fA-F]+$"
- hexcolorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
- rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$"
- rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
- hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$"
- hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
- emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
- base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
- base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
- iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
- iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
- uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
- uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
- uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
- uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
- uUID3RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
- uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
- uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
- uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
- aSCIIRegexString = "^[\x00-\x7F]*$"
- printableASCIIRegexString = "^[\x20-\x7E]*$"
- multibyteRegexString = "[^\x00-\x7F]"
- dataURIRegexString = "^data:.+\\/(.+);base64$"
- latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
- longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
- sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$`
- hostnameRegexStringRFC952 = `^[a-zA-Z][a-zA-Z0-9\-\.]+[a-z-Az0-9]$` // https://tools.ietf.org/html/rfc952
- hostnameRegexStringRFC1123 = `^[a-zA-Z0-9][a-zA-Z0-9\-\.]+[a-z-Az0-9]$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
- btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
- btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
- btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
- ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
- ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
- ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
- uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})`
- hTMLEncodedRegexString = `[x]?([0-9a-fA-F]{2})|(>)|(<)|(")|(&)+[;]?`
- hTMLRegexString = `<[/]?([a-zA-Z]+).*?>`
-)
-
-var (
- alphaRegex = regexp.MustCompile(alphaRegexString)
- alphaNumericRegex = regexp.MustCompile(alphaNumericRegexString)
- alphaUnicodeRegex = regexp.MustCompile(alphaUnicodeRegexString)
- alphaUnicodeNumericRegex = regexp.MustCompile(alphaUnicodeNumericRegexString)
- numericRegex = regexp.MustCompile(numericRegexString)
- numberRegex = regexp.MustCompile(numberRegexString)
- hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString)
- hexcolorRegex = regexp.MustCompile(hexcolorRegexString)
- rgbRegex = regexp.MustCompile(rgbRegexString)
- rgbaRegex = regexp.MustCompile(rgbaRegexString)
- hslRegex = regexp.MustCompile(hslRegexString)
- hslaRegex = regexp.MustCompile(hslaRegexString)
- emailRegex = regexp.MustCompile(emailRegexString)
- base64Regex = regexp.MustCompile(base64RegexString)
- base64URLRegex = regexp.MustCompile(base64URLRegexString)
- iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
- iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
- uUID3Regex = regexp.MustCompile(uUID3RegexString)
- uUID4Regex = regexp.MustCompile(uUID4RegexString)
- uUID5Regex = regexp.MustCompile(uUID5RegexString)
- uUIDRegex = regexp.MustCompile(uUIDRegexString)
- uUID3RFC4122Regex = regexp.MustCompile(uUID3RFC4122RegexString)
- uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString)
- uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString)
- uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString)
- aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
- printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
- multibyteRegex = regexp.MustCompile(multibyteRegexString)
- dataURIRegex = regexp.MustCompile(dataURIRegexString)
- latitudeRegex = regexp.MustCompile(latitudeRegexString)
- longitudeRegex = regexp.MustCompile(longitudeRegexString)
- sSNRegex = regexp.MustCompile(sSNRegexString)
- hostnameRegexRFC952 = regexp.MustCompile(hostnameRegexStringRFC952)
- hostnameRegexRFC1123 = regexp.MustCompile(hostnameRegexStringRFC1123)
- btcAddressRegex = regexp.MustCompile(btcAddressRegexString)
- btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32)
- btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32)
- ethAddressRegex = regexp.MustCompile(ethAddressRegexString)
- ethaddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString)
- ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString)
- uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString)
- hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString)
- hTMLRegex = regexp.MustCompile(hTMLRegexString)
-)
diff --git a/vendor/gopkg.in/go-playground/validator.v9/struct_level.go b/vendor/gopkg.in/go-playground/validator.v9/struct_level.go
deleted file mode 100644
index 57691ee..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/struct_level.go
+++ /dev/null
@@ -1,175 +0,0 @@
-package validator
-
-import (
- "context"
- "reflect"
-)
-
-// StructLevelFunc accepts all values needed for struct level validation
-type StructLevelFunc func(sl StructLevel)
-
-// StructLevelFuncCtx accepts all values needed for struct level validation
-// but also allows passing of contextual validation information via context.Context.
-type StructLevelFuncCtx func(ctx context.Context, sl StructLevel)
-
-// wrapStructLevelFunc wraps normal StructLevelFunc makes it compatible with StructLevelFuncCtx
-func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx {
- return func(ctx context.Context, sl StructLevel) {
- fn(sl)
- }
-}
-
-// StructLevel contains all the information and helper functions
-// to validate a struct
-type StructLevel interface {
-
- // returns the main validation object, in case one wants to call validations internally.
- // this is so you don't have to use anonymous functions to get access to the validate
- // instance.
- Validator() *Validate
-
- // returns the top level struct, if any
- Top() reflect.Value
-
- // returns the current fields parent struct, if any
- Parent() reflect.Value
-
- // returns the current struct.
- Current() reflect.Value
-
- // ExtractType gets the actual underlying type of field value.
- // It will dive into pointers, customTypes and return you the
- // underlying value and its kind.
- ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
-
- // reports an error just by passing the field and tag information
- //
- // NOTES:
- //
- // fieldName and altName get appended to the existing namespace that
- // validator is on. e.g. pass 'FirstName' or 'Names[0]' depending
- // on the nesting
- //
- // tag can be an existing validation tag or just something you make up
- // and process on the flip side it's up to you.
- ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
-
- // reports an error just by passing ValidationErrors
- //
- // NOTES:
- //
- // relativeNamespace and relativeActualNamespace get appended to the
- // existing namespace that validator is on.
- // e.g. pass 'User.FirstName' or 'Users[0].FirstName' depending
- // on the nesting. most of the time they will be blank, unless you validate
- // at a level lower the the current field depth
- ReportValidationErrors(relativeNamespace, relativeActualNamespace string, errs ValidationErrors)
-}
-
-var _ StructLevel = new(validate)
-
-// Top returns the top level struct
-//
-// NOTE: this can be the same as the current struct being validated
-// if not is a nested struct.
-//
-// this is only called when within Struct and Field Level validation and
-// should not be relied upon for an acurate value otherwise.
-func (v *validate) Top() reflect.Value {
- return v.top
-}
-
-// Parent returns the current structs parent
-//
-// NOTE: this can be the same as the current struct being validated
-// if not is a nested struct.
-//
-// this is only called when within Struct and Field Level validation and
-// should not be relied upon for an acurate value otherwise.
-func (v *validate) Parent() reflect.Value {
- return v.slflParent
-}
-
-// Current returns the current struct.
-func (v *validate) Current() reflect.Value {
- return v.slCurrent
-}
-
-// Validator returns the main validation object, in case one want to call validations internally.
-func (v *validate) Validator() *Validate {
- return v.v
-}
-
-// ExtractType gets the actual underlying type of field value.
-func (v *validate) ExtractType(field reflect.Value) (reflect.Value, reflect.Kind, bool) {
- return v.extractTypeInternal(field, false)
-}
-
-// ReportError reports an error just by passing the field and tag information
-func (v *validate) ReportError(field interface{}, fieldName, structFieldName, tag, param string) {
-
- fv, kind, _ := v.extractTypeInternal(reflect.ValueOf(field), false)
-
- if len(structFieldName) == 0 {
- structFieldName = fieldName
- }
-
- v.str1 = string(append(v.ns, fieldName...))
-
- if v.v.hasTagNameFunc || fieldName != structFieldName {
- v.str2 = string(append(v.actualNs, structFieldName...))
- } else {
- v.str2 = v.str1
- }
-
- if kind == reflect.Invalid {
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: tag,
- actualTag: tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(fieldName)),
- structfieldLen: uint8(len(structFieldName)),
- param: param,
- kind: kind,
- },
- )
- return
- }
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: tag,
- actualTag: tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(fieldName)),
- structfieldLen: uint8(len(structFieldName)),
- value: fv.Interface(),
- param: param,
- kind: kind,
- typ: fv.Type(),
- },
- )
-}
-
-// ReportValidationErrors reports ValidationErrors obtained from running validations within the Struct Level validation.
-//
-// NOTE: this function prepends the current namespace to the relative ones.
-func (v *validate) ReportValidationErrors(relativeNamespace, relativeStructNamespace string, errs ValidationErrors) {
-
- var err *fieldError
-
- for i := 0; i < len(errs); i++ {
-
- err = errs[i].(*fieldError)
- err.ns = string(append(append(v.ns, relativeNamespace...), err.ns...))
- err.structNs = string(append(append(v.actualNs, relativeStructNamespace...), err.structNs...))
-
- v.errs = append(v.errs, err)
- }
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/translations.go b/vendor/gopkg.in/go-playground/validator.v9/translations.go
deleted file mode 100644
index 4d9d75c..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/translations.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package validator
-
-import ut "github.com/go-playground/universal-translator"
-
-// TranslationFunc is the function type used to register or override
-// custom translations
-type TranslationFunc func(ut ut.Translator, fe FieldError) string
-
-// RegisterTranslationsFunc allows for registering of translations
-// for a 'ut.Translator' for use within the 'TranslationFunc'
-type RegisterTranslationsFunc func(ut ut.Translator) error
diff --git a/vendor/gopkg.in/go-playground/validator.v9/util.go b/vendor/gopkg.in/go-playground/validator.v9/util.go
deleted file mode 100644
index 16a5517..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/util.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package validator
-
-import (
- "reflect"
- "strconv"
- "strings"
-)
-
-// extractTypeInternal gets the actual underlying type of field value.
-// It will dive into pointers, customTypes and return you the
-// underlying value and it's kind.
-func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (reflect.Value, reflect.Kind, bool) {
-
-BEGIN:
- switch current.Kind() {
- case reflect.Ptr:
-
- nullable = true
-
- if current.IsNil() {
- return current, reflect.Ptr, nullable
- }
-
- current = current.Elem()
- goto BEGIN
-
- case reflect.Interface:
-
- nullable = true
-
- if current.IsNil() {
- return current, reflect.Interface, nullable
- }
-
- current = current.Elem()
- goto BEGIN
-
- case reflect.Invalid:
- return current, reflect.Invalid, nullable
-
- default:
-
- if v.v.hasCustomFuncs {
-
- if fn, ok := v.v.customFuncs[current.Type()]; ok {
- current = reflect.ValueOf(fn(current))
- goto BEGIN
- }
- }
-
- return current, current.Kind(), nullable
- }
-}
-
-// getStructFieldOKInternal traverses a struct to retrieve a specific field denoted by the provided namespace and
-// returns the field, field kind and whether is was successful in retrieving the field at all.
-//
-// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
-// could not be retrieved because it didn't exist.
-func (v *validate) getStructFieldOKInternal(val reflect.Value, namespace string) (current reflect.Value, kind reflect.Kind, found bool) {
-
-BEGIN:
- current, kind, _ = v.ExtractType(val)
-
- if kind == reflect.Invalid {
- return
- }
-
- if namespace == "" {
- found = true
- return
- }
-
- switch kind {
-
- case reflect.Ptr, reflect.Interface:
- return
-
- case reflect.Struct:
-
- typ := current.Type()
- fld := namespace
- var ns string
-
- if typ != timeType {
-
- idx := strings.Index(namespace, namespaceSeparator)
-
- if idx != -1 {
- fld = namespace[:idx]
- ns = namespace[idx+1:]
- } else {
- ns = ""
- }
-
- bracketIdx := strings.Index(fld, leftBracket)
- if bracketIdx != -1 {
- fld = fld[:bracketIdx]
-
- ns = namespace[bracketIdx:]
- }
-
- val = current.FieldByName(fld)
- namespace = ns
- goto BEGIN
- }
-
- case reflect.Array, reflect.Slice:
- idx := strings.Index(namespace, leftBracket)
- idx2 := strings.Index(namespace, rightBracket)
-
- arrIdx, _ := strconv.Atoi(namespace[idx+1 : idx2])
-
- if arrIdx >= current.Len() {
- return current, kind, false
- }
-
- startIdx := idx2 + 1
-
- if startIdx < len(namespace) {
- if namespace[startIdx:startIdx+1] == namespaceSeparator {
- startIdx++
- }
- }
-
- val = current.Index(arrIdx)
- namespace = namespace[startIdx:]
- goto BEGIN
-
- case reflect.Map:
- idx := strings.Index(namespace, leftBracket) + 1
- idx2 := strings.Index(namespace, rightBracket)
-
- endIdx := idx2
-
- if endIdx+1 < len(namespace) {
- if namespace[endIdx+1:endIdx+2] == namespaceSeparator {
- endIdx++
- }
- }
-
- key := namespace[idx:idx2]
-
- switch current.Type().Key().Kind() {
- case reflect.Int:
- i, _ := strconv.Atoi(key)
- val = current.MapIndex(reflect.ValueOf(i))
- namespace = namespace[endIdx+1:]
-
- case reflect.Int8:
- i, _ := strconv.ParseInt(key, 10, 8)
- val = current.MapIndex(reflect.ValueOf(int8(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Int16:
- i, _ := strconv.ParseInt(key, 10, 16)
- val = current.MapIndex(reflect.ValueOf(int16(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Int32:
- i, _ := strconv.ParseInt(key, 10, 32)
- val = current.MapIndex(reflect.ValueOf(int32(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Int64:
- i, _ := strconv.ParseInt(key, 10, 64)
- val = current.MapIndex(reflect.ValueOf(i))
- namespace = namespace[endIdx+1:]
-
- case reflect.Uint:
- i, _ := strconv.ParseUint(key, 10, 0)
- val = current.MapIndex(reflect.ValueOf(uint(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Uint8:
- i, _ := strconv.ParseUint(key, 10, 8)
- val = current.MapIndex(reflect.ValueOf(uint8(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Uint16:
- i, _ := strconv.ParseUint(key, 10, 16)
- val = current.MapIndex(reflect.ValueOf(uint16(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Uint32:
- i, _ := strconv.ParseUint(key, 10, 32)
- val = current.MapIndex(reflect.ValueOf(uint32(i)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Uint64:
- i, _ := strconv.ParseUint(key, 10, 64)
- val = current.MapIndex(reflect.ValueOf(i))
- namespace = namespace[endIdx+1:]
-
- case reflect.Float32:
- f, _ := strconv.ParseFloat(key, 32)
- val = current.MapIndex(reflect.ValueOf(float32(f)))
- namespace = namespace[endIdx+1:]
-
- case reflect.Float64:
- f, _ := strconv.ParseFloat(key, 64)
- val = current.MapIndex(reflect.ValueOf(f))
- namespace = namespace[endIdx+1:]
-
- case reflect.Bool:
- b, _ := strconv.ParseBool(key)
- val = current.MapIndex(reflect.ValueOf(b))
- namespace = namespace[endIdx+1:]
-
- // reflect.Type = string
- default:
- val = current.MapIndex(reflect.ValueOf(key))
- namespace = namespace[endIdx+1:]
- }
-
- goto BEGIN
- }
-
- // if got here there was more namespace, cannot go any deeper
- panic("Invalid field namespace")
-}
-
-// asInt returns the parameter as a int64
-// or panics if it can't convert
-func asInt(param string) int64 {
-
- i, err := strconv.ParseInt(param, 0, 64)
- panicIf(err)
-
- return i
-}
-
-// asUint returns the parameter as a uint64
-// or panics if it can't convert
-func asUint(param string) uint64 {
-
- i, err := strconv.ParseUint(param, 0, 64)
- panicIf(err)
-
- return i
-}
-
-// asFloat returns the parameter as a float64
-// or panics if it can't convert
-func asFloat(param string) float64 {
-
- i, err := strconv.ParseFloat(param, 64)
- panicIf(err)
-
- return i
-}
-
-func panicIf(err error) {
- if err != nil {
- panic(err.Error())
- }
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/validator.go b/vendor/gopkg.in/go-playground/validator.v9/validator.go
deleted file mode 100644
index 67473f1..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/validator.go
+++ /dev/null
@@ -1,475 +0,0 @@
-package validator
-
-import (
- "context"
- "fmt"
- "reflect"
- "strconv"
-)
-
-// per validate contruct
-type validate struct {
- v *Validate
- top reflect.Value
- ns []byte
- actualNs []byte
- errs ValidationErrors
- includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise
- ffn FilterFunc
- slflParent reflect.Value // StructLevel & FieldLevel
- slCurrent reflect.Value // StructLevel & FieldLevel
- flField reflect.Value // StructLevel & FieldLevel
- cf *cField // StructLevel & FieldLevel
- ct *cTag // StructLevel & FieldLevel
- misc []byte // misc reusable
- str1 string // misc reusable
- str2 string // misc reusable
- fldIsPointer bool // StructLevel & FieldLevel
- isPartial bool
- hasExcludes bool
-}
-
-// parent and current will be the same the first run of validateStruct
-func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, current reflect.Value, typ reflect.Type, ns []byte, structNs []byte, ct *cTag) {
-
- cs, ok := v.v.structCache.Get(typ)
- if !ok {
- cs = v.v.extractStructCache(current, typ.Name())
- }
-
- if len(ns) == 0 && len(cs.name) != 0 {
-
- ns = append(ns, cs.name...)
- ns = append(ns, '.')
-
- structNs = append(structNs, cs.name...)
- structNs = append(structNs, '.')
- }
-
- // ct is nil on top level struct, and structs as fields that have no tag info
- // so if nil or if not nil and the structonly tag isn't present
- if ct == nil || ct.typeof != typeStructOnly {
-
- var f *cField
-
- for i := 0; i < len(cs.fields); i++ {
-
- f = cs.fields[i]
-
- if v.isPartial {
-
- if v.ffn != nil {
- // used with StructFiltered
- if v.ffn(append(structNs, f.name...)) {
- continue
- }
-
- } else {
- // used with StructPartial & StructExcept
- _, ok = v.includeExclude[string(append(structNs, f.name...))]
-
- if (ok && v.hasExcludes) || (!ok && !v.hasExcludes) {
- continue
- }
- }
- }
-
- v.traverseField(ctx, parent, current.Field(f.idx), ns, structNs, f, f.cTags)
- }
- }
-
- // check if any struct level validations, after all field validations already checked.
- // first iteration will have no info about nostructlevel tag, and is checked prior to
- // calling the next iteration of validateStruct called from traverseField.
- if cs.fn != nil {
-
- v.slflParent = parent
- v.slCurrent = current
- v.ns = ns
- v.actualNs = structNs
-
- cs.fn(ctx, v)
- }
-}
-
-// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options
-func (v *validate) traverseField(ctx context.Context, parent reflect.Value, current reflect.Value, ns []byte, structNs []byte, cf *cField, ct *cTag) {
-
- var typ reflect.Type
- var kind reflect.Kind
-
- current, kind, v.fldIsPointer = v.extractTypeInternal(current, false)
-
- switch kind {
- case reflect.Ptr, reflect.Interface, reflect.Invalid:
-
- if ct == nil {
- return
- }
-
- if ct.typeof == typeOmitEmpty || ct.typeof == typeIsDefault {
- return
- }
-
- if ct.hasTag {
-
- v.str1 = string(append(ns, cf.altName...))
-
- if v.v.hasTagNameFunc {
- v.str2 = string(append(structNs, cf.name...))
- } else {
- v.str2 = v.str1
- }
-
- if kind == reflect.Invalid {
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: ct.aliasTag,
- actualTag: ct.tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- param: ct.param,
- kind: kind,
- },
- )
-
- return
- }
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: ct.aliasTag,
- actualTag: ct.tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- value: current.Interface(),
- param: ct.param,
- kind: kind,
- typ: current.Type(),
- },
- )
-
- return
- }
-
- case reflect.Struct:
-
- typ = current.Type()
-
- if typ != timeType {
-
- if ct != nil {
-
- if ct.typeof == typeStructOnly {
- goto CONTINUE
- } else if ct.typeof == typeIsDefault {
- // set Field Level fields
- v.slflParent = parent
- v.flField = current
- v.cf = cf
- v.ct = ct
-
- if !ct.fn(ctx, v) {
- v.str1 = string(append(ns, cf.altName...))
-
- if v.v.hasTagNameFunc {
- v.str2 = string(append(structNs, cf.name...))
- } else {
- v.str2 = v.str1
- }
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: ct.aliasTag,
- actualTag: ct.tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- value: current.Interface(),
- param: ct.param,
- kind: kind,
- typ: typ,
- },
- )
- return
- }
- }
-
- ct = ct.next
- }
-
- if ct != nil && ct.typeof == typeNoStructLevel {
- return
- }
-
- CONTINUE:
- // if len == 0 then validating using 'Var' or 'VarWithValue'
- // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
- // VarWithField - this allows for validating against each field within the struct against a specific value
- // pretty handy in certain situations
- if len(cf.name) > 0 {
- ns = append(append(ns, cf.altName...), '.')
- structNs = append(append(structNs, cf.name...), '.')
- }
-
- v.validateStruct(ctx, current, current, typ, ns, structNs, ct)
- return
- }
- }
-
- if !ct.hasTag {
- return
- }
-
- typ = current.Type()
-
-OUTER:
- for {
- if ct == nil {
- return
- }
-
- switch ct.typeof {
-
- case typeOmitEmpty:
-
- // set Field Level fields
- v.slflParent = parent
- v.flField = current
- v.cf = cf
- v.ct = ct
-
- if !v.fldIsPointer && !hasValue(v) {
- return
- }
-
- ct = ct.next
- continue
-
- case typeEndKeys:
- return
-
- case typeDive:
-
- ct = ct.next
-
- // traverse slice or map here
- // or panic ;)
- switch kind {
- case reflect.Slice, reflect.Array:
-
- var i64 int64
- reusableCF := &cField{}
-
- for i := 0; i < current.Len(); i++ {
-
- i64 = int64(i)
-
- v.misc = append(v.misc[0:0], cf.name...)
- v.misc = append(v.misc, '[')
- v.misc = strconv.AppendInt(v.misc, i64, 10)
- v.misc = append(v.misc, ']')
-
- reusableCF.name = string(v.misc)
-
- if cf.namesEqual {
- reusableCF.altName = reusableCF.name
- } else {
-
- v.misc = append(v.misc[0:0], cf.altName...)
- v.misc = append(v.misc, '[')
- v.misc = strconv.AppendInt(v.misc, i64, 10)
- v.misc = append(v.misc, ']')
-
- reusableCF.altName = string(v.misc)
- }
- v.traverseField(ctx, parent, current.Index(i), ns, structNs, reusableCF, ct)
- }
-
- case reflect.Map:
-
- var pv string
- reusableCF := &cField{}
-
- for _, key := range current.MapKeys() {
-
- pv = fmt.Sprintf("%v", key.Interface())
-
- v.misc = append(v.misc[0:0], cf.name...)
- v.misc = append(v.misc, '[')
- v.misc = append(v.misc, pv...)
- v.misc = append(v.misc, ']')
-
- reusableCF.name = string(v.misc)
-
- if cf.namesEqual {
- reusableCF.altName = reusableCF.name
- } else {
- v.misc = append(v.misc[0:0], cf.altName...)
- v.misc = append(v.misc, '[')
- v.misc = append(v.misc, pv...)
- v.misc = append(v.misc, ']')
-
- reusableCF.altName = string(v.misc)
- }
-
- if ct != nil && ct.typeof == typeKeys && ct.keys != nil {
- v.traverseField(ctx, parent, key, ns, structNs, reusableCF, ct.keys)
- // can be nil when just keys being validated
- if ct.next != nil {
- v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct.next)
- }
- } else {
- v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct)
- }
- }
-
- default:
- // throw error, if not a slice or map then should not have gotten here
- // bad dive tag
- panic("dive error! can't dive on a non slice or map")
- }
-
- return
-
- case typeOr:
-
- v.misc = v.misc[0:0]
-
- for {
-
- // set Field Level fields
- v.slflParent = parent
- v.flField = current
- v.cf = cf
- v.ct = ct
-
- if ct.fn(ctx, v) {
-
- // drain rest of the 'or' values, then continue or leave
- for {
-
- ct = ct.next
-
- if ct == nil {
- return
- }
-
- if ct.typeof != typeOr {
- continue OUTER
- }
- }
- }
-
- v.misc = append(v.misc, '|')
- v.misc = append(v.misc, ct.tag...)
-
- if ct.hasParam {
- v.misc = append(v.misc, '=')
- v.misc = append(v.misc, ct.param...)
- }
-
- if ct.isBlockEnd || ct.next == nil {
- // if we get here, no valid 'or' value and no more tags
- v.str1 = string(append(ns, cf.altName...))
-
- if v.v.hasTagNameFunc {
- v.str2 = string(append(structNs, cf.name...))
- } else {
- v.str2 = v.str1
- }
-
- if ct.hasAlias {
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: ct.aliasTag,
- actualTag: ct.actualAliasTag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- value: current.Interface(),
- param: ct.param,
- kind: kind,
- typ: typ,
- },
- )
-
- } else {
-
- tVal := string(v.misc)[1:]
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: tVal,
- actualTag: tVal,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- value: current.Interface(),
- param: ct.param,
- kind: kind,
- typ: typ,
- },
- )
- }
-
- return
- }
-
- ct = ct.next
- }
-
- default:
-
- // set Field Level fields
- v.slflParent = parent
- v.flField = current
- v.cf = cf
- v.ct = ct
-
- if !ct.fn(ctx, v) {
-
- v.str1 = string(append(ns, cf.altName...))
-
- if v.v.hasTagNameFunc {
- v.str2 = string(append(structNs, cf.name...))
- } else {
- v.str2 = v.str1
- }
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: ct.aliasTag,
- actualTag: ct.tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- value: current.Interface(),
- param: ct.param,
- kind: kind,
- typ: typ,
- },
- )
-
- return
- }
- ct = ct.next
- }
- }
-
-}
diff --git a/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go b/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go
deleted file mode 100644
index fc9db5a..0000000
--- a/vendor/gopkg.in/go-playground/validator.v9/validator_instance.go
+++ /dev/null
@@ -1,600 +0,0 @@
-package validator
-
-import (
- "context"
- "errors"
- "fmt"
- "reflect"
- "strings"
- "sync"
- "time"
-
- ut "github.com/go-playground/universal-translator"
-)
-
-const (
- defaultTagName = "validate"
- utf8HexComma = "0x2C"
- utf8Pipe = "0x7C"
- tagSeparator = ","
- orSeparator = "|"
- tagKeySeparator = "="
- structOnlyTag = "structonly"
- noStructLevelTag = "nostructlevel"
- omitempty = "omitempty"
- isdefault = "isdefault"
- skipValidationTag = "-"
- diveTag = "dive"
- keysTag = "keys"
- endKeysTag = "endkeys"
- requiredTag = "required"
- namespaceSeparator = "."
- leftBracket = "["
- rightBracket = "]"
- restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}"
- restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
- restrictedTagErr = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
-)
-
-var (
- timeType = reflect.TypeOf(time.Time{})
- defaultCField = &cField{namesEqual: true}
-)
-
-// FilterFunc is the type used to filter fields using
-// StructFiltered(...) function.
-// returning true results in the field being filtered/skiped from
-// validation
-type FilterFunc func(ns []byte) bool
-
-// CustomTypeFunc allows for overriding or adding custom field type handler functions
-// field = field value of the type to return a value to be validated
-// example Valuer from sql drive see https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29
-type CustomTypeFunc func(field reflect.Value) interface{}
-
-// TagNameFunc allows for adding of a custom tag name parser
-type TagNameFunc func(field reflect.StructField) string
-
-// Validate contains the validator settings and cache
-type Validate struct {
- tagName string
- pool *sync.Pool
- hasCustomFuncs bool
- hasTagNameFunc bool
- tagNameFunc TagNameFunc
- structLevelFuncs map[reflect.Type]StructLevelFuncCtx
- customFuncs map[reflect.Type]CustomTypeFunc
- aliases map[string]string
- validations map[string]FuncCtx
- transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc
- tagCache *tagCache
- structCache *structCache
-}
-
-// New returns a new instance of 'validate' with sane defaults.
-func New() *Validate {
-
- tc := new(tagCache)
- tc.m.Store(make(map[string]*cTag))
-
- sc := new(structCache)
- sc.m.Store(make(map[reflect.Type]*cStruct))
-
- v := &Validate{
- tagName: defaultTagName,
- aliases: make(map[string]string, len(bakedInAliases)),
- validations: make(map[string]FuncCtx, len(bakedInValidators)),
- tagCache: tc,
- structCache: sc,
- }
-
- // must copy alias validators for separate validations to be used in each validator instance
- for k, val := range bakedInAliases {
- v.RegisterAlias(k, val)
- }
-
- // must copy validators for separate validations to be used in each instance
- for k, val := range bakedInValidators {
-
- // no need to error check here, baked in will always be valid
- _ = v.registerValidation(k, wrapFunc(val), true)
- }
-
- v.pool = &sync.Pool{
- New: func() interface{} {
- return &validate{
- v: v,
- ns: make([]byte, 0, 64),
- actualNs: make([]byte, 0, 64),
- misc: make([]byte, 32),
- }
- },
- }
-
- return v
-}
-
-// SetTagName allows for changing of the default tag name of 'validate'
-func (v *Validate) SetTagName(name string) {
- v.tagName = name
-}
-
-// RegisterTagNameFunc registers a function to get alternate names for StructFields.
-//
-// eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names:
-//
-// validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
-// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
-// if name == "-" {
-// return ""
-// }
-// return name
-// })
-func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) {
- v.tagNameFunc = fn
- v.hasTagNameFunc = true
-}
-
-// RegisterValidation adds a validation with the given tag
-//
-// NOTES:
-// - if the key already exists, the previous validation function will be replaced.
-// - this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterValidation(tag string, fn Func) error {
- return v.RegisterValidationCtx(tag, wrapFunc(fn))
-}
-
-// RegisterValidationCtx does the same as RegisterValidation on accepts a FuncCtx validation
-// allowing context.Context validation support.
-func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx) error {
- return v.registerValidation(tag, fn, false)
-}
-
-func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool) error {
-
- if len(tag) == 0 {
- return errors.New("Function Key cannot be empty")
- }
-
- if fn == nil {
- return errors.New("Function cannot be empty")
- }
-
- _, ok := restrictedTags[tag]
-
- if !bakedIn && (ok || strings.ContainsAny(tag, restrictedTagChars)) {
- panic(fmt.Sprintf(restrictedTagErr, tag))
- }
-
- v.validations[tag] = fn
-
- return nil
-}
-
-// RegisterAlias registers a mapping of a single validation tag that
-// defines a common or complex set of validation(s) to simplify adding validation
-// to structs.
-//
-// NOTE: this function is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterAlias(alias, tags string) {
-
- _, ok := restrictedTags[alias]
-
- if ok || strings.ContainsAny(alias, restrictedTagChars) {
- panic(fmt.Sprintf(restrictedAliasErr, alias))
- }
-
- v.aliases[alias] = tags
-}
-
-// RegisterStructValidation registers a StructLevelFunc against a number of types.
-//
-// NOTE:
-// - this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interface{}) {
- v.RegisterStructValidationCtx(wrapStructLevelFunc(fn), types...)
-}
-
-// RegisterStructValidationCtx registers a StructLevelFuncCtx against a number of types and allows passing
-// of contextual validation information via context.Context.
-//
-// NOTE:
-// - this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...interface{}) {
-
- if v.structLevelFuncs == nil {
- v.structLevelFuncs = make(map[reflect.Type]StructLevelFuncCtx)
- }
-
- for _, t := range types {
- tv := reflect.ValueOf(t)
- if tv.Kind() == reflect.Ptr {
- t = reflect.Indirect(tv).Interface()
- }
-
- v.structLevelFuncs[reflect.TypeOf(t)] = fn
- }
-}
-
-// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
-//
-// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
-func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
-
- if v.customFuncs == nil {
- v.customFuncs = make(map[reflect.Type]CustomTypeFunc)
- }
-
- for _, t := range types {
- v.customFuncs[reflect.TypeOf(t)] = fn
- }
-
- v.hasCustomFuncs = true
-}
-
-// RegisterTranslation registers translations against the provided tag.
-func (v *Validate) RegisterTranslation(tag string, trans ut.Translator, registerFn RegisterTranslationsFunc, translationFn TranslationFunc) (err error) {
-
- if v.transTagFunc == nil {
- v.transTagFunc = make(map[ut.Translator]map[string]TranslationFunc)
- }
-
- if err = registerFn(trans); err != nil {
- return
- }
-
- m, ok := v.transTagFunc[trans]
- if !ok {
- m = make(map[string]TranslationFunc)
- v.transTagFunc[trans] = m
- }
-
- m[tag] = translationFn
-
- return
-}
-
-// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) Struct(s interface{}) error {
- return v.StructCtx(context.Background(), s)
-}
-
-// StructCtx validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified
-// and also allows passing of context.Context for contextual validation information.
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {
-
- val := reflect.ValueOf(s)
- top := val
-
- if val.Kind() == reflect.Ptr && !val.IsNil() {
- val = val.Elem()
- }
-
- if val.Kind() != reflect.Struct || val.Type() == timeType {
- return &InvalidValidationError{Type: reflect.TypeOf(s)}
- }
-
- // good to validate
- vd := v.pool.Get().(*validate)
- vd.top = top
- vd.isPartial = false
- // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
-
- vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
-
- if len(vd.errs) > 0 {
- err = vd.errs
- vd.errs = nil
- }
-
- v.pool.Put(vd)
-
- return
-}
-
-// StructFiltered validates a structs exposed fields, that pass the FilterFunc check and automatically validates
-// nested structs, unless otherwise specified.
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructFiltered(s interface{}, fn FilterFunc) error {
- return v.StructFilteredCtx(context.Background(), s, fn)
-}
-
-// StructFilteredCtx validates a structs exposed fields, that pass the FilterFunc check and automatically validates
-// nested structs, unless otherwise specified and also allows passing of contextual validation information via
-// context.Context
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn FilterFunc) (err error) {
- val := reflect.ValueOf(s)
- top := val
-
- if val.Kind() == reflect.Ptr && !val.IsNil() {
- val = val.Elem()
- }
-
- if val.Kind() != reflect.Struct || val.Type() == timeType {
- return &InvalidValidationError{Type: reflect.TypeOf(s)}
- }
-
- // good to validate
- vd := v.pool.Get().(*validate)
- vd.top = top
- vd.isPartial = true
- vd.ffn = fn
- // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
-
- vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
-
- if len(vd.errs) > 0 {
- err = vd.errs
- vd.errs = nil
- }
-
- v.pool.Put(vd)
-
- return
-}
-
-// StructPartial validates the fields passed in only, ignoring all others.
-// Fields may be provided in a namespaced fashion relative to the struct provided
-// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructPartial(s interface{}, fields ...string) error {
- return v.StructPartialCtx(context.Background(), s, fields...)
-}
-
-// StructPartialCtx validates the fields passed in only, ignoring all others and allows passing of contextual
-// validation validation information via context.Context
-// Fields may be provided in a namespaced fashion relative to the struct provided
-// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields ...string) (err error) {
- val := reflect.ValueOf(s)
- top := val
-
- if val.Kind() == reflect.Ptr && !val.IsNil() {
- val = val.Elem()
- }
-
- if val.Kind() != reflect.Struct || val.Type() == timeType {
- return &InvalidValidationError{Type: reflect.TypeOf(s)}
- }
-
- // good to validate
- vd := v.pool.Get().(*validate)
- vd.top = top
- vd.isPartial = true
- vd.ffn = nil
- vd.hasExcludes = false
- vd.includeExclude = make(map[string]struct{})
-
- typ := val.Type()
- name := typ.Name()
-
- for _, k := range fields {
-
- flds := strings.Split(k, namespaceSeparator)
- if len(flds) > 0 {
-
- vd.misc = append(vd.misc[0:0], name...)
- vd.misc = append(vd.misc, '.')
-
- for _, s := range flds {
-
- idx := strings.Index(s, leftBracket)
-
- if idx != -1 {
- for idx != -1 {
- vd.misc = append(vd.misc, s[:idx]...)
- vd.includeExclude[string(vd.misc)] = struct{}{}
-
- idx2 := strings.Index(s, rightBracket)
- idx2++
- vd.misc = append(vd.misc, s[idx:idx2]...)
- vd.includeExclude[string(vd.misc)] = struct{}{}
- s = s[idx2:]
- idx = strings.Index(s, leftBracket)
- }
- } else {
-
- vd.misc = append(vd.misc, s...)
- vd.includeExclude[string(vd.misc)] = struct{}{}
- }
-
- vd.misc = append(vd.misc, '.')
- }
- }
- }
-
- vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil)
-
- if len(vd.errs) > 0 {
- err = vd.errs
- vd.errs = nil
- }
-
- v.pool.Put(vd)
-
- return
-}
-
-// StructExcept validates all fields except the ones passed in.
-// Fields may be provided in a namespaced fashion relative to the struct provided
-// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructExcept(s interface{}, fields ...string) error {
- return v.StructExceptCtx(context.Background(), s, fields...)
-}
-
-// StructExceptCtx validates all fields except the ones passed in and allows passing of contextual
-// validation validation information via context.Context
-// Fields may be provided in a namespaced fashion relative to the struct provided
-// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ...string) (err error) {
- val := reflect.ValueOf(s)
- top := val
-
- if val.Kind() == reflect.Ptr && !val.IsNil() {
- val = val.Elem()
- }
-
- if val.Kind() != reflect.Struct || val.Type() == timeType {
- return &InvalidValidationError{Type: reflect.TypeOf(s)}
- }
-
- // good to validate
- vd := v.pool.Get().(*validate)
- vd.top = top
- vd.isPartial = true
- vd.ffn = nil
- vd.hasExcludes = true
- vd.includeExclude = make(map[string]struct{})
-
- typ := val.Type()
- name := typ.Name()
-
- for _, key := range fields {
-
- vd.misc = vd.misc[0:0]
-
- if len(name) > 0 {
- vd.misc = append(vd.misc, name...)
- vd.misc = append(vd.misc, '.')
- }
-
- vd.misc = append(vd.misc, key...)
- vd.includeExclude[string(vd.misc)] = struct{}{}
- }
-
- vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil)
-
- if len(vd.errs) > 0 {
- err = vd.errs
- vd.errs = nil
- }
-
- v.pool.Put(vd)
-
- return
-}
-
-// Var validates a single variable using tag style validation.
-// eg.
-// var i int
-// validate.Var(i, "gt=1,lt=10")
-//
-// WARNING: a struct can be passed for validation eg. time.Time is a struct or
-// if you have a custom type and have registered a custom type handler, so must
-// allow it; however unforeseen validations will occur if trying to validate a
-// struct that is meant to be passed to 'validate.Struct'
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-// validate Array, Slice and maps fields which may contain more than one error
-func (v *Validate) Var(field interface{}, tag string) error {
- return v.VarCtx(context.Background(), field, tag)
-}
-
-// VarCtx validates a single variable using tag style validation and allows passing of contextual
-// validation validation information via context.Context.
-// eg.
-// var i int
-// validate.Var(i, "gt=1,lt=10")
-//
-// WARNING: a struct can be passed for validation eg. time.Time is a struct or
-// if you have a custom type and have registered a custom type handler, so must
-// allow it; however unforeseen validations will occur if trying to validate a
-// struct that is meant to be passed to 'validate.Struct'
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-// validate Array, Slice and maps fields which may contain more than one error
-func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (err error) {
- if len(tag) == 0 || tag == skipValidationTag {
- return nil
- }
-
- ctag := v.fetchCacheTag(tag)
- val := reflect.ValueOf(field)
- vd := v.pool.Get().(*validate)
- vd.top = val
- vd.isPartial = false
- vd.traverseField(ctx, val, val, vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag)
-
- if len(vd.errs) > 0 {
- err = vd.errs
- vd.errs = nil
- }
- v.pool.Put(vd)
- return
-}
-
-// VarWithValue validates a single variable, against another variable/field's value using tag style validation
-// eg.
-// s1 := "abcd"
-// s2 := "abcd"
-// validate.VarWithValue(s1, s2, "eqcsfield") // returns true
-//
-// WARNING: a struct can be passed for validation eg. time.Time is a struct or
-// if you have a custom type and have registered a custom type handler, so must
-// allow it; however unforeseen validations will occur if trying to validate a
-// struct that is meant to be passed to 'validate.Struct'
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-// validate Array, Slice and maps fields which may contain more than one error
-func (v *Validate) VarWithValue(field interface{}, other interface{}, tag string) error {
- return v.VarWithValueCtx(context.Background(), field, other, tag)
-}
-
-// VarWithValueCtx validates a single variable, against another variable/field's value using tag style validation and
-// allows passing of contextual validation validation information via context.Context.
-// eg.
-// s1 := "abcd"
-// s2 := "abcd"
-// validate.VarWithValue(s1, s2, "eqcsfield") // returns true
-//
-// WARNING: a struct can be passed for validation eg. time.Time is a struct or
-// if you have a custom type and have registered a custom type handler, so must
-// allow it; however unforeseen validations will occur if trying to validate a
-// struct that is meant to be passed to 'validate.Struct'
-//
-// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
-// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
-// validate Array, Slice and maps fields which may contain more than one error
-func (v *Validate) VarWithValueCtx(ctx context.Context, field interface{}, other interface{}, tag string) (err error) {
- if len(tag) == 0 || tag == skipValidationTag {
- return nil
- }
- ctag := v.fetchCacheTag(tag)
- otherVal := reflect.ValueOf(other)
- vd := v.pool.Get().(*validate)
- vd.top = otherVal
- vd.isPartial = false
- vd.traverseField(ctx, otherVal, reflect.ValueOf(field), vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag)
-
- if len(vd.errs) > 0 {
- err = vd.errs
- vd.errs = nil
- }
- v.pool.Put(vd)
- return
-}