Merge pull request #81 from moul/dev/moul/bump-deps
Bump deps + add helpers examples
This commit is contained in:
commit
f84ba571b5
1
Makefile
1
Makefile
@ -19,6 +19,7 @@ test: install
|
||||
cd examples/sitemap && make
|
||||
cd examples/go-generate && make
|
||||
cd examples/single-package-mode && make
|
||||
cd examples/helpers && make
|
||||
# cd examples/go-kit && make
|
||||
|
||||
.PHONY: docker.build
|
||||
|
13
examples/helpers/Makefile
Normal file
13
examples/helpers/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
.PHONY: build
|
||||
build:
|
||||
mkdir -p output
|
||||
protoc -I. --gotemplate_out=template_dir=.,debug=true:. *.proto
|
||||
|
||||
|
||||
.PHONY: re
|
||||
re: clean build
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf output
|
55
examples/helpers/example.txt
Normal file
55
examples/helpers/example.txt
Normal file
@ -0,0 +1,55 @@
|
||||
# Common variables
|
||||
{{.File.Name}}: helpers.proto
|
||||
{{.File.Name | upper}}: HELPERS.PROTO
|
||||
{{.File.Package | base | replace "." "-"}} dummy
|
||||
{{$packageDir := .File.Name | dir}}{{$packageDir}} .
|
||||
{{$packageName := .File.Name | base | replace ".proto" ""}}{{$packageName}} helpers
|
||||
{{$packageImport := .File.Package | replace "." "_"}}{{$packageImport}} dummy
|
||||
{{$namespacedPackage := .File.Package}}{{$namespacedPackage}} dummy
|
||||
{{$currentFile := .File.Name | getProtoFile}}{{$currentFile}} <nil>
|
||||
{{- /*{{- $currentPackageName := $currentFile.GoPkg.Name}}{{$currentPackageName}}*/}}
|
||||
# TODO: more variables
|
||||
|
||||
# Sprig: strings
|
||||
{{trim " hello "}}: hello
|
||||
{{trimAll "$" "$5.00"}}: 5.00
|
||||
{{trimSuffix "-" "hello-"}}: hello
|
||||
{{upper "hello"}}: HELLO
|
||||
{{lower "HELLO"}}: hello
|
||||
{{title "hello world"}}: Hello World
|
||||
{{untitle "Hello World"}}: hello world
|
||||
{{repeat 3 "hello"}}: hellohellohello
|
||||
{{substr 0 5 "hello world"}}: hello
|
||||
{{nospace "hello w o r l d"}}: helloworld
|
||||
{{trunc 5 "hello world"}}: hello
|
||||
{{abbrev 5 "hello world"}}: he...
|
||||
{{abbrevboth 5 10 "1234 5678 9123"}}: ...5678...
|
||||
{{initials "First Try"}}: FT
|
||||
{{randNumeric 3}}: 146
|
||||
{{- /*{{wrap 80 $someText}}*/}}:
|
||||
{{wrapWith 5 "\t" "Hello World"}}: Hello World
|
||||
{{contains "cat" "catch"}}: true
|
||||
{{hasPrefix "cat" "catch"}}: true
|
||||
{{cat "hello" "beautiful" "world"}}: hello beautiful world
|
||||
{{- /*{{indent 4 $lots_of_text}}*/}}:
|
||||
{{- /*{{indent 4 $lots_of_text}}*/}}:
|
||||
{{"I Am Henry VIII" | replace " " "-"}}: I-Am-Henry-VIII
|
||||
{{len .Service.Method | plural "one anchovy" "many anchovies"}}: many anchovies
|
||||
{{snakecase "FirstName"}}: first_name
|
||||
{{camelcase "http_server"}}: HttpServer
|
||||
{{shuffle "hello"}}: holle
|
||||
{{regexMatch "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" "test@acme.com"}}: true
|
||||
{{- /*{{regexFindAll "[2,4,6,8]" "123456789"}}*/}}:
|
||||
{{regexFind "[a-zA-Z][1-9]" "abcd1234"}}: d1
|
||||
{{regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"}}: -W-xxW-
|
||||
{{regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"}}: -${1}-${1}-
|
||||
{{regexSplit "z+" "pizza" -1}}: [pi a]
|
||||
|
||||
# Sprig: advanced
|
||||
{{if contains "cat" "catch"}}yes{{else}}no{{end}}: yes
|
||||
{{1 | plural "one anchovy" "many anchovies"}}: one anchovy
|
||||
{{2 | plural "one anchovy" "many anchovies"}}: many anchovies
|
||||
{{3 | plural "one anchovy" "many anchovies"}}: many anchovies
|
||||
|
||||
# TODO: more sprig examples
|
||||
# TODO: all built-in examples
|
56
examples/helpers/example.txt.tmpl
Normal file
56
examples/helpers/example.txt.tmpl
Normal file
@ -0,0 +1,56 @@
|
||||
# Common variables
|
||||
{{`{{.File.Name}}`}}: {{.File.Name}}
|
||||
{{`{{.File.Name | upper}}`}}: {{.File.Name | upper}}
|
||||
{{`{{.File.Package | base | replace "." "-"}}`}} {{.File.Package | base | replace "." "-"}}
|
||||
{{- /*{{`{{$file := .File}}{{$file}}`}} {{$file := .File}}{{$file}}*/}}
|
||||
{{`{{$packageDir := .File.Name | dir}}{{$packageDir}}`}} {{$packageDir := .File.Name | dir}}{{$packageDir}}
|
||||
{{`{{$packageName := .File.Name | base | replace ".proto" ""}}{{$packageName}}`}} {{$packageName := .File.Name | base | replace ".proto" ""}}{{$packageName}}
|
||||
{{`{{$packageImport := .File.Package | replace "." "_"}}{{$packageImport}}`}} {{$packageImport := .File.Package | replace "." "_"}}{{$packageImport}}
|
||||
{{`{{$namespacedPackage := .File.Package}}{{$namespacedPackage}}`}} {{$namespacedPackage := .File.Package}}{{$namespacedPackage}}
|
||||
{{`{{$currentFile := .File.Name | getProtoFile}}{{$currentFile}}`}} {{$currentFile := .File.Name | getProtoFile}}{{$currentFile}}
|
||||
{{`{{- /*{{- $currentPackageName := $currentFile.GoPkg.Name}}{{$currentPackageName}}*/}}`}} {{- /*{{- $currentPackageName := $currentFile.GoPkg.Name}}{{$currentPackageName}}*/}}
|
||||
# TODO: more variables
|
||||
|
||||
# Sprig: strings
|
||||
{{`{{trim " hello "}}`}}: {{trim " hello "}}
|
||||
{{`{{trimAll "$" "$5.00"}}`}}: {{trimAll "$" "$5.00"}}
|
||||
{{`{{trimSuffix "-" "hello-"}}`}}: {{trimSuffix "-" "hello-"}}
|
||||
{{`{{upper "hello"}}`}}: {{upper "hello"}}
|
||||
{{`{{lower "HELLO"}}`}}: {{lower "HELLO"}}
|
||||
{{`{{title "hello world"}}`}}: {{title "hello world"}}
|
||||
{{`{{untitle "Hello World"}}`}}: {{untitle "Hello World"}}
|
||||
{{`{{repeat 3 "hello"}}`}}: {{repeat 3 "hello"}}
|
||||
{{`{{substr 0 5 "hello world"}}`}}: {{substr 0 5 "hello world"}}
|
||||
{{`{{nospace "hello w o r l d"}}`}}: {{nospace "hello w o r l d"}}
|
||||
{{`{{trunc 5 "hello world"}}`}}: {{trunc 5 "hello world"}}
|
||||
{{`{{abbrev 5 "hello world"}}`}}: {{abbrev 5 "hello world"}}
|
||||
{{`{{abbrevboth 5 10 "1234 5678 9123"}}`}}: {{abbrevboth 5 10 "1234 5678 9123"}}
|
||||
{{`{{initials "First Try"}}`}}: {{initials "First Try"}}
|
||||
{{`{{randNumeric 3}}`}}: {{randNumeric 3}}
|
||||
{{`{{- /*{{wrap 80 $someText}}*/}}`}}: {{- /*{{wrap 80 $someText}}*/}}
|
||||
{{`{{wrapWith 5 "\t" "Hello World"}}`}}: {{wrapWith 5 "\t" "Hello World"}}
|
||||
{{`{{contains "cat" "catch"}}`}}: {{contains "cat" "catch"}}
|
||||
{{`{{hasPrefix "cat" "catch"}}`}}: {{hasPrefix "cat" "catch"}}
|
||||
{{`{{cat "hello" "beautiful" "world"}}`}}: {{cat "hello" "beautiful" "world"}}
|
||||
{{`{{- /*{{indent 4 $lots_of_text}}*/}}`}}: {{- /*{{indent 4 $lots_of_text}}*/}}
|
||||
{{`{{- /*{{indent 4 $lots_of_text}}*/}}`}}: {{- /*{{indent 4 $lots_of_text}}*/}}
|
||||
{{`{{"I Am Henry VIII" | replace " " "-"}}`}}: {{"I Am Henry VIII" | replace " " "-"}}
|
||||
{{`{{len .Service.Method | plural "one anchovy" "many anchovies"}}`}}: {{len .Service.Method | plural "one anchovy" "many anchovies"}}
|
||||
{{`{{snakecase "FirstName"}}`}}: {{snakecase "FirstName"}}
|
||||
{{`{{camelcase "http_server"}}`}}: {{camelcase "http_server"}}
|
||||
{{`{{shuffle "hello"}}`}}: {{shuffle "hello"}}
|
||||
{{`{{regexMatch "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" "test@acme.com"}}`}}: {{regexMatch "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" "test@acme.com"}}
|
||||
{{`{{- /*{{regexFindAll "[2,4,6,8]" "123456789"}}*/}}`}}: {{- /*{{regexFindAll "[2,4,6,8]" "123456789"}}*/}}
|
||||
{{`{{regexFind "[a-zA-Z][1-9]" "abcd1234"}}`}}: {{regexFind "[a-zA-Z][1-9]" "abcd1234"}}
|
||||
{{`{{regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"}}`}}: {{regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"}}
|
||||
{{`{{regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"}}`}}: {{regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"}}
|
||||
{{`{{regexSplit "z+" "pizza" -1}}`}}: {{regexSplit "z+" "pizza" -1}}
|
||||
|
||||
# Sprig: advanced
|
||||
{{`{{if contains "cat" "catch"}}yes{{else}}no{{end}}`}}: {{if contains "cat" "catch"}}yes{{else}}no{{end}}
|
||||
{{`{{1 | plural "one anchovy" "many anchovies"}}`}}: {{1 | plural "one anchovy" "many anchovies"}}
|
||||
{{`{{2 | plural "one anchovy" "many anchovies"}}`}}: {{2 | plural "one anchovy" "many anchovies"}}
|
||||
{{`{{3 | plural "one anchovy" "many anchovies"}}`}}: {{3 | plural "one anchovy" "many anchovies"}}
|
||||
|
||||
# TODO: more sprig examples
|
||||
# TODO: all built-in examples
|
25
examples/helpers/helpers.proto
Normal file
25
examples/helpers/helpers.proto
Normal file
@ -0,0 +1,25 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package dummy;
|
||||
|
||||
option go_package = "github.com/moul/protoc-gen-gotemplate/examples/helpers";
|
||||
|
||||
message Dummy1 {
|
||||
float aaa = 1;
|
||||
string bbb = 2;
|
||||
int32 ccc = 3;
|
||||
int64 ddd = 4;
|
||||
repeated string eee = 5;
|
||||
}
|
||||
|
||||
message Dummy2 {
|
||||
float fff = 1;
|
||||
Dummy1 ggg = 2;
|
||||
}
|
||||
|
||||
message Dummy3 {}
|
||||
|
||||
service DummyService {
|
||||
rpc Hhh(Dummy1) returns (Dummy2) {}
|
||||
rpc Iii(Dummy2) returns (Dummy1) {}
|
||||
}
|
94
glide.lock
generated
94
glide.lock
generated
@ -1,94 +0,0 @@
|
||||
hash: 1971d053430c1e52bc18cb507ed44360e28782c9d1f5ff4c5d8d4acfb226c882
|
||||
updated: 2017-10-26T17:01:26.57468+02:00
|
||||
imports:
|
||||
- name: github.com/aokoli/goutils
|
||||
version: e57d01ace047c1a43e6a49ecf3ecc50ed2be81d1
|
||||
- name: github.com/dgrijalva/jwt-go
|
||||
version: c9eaceb2896dbb515dae7ec352b377a226a52721
|
||||
- name: github.com/go-kit/kit
|
||||
version: 9f5c614cd1e70102f80b644edbc760805ebf16d5
|
||||
subpackages:
|
||||
- auth/jwt
|
||||
- endpoint
|
||||
- log
|
||||
- transport/grpc
|
||||
- transport/http
|
||||
- name: github.com/go-logfmt/logfmt
|
||||
version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
|
||||
- name: github.com/go-stack/stack
|
||||
version: 7a2f19628aabfe68f0766b59e74d6315f8347d22
|
||||
- name: github.com/golang/glog
|
||||
version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998
|
||||
- name: github.com/golang/protobuf
|
||||
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
|
||||
subpackages:
|
||||
- proto
|
||||
- protoc-gen-go/descriptor
|
||||
- protoc-gen-go/generator
|
||||
- protoc-gen-go/plugin
|
||||
- ptypes/timestamp
|
||||
- name: github.com/gorilla/context
|
||||
version: 1ea25387ff6f684839d82767c1733ff4d4d15d0a
|
||||
- name: github.com/gorilla/handlers
|
||||
version: e1b2144f2167de0e1042d1d35e5cba5119d4fb5d
|
||||
- name: github.com/gorilla/mux
|
||||
version: 24fca303ac6da784b9e8269f724ddeb0b2eea5e7
|
||||
- name: github.com/grpc-ecosystem/grpc-gateway
|
||||
version: 589b126116b5fc961939b3e156c29e4d9d58222f
|
||||
subpackages:
|
||||
- protoc-gen-grpc-gateway/descriptor
|
||||
- protoc-gen-grpc-gateway/httprule
|
||||
- utilities
|
||||
- name: github.com/huandu/xstrings
|
||||
version: 3959339b333561bf62a38b424fd41517c2c90f40
|
||||
- name: github.com/imdario/mergo
|
||||
version: 7fe0c75c13abdee74b09fcacef5ea1c6bba6a874
|
||||
- name: github.com/kr/fs
|
||||
version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b
|
||||
- name: github.com/kr/logfmt
|
||||
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
|
||||
- name: github.com/Masterminds/semver
|
||||
version: 59c29afe1a994eacb71c833025ca7acf874bb1da
|
||||
- name: github.com/Masterminds/sprig
|
||||
version: 2f4371ac162f912989f01cc2b6af4ba6660e6a30
|
||||
- name: github.com/satori/go.uuid
|
||||
version: 879c5887cd475cd7864858769793b2ceb0d44feb
|
||||
- name: golang.org/x/crypto
|
||||
version: 0fe963104e9d1877082f8fb38f816fcd97eb1d10
|
||||
subpackages:
|
||||
- pbkdf2
|
||||
- scrypt
|
||||
- name: golang.org/x/net
|
||||
version: da2b4fa28524a3baf148c1b94df4440267063c88
|
||||
subpackages:
|
||||
- context
|
||||
- context/ctxhttp
|
||||
- http2
|
||||
- http2/hpack
|
||||
- idna
|
||||
- internal/timeseries
|
||||
- lex/httplex
|
||||
- trace
|
||||
- name: golang.org/x/text
|
||||
version: a49bea13b776691cb1b49873e5d8df96ec74831a
|
||||
subpackages:
|
||||
- secure/bidirule
|
||||
- transform
|
||||
- unicode/bidi
|
||||
- unicode/norm
|
||||
- name: google.golang.org/genproto
|
||||
version: bb3573be0c484136831138976d444b8754777aff
|
||||
subpackages:
|
||||
- googleapis/api/annotations
|
||||
- name: google.golang.org/grpc
|
||||
version: 777daa17ff9b5daef1cfdf915088a2ada3332bf0
|
||||
subpackages:
|
||||
- codes
|
||||
- credentials
|
||||
- grpclog
|
||||
- internal
|
||||
- metadata
|
||||
- naming
|
||||
- peer
|
||||
- transport
|
||||
testImports: []
|
18
glide.yaml
18
glide.yaml
@ -1,18 +0,0 @@
|
||||
package: github.com/moul/protoc-gen-gotemplate
|
||||
import:
|
||||
- package: github.com/golang/protobuf
|
||||
subpackages:
|
||||
- proto
|
||||
- protoc-gen-go/descriptor
|
||||
- protoc-gen-go/generator
|
||||
- protoc-gen-go/plugin
|
||||
- package: github.com/kr/fs
|
||||
- package: github.com/Masterminds/sprig
|
||||
- package: github.com/huandu/xstrings
|
||||
- package: google.golang.org/genproto
|
||||
subpackages:
|
||||
- googleapis/api/annotations
|
||||
- package: github.com/grpc-ecosystem/grpc-gateway
|
||||
version: 1.2.2
|
||||
- package: github.com/gorilla/mux
|
||||
version: ^1.5.0
|
25
vendor/github.com/Masterminds/semver/.travis.yml
generated
vendored
25
vendor/github.com/Masterminds/semver/.travis.yml
generated
vendored
@ -1,25 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- tip
|
||||
|
||||
# Setting sudo access to false will let Travis CI use containers rather than
|
||||
# VMs to run the tests. For more details see:
|
||||
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
||||
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
|
||||
sudo: false
|
||||
|
||||
script:
|
||||
- GO15VENDOREXPERIMENT=1 make setup
|
||||
- GO15VENDOREXPERIMENT=1 make test
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: never # options: [always|never|change] default: always
|
157
vendor/github.com/Masterminds/semver/benchmark_test.go
generated
vendored
157
vendor/github.com/Masterminds/semver/benchmark_test.go
generated
vendored
@ -1,157 +0,0 @@
|
||||
package semver_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
)
|
||||
|
||||
/* Constraint creation benchmarks */
|
||||
|
||||
func benchNewConstraint(c string, b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
semver.NewConstraint(c)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewConstraintUnary(b *testing.B) {
|
||||
benchNewConstraint("=2.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewConstraintTilde(b *testing.B) {
|
||||
benchNewConstraint("~2.0.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewConstraintCaret(b *testing.B) {
|
||||
benchNewConstraint("^2.0.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewConstraintWildcard(b *testing.B) {
|
||||
benchNewConstraint("1.x", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewConstraintRange(b *testing.B) {
|
||||
benchNewConstraint(">=2.1.x, <3.1.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewConstraintUnion(b *testing.B) {
|
||||
benchNewConstraint("~2.0.0 || =3.1.0", b)
|
||||
}
|
||||
|
||||
/* Check benchmarks */
|
||||
|
||||
func benchCheckVersion(c, v string, b *testing.B) {
|
||||
version, _ := semver.NewVersion(v)
|
||||
constraint, _ := semver.NewConstraint(c)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
constraint.Check(version)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCheckVersionUnary(b *testing.B) {
|
||||
benchCheckVersion("=2.0", "2.0.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkCheckVersionTilde(b *testing.B) {
|
||||
benchCheckVersion("~2.0.0", "2.0.5", b)
|
||||
}
|
||||
|
||||
func BenchmarkCheckVersionCaret(b *testing.B) {
|
||||
benchCheckVersion("^2.0.0", "2.1.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkCheckVersionWildcard(b *testing.B) {
|
||||
benchCheckVersion("1.x", "1.4.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkCheckVersionRange(b *testing.B) {
|
||||
benchCheckVersion(">=2.1.x, <3.1.0", "2.4.5", b)
|
||||
}
|
||||
|
||||
func BenchmarkCheckVersionUnion(b *testing.B) {
|
||||
benchCheckVersion("~2.0.0 || =3.1.0", "3.1.0", b)
|
||||
}
|
||||
|
||||
func benchValidateVersion(c, v string, b *testing.B) {
|
||||
version, _ := semver.NewVersion(v)
|
||||
constraint, _ := semver.NewConstraint(c)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
constraint.Validate(version)
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate benchmarks, including fails */
|
||||
|
||||
func BenchmarkValidateVersionUnary(b *testing.B) {
|
||||
benchValidateVersion("=2.0", "2.0.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionUnaryFail(b *testing.B) {
|
||||
benchValidateVersion("=2.0", "2.0.1", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionTilde(b *testing.B) {
|
||||
benchValidateVersion("~2.0.0", "2.0.5", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionTildeFail(b *testing.B) {
|
||||
benchValidateVersion("~2.0.0", "1.0.5", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionCaret(b *testing.B) {
|
||||
benchValidateVersion("^2.0.0", "2.1.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionCaretFail(b *testing.B) {
|
||||
benchValidateVersion("^2.0.0", "4.1.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionWildcard(b *testing.B) {
|
||||
benchValidateVersion("1.x", "1.4.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionWildcardFail(b *testing.B) {
|
||||
benchValidateVersion("1.x", "2.4.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionRange(b *testing.B) {
|
||||
benchValidateVersion(">=2.1.x, <3.1.0", "2.4.5", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionRangeFail(b *testing.B) {
|
||||
benchValidateVersion(">=2.1.x, <3.1.0", "1.4.5", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionUnion(b *testing.B) {
|
||||
benchValidateVersion("~2.0.0 || =3.1.0", "3.1.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkValidateVersionUnionFail(b *testing.B) {
|
||||
benchValidateVersion("~2.0.0 || =3.1.0", "3.1.1", b)
|
||||
}
|
||||
|
||||
/* Version creation benchmarks */
|
||||
|
||||
func benchNewVersion(v string, b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
semver.NewVersion(v)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewVersionSimple(b *testing.B) {
|
||||
benchNewVersion("1.0.0", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewVersionPre(b *testing.B) {
|
||||
benchNewVersion("1.0.0-alpha", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewVersionMeta(b *testing.B) {
|
||||
benchNewVersion("1.0.0+metadata", b)
|
||||
}
|
||||
|
||||
func BenchmarkNewVersionMetaDash(b *testing.B) {
|
||||
benchNewVersion("1.0.0+metadata-dash", b)
|
||||
}
|
46
vendor/github.com/Masterminds/semver/collection_test.go
generated
vendored
46
vendor/github.com/Masterminds/semver/collection_test.go
generated
vendored
@ -1,46 +0,0 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCollection(t *testing.T) {
|
||||
raw := []string{
|
||||
"1.2.3",
|
||||
"1.0",
|
||||
"1.3",
|
||||
"2",
|
||||
"0.4.2",
|
||||
}
|
||||
|
||||
vs := make([]*Version, len(raw))
|
||||
for i, r := range raw {
|
||||
v, err := NewVersion(r)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
vs[i] = v
|
||||
}
|
||||
|
||||
sort.Sort(Collection(vs))
|
||||
|
||||
e := []string{
|
||||
"0.4.2",
|
||||
"1.0.0",
|
||||
"1.2.3",
|
||||
"1.3.0",
|
||||
"2.0.0",
|
||||
}
|
||||
|
||||
a := make([]string, len(vs))
|
||||
for i, v := range vs {
|
||||
a[i] = v.String()
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(a, e) {
|
||||
t.Error("Sorting Collection failed")
|
||||
}
|
||||
}
|
452
vendor/github.com/Masterminds/semver/constraints_test.go
generated
vendored
452
vendor/github.com/Masterminds/semver/constraints_test.go
generated
vendored
@ -1,452 +0,0 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseConstraint(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
f cfunc
|
||||
v string
|
||||
err bool
|
||||
}{
|
||||
{">= 1.2", constraintGreaterThanEqual, "1.2.0", false},
|
||||
{"1.0", constraintTildeOrEqual, "1.0.0", false},
|
||||
{"foo", nil, "", true},
|
||||
{"<= 1.2", constraintLessThanEqual, "1.2.0", false},
|
||||
{"=< 1.2", constraintLessThanEqual, "1.2.0", false},
|
||||
{"=> 1.2", constraintGreaterThanEqual, "1.2.0", false},
|
||||
{"v1.2", constraintTildeOrEqual, "1.2.0", false},
|
||||
{"=1.5", constraintTildeOrEqual, "1.5.0", false},
|
||||
{"> 1.3", constraintGreaterThan, "1.3.0", false},
|
||||
{"< 1.4.1", constraintLessThan, "1.4.1", false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
c, err := parseConstraint(tc.in)
|
||||
if tc.err && err == nil {
|
||||
t.Errorf("Expected error for %s didn't occur", tc.in)
|
||||
} else if !tc.err && err != nil {
|
||||
t.Errorf("Unexpected error for %s", tc.in)
|
||||
}
|
||||
|
||||
// If an error was expected continue the loop and don't try the other
|
||||
// tests as they will cause errors.
|
||||
if tc.err {
|
||||
continue
|
||||
}
|
||||
|
||||
if tc.v != c.con.String() {
|
||||
t.Errorf("Incorrect version found on %s", tc.in)
|
||||
}
|
||||
|
||||
f1 := reflect.ValueOf(tc.f)
|
||||
f2 := reflect.ValueOf(c.function)
|
||||
if f1 != f2 {
|
||||
t.Errorf("Wrong constraint found for %s", tc.in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstraintCheck(t *testing.T) {
|
||||
tests := []struct {
|
||||
constraint string
|
||||
version string
|
||||
check bool
|
||||
}{
|
||||
{"= 2.0", "1.2.3", false},
|
||||
{"= 2.0", "2.0.0", true},
|
||||
{"4.1", "4.1.0", true},
|
||||
{"!=4.1", "4.1.0", false},
|
||||
{"!=4.1", "5.1.0", true},
|
||||
{">1.1", "4.1.0", true},
|
||||
{">1.1", "1.1.0", false},
|
||||
{"<1.1", "0.1.0", true},
|
||||
{"<1.1", "1.1.0", false},
|
||||
{"<1.1", "1.1.1", false},
|
||||
{">=1.1", "4.1.0", true},
|
||||
{">=1.1", "1.1.0", true},
|
||||
{">=1.1", "0.0.9", false},
|
||||
{"<=1.1", "0.1.0", true},
|
||||
{"<=1.1", "1.1.0", true},
|
||||
{"<=1.1", "1.1.1", false},
|
||||
{">0", "0.0.1-alpha", true},
|
||||
{">=0", "0.0.1-alpha", true},
|
||||
{">0", "0", false},
|
||||
{">=0", "0", true},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
c, err := parseConstraint(tc.constraint)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
v, err := NewVersion(tc.version)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
a := c.check(v)
|
||||
if a != tc.check {
|
||||
t.Errorf("Constraint %q failing with %q", tc.constraint, tc.version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewConstraint(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
ors int
|
||||
count int
|
||||
err bool
|
||||
}{
|
||||
{">= 1.1", 1, 1, false},
|
||||
{"2.0", 1, 1, false},
|
||||
{"v2.3.5-20161202202307-sha.e8fc5e5", 1, 1, false},
|
||||
{">= bar", 0, 0, true},
|
||||
{">= 1.2.3, < 2.0", 1, 2, false},
|
||||
{">= 1.2.3, < 2.0 || => 3.0, < 4", 2, 2, false},
|
||||
|
||||
// The 3 - 4 should be broken into 2 by the range rewriting
|
||||
{"3 - 4 || => 3.0, < 4", 2, 2, false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v, err := NewConstraint(tc.input)
|
||||
if tc.err && err == nil {
|
||||
t.Errorf("expected but did not get error for: %s", tc.input)
|
||||
continue
|
||||
} else if !tc.err && err != nil {
|
||||
t.Errorf("unexpectederror for input %s: %s", tc.input, err)
|
||||
continue
|
||||
}
|
||||
if tc.err {
|
||||
continue
|
||||
}
|
||||
|
||||
l := len(v.constraints)
|
||||
if tc.ors != l {
|
||||
t.Errorf("Expected %s to have %d ORs but got %d",
|
||||
tc.input, tc.ors, l)
|
||||
}
|
||||
|
||||
l = len(v.constraints[0])
|
||||
if tc.count != l {
|
||||
t.Errorf("Expected %s to have %d constraints but got %d",
|
||||
tc.input, tc.count, l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstraintsCheck(t *testing.T) {
|
||||
tests := []struct {
|
||||
constraint string
|
||||
version string
|
||||
check bool
|
||||
}{
|
||||
{"*", "1.2.3", true},
|
||||
{"~0.0.0", "1.2.3", true},
|
||||
{"= 2.0", "1.2.3", false},
|
||||
{"= 2.0", "2.0.0", true},
|
||||
{"4.1", "4.1.0", true},
|
||||
{"4.1.x", "4.1.3", true},
|
||||
{"1.x", "1.4", true},
|
||||
{"!=4.1", "4.1.0", false},
|
||||
{"!=4.1-alpha", "4.1.0-alpha", false},
|
||||
{"!=4.1-alpha", "4.1.0", true},
|
||||
{"!=4.1", "5.1.0", true},
|
||||
{"!=4.x", "5.1.0", true},
|
||||
{"!=4.x", "4.1.0", false},
|
||||
{"!=4.1.x", "4.2.0", true},
|
||||
{"!=4.2.x", "4.2.3", false},
|
||||
{">1.1", "4.1.0", true},
|
||||
{">1.1", "1.1.0", false},
|
||||
{"<1.1", "0.1.0", true},
|
||||
{"<1.1", "1.1.0", false},
|
||||
{"<1.1", "1.1.1", false},
|
||||
{"<1.x", "1.1.1", true},
|
||||
{"<1.x", "2.1.1", false},
|
||||
{"<1.1.x", "1.2.1", false},
|
||||
{"<1.1.x", "1.1.500", true},
|
||||
{"<1.2.x", "1.1.1", true},
|
||||
{">=1.1", "4.1.0", true},
|
||||
{">=1.1", "4.1.0-beta", false},
|
||||
{">=1.1", "1.1.0", true},
|
||||
{">=1.1", "0.0.9", false},
|
||||
{"<=1.1", "0.1.0", true},
|
||||
{"<=1.1", "0.1.0-alpha", false},
|
||||
{"<=1.1-a", "0.1.0-alpha", true},
|
||||
{"<=1.1", "1.1.0", true},
|
||||
{"<=1.x", "1.1.0", true},
|
||||
{"<=2.x", "3.1.0", false},
|
||||
{"<=1.1", "1.1.1", false},
|
||||
{"<=1.1.x", "1.2.500", false},
|
||||
{">1.1, <2", "1.1.1", true},
|
||||
{">1.1, <3", "4.3.2", false},
|
||||
{">=1.1, <2, !=1.2.3", "1.2.3", false},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "3.1.2", true},
|
||||
{">=1.1, <2, !=1.2.3 || >= 3", "3.0.0", true},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "3.0.0", false},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "1.2.3", false},
|
||||
{"1.1 - 2", "1.1.1", true},
|
||||
{"1.1-3", "4.3.2", false},
|
||||
{"^1.1", "1.1.1", true},
|
||||
{"^1.1", "4.3.2", false},
|
||||
{"^1.x", "1.1.1", true},
|
||||
{"^2.x", "1.1.1", false},
|
||||
{"^1.x", "2.1.1", false},
|
||||
{"^1.x", "1.1.1-beta1", false},
|
||||
{"^1.1.2-alpha", "1.2.1-beta1", true},
|
||||
{"^1.2.x-alpha", "1.1.1-beta1", false},
|
||||
{"~*", "2.1.1", true},
|
||||
{"~1.x", "2.1.1", false},
|
||||
{"~1.x", "1.3.5", true},
|
||||
{"~1.x", "1.4", true},
|
||||
{"~1.1", "1.1.1", true},
|
||||
{"~1.1", "1.1.1-alpha", false},
|
||||
{"~1.1-alpha", "1.1.1-beta", true},
|
||||
{"~1.1.1-beta", "1.1.1-alpha", false},
|
||||
{"~1.1.1-beta", "1.1.1", true},
|
||||
{"~1.2.3", "1.2.5", true},
|
||||
{"~1.2.3", "1.2.2", false},
|
||||
{"~1.2.3", "1.3.2", false},
|
||||
{"~1.1", "1.2.3", false},
|
||||
{"~1.3", "2.4.5", false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
c, err := NewConstraint(tc.constraint)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
v, err := NewVersion(tc.version)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
a := c.Check(v)
|
||||
if a != tc.check {
|
||||
t.Errorf("Constraint '%s' failing with '%s'", tc.constraint, tc.version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRewriteRange(t *testing.T) {
|
||||
tests := []struct {
|
||||
c string
|
||||
nc string
|
||||
}{
|
||||
{"2 - 3", ">= 2, <= 3"},
|
||||
{"2 - 3, 2 - 3", ">= 2, <= 3,>= 2, <= 3"},
|
||||
{"2 - 3, 4.0.0 - 5.1", ">= 2, <= 3,>= 4.0.0, <= 5.1"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
o := rewriteRange(tc.c)
|
||||
|
||||
if o != tc.nc {
|
||||
t.Errorf("Range %s rewritten incorrectly as '%s'", tc.c, o)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsX(t *testing.T) {
|
||||
tests := []struct {
|
||||
t string
|
||||
c bool
|
||||
}{
|
||||
{"A", false},
|
||||
{"%", false},
|
||||
{"X", true},
|
||||
{"x", true},
|
||||
{"*", true},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
a := isX(tc.t)
|
||||
if a != tc.c {
|
||||
t.Errorf("Function isX error on %s", tc.t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConstraintsValidate(t *testing.T) {
|
||||
tests := []struct {
|
||||
constraint string
|
||||
version string
|
||||
check bool
|
||||
}{
|
||||
{"*", "1.2.3", true},
|
||||
{"~0.0.0", "1.2.3", true},
|
||||
{"= 2.0", "1.2.3", false},
|
||||
{"= 2.0", "2.0.0", true},
|
||||
{"4.1", "4.1.0", true},
|
||||
{"4.1.x", "4.1.3", true},
|
||||
{"1.x", "1.4", true},
|
||||
{"!=4.1", "4.1.0", false},
|
||||
{"!=4.1", "5.1.0", true},
|
||||
{"!=4.x", "5.1.0", true},
|
||||
{"!=4.x", "4.1.0", false},
|
||||
{"!=4.1.x", "4.2.0", true},
|
||||
{"!=4.2.x", "4.2.3", false},
|
||||
{">1.1", "4.1.0", true},
|
||||
{">1.1", "1.1.0", false},
|
||||
{"<1.1", "0.1.0", true},
|
||||
{"<1.1", "1.1.0", false},
|
||||
{"<1.1", "1.1.1", false},
|
||||
{"<1.x", "1.1.1", true},
|
||||
{"<1.x", "2.1.1", false},
|
||||
{"<1.1.x", "1.2.1", false},
|
||||
{"<1.1.x", "1.1.500", true},
|
||||
{"<1.2.x", "1.1.1", true},
|
||||
{">=1.1", "4.1.0", true},
|
||||
{">=1.1", "1.1.0", true},
|
||||
{">=1.1", "0.0.9", false},
|
||||
{"<=1.1", "0.1.0", true},
|
||||
{"<=1.1", "1.1.0", true},
|
||||
{"<=1.x", "1.1.0", true},
|
||||
{"<=2.x", "3.1.0", false},
|
||||
{"<=1.1", "1.1.1", false},
|
||||
{"<=1.1.x", "1.2.500", false},
|
||||
{">1.1, <2", "1.1.1", true},
|
||||
{">1.1, <3", "4.3.2", false},
|
||||
{">=1.1, <2, !=1.2.3", "1.2.3", false},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "3.1.2", true},
|
||||
{">=1.1, <2, !=1.2.3 || >= 3", "3.0.0", true},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "3.0.0", false},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "1.2.3", false},
|
||||
{"1.1 - 2", "1.1.1", true},
|
||||
{"1.1-3", "4.3.2", false},
|
||||
{"^1.1", "1.1.1", true},
|
||||
{"^1.1", "1.1.1-alpha", false},
|
||||
{"^1.1.1-alpha", "1.1.1-beta", true},
|
||||
{"^1.1.1-beta", "1.1.1-alpha", false},
|
||||
{"^1.1", "4.3.2", false},
|
||||
{"^1.x", "1.1.1", true},
|
||||
{"^2.x", "1.1.1", false},
|
||||
{"^1.x", "2.1.1", false},
|
||||
{"~*", "2.1.1", true},
|
||||
{"~1.x", "2.1.1", false},
|
||||
{"~1.x", "1.3.5", true},
|
||||
{"~1.x", "1.3.5-beta", false},
|
||||
{"~1.3.6-alpha", "1.3.5-beta", false},
|
||||
{"~1.3.5-alpha", "1.3.5-beta", true},
|
||||
{"~1.3.5-beta", "1.3.5-alpha", false},
|
||||
{"~1.x", "1.4", true},
|
||||
{"~1.1", "1.1.1", true},
|
||||
{"~1.2.3", "1.2.5", true},
|
||||
{"~1.2.3", "1.2.2", false},
|
||||
{"~1.2.3", "1.3.2", false},
|
||||
{"~1.1", "1.2.3", false},
|
||||
{"~1.3", "2.4.5", false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
c, err := NewConstraint(tc.constraint)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
v, err := NewVersion(tc.version)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
a, msgs := c.Validate(v)
|
||||
if a != tc.check {
|
||||
t.Errorf("Constraint '%s' failing with '%s'", tc.constraint, tc.version)
|
||||
} else if !a && len(msgs) == 0 {
|
||||
t.Errorf("%q failed with %q but no errors returned", tc.constraint, tc.version)
|
||||
}
|
||||
|
||||
// if a == false {
|
||||
// for _, m := range msgs {
|
||||
// t.Errorf("%s", m)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
v, err := NewVersion("1.2.3")
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
}
|
||||
|
||||
c, err := NewConstraint("!= 1.2.5, ^2, <= 1.1.x")
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
}
|
||||
|
||||
_, msgs := c.Validate(v)
|
||||
if len(msgs) != 2 {
|
||||
t.Error("Invalid number of validations found")
|
||||
}
|
||||
e := msgs[0].Error()
|
||||
if e != "1.2.3 does not have same major version as 2" {
|
||||
t.Error("Did not get expected message: 1.2.3 does not have same major version as 2")
|
||||
}
|
||||
e = msgs[1].Error()
|
||||
if e != "1.2.3 is greater than 1.1.x" {
|
||||
t.Error("Did not get expected message: 1.2.3 is greater than 1.1.x")
|
||||
}
|
||||
|
||||
tests2 := []struct {
|
||||
constraint, version, msg string
|
||||
}{
|
||||
{"= 2.0", "1.2.3", "1.2.3 is not equal to 2.0"},
|
||||
{"!=4.1", "4.1.0", "4.1.0 is equal to 4.1"},
|
||||
{"!=4.x", "4.1.0", "4.1.0 is equal to 4.x"},
|
||||
{"!=4.2.x", "4.2.3", "4.2.3 is equal to 4.2.x"},
|
||||
{">1.1", "1.1.0", "1.1.0 is less than or equal to 1.1"},
|
||||
{"<1.1", "1.1.0", "1.1.0 is greater than or equal to 1.1"},
|
||||
{"<1.1", "1.1.1", "1.1.1 is greater than or equal to 1.1"},
|
||||
{"<1.x", "2.1.1", "2.1.1 is greater than or equal to 1.x"},
|
||||
{"<1.1.x", "1.2.1", "1.2.1 is greater than or equal to 1.1.x"},
|
||||
{">=1.1", "0.0.9", "0.0.9 is less than 1.1"},
|
||||
{"<=2.x", "3.1.0", "3.1.0 is greater than 2.x"},
|
||||
{"<=1.1", "1.1.1", "1.1.1 is greater than 1.1"},
|
||||
{"<=1.1.x", "1.2.500", "1.2.500 is greater than 1.1.x"},
|
||||
{">1.1, <3", "4.3.2", "4.3.2 is greater than or equal to 3"},
|
||||
{">=1.1, <2, !=1.2.3", "1.2.3", "1.2.3 is equal to 1.2.3"},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "3.0.0", "3.0.0 is greater than or equal to 2"},
|
||||
{">=1.1, <2, !=1.2.3 || > 3", "1.2.3", "1.2.3 is equal to 1.2.3"},
|
||||
{"1.1 - 3", "4.3.2", "4.3.2 is greater than 3"},
|
||||
{"^1.1", "4.3.2", "4.3.2 does not have same major version as 1.1"},
|
||||
{"^2.x", "1.1.1", "1.1.1 does not have same major version as 2.x"},
|
||||
{"^1.x", "2.1.1", "2.1.1 does not have same major version as 1.x"},
|
||||
{"~1.x", "2.1.1", "2.1.1 does not have same major and minor version as 1.x"},
|
||||
{"~1.2.3", "1.2.2", "1.2.2 does not have same major and minor version as 1.2.3"},
|
||||
{"~1.2.3", "1.3.2", "1.3.2 does not have same major and minor version as 1.2.3"},
|
||||
{"~1.1", "1.2.3", "1.2.3 does not have same major and minor version as 1.1"},
|
||||
{"~1.3", "2.4.5", "2.4.5 does not have same major and minor version as 1.3"},
|
||||
}
|
||||
|
||||
for _, tc := range tests2 {
|
||||
c, err := NewConstraint(tc.constraint)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
v, err := NewVersion(tc.version)
|
||||
if err != nil {
|
||||
t.Errorf("err: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, msgs := c.Validate(v)
|
||||
e := msgs[0].Error()
|
||||
if e != tc.msg {
|
||||
t.Errorf("Did not get expected message %q: %s", tc.msg, e)
|
||||
}
|
||||
}
|
||||
}
|
450
vendor/github.com/Masterminds/semver/version_test.go
generated
vendored
450
vendor/github.com/Masterminds/semver/version_test.go
generated
vendored
@ -1,450 +0,0 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
version string
|
||||
err bool
|
||||
}{
|
||||
{"1.2.3", false},
|
||||
{"v1.2.3", false},
|
||||
{"1.0", false},
|
||||
{"v1.0", false},
|
||||
{"1", false},
|
||||
{"v1", false},
|
||||
{"1.2.beta", true},
|
||||
{"v1.2.beta", true},
|
||||
{"foo", true},
|
||||
{"1.2-5", false},
|
||||
{"v1.2-5", false},
|
||||
{"1.2-beta.5", false},
|
||||
{"v1.2-beta.5", false},
|
||||
{"\n1.2", true},
|
||||
{"\nv1.2", true},
|
||||
{"1.2.0-x.Y.0+metadata", false},
|
||||
{"v1.2.0-x.Y.0+metadata", false},
|
||||
{"1.2.0-x.Y.0+metadata-width-hypen", false},
|
||||
{"v1.2.0-x.Y.0+metadata-width-hypen", false},
|
||||
{"1.2.3-rc1-with-hypen", false},
|
||||
{"v1.2.3-rc1-with-hypen", false},
|
||||
{"1.2.3.4", true},
|
||||
{"v1.2.3.4", true},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
_, err := NewVersion(tc.version)
|
||||
if tc.err && err == nil {
|
||||
t.Fatalf("expected error for version: %s", tc.version)
|
||||
} else if !tc.err && err != nil {
|
||||
t.Fatalf("error for version %s: %s", tc.version, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOriginal(t *testing.T) {
|
||||
tests := []string{
|
||||
"1.2.3",
|
||||
"v1.2.3",
|
||||
"1.0",
|
||||
"v1.0",
|
||||
"1",
|
||||
"v1",
|
||||
"1.2-5",
|
||||
"v1.2-5",
|
||||
"1.2-beta.5",
|
||||
"v1.2-beta.5",
|
||||
"1.2.0-x.Y.0+metadata",
|
||||
"v1.2.0-x.Y.0+metadata",
|
||||
"1.2.0-x.Y.0+metadata-width-hypen",
|
||||
"v1.2.0-x.Y.0+metadata-width-hypen",
|
||||
"1.2.3-rc1-with-hypen",
|
||||
"v1.2.3-rc1-with-hypen",
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v, err := NewVersion(tc)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version %s", tc)
|
||||
}
|
||||
|
||||
o := v.Original()
|
||||
if o != tc {
|
||||
t.Errorf("Error retrieving originl. Expected '%s' but got '%s'", tc, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParts(t *testing.T) {
|
||||
v, err := NewVersion("1.2.3-beta.1+build.123")
|
||||
if err != nil {
|
||||
t.Error("Error parsing version 1.2.3-beta.1+build.123")
|
||||
}
|
||||
|
||||
if v.Major() != 1 {
|
||||
t.Error("Major() returning wrong value")
|
||||
}
|
||||
if v.Minor() != 2 {
|
||||
t.Error("Minor() returning wrong value")
|
||||
}
|
||||
if v.Patch() != 3 {
|
||||
t.Error("Patch() returning wrong value")
|
||||
}
|
||||
if v.Prerelease() != "beta.1" {
|
||||
t.Error("Prerelease() returning wrong value")
|
||||
}
|
||||
if v.Metadata() != "build.123" {
|
||||
t.Error("Metadata() returning wrong value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
tests := []struct {
|
||||
version string
|
||||
expected string
|
||||
}{
|
||||
{"1.2.3", "1.2.3"},
|
||||
{"v1.2.3", "1.2.3"},
|
||||
{"1.0", "1.0.0"},
|
||||
{"v1.0", "1.0.0"},
|
||||
{"1", "1.0.0"},
|
||||
{"v1", "1.0.0"},
|
||||
{"1.2-5", "1.2.0-5"},
|
||||
{"v1.2-5", "1.2.0-5"},
|
||||
{"1.2-beta.5", "1.2.0-beta.5"},
|
||||
{"v1.2-beta.5", "1.2.0-beta.5"},
|
||||
{"1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"},
|
||||
{"v1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"},
|
||||
{"1.2.0-x.Y.0+metadata-width-hypen", "1.2.0-x.Y.0+metadata-width-hypen"},
|
||||
{"v1.2.0-x.Y.0+metadata-width-hypen", "1.2.0-x.Y.0+metadata-width-hypen"},
|
||||
{"1.2.3-rc1-with-hypen", "1.2.3-rc1-with-hypen"},
|
||||
{"v1.2.3-rc1-with-hypen", "1.2.3-rc1-with-hypen"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v, err := NewVersion(tc.version)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version %s", tc)
|
||||
}
|
||||
|
||||
s := v.String()
|
||||
if s != tc.expected {
|
||||
t.Errorf("Error generating string. Expected '%s' but got '%s'", tc.expected, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompare(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected int
|
||||
}{
|
||||
{"1.2.3", "1.5.1", -1},
|
||||
{"2.2.3", "1.5.1", 1},
|
||||
{"2.2.3", "2.2.2", 1},
|
||||
{"3.2-beta", "3.2-beta", 0},
|
||||
{"1.3", "1.1.4", 1},
|
||||
{"4.2", "4.2-beta", 1},
|
||||
{"4.2-beta", "4.2", -1},
|
||||
{"4.2-alpha", "4.2-beta", -1},
|
||||
{"4.2-alpha", "4.2-alpha", 0},
|
||||
{"4.2-beta.2", "4.2-beta.1", 1},
|
||||
{"4.2-beta2", "4.2-beta1", 1},
|
||||
{"4.2-beta", "4.2-beta.2", -1},
|
||||
{"4.2-beta", "4.2-beta.foo", 1},
|
||||
{"4.2-beta.2", "4.2-beta", 1},
|
||||
{"4.2-beta.foo", "4.2-beta", -1},
|
||||
{"1.2+bar", "1.2+baz", 0},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
v2, err := NewVersion(tc.v2)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
a := v1.Compare(v2)
|
||||
e := tc.expected
|
||||
if a != e {
|
||||
t.Errorf(
|
||||
"Comparison of '%s' and '%s' failed. Expected '%d', got '%d'",
|
||||
tc.v1, tc.v2, e, a,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLessThan(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected bool
|
||||
}{
|
||||
{"1.2.3", "1.5.1", true},
|
||||
{"2.2.3", "1.5.1", false},
|
||||
{"3.2-beta", "3.2-beta", false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
v2, err := NewVersion(tc.v2)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
a := v1.LessThan(v2)
|
||||
e := tc.expected
|
||||
if a != e {
|
||||
t.Errorf(
|
||||
"Comparison of '%s' and '%s' failed. Expected '%t', got '%t'",
|
||||
tc.v1, tc.v2, e, a,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGreaterThan(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected bool
|
||||
}{
|
||||
{"1.2.3", "1.5.1", false},
|
||||
{"2.2.3", "1.5.1", true},
|
||||
{"3.2-beta", "3.2-beta", false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
v2, err := NewVersion(tc.v2)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
a := v1.GreaterThan(v2)
|
||||
e := tc.expected
|
||||
if a != e {
|
||||
t.Errorf(
|
||||
"Comparison of '%s' and '%s' failed. Expected '%t', got '%t'",
|
||||
tc.v1, tc.v2, e, a,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqual(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected bool
|
||||
}{
|
||||
{"1.2.3", "1.5.1", false},
|
||||
{"2.2.3", "1.5.1", false},
|
||||
{"3.2-beta", "3.2-beta", true},
|
||||
{"3.2-beta+foo", "3.2-beta+bar", true},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
v2, err := NewVersion(tc.v2)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
a := v1.Equal(v2)
|
||||
e := tc.expected
|
||||
if a != e {
|
||||
t.Errorf(
|
||||
"Comparison of '%s' and '%s' failed. Expected '%t', got '%t'",
|
||||
tc.v1, tc.v2, e, a,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInc(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
expected string
|
||||
how string
|
||||
expectedOriginal string
|
||||
}{
|
||||
{"1.2.3", "1.2.4", "patch", "1.2.4"},
|
||||
{"v1.2.4", "1.2.5", "patch", "v1.2.5"},
|
||||
{"1.2.3", "1.3.0", "minor", "1.3.0"},
|
||||
{"v1.2.4", "1.3.0", "minor", "v1.3.0"},
|
||||
{"1.2.3", "2.0.0", "major", "2.0.0"},
|
||||
{"v1.2.4", "2.0.0", "major", "v2.0.0"},
|
||||
{"1.2.3+meta", "1.2.4", "patch", "1.2.4"},
|
||||
{"1.2.3-beta+meta", "1.2.3", "patch", "1.2.3"},
|
||||
{"v1.2.4-beta+meta", "1.2.4", "patch", "v1.2.4"},
|
||||
{"1.2.3-beta+meta", "1.3.0", "minor", "1.3.0"},
|
||||
{"v1.2.4-beta+meta", "1.3.0", "minor", "v1.3.0"},
|
||||
{"1.2.3-beta+meta", "2.0.0", "major", "2.0.0"},
|
||||
{"v1.2.4-beta+meta", "2.0.0", "major", "v2.0.0"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
var v2 Version
|
||||
switch tc.how {
|
||||
case "patch":
|
||||
v2 = v1.IncPatch()
|
||||
case "minor":
|
||||
v2 = v1.IncMinor()
|
||||
case "major":
|
||||
v2 = v1.IncMajor()
|
||||
}
|
||||
|
||||
a := v2.String()
|
||||
e := tc.expected
|
||||
if a != e {
|
||||
t.Errorf(
|
||||
"Inc %q failed. Expected %q got %q",
|
||||
tc.how, e, a,
|
||||
)
|
||||
}
|
||||
|
||||
a = v2.Original()
|
||||
e = tc.expectedOriginal
|
||||
if a != e {
|
||||
t.Errorf(
|
||||
"Inc %q failed. Expected original %q got %q",
|
||||
tc.how, e, a,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetPrerelease(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
prerelease string
|
||||
expectedVersion string
|
||||
expectedPrerelease string
|
||||
expectedOriginal string
|
||||
expectedErr error
|
||||
}{
|
||||
{"1.2.3", "**", "1.2.3", "", "1.2.3", ErrInvalidPrerelease},
|
||||
{"1.2.3", "beta", "1.2.3-beta", "beta", "1.2.3-beta", nil},
|
||||
{"v1.2.4", "beta", "1.2.4-beta", "beta", "v1.2.4-beta", nil},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
v2, err := v1.SetPrerelease(tc.prerelease)
|
||||
if err != tc.expectedErr {
|
||||
t.Errorf("Expected to get err=%s, but got err=%s", tc.expectedErr, err)
|
||||
}
|
||||
|
||||
a := v2.Prerelease()
|
||||
e := tc.expectedPrerelease
|
||||
if a != e {
|
||||
t.Errorf("Expected prerelease value=%q, but got %q", e, a)
|
||||
}
|
||||
|
||||
a = v2.String()
|
||||
e = tc.expectedVersion
|
||||
if a != e {
|
||||
t.Errorf("Expected version string=%q, but got %q", e, a)
|
||||
}
|
||||
|
||||
a = v2.Original()
|
||||
e = tc.expectedOriginal
|
||||
if a != e {
|
||||
t.Errorf("Expected version original=%q, but got %q", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMetadata(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
metadata string
|
||||
expectedVersion string
|
||||
expectedMetadata string
|
||||
expectedOriginal string
|
||||
expectedErr error
|
||||
}{
|
||||
{"1.2.3", "**", "1.2.3", "", "1.2.3", ErrInvalidMetadata},
|
||||
{"1.2.3", "meta", "1.2.3+meta", "meta", "1.2.3+meta", nil},
|
||||
{"v1.2.4", "meta", "1.2.4+meta", "meta", "v1.2.4+meta", nil},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, err := NewVersion(tc.v1)
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
v2, err := v1.SetMetadata(tc.metadata)
|
||||
if err != tc.expectedErr {
|
||||
t.Errorf("Expected to get err=%s, but got err=%s", tc.expectedErr, err)
|
||||
}
|
||||
|
||||
a := v2.Metadata()
|
||||
e := tc.expectedMetadata
|
||||
if a != e {
|
||||
t.Errorf("Expected metadata value=%q, but got %q", e, a)
|
||||
}
|
||||
|
||||
a = v2.String()
|
||||
e = tc.expectedVersion
|
||||
if e != a {
|
||||
t.Errorf("Expected version string=%q, but got %q", e, a)
|
||||
}
|
||||
|
||||
a = v2.Original()
|
||||
e = tc.expectedOriginal
|
||||
if a != e {
|
||||
t.Errorf("Expected version original=%q, but got %q", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOriginalVPrefix(t *testing.T) {
|
||||
tests := []struct {
|
||||
version string
|
||||
vprefix string
|
||||
}{
|
||||
{"1.2.3", ""},
|
||||
{"v1.2.4", "v"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
v1, _ := NewVersion(tc.version)
|
||||
a := v1.originalVPrefix()
|
||||
e := tc.vprefix
|
||||
if a != e {
|
||||
t.Errorf("Expected vprefix=%q, but got %q", e, a)
|
||||
}
|
||||
}
|
||||
}
|
2
vendor/github.com/Masterminds/sprig/.gitignore
generated
vendored
2
vendor/github.com/Masterminds/sprig/.gitignore
generated
vendored
@ -1,2 +0,0 @@
|
||||
vendor/
|
||||
/.glide
|
24
vendor/github.com/Masterminds/sprig/.travis.yml
generated
vendored
24
vendor/github.com/Masterminds/sprig/.travis.yml
generated
vendored
@ -1,24 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
||||
|
||||
# Setting sudo access to false will let Travis CI use containers rather than
|
||||
# VMs to run the tests. For more details see:
|
||||
# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
||||
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
|
||||
sudo: false
|
||||
|
||||
script:
|
||||
- make setup test
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: never # options: [always|never|change] default: always
|
121
vendor/github.com/Masterminds/sprig/CHANGELOG.md
generated
vendored
121
vendor/github.com/Masterminds/sprig/CHANGELOG.md
generated
vendored
@ -1,16 +1,131 @@
|
||||
# Release 1.2.0 (2016-02-01)
|
||||
# Changelog
|
||||
|
||||
## Release 2.14.1 (2017-12-01)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #60: Fix typo in function name documentation (thanks @neil-ca-moore)
|
||||
- #61: Removing line with {{ due to blocking github pages genertion
|
||||
- #64: Update the list functions to handle int, string, and other slices for compatibility
|
||||
|
||||
## Release 2.14.0 (2017-10-06)
|
||||
|
||||
This new version of Sprig adds a set of functions for generating and working with SSL certificates.
|
||||
|
||||
- `genCA` generates an SSL Certificate Authority
|
||||
- `genSelfSignedCert` generates an SSL self-signed certificate
|
||||
- `genSignedCert` generates an SSL certificate and key based on a given CA
|
||||
|
||||
## Release 2.13.0 (2017-09-18)
|
||||
|
||||
This release adds new functions, including:
|
||||
|
||||
- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions
|
||||
- `floor`, `ceil`, and `round` math functions
|
||||
- `toDate` converts a string to a date
|
||||
- `nindent` is just like `indent` but also prepends a new line
|
||||
- `ago` returns the time from `time.Now`
|
||||
|
||||
### Added
|
||||
|
||||
- #40: Added basic regex functionality (thanks @alanquillin)
|
||||
- #41: Added ceil floor and round functions (thanks @alanquillin)
|
||||
- #48: Added toDate function (thanks @andreynering)
|
||||
- #50: Added nindent function (thanks @binoculars)
|
||||
- #46: Added ago function (thanks @slayer)
|
||||
|
||||
### Changed
|
||||
|
||||
- #51: Updated godocs to include new string functions (thanks @curtisallen)
|
||||
- #49: Added ability to merge multiple dicts (thanks @binoculars)
|
||||
|
||||
## Release 2.12.0 (2017-05-17)
|
||||
|
||||
- `snakecase`, `camelcase`, and `shuffle` are three new string functions
|
||||
- `fail` allows you to bail out of a template render when conditions are not met
|
||||
|
||||
## Release 2.11.0 (2017-05-02)
|
||||
|
||||
- Added `toJson` and `toPrettyJson`
|
||||
- Added `merge`
|
||||
- Refactored documentation
|
||||
|
||||
## Release 2.10.0 (2017-03-15)
|
||||
|
||||
- Added `semver` and `semverCompare` for Semantic Versions
|
||||
- `list` replaces `tuple`
|
||||
- Fixed issue with `join`
|
||||
- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without`
|
||||
|
||||
## Release 2.9.0 (2017-02-23)
|
||||
|
||||
- Added `splitList` to split a list
|
||||
- Added crypto functions of `genPrivateKey` and `derivePassword`
|
||||
|
||||
## Release 2.8.0 (2016-12-21)
|
||||
|
||||
- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`)
|
||||
- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`)
|
||||
|
||||
## Release 2.7.0 (2016-12-01)
|
||||
|
||||
- Added `sha256sum` to generate a hash of an input
|
||||
- Added functions to convert a numeric or string to `int`, `int64`, `float64`
|
||||
|
||||
## Release 2.6.0 (2016-10-03)
|
||||
|
||||
- Added a `uuidv4` template function for generating UUIDs inside of a template.
|
||||
|
||||
## Release 2.5.0 (2016-08-19)
|
||||
|
||||
- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions
|
||||
- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`)
|
||||
- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0
|
||||
|
||||
## Release 2.4.0 (2016-08-16)
|
||||
|
||||
- Adds two functions: `until` and `untilStep`
|
||||
|
||||
## Release 2.3.0 (2016-06-21)
|
||||
|
||||
- cat: Concatenate strings with whitespace separators.
|
||||
- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First"
|
||||
- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos"
|
||||
- indent: Indent blocks of text in a way that is sensitive to "\n" characters.
|
||||
|
||||
## Release 2.2.0 (2016-04-21)
|
||||
|
||||
- Added a `genPrivateKey` function (Thanks @bacongobbler)
|
||||
|
||||
## Release 2.1.0 (2016-03-30)
|
||||
|
||||
- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`.
|
||||
- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output.
|
||||
|
||||
## Release 2.0.0 (2016-03-29)
|
||||
|
||||
Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented.
|
||||
|
||||
- `min` complements `max` (formerly `biggest`)
|
||||
- `empty` indicates that a value is the empty value for its type
|
||||
- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}`
|
||||
- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}`
|
||||
- Date formatters have been added for HTML dates (as used in `date` input fields)
|
||||
- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`).
|
||||
|
||||
## Release 1.2.0 (2016-02-01)
|
||||
|
||||
- Added quote and squote
|
||||
- Added b32enc and b32dec
|
||||
- add now takes varargs
|
||||
- biggest now takes varargs
|
||||
|
||||
# Release 1.1.0 (2015-12-29)
|
||||
## Release 1.1.0 (2015-12-29)
|
||||
|
||||
- Added #4: Added contains function. strings.Contains, but with the arguments
|
||||
switched to simplify common pipelines. (thanks krancour)
|
||||
- Added Travis-CI testing support
|
||||
|
||||
# Release 1.0.0 (2015-12-23)
|
||||
## Release 1.0.0 (2015-12-23)
|
||||
|
||||
- Initial release
|
||||
|
232
vendor/github.com/Masterminds/sprig/crypto.go
generated
vendored
232
vendor/github.com/Masterminds/sprig/crypto.go
generated
vendored
@ -10,12 +10,16 @@ import (
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"golang.org/x/crypto/scrypt"
|
||||
@ -146,3 +150,231 @@ func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type certificate struct {
|
||||
Cert string
|
||||
Key string
|
||||
}
|
||||
|
||||
func generateCertificateAuthority(
|
||||
cn string,
|
||||
daysValid int,
|
||||
) (certificate, error) {
|
||||
ca := certificate{}
|
||||
|
||||
template, err := getBaseCertTemplate(cn, nil, nil, daysValid)
|
||||
if err != nil {
|
||||
return ca, err
|
||||
}
|
||||
// Override KeyUsage and IsCA
|
||||
template.KeyUsage = x509.KeyUsageKeyEncipherment |
|
||||
x509.KeyUsageDigitalSignature |
|
||||
x509.KeyUsageCertSign
|
||||
template.IsCA = true
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return ca, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
|
||||
if err != nil {
|
||||
return ca, err
|
||||
}
|
||||
|
||||
return ca, nil
|
||||
}
|
||||
|
||||
func generateSelfSignedCertificate(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
) (certificate, error) {
|
||||
cert := certificate{}
|
||||
|
||||
template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
|
||||
if err != nil {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
|
||||
if err != nil {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func generateSignedCertificate(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
ca certificate,
|
||||
) (certificate, error) {
|
||||
cert := certificate{}
|
||||
|
||||
decodedSignerCert, _ := pem.Decode([]byte(ca.Cert))
|
||||
if decodedSignerCert == nil {
|
||||
return cert, errors.New("unable to decode certificate")
|
||||
}
|
||||
signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf(
|
||||
"error parsing certificate: decodedSignerCert.Bytes: %s",
|
||||
err,
|
||||
)
|
||||
}
|
||||
decodedSignerKey, _ := pem.Decode([]byte(ca.Key))
|
||||
if decodedSignerKey == nil {
|
||||
return cert, errors.New("unable to decode key")
|
||||
}
|
||||
signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf(
|
||||
"error parsing prive key: decodedSignerKey.Bytes: %s",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
|
||||
if err != nil {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return cert, fmt.Errorf("error generating rsa key: %s", err)
|
||||
}
|
||||
|
||||
cert.Cert, cert.Key, err = getCertAndKey(
|
||||
template,
|
||||
priv,
|
||||
signerCert,
|
||||
signerKey,
|
||||
)
|
||||
if err != nil {
|
||||
return cert, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func getCertAndKey(
|
||||
template *x509.Certificate,
|
||||
signeeKey *rsa.PrivateKey,
|
||||
parent *x509.Certificate,
|
||||
signingKey *rsa.PrivateKey,
|
||||
) (string, string, error) {
|
||||
derBytes, err := x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
template,
|
||||
parent,
|
||||
&signeeKey.PublicKey,
|
||||
signingKey,
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("error creating certificate: %s", err)
|
||||
}
|
||||
|
||||
certBuffer := bytes.Buffer{}
|
||||
if err := pem.Encode(
|
||||
&certBuffer,
|
||||
&pem.Block{Type: "CERTIFICATE", Bytes: derBytes},
|
||||
); err != nil {
|
||||
return "", "", fmt.Errorf("error pem-encoding certificate: %s", err)
|
||||
}
|
||||
|
||||
keyBuffer := bytes.Buffer{}
|
||||
if err := pem.Encode(
|
||||
&keyBuffer,
|
||||
&pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(signeeKey),
|
||||
},
|
||||
); err != nil {
|
||||
return "", "", fmt.Errorf("error pem-encoding key: %s", err)
|
||||
}
|
||||
|
||||
return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil
|
||||
}
|
||||
|
||||
func getBaseCertTemplate(
|
||||
cn string,
|
||||
ips []interface{},
|
||||
alternateDNS []interface{},
|
||||
daysValid int,
|
||||
) (*x509.Certificate, error) {
|
||||
ipAddresses, err := getNetIPs(ips)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dnsNames, err := getAlternateDNSStrs(alternateDNS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: cn,
|
||||
},
|
||||
IPAddresses: ipAddresses,
|
||||
DNSNames: dnsNames,
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * time.Duration(daysValid)),
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{
|
||||
x509.ExtKeyUsageServerAuth,
|
||||
x509.ExtKeyUsageClientAuth,
|
||||
},
|
||||
BasicConstraintsValid: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getNetIPs(ips []interface{}) ([]net.IP, error) {
|
||||
if ips == nil {
|
||||
return []net.IP{}, nil
|
||||
}
|
||||
var ipStr string
|
||||
var ok bool
|
||||
var netIP net.IP
|
||||
netIPs := make([]net.IP, len(ips))
|
||||
for i, ip := range ips {
|
||||
ipStr, ok = ip.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error parsing ip: %v is not a string", ip)
|
||||
}
|
||||
netIP = net.ParseIP(ipStr)
|
||||
if netIP == nil {
|
||||
return nil, fmt.Errorf("error parsing ip: %s", ipStr)
|
||||
}
|
||||
netIPs[i] = netIP
|
||||
}
|
||||
return netIPs, nil
|
||||
}
|
||||
|
||||
func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) {
|
||||
if alternateDNS == nil {
|
||||
return []string{}, nil
|
||||
}
|
||||
var dnsStr string
|
||||
var ok bool
|
||||
alternateDNSStrs := make([]string, len(alternateDNS))
|
||||
for i, dns := range alternateDNS {
|
||||
dnsStr, ok = dns.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"error processing alternate dns name: %v is not a string",
|
||||
dns,
|
||||
)
|
||||
}
|
||||
alternateDNSStrs[i] = dnsStr
|
||||
}
|
||||
return alternateDNSStrs, nil
|
||||
}
|
||||
|
110
vendor/github.com/Masterminds/sprig/crypto_test.go
generated
vendored
110
vendor/github.com/Masterminds/sprig/crypto_test.go
generated
vendored
@ -1,110 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSha256Sum(t *testing.T) {
|
||||
tpl := `{{"abc" | sha256sum}}`
|
||||
if err := runt(tpl, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDerivePassword(t *testing.T) {
|
||||
expectations := map[string]string{
|
||||
`{{derivePassword 1 "long" "password" "user" "example.com"}}`: "ZedaFaxcZaso9*",
|
||||
`{{derivePassword 2 "long" "password" "user" "example.com"}}`: "Fovi2@JifpTupx",
|
||||
`{{derivePassword 1 "maximum" "password" "user" "example.com"}}`: "pf4zS1LjCg&LjhsZ7T2~",
|
||||
`{{derivePassword 1 "medium" "password" "user" "example.com"}}`: "ZedJuz8$",
|
||||
`{{derivePassword 1 "basic" "password" "user" "example.com"}}`: "pIS54PLs",
|
||||
`{{derivePassword 1 "short" "password" "user" "example.com"}}`: "Zed5",
|
||||
`{{derivePassword 1 "pin" "password" "user" "example.com"}}`: "6685",
|
||||
}
|
||||
|
||||
for tpl, result := range expectations {
|
||||
out, err := runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if 0 != strings.Compare(out, result) {
|
||||
t.Error("Generated password does not match for", tpl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(bacongobbler): this test is really _slow_ because of how long it takes to compute
|
||||
// and generate a new crypto key.
|
||||
func TestGenPrivateKey(t *testing.T) {
|
||||
// test that calling by default generates an RSA private key
|
||||
tpl := `{{genPrivateKey ""}}`
|
||||
out, err := runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !strings.Contains(out, "RSA PRIVATE KEY") {
|
||||
t.Error("Expected RSA PRIVATE KEY")
|
||||
}
|
||||
// test all acceptable arguments
|
||||
tpl = `{{genPrivateKey "rsa"}}`
|
||||
out, err = runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !strings.Contains(out, "RSA PRIVATE KEY") {
|
||||
t.Error("Expected RSA PRIVATE KEY")
|
||||
}
|
||||
tpl = `{{genPrivateKey "dsa"}}`
|
||||
out, err = runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !strings.Contains(out, "DSA PRIVATE KEY") {
|
||||
t.Error("Expected DSA PRIVATE KEY")
|
||||
}
|
||||
tpl = `{{genPrivateKey "ecdsa"}}`
|
||||
out, err = runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !strings.Contains(out, "EC PRIVATE KEY") {
|
||||
t.Error("Expected EC PRIVATE KEY")
|
||||
}
|
||||
// test bad
|
||||
tpl = `{{genPrivateKey "bad"}}`
|
||||
out, err = runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if out != "Unknown type bad" {
|
||||
t.Error("Expected type 'bad' to be an unknown crypto algorithm")
|
||||
}
|
||||
// ensure that we can base64 encode the string
|
||||
tpl = `{{genPrivateKey "rsa" | b64enc}}`
|
||||
out, err = runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUUIDGeneration(t *testing.T) {
|
||||
tpl := `{{uuidv4}}`
|
||||
out, err := runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if len(out) != 36 {
|
||||
t.Error("Expected UUID of length 36")
|
||||
}
|
||||
|
||||
out2, err := runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if out == out2 {
|
||||
t.Error("Expected subsequent UUID generations to be different")
|
||||
}
|
||||
}
|
23
vendor/github.com/Masterminds/sprig/date.go
generated
vendored
23
vendor/github.com/Masterminds/sprig/date.go
generated
vendored
@ -51,3 +51,26 @@ func dateModify(fmt string, date time.Time) time.Time {
|
||||
}
|
||||
return date.Add(d)
|
||||
}
|
||||
|
||||
func dateAgo(date interface{}) string {
|
||||
var t time.Time
|
||||
|
||||
switch date := date.(type) {
|
||||
default:
|
||||
t = time.Now()
|
||||
case time.Time:
|
||||
t = date
|
||||
case int64:
|
||||
t = time.Unix(date, 0)
|
||||
case int:
|
||||
t = time.Unix(int64(date), 0)
|
||||
}
|
||||
// Drop resolution to seconds
|
||||
duration := time.Since(t) / time.Second * time.Second
|
||||
return duration.String()
|
||||
}
|
||||
|
||||
func toDate(fmt, str string) time.Time {
|
||||
t, _ := time.ParseInLocation(fmt, str, time.Local)
|
||||
return t
|
||||
}
|
||||
|
13
vendor/github.com/Masterminds/sprig/date_test.go
generated
vendored
13
vendor/github.com/Masterminds/sprig/date_test.go
generated
vendored
@ -1,13 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHtmlDate(t *testing.T) {
|
||||
t.Skip()
|
||||
tpl := `{{ htmlDate 0}}`
|
||||
if err := runt(tpl, "1970-01-01"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
107
vendor/github.com/Masterminds/sprig/defaults_test.go
generated
vendored
107
vendor/github.com/Masterminds/sprig/defaults_test.go
generated
vendored
@ -1,107 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDefault(t *testing.T) {
|
||||
tpl := `{{"" | default "foo"}}`
|
||||
if err := runt(tpl, "foo"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{default "foo" 234}}`
|
||||
if err := runt(tpl, "234"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{default "foo" 2.34}}`
|
||||
if err := runt(tpl, "2.34"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
tpl = `{{ .Nothing | default "123" }}`
|
||||
if err := runt(tpl, "123"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{ default "123" }}`
|
||||
if err := runt(tpl, "123"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
tpl := `{{if empty 1}}1{{else}}0{{end}}`
|
||||
if err := runt(tpl, "0"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
tpl = `{{if empty 0}}1{{else}}0{{end}}`
|
||||
if err := runt(tpl, "1"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{if empty ""}}1{{else}}0{{end}}`
|
||||
if err := runt(tpl, "1"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{if empty 0.0}}1{{else}}0{{end}}`
|
||||
if err := runt(tpl, "1"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{if empty false}}1{{else}}0{{end}}`
|
||||
if err := runt(tpl, "1"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
dict := map[string]interface{}{"top": map[string]interface{}{}}
|
||||
tpl = `{{if empty .top.NoSuchThing}}1{{else}}0{{end}}`
|
||||
if err := runtv(tpl, "1", dict); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{if empty .bottom.NoSuchThing}}1{{else}}0{{end}}`
|
||||
if err := runtv(tpl, "1", dict); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestCoalesce(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ coalesce 1 }}`: "1",
|
||||
`{{ coalesce "" 0 nil 2 }}`: "2",
|
||||
`{{ $two := 2 }}{{ coalesce "" 0 nil $two }}`: "2",
|
||||
`{{ $two := 2 }}{{ coalesce "" $two 0 0 0 }}`: "2",
|
||||
`{{ $two := 2 }}{{ coalesce "" $two 3 4 5 }}`: "2",
|
||||
`{{ coalesce }}`: "<no value>",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
|
||||
dict := map[string]interface{}{"top": map[string]interface{}{}}
|
||||
tpl := `{{ coalesce .top.NoSuchThing .bottom .bottom.dollar "airplane"}}`
|
||||
if err := runtv(tpl, "airplane", dict); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToJson(t *testing.T) {
|
||||
dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}}
|
||||
|
||||
tpl := `{{.Top | toJson}}`
|
||||
expected := `{"bool":true,"number":42,"string":"test"}`
|
||||
if err := runtv(tpl, expected, dict); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPrettyJson(t *testing.T) {
|
||||
dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}}
|
||||
tpl := `{{.Top | toPrettyJson}}`
|
||||
expected := `{
|
||||
"bool": true,
|
||||
"number": 42,
|
||||
"string": "test"
|
||||
}`
|
||||
if err := runtv(tpl, expected, dict); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
4
vendor/github.com/Masterminds/sprig/dict.go
generated
vendored
4
vendor/github.com/Masterminds/sprig/dict.go
generated
vendored
@ -75,10 +75,12 @@ func dict(v ...interface{}) map[string]interface{} {
|
||||
return dict
|
||||
}
|
||||
|
||||
func merge(dst map[string]interface{}, src map[string]interface{}) interface{} {
|
||||
func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
|
||||
for _, src := range srcs {
|
||||
if err := mergo.Merge(&dst, src); err != nil {
|
||||
// Swallow errors inside of a template.
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
174
vendor/github.com/Masterminds/sprig/dict_test.go
generated
vendored
174
vendor/github.com/Masterminds/sprig/dict_test.go
generated
vendored
@ -1,174 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDict(t *testing.T) {
|
||||
tpl := `{{$d := dict 1 2 "three" "four" 5}}{{range $k, $v := $d}}{{$k}}{{$v}}{{end}}`
|
||||
out, err := runRaw(tpl, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(out) != 12 {
|
||||
t.Errorf("Expected length 12, got %d", len(out))
|
||||
}
|
||||
// dict does not guarantee ordering because it is backed by a map.
|
||||
if !strings.Contains(out, "12") {
|
||||
t.Error("Expected grouping 12")
|
||||
}
|
||||
if !strings.Contains(out, "threefour") {
|
||||
t.Error("Expected grouping threefour")
|
||||
}
|
||||
if !strings.Contains(out, "5") {
|
||||
t.Error("Expected 5")
|
||||
}
|
||||
tpl = `{{$t := dict "I" "shot" "the" "albatross"}}{{$t.the}} {{$t.I}}`
|
||||
if err := runt(tpl, "albatross shot"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnset(t *testing.T) {
|
||||
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
|
||||
{{- $_ := unset $d "two" -}}
|
||||
{{- range $k, $v := $d}}{{$k}}{{$v}}{{- end -}}
|
||||
`
|
||||
|
||||
expect := "one1"
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestHasKey(t *testing.T) {
|
||||
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
|
||||
{{- if hasKey $d "one" -}}1{{- end -}}
|
||||
`
|
||||
|
||||
expect := "1"
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluck(t *testing.T) {
|
||||
tpl := `
|
||||
{{- $d := dict "one" 1 "two" 222222 -}}
|
||||
{{- $d2 := dict "one" 1 "two" 33333 -}}
|
||||
{{- $d3 := dict "one" 1 -}}
|
||||
{{- $d4 := dict "one" 1 "two" 4444 -}}
|
||||
{{- pluck "two" $d $d2 $d3 $d4 -}}
|
||||
`
|
||||
|
||||
expect := "[222222 33333 4444]"
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeys(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ dict "foo" 1 "bar" 2 | keys | sortAlpha }}`: "[bar foo]",
|
||||
`{{ dict | keys }}`: "[]",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPick(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "two" | len -}}`: "1",
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "two" -}}`: "map[two:222222]",
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "one" "two" | len -}}`: "2",
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "one" "two" "three" | len -}}`: "2",
|
||||
`{{- $d := dict }}{{ pick $d "two" | len -}}`: "0",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestOmit(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "one" | len -}}`: "1",
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "one" -}}`: "map[two:222222]",
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "one" "two" | len -}}`: "0",
|
||||
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "two" "three" | len -}}`: "1",
|
||||
`{{- $d := dict }}{{ omit $d "two" | len -}}`: "0",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
|
||||
{{- $_ := set $d "two" 2 -}}
|
||||
{{- $_ := set $d "three" 3 -}}
|
||||
{{- if hasKey $d "one" -}}{{$d.one}}{{- end -}}
|
||||
{{- if hasKey $d "two" -}}{{$d.two}}{{- end -}}
|
||||
{{- if hasKey $d "three" -}}{{$d.three}}{{- end -}}
|
||||
`
|
||||
|
||||
expect := "123"
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompact(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 0 "" "hello" | compact }}`: `[1 hello]`,
|
||||
`{{ list "" "" | compact }}`: `[]`,
|
||||
`{{ list | compact }}`: `[]`,
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
dict := map[string]interface{}{
|
||||
"src": map[string]interface{}{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"d": map[string]interface{}{
|
||||
"e": "four",
|
||||
},
|
||||
"g": []int{6, 7},
|
||||
},
|
||||
"dst": map[string]interface{}{
|
||||
"a": "one",
|
||||
"c": 3,
|
||||
"d": map[string]interface{}{
|
||||
"f": 5,
|
||||
},
|
||||
"g": []int{8, 9},
|
||||
},
|
||||
}
|
||||
tpl := `{{merge .dst .src}}`
|
||||
_, err := runRaw(tpl, dict)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expected := map[string]interface{}{
|
||||
"a": "one", // key overridden
|
||||
"b": 2, // merged from src
|
||||
"c": 3, // merged from dst
|
||||
"d": map[string]interface{}{ // deep merge
|
||||
"e": "four",
|
||||
"f": 5,
|
||||
},
|
||||
"g": []int{8, 9}, // overridden - arrays are not merged
|
||||
}
|
||||
assert.Equal(t, expected, dict["dst"])
|
||||
}
|
7
vendor/github.com/Masterminds/sprig/doc.go
generated
vendored
7
vendor/github.com/Masterminds/sprig/doc.go
generated
vendored
@ -48,6 +48,10 @@ String Functions
|
||||
- randAlpha: Given a length, generate an alphabetic string
|
||||
- randAscii: Given a length, generate a random ASCII string (symbols included)
|
||||
- randNumeric: Given a length, generate a string of digits.
|
||||
- swapcase: SwapCase swaps the case of a string using a word based algorithm. see https://godoc.org/github.com/Masterminds/goutils#SwapCase
|
||||
- shuffle: Shuffle randomizes runes in a string and returns the result. It uses default random source in `math/rand`
|
||||
- snakecase: convert all upper case characters in a string to underscore format.
|
||||
- camelcase: convert all lower case characters behind underscores to upper case character
|
||||
- wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"`
|
||||
- wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "<br>", $html`
|
||||
- contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines)
|
||||
@ -57,6 +61,7 @@ String Functions
|
||||
- squote: Wrap string(s) in double quotation marks, does not escape content.
|
||||
- cat: Concatenate strings, separating them by spaces. `cat $a $b $c`.
|
||||
- indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar"
|
||||
- nindent: Indent a string using space characters and prepend a new line. `indent 4 "foo\nbar"` produces "\n foo\n bar"
|
||||
- replace: Replace an old with a new in a string: `$name | replace " " "-"`
|
||||
- plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"`
|
||||
- sha256sum: Generate a hex encoded sha256 hash of the input
|
||||
@ -84,7 +89,7 @@ Integer Slice Functions:
|
||||
Conversions:
|
||||
|
||||
- atoi: Convert a string to an integer. 0 if the integer could not be parsed.
|
||||
- in64: Convert a string or another numeric type to an int64.
|
||||
- int64: Convert a string or another numeric type to an int64.
|
||||
- int: Convert a string or another numeric type to an int.
|
||||
- float64: Convert a string or another numeric type to a float64.
|
||||
|
||||
|
1
vendor/github.com/Masterminds/sprig/docs/_config.yml
generated
vendored
1
vendor/github.com/Masterminds/sprig/docs/_config.yml
generated
vendored
@ -1 +0,0 @@
|
||||
theme: jekyll-theme-slate
|
25
vendor/github.com/Masterminds/sprig/docs/conversion.md
generated
vendored
25
vendor/github.com/Masterminds/sprig/docs/conversion.md
generated
vendored
@ -1,25 +0,0 @@
|
||||
# Type Conversion Functions
|
||||
|
||||
The following type conversion functions are provided by Sprig:
|
||||
|
||||
- `atoi`: Convert a string to an integer
|
||||
- `float64`: Convert to a float64
|
||||
- `int`: Convert to an `int` at the system's width.
|
||||
- `int64`: Convert to an `int64`
|
||||
- `toString`: Convert to a string
|
||||
- `toStrings`: Convert a list, slice, or array to a list of strings.
|
||||
|
||||
Only `atoi` requires that the input be a specific type. The others will attempt
|
||||
to convert from any type to the destination type. For example, `int64` can convert
|
||||
floats to ints, and it can also convert strings to ints.
|
||||
|
||||
## toStrings
|
||||
|
||||
Given a list-like collection, produce a slice of strings.
|
||||
|
||||
```
|
||||
list 1 2 3 | toStrings
|
||||
```
|
||||
|
||||
The above converts `1` to `"1"`, `2` to `"2"`, and so on, and then returns
|
||||
them as a list.
|
37
vendor/github.com/Masterminds/sprig/docs/crypto.md
generated
vendored
37
vendor/github.com/Masterminds/sprig/docs/crypto.md
generated
vendored
@ -1,37 +0,0 @@
|
||||
# Cryptographic and Security Functions
|
||||
|
||||
Sprig provides a couple of advanced cryptographic functions.
|
||||
|
||||
## sha256sum
|
||||
|
||||
The `sha256sum` function receives a string, and computes it's SHA256 digest.
|
||||
|
||||
```
|
||||
sha256sum "Hello world!"
|
||||
```
|
||||
|
||||
The above will compute the SHA 256 sum in an "ASCII armored" format that is
|
||||
safe to print.
|
||||
|
||||
## derivePassword
|
||||
|
||||
The `derivePassword` function can be used to derive a specific password based on
|
||||
some shared "master password" constraints. The algorithm for this is
|
||||
[well specified](http://masterpasswordapp.com/algorithm.html).
|
||||
|
||||
```
|
||||
derivePassword 1 "long" "password" "user" "example.com"
|
||||
```
|
||||
|
||||
Note that it is considered insecure to store the parts directly in the template.
|
||||
|
||||
## generatePrivateKey
|
||||
|
||||
The `generatePrivateKey` function generates a new private key encoded into a PEM
|
||||
block.
|
||||
|
||||
It takes one of the values for its first param:
|
||||
|
||||
- `ecdsa`: Generate an elyptical curve DSA key (P256)
|
||||
- `dsa`: Generate a DSA key (L2048N256)
|
||||
- `rsa`: Generate an RSA 4096 key
|
62
vendor/github.com/Masterminds/sprig/docs/date.md
generated
vendored
62
vendor/github.com/Masterminds/sprig/docs/date.md
generated
vendored
@ -1,62 +0,0 @@
|
||||
# Date Functions
|
||||
|
||||
## now
|
||||
|
||||
The current date/time. Use this in conjunction with other date functions.
|
||||
|
||||
## date
|
||||
|
||||
The `date` function formats a date.
|
||||
|
||||
|
||||
Format the date to YEAR-MONTH-DAY:
|
||||
```
|
||||
now | date "2006-01-02"
|
||||
```
|
||||
|
||||
Date formatting in Go is a [little bit different](https://pauladamsmith.com/blog/2011/05/go_time.html).
|
||||
|
||||
In short, take this as the base date:
|
||||
|
||||
```
|
||||
Mon Jan 2 15:04:05 MST 2006
|
||||
```
|
||||
|
||||
Write it in the format you want. Above, `2006-01-02` is the same date, but
|
||||
in the format we want.
|
||||
|
||||
## dateInZone
|
||||
|
||||
Same as `date`, but with a timezone.
|
||||
|
||||
```
|
||||
date "2006-01-02" (now) "UTC"
|
||||
```
|
||||
|
||||
## dateModify
|
||||
|
||||
The `dateModify` takes a modification and a date and returns the timestamp.
|
||||
|
||||
Subtract an hour and thirty minutes from the current time:
|
||||
|
||||
```
|
||||
now | date_modify "-1.5h"
|
||||
```
|
||||
|
||||
## htmlDate
|
||||
|
||||
The `htmlDate` function formates a date for inserting into an HTML date picker
|
||||
input field.
|
||||
|
||||
```
|
||||
now | htmlDate
|
||||
```
|
||||
|
||||
## htmlDateInZone
|
||||
|
||||
Same as htmlDate, but with a timezone.
|
||||
|
||||
```
|
||||
htmlDate (now) "UTC"
|
||||
```
|
||||
|
59
vendor/github.com/Masterminds/sprig/docs/defaults.md
generated
vendored
59
vendor/github.com/Masterminds/sprig/docs/defaults.md
generated
vendored
@ -1,59 +0,0 @@
|
||||
# Default Functions
|
||||
|
||||
Sprig provides tools for setting default values for templates.
|
||||
|
||||
## default
|
||||
|
||||
To set a simple default value, use `default`:
|
||||
|
||||
```
|
||||
default "foo" .Bar
|
||||
```
|
||||
|
||||
In the above, if `.Bar` evaluates to a non-empty value, it will be used. But if
|
||||
it is empty, `foo` will be returned instead.
|
||||
|
||||
The definition of "empty" depends on type:
|
||||
|
||||
- Numeric: 0
|
||||
- String: ""
|
||||
- Lists: `[]`
|
||||
- Dicts: `{}`
|
||||
- Boolean: `false`
|
||||
- And always `nil` (aka null)
|
||||
|
||||
For structs, there is no definition of empty, so a struct will never return the
|
||||
default.
|
||||
|
||||
## empty
|
||||
|
||||
The `empty` function returns `true` if the given value is considered empty, and
|
||||
`false` otherwise. The empty values are listed in the `default` section.
|
||||
|
||||
```
|
||||
empty .Foo
|
||||
```
|
||||
|
||||
Note that in Go template conditionals, emptiness is calculated for you. Thus,
|
||||
you rarely need `if empty .Foo`. Instead, just use `if .Foo`.
|
||||
|
||||
## coalesce
|
||||
|
||||
The `coalesce` function takes a list of values and returns the first non-empty
|
||||
one.
|
||||
|
||||
```
|
||||
coalesce 0 1 2
|
||||
```
|
||||
|
||||
The above returns `1`.
|
||||
|
||||
This function is useful for scanning through multiple variables or values:
|
||||
|
||||
```
|
||||
coalesce .name .parent.name "Matt"
|
||||
```
|
||||
|
||||
The above will first check to see if `.name` is empty. If it is not, it will return
|
||||
that value. If it _is_ empty, `coalesce` will evaluate `.parent.name` for emptiness.
|
||||
Finally, if both `.name` and `.parent.name` are empty, it will return `Matt`.
|
124
vendor/github.com/Masterminds/sprig/docs/dicts.md
generated
vendored
124
vendor/github.com/Masterminds/sprig/docs/dicts.md
generated
vendored
@ -1,124 +0,0 @@
|
||||
# Dictionaries and Dict Functions
|
||||
|
||||
Sprig provides a key/value storage type called a `dict` (short for "dictionary",
|
||||
as in Python). A `dict` is an _unorder_ type.
|
||||
|
||||
The key to a dictionary **must be a string**. However, the value can be any
|
||||
type, even another `dict` or `list`.
|
||||
|
||||
Unlike `list`s, `dict`s are not immutable. The `set` and `unset` functions will
|
||||
modify the contents of a dictionary.
|
||||
|
||||
## dict
|
||||
|
||||
Creating dictionaries is done by calling the `dict` function and passing it a
|
||||
list of pairs.
|
||||
|
||||
The following creates a dictionary with three items:
|
||||
|
||||
```
|
||||
$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3"
|
||||
```
|
||||
|
||||
## set
|
||||
|
||||
Use `set` to add a new key/value pair to a dictionary.
|
||||
|
||||
```
|
||||
$_ := set $myDict "name4" "value4"
|
||||
```
|
||||
|
||||
Note that `set` _returns the dictionary_ (a requirement of Go template functions),
|
||||
so you may need to trap the value as done above with the `$_` assignment.
|
||||
|
||||
## unset
|
||||
|
||||
Given a map and a key, delete the key from the map.
|
||||
|
||||
```
|
||||
$_ := unset $myDict "name4"
|
||||
```
|
||||
|
||||
As with `set`, this returns the dictionary.
|
||||
|
||||
Note that if the key is not found, this operation will simply return. No error
|
||||
will be generated.
|
||||
|
||||
## hasKey
|
||||
|
||||
The `hasKey` function returns `true` if the given dict contains the given key.
|
||||
|
||||
```
|
||||
hasKey $myDict "name1"
|
||||
```
|
||||
|
||||
If the key is not found, this returns `false`.
|
||||
|
||||
## pluck
|
||||
|
||||
The `pluck` function makes it possible to give one key and multiple maps, and
|
||||
get a list of all of the matches:
|
||||
|
||||
```
|
||||
pluck "name1" $myDict $myOtherDict
|
||||
```
|
||||
|
||||
The above will return a `list` containing every found value (`[value1 otherValue1]`).
|
||||
|
||||
If the give key is _not found_ in a map, that map will not have an item in the
|
||||
list (and the length of the returned list will be less than the number of dicts
|
||||
in the call to `pluck`.
|
||||
|
||||
If the key is _found_ but the value is an empty value, that value will be
|
||||
inserted.
|
||||
|
||||
A common idiom in Sprig templates is to uses `pluck... | first` to get the first
|
||||
matching key out of a collection of dictionaries.
|
||||
|
||||
## merge
|
||||
|
||||
Merge two dictionaries into one, giving precedence to the dest dictionary:
|
||||
|
||||
```
|
||||
$newdict := merge $dest $source
|
||||
```
|
||||
|
||||
This is a deep merge operation.
|
||||
|
||||
## keys
|
||||
|
||||
The `keys` function will return a `list` of all of the keys in a `dict`. Since
|
||||
a dictionary is _unordered_, the keys will not be in a predictable order. They
|
||||
can be sorted with `sortAlpha`.
|
||||
|
||||
```
|
||||
keys $myDict | sortAlpha
|
||||
```
|
||||
|
||||
## pick
|
||||
|
||||
The `pick` function selects just the given keys out of a dictionary, creating a
|
||||
new `dict`.
|
||||
|
||||
```
|
||||
$new := pick $myDict "name1" "name3"
|
||||
```
|
||||
|
||||
The above returns `{name1: value1, name2: value2}`
|
||||
|
||||
## omit
|
||||
|
||||
The `omit` function is similar to `pick`, except it returns a new `dict` with all
|
||||
the keys that _do not_ match the given keys.
|
||||
|
||||
```
|
||||
$new := omit $myDict "name1" "name3"
|
||||
```
|
||||
|
||||
The above returns `{name2: value2}`
|
||||
|
||||
## A Note on Dict Internals
|
||||
|
||||
A `dict` is implemented in Go as a `map[string]interface{}`. Go developers can
|
||||
pass `map[string]interface{}` values into the context to make them available
|
||||
to templates as `dict`s.
|
6
vendor/github.com/Masterminds/sprig/docs/encoding.md
generated
vendored
6
vendor/github.com/Masterminds/sprig/docs/encoding.md
generated
vendored
@ -1,6 +0,0 @@
|
||||
# Encoding Functions
|
||||
|
||||
Sprig has the following encoding and decoding functions:
|
||||
|
||||
- `b64enc`/`b64dec`: Encode or decode with Base64
|
||||
- `b32enc`/`b32dec`: Encode or decode with Base32
|
11
vendor/github.com/Masterminds/sprig/docs/flow_control.md
generated
vendored
11
vendor/github.com/Masterminds/sprig/docs/flow_control.md
generated
vendored
@ -1,11 +0,0 @@
|
||||
# Flow Control Functions
|
||||
|
||||
## fail
|
||||
|
||||
Unconditionally returns an empty `string` and an `error` with the specified
|
||||
text. This is useful in scenarios where other conditionals have determined that
|
||||
template rendering should fail.
|
||||
|
||||
```
|
||||
fail "Please accept the end user license agreement"
|
||||
```
|
23
vendor/github.com/Masterminds/sprig/docs/index.md
generated
vendored
23
vendor/github.com/Masterminds/sprig/docs/index.md
generated
vendored
@ -1,23 +0,0 @@
|
||||
# Sprig Function Documentation
|
||||
|
||||
The Sprig library provides over 70 template functions for Go's template language.
|
||||
|
||||
- [String Functions](strings.md): `trim`, `wrap`, `randAlpha`, `plural`, etc.
|
||||
- [String List Functions](string_slice.md): `splitList`, `sortAlpha`, etc.
|
||||
- [Math Functions](math.md): `add`, `max`, `mul`, etc.
|
||||
- [Integer Slice Functions](integer_slice.md): `until`, `untilStep`
|
||||
- [Date Functions](date.md): `now`, `date`, etc.
|
||||
- [Defaults Functions](defaults.md): `default`, `empty`, `coalesce`
|
||||
- [Encoding Functions](encoding.md): `b64enc`, `b64dec`, etc.
|
||||
- [Lists and List Functions](lists.md): `list`, `first`, `uniq`, etc.
|
||||
- [Dictionaries and Dict Functions](dicts.md): `dict`, `hasKey`, `pluck`, etc.
|
||||
- [Type Conversion Functions](conversion.md): `atoi`, `int64`, `toString`, etc.
|
||||
- [File Path Functions](paths.md): `base`, `dir`, `ext`, `clean`, `isAbs`
|
||||
- [Flow Control Functions](flow_control.md): `fail`
|
||||
- Advanced Functions
|
||||
- [UUID Functions](uuid.md): `uuidv4`
|
||||
- [OS Functions](os.md): `env`, `expandenv`
|
||||
- [Version Comparison Functions](semver.md): `semver`, `semverCompare`
|
||||
- [Reflection](reflection.md): `typeOf`, `kindIs`, `typeIsLike`, etc.
|
||||
- [Cryptographic and Security Functions](crypto.md): `derivePassword`, `sha256sum`, `genPrivateKey`
|
||||
|
25
vendor/github.com/Masterminds/sprig/docs/integer_slice.md
generated
vendored
25
vendor/github.com/Masterminds/sprig/docs/integer_slice.md
generated
vendored
@ -1,25 +0,0 @@
|
||||
# Integer Slice Functions
|
||||
|
||||
## until
|
||||
|
||||
The `until` function builds a range of integers.
|
||||
|
||||
```
|
||||
until 5
|
||||
```
|
||||
|
||||
The above generates the list `[0, 1, 2, 3, 4]`.
|
||||
|
||||
This is useful for looping with `range $i, $e := until 5`.
|
||||
|
||||
## untilStep
|
||||
|
||||
Like `until`, `untilStep` generates a list of counting integers. But it allows
|
||||
you to define a start, stop, and step:
|
||||
|
||||
```
|
||||
untilStep 3 6 2
|
||||
```
|
||||
|
||||
The above will produce `[3 5]` by starting with 3, and adding 2 until it is equal
|
||||
or greater than 6. This is similar to Python's `range` function.
|
111
vendor/github.com/Masterminds/sprig/docs/lists.md
generated
vendored
111
vendor/github.com/Masterminds/sprig/docs/lists.md
generated
vendored
@ -1,111 +0,0 @@
|
||||
# Lists and List Functions
|
||||
|
||||
Sprig provides a simple `list` type that can contain arbitrary sequential lists
|
||||
of data. This is similar to arrays or slices, but lists are designed to be used
|
||||
as immutable data types.
|
||||
|
||||
Create a list of integers:
|
||||
|
||||
```
|
||||
$myList := list 1 2 3 4 5
|
||||
```
|
||||
|
||||
The above creates a list of `[1 2 3 4 5]`.
|
||||
|
||||
## first
|
||||
|
||||
To get the head item on a list, use `first`.
|
||||
|
||||
`first $myList` returns `1`
|
||||
|
||||
## rest
|
||||
|
||||
To get the tail of the list (everything but the first item), use `rest`.
|
||||
|
||||
`rest $myList` returns `[2 3 4 5]`
|
||||
|
||||
## last
|
||||
|
||||
To get the last item on a list, use `last`:
|
||||
|
||||
`last $myList` returns `5`. This is roughly analogous to reversing a list and
|
||||
then calling `first`.
|
||||
|
||||
## initial
|
||||
|
||||
This compliments `last` by returning all _but_ the last element.
|
||||
`initial $myList` returns `[1 2 3 4]`.
|
||||
|
||||
## append
|
||||
|
||||
Append a new item to an existing list, creating a new list.
|
||||
|
||||
```
|
||||
$new = append $myList 6
|
||||
```
|
||||
|
||||
The above would set `$new` to `[1 2 3 4 5 6]`. `$myList` would remain unaltered.
|
||||
|
||||
## prepend
|
||||
|
||||
Push an alement onto the front of a list, creating a new list.
|
||||
|
||||
```
|
||||
prepend $myList 0
|
||||
```
|
||||
|
||||
The above would produce `[0 1 2 3 4 5]`. `$myList` would remain unaltered.
|
||||
|
||||
## reverse
|
||||
|
||||
Produce a new list with the reversed elements of the given list.
|
||||
|
||||
```
|
||||
reverse $myList
|
||||
```
|
||||
|
||||
The above would generate the list `[5 4 3 2 1]`.
|
||||
|
||||
## uniq
|
||||
|
||||
Generate a list with all of the duplicates removed.
|
||||
|
||||
```
|
||||
list 1 1 1 2 | uniq
|
||||
```
|
||||
|
||||
The above would produce `[1 2]`
|
||||
|
||||
## without
|
||||
|
||||
The `without` function filters items out of a list.
|
||||
|
||||
```
|
||||
without $myList 3
|
||||
```
|
||||
|
||||
The above would produce `[1 2 4 5]`
|
||||
|
||||
Without can take more than one filter:
|
||||
|
||||
```
|
||||
without $myList 1 3 5
|
||||
```
|
||||
|
||||
That would produce `[2 4]`
|
||||
|
||||
## has
|
||||
|
||||
Test to see if a list has a particular element.
|
||||
|
||||
```
|
||||
has $myList 4
|
||||
```
|
||||
|
||||
The above would return `true`, while `has $myList "hello"` would return false.
|
||||
|
||||
## A Note on List Internals
|
||||
|
||||
A list is implemented in Go as a `[]interface{}`. For Go developers embedding
|
||||
Sprig, you may pass `[]interface{}` items into your template context and be
|
||||
able to use all of the `list` functions on those items.
|
46
vendor/github.com/Masterminds/sprig/docs/math.md
generated
vendored
46
vendor/github.com/Masterminds/sprig/docs/math.md
generated
vendored
@ -1,46 +0,0 @@
|
||||
# Math Functions
|
||||
|
||||
All math functions operate on `int64` values unless specified otherwise.
|
||||
|
||||
(In the future, these will be extended to handle floats as well)
|
||||
|
||||
## add
|
||||
|
||||
Sum numbers with `add`
|
||||
|
||||
## add1
|
||||
|
||||
To increment by 1, use `add1`
|
||||
|
||||
## sub
|
||||
|
||||
To subtract, use `sub`
|
||||
|
||||
## div
|
||||
|
||||
Perform integer division with `div`
|
||||
|
||||
## mod
|
||||
|
||||
Modulo with `mod`
|
||||
|
||||
## mul
|
||||
|
||||
Multiply with `mul`
|
||||
|
||||
## max
|
||||
|
||||
Return the largest of a series of integers:
|
||||
|
||||
This will return `3`:
|
||||
|
||||
```
|
||||
max 1 2 3
|
||||
```
|
||||
|
||||
## min
|
||||
|
||||
Return the smallest of a series of integers.
|
||||
|
||||
`min 1 2 3` will return `1`.
|
||||
|
24
vendor/github.com/Masterminds/sprig/docs/os.md
generated
vendored
24
vendor/github.com/Masterminds/sprig/docs/os.md
generated
vendored
@ -1,24 +0,0 @@
|
||||
# OS Functions
|
||||
|
||||
_WARNING:_ These functions can lead to information leakage if not used
|
||||
appropriately.
|
||||
|
||||
_WARNING:_ Some notable implementations of Sprig (such as
|
||||
[Kubernetes Helm](http://helm.sh) _do not provide these functions for security
|
||||
reasons_.
|
||||
|
||||
## env
|
||||
|
||||
The `env` function reads an environment variable:
|
||||
|
||||
```
|
||||
env "HOME"
|
||||
```
|
||||
|
||||
## expandenv
|
||||
|
||||
To substitute environment variables in a string, use `expandenv`:
|
||||
|
||||
```
|
||||
expandenv "Your path is set to $PATH"
|
||||
```
|
43
vendor/github.com/Masterminds/sprig/docs/paths.md
generated
vendored
43
vendor/github.com/Masterminds/sprig/docs/paths.md
generated
vendored
@ -1,43 +0,0 @@
|
||||
# File Path Functions
|
||||
|
||||
While Sprig does not grant access to the filesystem, it does provide functions
|
||||
for working with strings that follow file path conventions.
|
||||
|
||||
# base
|
||||
|
||||
Return the last element of a path.
|
||||
|
||||
```
|
||||
base "foo/bar/baz"
|
||||
```
|
||||
|
||||
The above prints "baz"
|
||||
|
||||
# dir
|
||||
|
||||
Return the directory, stripping the last part of the path. So `dir "foo/bar/baz"`
|
||||
returns `foo/bar`
|
||||
|
||||
# clean
|
||||
|
||||
Clean up a path.
|
||||
|
||||
```
|
||||
clean "foo/bar/../baz"
|
||||
```
|
||||
|
||||
The above resolves the `..` and returns `foo/baz`
|
||||
|
||||
# ext
|
||||
|
||||
Return the file extension.
|
||||
|
||||
```
|
||||
ext "foo.bar"
|
||||
```
|
||||
|
||||
The above returns `.bar`.
|
||||
|
||||
# isAbs
|
||||
|
||||
To check whether a file path is absolute, use `isAbs`.
|
38
vendor/github.com/Masterminds/sprig/docs/reflection.md
generated
vendored
38
vendor/github.com/Masterminds/sprig/docs/reflection.md
generated
vendored
@ -1,38 +0,0 @@
|
||||
# Reflection Functions
|
||||
|
||||
Sprig provides rudimentary reflection tools. These help advanced template
|
||||
developers understand the underlying Go type information for a particular value.
|
||||
|
||||
Go has several primitive _kinds_, like `string`, `slice`, `int64`, and `bool`.
|
||||
|
||||
Go has an open _type_ system that allows developers to create their own types.
|
||||
|
||||
Sprig provides a set of functions for each.
|
||||
|
||||
## Kind Functions
|
||||
|
||||
There are two Kind functions: `kindOf` returns the kind of an object.
|
||||
|
||||
```
|
||||
kindOf "hello"
|
||||
```
|
||||
|
||||
The above would return `string`. For simple tests (like in `if` blocks), the
|
||||
`isKind` function will let you verify that a value is a particular kind:
|
||||
|
||||
```
|
||||
kindIs "int" 123
|
||||
```
|
||||
|
||||
The above will return `true`
|
||||
|
||||
## Type Functions
|
||||
|
||||
Types are slightly harder to work with, so there are three different functions:
|
||||
|
||||
- `typeOf` returns the underlying type of a value: `typeOf $foo`
|
||||
- `typeIs` is like `kindIs`, but for types: `typeIs "*io.Buffer" $myVal`
|
||||
- `typeIsLike` works as `kindIs`, except that it also dereferences pointers.
|
||||
|
||||
**Note:** None of these can test whether or not something implements a given
|
||||
interface, since doing so would require compiling the interface in ahead of time.
|
124
vendor/github.com/Masterminds/sprig/docs/semver.md
generated
vendored
124
vendor/github.com/Masterminds/sprig/docs/semver.md
generated
vendored
@ -1,124 +0,0 @@
|
||||
# Semantic Version Functions
|
||||
|
||||
Some version schemes are easily parseable and comparable. Sprig provides functions
|
||||
for working with [SemVer 2](http://semver.org) versions.
|
||||
|
||||
## semver
|
||||
|
||||
The `semver` function parses a string into a Semantic Version:
|
||||
|
||||
```
|
||||
$version := semver "1.2.3-alpha.1+123"
|
||||
```
|
||||
|
||||
_If the parser fails, it will cause template execution to halt with an error._
|
||||
|
||||
At this point, `$version` is a pointer to a `Version` object with the following
|
||||
properties:
|
||||
|
||||
- `$version.Major`: The major number (`1` above)
|
||||
- `$version.Minor`: The minor number (`2` above)
|
||||
- `$version.Patch`: The patch number (`3` above)
|
||||
- `$version.Prerelease`: The prerelease (`alpha.1` above)
|
||||
- `$version.Metadata`: The build metadata (`123` above)
|
||||
- `$version.Original`: The original version as a string
|
||||
|
||||
Additionally, you can compare a `Version` to another `version` using the `Compare`
|
||||
function:
|
||||
|
||||
```
|
||||
semver "1.4.3" | (semver "1.2.3").Compare
|
||||
```
|
||||
|
||||
The above will return `-1`.
|
||||
|
||||
The return values are:
|
||||
|
||||
- `-1` if the given semver is greater than the semver whose `Compare` method was called
|
||||
- `1` if the version who's `Compare` function was called is greater.
|
||||
- `0` if they are the same version
|
||||
|
||||
(Note that in SemVer, the `Metadata` field is not compared during version
|
||||
comparison operations.)
|
||||
|
||||
|
||||
## semverCompare
|
||||
|
||||
A more robust comparison function is provided as `semverCompare`. This version
|
||||
supports version ranges:
|
||||
|
||||
- `semverCompare "1.2.3" "1.2.3"` checks for an exact match
|
||||
- `semverCompare "^1.2.0" "1.2.3"` checks that the major and minor versions match, and that the patch
|
||||
number of the second version is _greater than or equal to_ the first parameter.
|
||||
|
||||
The SemVer functions use the [Masterminds semver library](https://github.com/Masterminds/semver),
|
||||
from the creators of Sprig.
|
||||
|
||||
|
||||
## Basic Comparisons
|
||||
|
||||
There are two elements to the comparisons. First, a comparison string is a list
|
||||
of comma separated and comparisons. These are then separated by || separated or
|
||||
comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
|
||||
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
|
||||
greater than or equal to 4.2.3.
|
||||
|
||||
The basic comparisons are:
|
||||
|
||||
* `=`: equal (aliased to no operator)
|
||||
* `!=`: not equal
|
||||
* `>`: greater than
|
||||
* `<`: less than
|
||||
* `>=`: greater than or equal to
|
||||
* `<=`: less than or equal to
|
||||
|
||||
_Note, according to the Semantic Version specification pre-releases may not be
|
||||
API compliant with their release counterpart. It says,_
|
||||
|
||||
> _A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version._
|
||||
|
||||
_SemVer comparisons without a pre-release value will skip pre-release versions.
|
||||
For example, `>1.2.3` will skip pre-releases when looking at a list of values
|
||||
while `>1.2.3-alpha.1` will evaluate pre-releases._
|
||||
|
||||
## Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
These look like:
|
||||
|
||||
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
|
||||
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
|
||||
|
||||
## Wildcards In Comparisons
|
||||
|
||||
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
|
||||
for all comparison operators. When used on the `=` operator it falls
|
||||
back to the pack level comparison (see tilde below). For example,
|
||||
|
||||
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||
* `>= 1.2.x` is equivalent to `>= 1.2.0`
|
||||
* `<= 2.x` is equivalent to `<= 3`
|
||||
* `*` is equivalent to `>= 0.0.0`
|
||||
|
||||
## Tilde Range Comparisons (Patch)
|
||||
|
||||
The tilde (`~`) comparison operator is for patch level ranges when a minor
|
||||
version is specified and major level changes when the minor number is missing.
|
||||
For example,
|
||||
|
||||
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
|
||||
* `~1` is equivalent to `>= 1, < 2`
|
||||
* `~2.3` is equivalent to `>= 2.3, < 2.4`
|
||||
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
|
||||
* `~1.x` is equivalent to `>= 1, < 2`
|
||||
|
||||
## Caret Range Comparisons (Major)
|
||||
|
||||
The caret (`^`) comparison operator is for major level changes. This is useful
|
||||
when comparisons of API versions as a major change is API breaking. For example,
|
||||
|
||||
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
|
||||
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
|
||||
* `^2.3` is equivalent to `>= 2.3, < 3`
|
||||
* `^2.x` is equivalent to `>= 2.0.0, < 3`
|
||||
|
55
vendor/github.com/Masterminds/sprig/docs/string_slice.md
generated
vendored
55
vendor/github.com/Masterminds/sprig/docs/string_slice.md
generated
vendored
@ -1,55 +0,0 @@
|
||||
# String Slice Functions
|
||||
|
||||
These function operate on or generate slices of strings. In Go, a slice is a
|
||||
growable array. In Sprig, it's a special case of a `list`.
|
||||
|
||||
## join
|
||||
|
||||
Join a list of strings into a single string, with the given separator.
|
||||
|
||||
```
|
||||
list "hello" "world" | join "_"
|
||||
```
|
||||
|
||||
The above will produce `hello_world`
|
||||
|
||||
`join` will try to convert non-strings to a string value:
|
||||
|
||||
```
|
||||
list 1 2 3 | join "+"
|
||||
```
|
||||
|
||||
The above will produce `1+2+3`
|
||||
|
||||
## splitList and split
|
||||
|
||||
Split a string into a list of strings:
|
||||
|
||||
```
|
||||
splitList "$" "foo$bar$baz"
|
||||
```
|
||||
|
||||
The above will return `[foo bar baz]`
|
||||
|
||||
The older `split` function splits a string into a `dict`. It is designed to make
|
||||
it easy to use template dot notation for accessing members:
|
||||
|
||||
```
|
||||
$a := split "$" "foo$bar$baz"
|
||||
```
|
||||
|
||||
The above produces a map with index keys. `{_0: foo, _1: bar, _2: baz}`
|
||||
|
||||
```
|
||||
$a._0
|
||||
```
|
||||
|
||||
The above produces `foo`
|
||||
|
||||
## sortAlpha
|
||||
|
||||
The `sortAlpha` function sorts a list of strings into alphabetical (lexicographical)
|
||||
order.
|
||||
|
||||
It does _not_ sort in place, but returns a sorted copy of the list, in keeping
|
||||
with the immutability of lists.
|
322
vendor/github.com/Masterminds/sprig/docs/strings.md
generated
vendored
322
vendor/github.com/Masterminds/sprig/docs/strings.md
generated
vendored
@ -1,322 +0,0 @@
|
||||
# String Functions
|
||||
|
||||
Sprig has a number of string manipulation functions.
|
||||
|
||||
## trim
|
||||
|
||||
The `trim` function removes space from either side of a string:
|
||||
|
||||
```
|
||||
trim " hello "
|
||||
```
|
||||
|
||||
The above produces `hello`
|
||||
|
||||
## trimAll
|
||||
|
||||
Remove given characters from the front or back of a string:
|
||||
|
||||
```
|
||||
trimAll "$" "$5.00"
|
||||
```
|
||||
|
||||
The above returns `5.00` (as a string).
|
||||
|
||||
## trimSuffix
|
||||
|
||||
Trim just the suffix from a string:
|
||||
|
||||
```
|
||||
trimSuffix "-" "hello-"
|
||||
```
|
||||
|
||||
The above returns `hello`
|
||||
|
||||
## upper
|
||||
|
||||
Convert the entire string to uppercase:
|
||||
|
||||
```
|
||||
upper "hello"
|
||||
```
|
||||
|
||||
The above returns `HELLO`
|
||||
|
||||
## lower
|
||||
|
||||
Convert the entire string to lowercase:
|
||||
|
||||
```
|
||||
lower "HELLO"
|
||||
```
|
||||
|
||||
The above returns `hello`
|
||||
|
||||
## title
|
||||
|
||||
Convert to title case:
|
||||
|
||||
```
|
||||
title "hello world"
|
||||
```
|
||||
|
||||
The above returns `Hello World`
|
||||
|
||||
## untitle
|
||||
|
||||
Remove title casing. `untitle "Hello World"` produces `hello world`.
|
||||
|
||||
## repeat
|
||||
|
||||
Repeat a string multiple times:
|
||||
|
||||
```
|
||||
repeat 3 "hello"
|
||||
```
|
||||
|
||||
The above returns `hellohellohello`
|
||||
|
||||
## substr
|
||||
|
||||
Get a substring from a string. It takes three parameters:
|
||||
|
||||
- start (int)
|
||||
- length (int)
|
||||
- string (string)
|
||||
|
||||
```
|
||||
substr 0 5 "hello world"
|
||||
```
|
||||
|
||||
The above returns `hello`
|
||||
|
||||
## nospace
|
||||
|
||||
Remove all whitespace from a string.
|
||||
|
||||
```
|
||||
nospace "hello w o r l d"
|
||||
```
|
||||
|
||||
The above returns `helloworld`
|
||||
|
||||
## trunc
|
||||
|
||||
Truncate a string (and add no suffix)
|
||||
|
||||
```
|
||||
trunc 5 "hello world"
|
||||
```
|
||||
|
||||
The above produces `hello`.
|
||||
|
||||
## abbrev
|
||||
|
||||
Truncate a string with ellipses (`...`)
|
||||
|
||||
Parameters:
|
||||
- max length
|
||||
- the string
|
||||
|
||||
```
|
||||
abbrev 5 "hello world"
|
||||
```
|
||||
|
||||
The above returns `he...`, since it counts the width of the ellipses against the
|
||||
maximum length.
|
||||
|
||||
## abbrevboth
|
||||
|
||||
Abbreviate both sides:
|
||||
|
||||
```
|
||||
abbrevboth 5 10 "1234 5678 9123"
|
||||
```
|
||||
|
||||
the above produces `...5678...`
|
||||
|
||||
It takes:
|
||||
|
||||
- left offset
|
||||
- max length
|
||||
- the string
|
||||
|
||||
## initials
|
||||
|
||||
Given multiple words, take the first letter of each word and combine.
|
||||
|
||||
```
|
||||
initials "First Try"
|
||||
```
|
||||
|
||||
The above returns `FT`
|
||||
|
||||
## randAlphaNum, randAlpha, randNumeric, and randAscii
|
||||
|
||||
These four functions generate random strings, but with different base character
|
||||
sets:
|
||||
|
||||
- `randAlphaNum` uses `0-9a-zA-Z`
|
||||
- `randAlpha` uses `a-zA-Z`
|
||||
- `randNumeric` uses `0-9`
|
||||
- `randAscii` uses all printable ASCII characters
|
||||
|
||||
Each of them takes one parameter: the integer length of the string.
|
||||
|
||||
```
|
||||
randNumeric 3
|
||||
```
|
||||
|
||||
The above will produce a random string with three digits.
|
||||
|
||||
## wrap
|
||||
|
||||
Wrap text at a given column count:
|
||||
|
||||
```
|
||||
wrap 80 $someText
|
||||
```
|
||||
|
||||
The above will wrap the string in `$someText` at 80 columns.
|
||||
|
||||
## wrapWith
|
||||
|
||||
`wrapWith` works as `wrap`, but lets you specify the string to wrap with.
|
||||
(`wrap` uses `\n`)
|
||||
|
||||
```
|
||||
wrapWith 5 "\t" "Hello World"
|
||||
```
|
||||
|
||||
The above produces `hello world` (where the whitespace is an ASCII tab
|
||||
character)
|
||||
|
||||
## contains
|
||||
|
||||
Test to see if one string is contained inside of another:
|
||||
|
||||
```
|
||||
contains "cat" "catch"
|
||||
```
|
||||
|
||||
The above returns `true` because `catch` contains `cat`.
|
||||
|
||||
## hasPrefix and hasSuffix
|
||||
|
||||
The `hasPrefix` and `hasSuffix` functions test whether a string has a given
|
||||
prefix or suffix:
|
||||
|
||||
```
|
||||
hasPrefix "cat" "catch"
|
||||
```
|
||||
|
||||
The above returns `true` because `catch` has the prefix `cat`.
|
||||
|
||||
## quote and squote
|
||||
|
||||
These functions wrap a string in double quotes (`quote`) or single quotes
|
||||
(`squote`).
|
||||
|
||||
## cat
|
||||
|
||||
The `cat` function concatenates multiple strings together into one, separating
|
||||
them with spaces:
|
||||
|
||||
```
|
||||
cat "hello" "beautiful" "world"
|
||||
```
|
||||
|
||||
The above produces `hello beautiful world`
|
||||
|
||||
## indent
|
||||
|
||||
The `indent` function indents every line in a given string to the specified
|
||||
indent width. This is useful when aligning multi-line strings:
|
||||
|
||||
```
|
||||
indent 4 $lots_of_text
|
||||
```
|
||||
|
||||
The above will indent every line of text by 4 space characters.
|
||||
|
||||
## replace
|
||||
|
||||
Perform simple string replacement.
|
||||
|
||||
It takes three arguments:
|
||||
|
||||
- string to replace
|
||||
- string to replace with
|
||||
- source string
|
||||
|
||||
```
|
||||
"I Am Henry VIII" | replace " " "-"
|
||||
```
|
||||
|
||||
The above will produce `I-Am-Henry-VIII`
|
||||
|
||||
## plural
|
||||
|
||||
Pluralize a string.
|
||||
|
||||
```
|
||||
len $fish | plural "one anchovy" "many anchovies"
|
||||
```
|
||||
|
||||
In the above, if the length of the string is 1, the first argument will be
|
||||
printed (`one anchovy`). Otherwise, the second argument will be printed
|
||||
(`many anchovies`).
|
||||
|
||||
The arguments are:
|
||||
|
||||
- singular string
|
||||
- plural string
|
||||
- length integer
|
||||
|
||||
NOTE: Sprig does not currently support languages with more complex pluralization
|
||||
rules. And `0` is considered a plural because the English language treats it
|
||||
as such (`zero anchovies`). The Sprig developers are working on a solution for
|
||||
better internationalization.
|
||||
|
||||
## snakecase
|
||||
|
||||
Convert string from camelCase to snake_case.
|
||||
|
||||
Introduced in 2.12.0.
|
||||
|
||||
```
|
||||
snakecase "FirstName"
|
||||
```
|
||||
|
||||
This above will produce `first_name`.
|
||||
|
||||
## camelcase
|
||||
|
||||
Convert string from snake_case to CamelCase
|
||||
|
||||
Introduced in 2.12.0.
|
||||
|
||||
```
|
||||
camelcase "http_server"
|
||||
```
|
||||
|
||||
This above will produce `HttpServer`.
|
||||
|
||||
## shuffle
|
||||
|
||||
Shuffle a string.
|
||||
|
||||
Introduced in 2.12.0.
|
||||
|
||||
|
||||
```
|
||||
shuffle "hello"
|
||||
```
|
||||
|
||||
The above will randomize the letters in `hello`, perhaps producing `oelhl`.
|
||||
|
||||
## See Also...
|
||||
|
||||
The [Conversion Functions](conversion.html) contain functions for converting
|
||||
strings. The [String Slice Functions](string_slice.html) contains functions
|
||||
for working with an array of strings.
|
9
vendor/github.com/Masterminds/sprig/docs/uuid.md
generated
vendored
9
vendor/github.com/Masterminds/sprig/docs/uuid.md
generated
vendored
@ -1,9 +0,0 @@
|
||||
# UUID Functions
|
||||
|
||||
Sprig can generate UUID v4 universally unique IDs.
|
||||
|
||||
```
|
||||
uuidv4
|
||||
```
|
||||
|
||||
The above returns a new UUID of the v4 (randomly generated) type.
|
25
vendor/github.com/Masterminds/sprig/example_test.go
generated
vendored
25
vendor/github.com/Masterminds/sprig/example_test.go
generated
vendored
@ -1,25 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
// Set up variables and template.
|
||||
vars := map[string]interface{}{"Name": " John Jacob Jingleheimer Schmidt "}
|
||||
tpl := `Hello {{.Name | trim | lower}}`
|
||||
|
||||
// Get the Sprig function map.
|
||||
fmap := TxtFuncMap()
|
||||
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
|
||||
|
||||
err := t.Execute(os.Stdout, vars)
|
||||
if err != nil {
|
||||
fmt.Printf("Error during template execution: %s", err)
|
||||
return
|
||||
}
|
||||
// Output:
|
||||
// Hello john jacob jingleheimer schmidt
|
||||
}
|
16
vendor/github.com/Masterminds/sprig/flow_control_test.go
generated
vendored
16
vendor/github.com/Masterminds/sprig/flow_control_test.go
generated
vendored
@ -1,16 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFail(t *testing.T) {
|
||||
const msg = "This is an error!"
|
||||
tpl := fmt.Sprintf(`{{fail "%s"}}`, msg)
|
||||
_, err := runRaw(tpl, nil)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), msg)
|
||||
}
|
19
vendor/github.com/Masterminds/sprig/functions.go
generated
vendored
19
vendor/github.com/Masterminds/sprig/functions.go
generated
vendored
@ -98,6 +98,8 @@ var genericMap = map[string]interface{}{
|
||||
"htmlDateInZone": htmlDateInZone,
|
||||
"dateInZone": dateInZone,
|
||||
"dateModify": dateModify,
|
||||
"ago": dateAgo,
|
||||
"toDate": toDate,
|
||||
|
||||
// Strings
|
||||
"abbrev": abbrev,
|
||||
@ -137,6 +139,7 @@ var genericMap = map[string]interface{}{
|
||||
"squote": squote,
|
||||
"cat": cat,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"replace": replace,
|
||||
"plural": plural,
|
||||
"sha256sum": sha256sum,
|
||||
@ -183,6 +186,9 @@ var genericMap = map[string]interface{}{
|
||||
"biggest": max,
|
||||
"max": max,
|
||||
"min": min,
|
||||
"ceil": ceil,
|
||||
"floor": floor,
|
||||
"round": round,
|
||||
|
||||
// string slices. Note that we reverse the order b/c that's better
|
||||
// for template processing.
|
||||
@ -243,11 +249,14 @@ var genericMap = map[string]interface{}{
|
||||
"reverse": reverse,
|
||||
"uniq": uniq,
|
||||
"without": without,
|
||||
"has": func(needle interface{}, haystack []interface{}) bool { return inList(haystack, needle) },
|
||||
"has": has,
|
||||
|
||||
// Crypto:
|
||||
"genPrivateKey": generatePrivateKey,
|
||||
"derivePassword": derivePassword,
|
||||
"genCA": generateCertificateAuthority,
|
||||
"genSelfSignedCert": generateSelfSignedCertificate,
|
||||
"genSignedCert": generateSignedCertificate,
|
||||
|
||||
// UUIDs:
|
||||
"uuidv4": uuidv4,
|
||||
@ -258,4 +267,12 @@ var genericMap = map[string]interface{}{
|
||||
|
||||
// Flow Control:
|
||||
"fail": func(msg string) (string, error) { return "", errors.New(msg) },
|
||||
|
||||
// Regex
|
||||
"regexMatch": regexMatch,
|
||||
"regexFindAll": regexFindAll,
|
||||
"regexFind": regexFind,
|
||||
"regexReplaceAll": regexReplaceAll,
|
||||
"regexReplaceAllLiteral": regexReplaceAllLiteral,
|
||||
"regexSplit": regexSplit,
|
||||
}
|
||||
|
108
vendor/github.com/Masterminds/sprig/functions_test.go
generated
vendored
108
vendor/github.com/Masterminds/sprig/functions_test.go
generated
vendored
@ -1,108 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"testing"
|
||||
"text/template"
|
||||
|
||||
"github.com/aokoli/goutils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEnv(t *testing.T) {
|
||||
os.Setenv("FOO", "bar")
|
||||
tpl := `{{env "FOO"}}`
|
||||
if err := runt(tpl, "bar"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpandEnv(t *testing.T) {
|
||||
os.Setenv("FOO", "bar")
|
||||
tpl := `{{expandenv "Hello $FOO"}}`
|
||||
if err := runt(tpl, "Hello bar"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBase(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ base "foo/bar" }}`, "bar"))
|
||||
}
|
||||
|
||||
func TestDir(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ dir "foo/bar/baz" }}`, "foo/bar"))
|
||||
}
|
||||
|
||||
func TestIsAbs(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ isAbs "/foo" }}`, "true"))
|
||||
assert.NoError(t, runt(`{{ isAbs "foo" }}`, "false"))
|
||||
}
|
||||
|
||||
func TestClean(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ clean "/foo/../foo/../bar" }}`, "/bar"))
|
||||
}
|
||||
|
||||
func TestExt(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ ext "/foo/bar/baz.txt" }}`, ".txt"))
|
||||
}
|
||||
|
||||
func TestSnakeCase(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ snakecase "FirstName" }}`, "first_name"))
|
||||
assert.NoError(t, runt(`{{ snakecase "HTTPServer" }}`, "http_server"))
|
||||
assert.NoError(t, runt(`{{ snakecase "NoHTTPS" }}`, "no_https"))
|
||||
assert.NoError(t, runt(`{{ snakecase "GO_PATH" }}`, "go_path"))
|
||||
assert.NoError(t, runt(`{{ snakecase "GO PATH" }}`, "go_path"))
|
||||
assert.NoError(t, runt(`{{ snakecase "GO-PATH" }}`, "go_path"))
|
||||
}
|
||||
|
||||
func TestCamelCase(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ camelcase "http_server" }}`, "HttpServer"))
|
||||
assert.NoError(t, runt(`{{ camelcase "_camel_case" }}`, "_CamelCase"))
|
||||
assert.NoError(t, runt(`{{ camelcase "no_https" }}`, "NoHttps"))
|
||||
assert.NoError(t, runt(`{{ camelcase "_complex__case_" }}`, "_Complex_Case_"))
|
||||
assert.NoError(t, runt(`{{ camelcase "all" }}`, "All"))
|
||||
}
|
||||
|
||||
func TestShuffle(t *testing.T) {
|
||||
goutils.RANDOM = rand.New(rand.NewSource(1))
|
||||
// Because we're using a random number generator, we need these to go in
|
||||
// a predictable sequence:
|
||||
assert.NoError(t, runt(`{{ shuffle "Hello World" }}`, "rldo HWlloe"))
|
||||
}
|
||||
|
||||
// runt runs a template and checks that the output exactly matches the expected string.
|
||||
func runt(tpl, expect string) error {
|
||||
return runtv(tpl, expect, map[string]string{})
|
||||
}
|
||||
|
||||
// runtv takes a template, and expected return, and values for substitution.
|
||||
//
|
||||
// It runs the template and verifies that the output is an exact match.
|
||||
func runtv(tpl, expect string, vars interface{}) error {
|
||||
fmap := TxtFuncMap()
|
||||
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
|
||||
var b bytes.Buffer
|
||||
err := t.Execute(&b, vars)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if expect != b.String() {
|
||||
return fmt.Errorf("Expected '%s', got '%s'", expect, b.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// runRaw runs a template with the given variables and returns the result.
|
||||
func runRaw(tpl string, vars interface{}) (string, error) {
|
||||
fmap := TxtFuncMap()
|
||||
t := template.Must(template.New("test").Funcs(fmap).Parse(tpl))
|
||||
var b bytes.Buffer
|
||||
err := t.Execute(&b, vars)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return b.String(), nil
|
||||
}
|
228
vendor/github.com/Masterminds/sprig/list.go
generated
vendored
228
vendor/github.com/Masterminds/sprig/list.go
generated
vendored
@ -1,50 +1,135 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Reflection is used in these functions so that slices and arrays of strings,
|
||||
// ints, and other types not implementing []interface{} can be worked with.
|
||||
// For example, this is useful if you need to work on the output of regexs.
|
||||
|
||||
func list(v ...interface{}) []interface{} {
|
||||
return v
|
||||
}
|
||||
|
||||
func push(list []interface{}, v interface{}) []interface{} {
|
||||
return append(list, v)
|
||||
func push(list interface{}, v interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
nl := make([]interface{}, l)
|
||||
for i := 0; i < l; i++ {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
func prepend(list []interface{}, v interface{}) []interface{} {
|
||||
return append([]interface{}{v}, list...)
|
||||
return append(nl, v)
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot push on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func last(list []interface{}) interface{} {
|
||||
l := len(list)
|
||||
func prepend(list interface{}, v interface{}) []interface{} {
|
||||
//return append([]interface{}{v}, list...)
|
||||
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
nl := make([]interface{}, l)
|
||||
for i := 0; i < l; i++ {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return append([]interface{}{v}, nl...)
|
||||
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot prepend on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func last(list interface{}) interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
return list[l-1]
|
||||
|
||||
return l2.Index(l - 1).Interface()
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find last on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func first(list []interface{}) interface{} {
|
||||
if len(list) == 0 {
|
||||
func first(list interface{}) interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
return list[0]
|
||||
|
||||
return l2.Index(0).Interface()
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find first on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func rest(list []interface{}) []interface{} {
|
||||
if len(list) == 0 {
|
||||
return list
|
||||
}
|
||||
return list[1:]
|
||||
}
|
||||
func rest(list interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
func initial(list []interface{}) []interface{} {
|
||||
l := len(list)
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return list
|
||||
return nil
|
||||
}
|
||||
|
||||
nl := make([]interface{}, l-1)
|
||||
for i := 1; i < l; i++ {
|
||||
nl[i-1] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find rest on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func initial(list interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
nl := make([]interface{}, l-1)
|
||||
for i := 0; i < l-1; i++ {
|
||||
nl[i] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
return nl
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find initial on type %s", tp))
|
||||
}
|
||||
return list[:l-1]
|
||||
}
|
||||
|
||||
func sortAlpha(list interface{}) []string {
|
||||
@ -59,34 +144,67 @@ func sortAlpha(list interface{}) []string {
|
||||
return []string{strval(list)}
|
||||
}
|
||||
|
||||
func reverse(v []interface{}) []interface{} {
|
||||
// We do not sort in place because the incomming array should not be altered.
|
||||
l := len(v)
|
||||
c := make([]interface{}, l)
|
||||
func reverse(v interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(v).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(v)
|
||||
|
||||
l := l2.Len()
|
||||
// We do not sort in place because the incoming array should not be altered.
|
||||
nl := make([]interface{}, l)
|
||||
for i := 0; i < l; i++ {
|
||||
c[l-i-1] = v[i]
|
||||
}
|
||||
return c
|
||||
nl[l-i-1] = l2.Index(i).Interface()
|
||||
}
|
||||
|
||||
func compact(list []interface{}) []interface{} {
|
||||
res := []interface{}{}
|
||||
for _, item := range list {
|
||||
return nl
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find reverse on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func compact(list interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
nl := []interface{}{}
|
||||
var item interface{}
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
if !empty(item) {
|
||||
res = append(res, item)
|
||||
nl = append(nl, item)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func uniq(list []interface{}) []interface{} {
|
||||
return nl
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot compact on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func uniq(list interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
dest := []interface{}{}
|
||||
for _, item := range list {
|
||||
var item interface{}
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
if !inList(dest, item) {
|
||||
dest = append(dest, item)
|
||||
}
|
||||
}
|
||||
|
||||
return dest
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find uniq on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func inList(haystack []interface{}, needle interface{}) bool {
|
||||
@ -98,12 +216,44 @@ func inList(haystack []interface{}, needle interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func without(list []interface{}, omit ...interface{}) []interface{} {
|
||||
func without(list interface{}, omit ...interface{}) []interface{} {
|
||||
tp := reflect.TypeOf(list).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(list)
|
||||
|
||||
l := l2.Len()
|
||||
res := []interface{}{}
|
||||
for _, i := range list {
|
||||
if !inList(omit, i) {
|
||||
res = append(res, i)
|
||||
var item interface{}
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
if !inList(omit, item) {
|
||||
res = append(res, item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find without on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
||||
func has(needle interface{}, haystack interface{}) bool {
|
||||
tp := reflect.TypeOf(haystack).Kind()
|
||||
switch tp {
|
||||
case reflect.Slice, reflect.Array:
|
||||
l2 := reflect.ValueOf(haystack)
|
||||
var item interface{}
|
||||
l := l2.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
item = l2.Index(i).Interface()
|
||||
if reflect.DeepEqual(needle, item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
default:
|
||||
panic(fmt.Sprintf("Cannot find has on type %s", tp))
|
||||
}
|
||||
}
|
||||
|
135
vendor/github.com/Masterminds/sprig/list_test.go
generated
vendored
135
vendor/github.com/Masterminds/sprig/list_test.go
generated
vendored
@ -1,135 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestTuple(t *testing.T) {
|
||||
tpl := `{{$t := tuple 1 "a" "foo"}}{{index $t 2}}{{index $t 0 }}{{index $t 1}}`
|
||||
if err := runt(tpl, "foo1a"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
tpl := `{{$t := list 1 "a" "foo"}}{{index $t 2}}{{index $t 0 }}{{index $t 1}}`
|
||||
if err := runt(tpl, "foo1a"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPush(t *testing.T) {
|
||||
// Named `append` in the function map
|
||||
tests := map[string]string{
|
||||
`{{ $t := tuple 1 2 3 }}{{ append $t 4 | len }}`: "4",
|
||||
`{{ $t := tuple 1 2 3 4 }}{{ append $t 5 | join "-" }}`: "1-2-3-4-5",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
func TestPrepend(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ $t := tuple 1 2 3 }}{{ prepend $t 0 | len }}`: "4",
|
||||
`{{ $t := tuple 1 2 3 4 }}{{ prepend $t 0 | join "-" }}`: "0-1-2-3-4",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirst(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 | first }}`: "1",
|
||||
`{{ list | first }}`: "<no value>",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
func TestLast(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 | last }}`: "3",
|
||||
`{{ list | last }}`: "<no value>",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitial(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 | initial | len }}`: "2",
|
||||
`{{ list 1 2 3 | initial | last }}`: "2",
|
||||
`{{ list 1 2 3 | initial | first }}`: "1",
|
||||
`{{ list | initial }}`: "[]",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRest(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 | rest | len }}`: "2",
|
||||
`{{ list 1 2 3 | rest | last }}`: "3",
|
||||
`{{ list 1 2 3 | rest | first }}`: "2",
|
||||
`{{ list | rest }}`: "[]",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 | reverse | first }}`: "3",
|
||||
`{{ list 1 2 3 | reverse | rest | first }}`: "2",
|
||||
`{{ list 1 2 3 | reverse | last }}`: "1",
|
||||
`{{ list 1 2 3 4 | reverse }}`: "[4 3 2 1]",
|
||||
`{{ list 1 | reverse }}`: "[1]",
|
||||
`{{ list | reverse }}`: "[]",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUniq(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 4 | uniq }}`: `[1 2 3 4]`,
|
||||
`{{ list "a" "b" "c" "d" | uniq }}`: `[a b c d]`,
|
||||
`{{ list 1 1 1 1 2 2 2 2 | uniq }}`: `[1 2]`,
|
||||
`{{ list "foo" 1 1 1 1 "foo" "foo" | uniq }}`: `[foo 1]`,
|
||||
`{{ list | uniq }}`: `[]`,
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithout(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ without (list 1 2 3 4) 1 }}`: `[2 3 4]`,
|
||||
`{{ without (list "a" "b" "c" "d") "a" }}`: `[b c d]`,
|
||||
`{{ without (list 1 1 1 1 2) 1 }}`: `[2]`,
|
||||
`{{ without (list) 1 }}`: `[]`,
|
||||
`{{ without (list 1 2 3) }}`: `[1 2 3]`,
|
||||
`{{ without list }}`: `[]`,
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestHas(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ list 1 2 3 | has 1 }}`: `true`,
|
||||
`{{ list 1 2 3 | has 4 }}`: `false`,
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
30
vendor/github.com/Masterminds/sprig/numeric.go
generated
vendored
30
vendor/github.com/Masterminds/sprig/numeric.go
generated
vendored
@ -127,3 +127,33 @@ func untilStep(start, stop, step int) []int {
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func floor(a interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
return math.Floor(aa)
|
||||
}
|
||||
|
||||
func ceil(a interface{}) float64 {
|
||||
aa := toFloat64(a)
|
||||
return math.Ceil(aa)
|
||||
}
|
||||
|
||||
func round(a interface{}, p int, r_opt ...float64) float64 {
|
||||
roundOn := .5
|
||||
if len(r_opt) > 0 {
|
||||
roundOn = r_opt[0]
|
||||
}
|
||||
val := toFloat64(a)
|
||||
places := toFloat64(p)
|
||||
|
||||
var round float64
|
||||
pow := math.Pow(10, places)
|
||||
digit := pow * val
|
||||
_, div := math.Modf(digit)
|
||||
if div >= roundOn {
|
||||
round = math.Ceil(digit)
|
||||
} else {
|
||||
round = math.Floor(digit)
|
||||
}
|
||||
return round / pow
|
||||
}
|
180
vendor/github.com/Masterminds/sprig/numeric_test.go
generated
vendored
180
vendor/github.com/Masterminds/sprig/numeric_test.go
generated
vendored
@ -1,180 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUntil(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{range $i, $e := until 5}}{{$i}}{{$e}}{{end}}`: "0011223344",
|
||||
`{{range $i, $e := until -5}}{{$i}}{{$e}} {{end}}`: "00 1-1 2-2 3-3 4-4 ",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestUntilStep(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{range $i, $e := untilStep 0 5 1}}{{$i}}{{$e}}{{end}}`: "0011223344",
|
||||
`{{range $i, $e := untilStep 3 6 1}}{{$i}}{{$e}}{{end}}`: "031425",
|
||||
`{{range $i, $e := untilStep 0 -10 -2}}{{$i}}{{$e}} {{end}}`: "00 1-2 2-4 3-6 4-8 ",
|
||||
`{{range $i, $e := untilStep 3 0 1}}{{$i}}{{$e}}{{end}}`: "",
|
||||
`{{range $i, $e := untilStep 3 99 0}}{{$i}}{{$e}}{{end}}`: "",
|
||||
`{{range $i, $e := untilStep 3 99 -1}}{{$i}}{{$e}}{{end}}`: "",
|
||||
`{{range $i, $e := untilStep 3 0 0}}{{$i}}{{$e}}{{end}}`: "",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func TestBiggest(t *testing.T) {
|
||||
tpl := `{{ biggest 1 2 3 345 5 6 7}}`
|
||||
if err := runt(tpl, `345`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
tpl = `{{ max 345}}`
|
||||
if err := runt(tpl, `345`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestMin(t *testing.T) {
|
||||
tpl := `{{ min 1 2 3 345 5 6 7}}`
|
||||
if err := runt(tpl, `1`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
tpl = `{{ min 345}}`
|
||||
if err := runt(tpl, `345`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToFloat64(t *testing.T) {
|
||||
target := float64(102)
|
||||
if target != toFloat64(int8(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toFloat64(int(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toFloat64(int32(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toFloat64(int16(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toFloat64(int64(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toFloat64("102") {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if 0 != toFloat64("frankie") {
|
||||
t.Errorf("Expected 0")
|
||||
}
|
||||
if target != toFloat64(uint16(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toFloat64(uint64(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if 102.1234 != toFloat64(float64(102.1234)) {
|
||||
t.Errorf("Expected 102.1234")
|
||||
}
|
||||
if 1 != toFloat64(true) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
}
|
||||
func TestToInt64(t *testing.T) {
|
||||
target := int64(102)
|
||||
if target != toInt64(int8(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64(int(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64(int32(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64(int16(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64(int64(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64("102") {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if 0 != toInt64("frankie") {
|
||||
t.Errorf("Expected 0")
|
||||
}
|
||||
if target != toInt64(uint16(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64(uint64(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt64(float64(102.1234)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if 1 != toInt64(true) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToInt(t *testing.T) {
|
||||
target := int(102)
|
||||
if target != toInt(int8(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt(int(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt(int32(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt(int16(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt(int64(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt("102") {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if 0 != toInt("frankie") {
|
||||
t.Errorf("Expected 0")
|
||||
}
|
||||
if target != toInt(uint16(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt(uint64(102)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if target != toInt(float64(102.1234)) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
if 1 != toInt(true) {
|
||||
t.Errorf("Expected 102")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
tpl := `{{ 3 | add 1 2}}`
|
||||
if err := runt(tpl, `6`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMul(t *testing.T) {
|
||||
tpl := `{{ 1 | mul "2" 3 "4"}}`
|
||||
if err := runt(tpl, `24`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
73
vendor/github.com/Masterminds/sprig/reflect_test.go
generated
vendored
73
vendor/github.com/Masterminds/sprig/reflect_test.go
generated
vendored
@ -1,73 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type fixtureTO struct {
|
||||
Name, Value string
|
||||
}
|
||||
|
||||
func TestTypeOf(t *testing.T) {
|
||||
f := &fixtureTO{"hello", "world"}
|
||||
tpl := `{{typeOf .}}`
|
||||
if err := runtv(tpl, "*sprig.fixtureTO", f); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKindOf(t *testing.T) {
|
||||
tpl := `{{kindOf .}}`
|
||||
|
||||
f := fixtureTO{"hello", "world"}
|
||||
if err := runtv(tpl, "struct", f); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f2 := []string{"hello"}
|
||||
if err := runtv(tpl, "slice", f2); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
var f3 *fixtureTO = nil
|
||||
if err := runtv(tpl, "ptr", f3); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeIs(t *testing.T) {
|
||||
f := &fixtureTO{"hello", "world"}
|
||||
tpl := `{{if typeIs "*sprig.fixtureTO" .}}t{{else}}f{{end}}`
|
||||
if err := runtv(tpl, "t", f); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
f2 := "hello"
|
||||
if err := runtv(tpl, "f", f2); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestTypeIsLike(t *testing.T) {
|
||||
f := "foo"
|
||||
tpl := `{{if typeIsLike "string" .}}t{{else}}f{{end}}`
|
||||
if err := runtv(tpl, "t", f); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// Now make a pointer. Should still match.
|
||||
f2 := &f
|
||||
if err := runtv(tpl, "t", f2); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestKindIs(t *testing.T) {
|
||||
f := &fixtureTO{"hello", "world"}
|
||||
tpl := `{{if kindIs "ptr" .}}t{{else}}f{{end}}`
|
||||
if err := runtv(tpl, "t", f); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
f2 := "hello"
|
||||
if err := runtv(tpl, "f", f2); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
35
vendor/github.com/Masterminds/sprig/regex.go
generated
vendored
Normal file
35
vendor/github.com/Masterminds/sprig/regex.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func regexMatch(regex string, s string) bool {
|
||||
match, _ := regexp.MatchString(regex, s)
|
||||
return match
|
||||
}
|
||||
|
||||
func regexFindAll(regex string, s string, n int) []string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.FindAllString(s, n)
|
||||
}
|
||||
|
||||
func regexFind(regex string, s string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.FindString(s)
|
||||
}
|
||||
|
||||
func regexReplaceAll(regex string, s string, repl string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.ReplaceAllString(s, repl)
|
||||
}
|
||||
|
||||
func regexReplaceAllLiteral(regex string, s string, repl string) string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.ReplaceAllLiteralString(s, repl)
|
||||
}
|
||||
|
||||
func regexSplit(regex string, s string, n int) []string {
|
||||
r := regexp.MustCompile(regex)
|
||||
return r.Split(s, n)
|
||||
}
|
31
vendor/github.com/Masterminds/sprig/semver_test.go
generated
vendored
31
vendor/github.com/Masterminds/sprig/semver_test.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSemverCompare(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ semverCompare "1.2.3" "1.2.3" }}`: `true`,
|
||||
`{{ semverCompare "^1.2.0" "1.2.3" }}`: `true`,
|
||||
`{{ semverCompare "^1.2.0" "2.2.3" }}`: `false`,
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSemver(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{ $s := semver "1.2.3-beta.1+c0ff33" }}{{ $s.Prerelease }}`: "beta.1",
|
||||
`{{ $s := semver "1.2.3-beta.1+c0ff33" }}{{ $s.Major}}`: "1",
|
||||
`{{ semver "1.2.3" | (semver "1.2.3").Compare }}`: `0`,
|
||||
`{{ semver "1.2.3" | (semver "1.3.3").Compare }}`: `1`,
|
||||
`{{ semver "1.4.3" | (semver "1.2.3").Compare }}`: `-1`,
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
4
vendor/github.com/Masterminds/sprig/strings.go
generated
vendored
4
vendor/github.com/Masterminds/sprig/strings.go
generated
vendored
@ -106,6 +106,10 @@ func indent(spaces int, v string) string {
|
||||
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||
}
|
||||
|
||||
func nindent(spaces int, v string) string {
|
||||
return "\n" + indent(spaces, v)
|
||||
}
|
||||
|
||||
func replace(old, new, src string) string {
|
||||
return strings.Replace(src, old, new, -1)
|
||||
}
|
||||
|
220
vendor/github.com/Masterminds/sprig/strings_test.go
generated
vendored
220
vendor/github.com/Masterminds/sprig/strings_test.go
generated
vendored
@ -1,220 +0,0 @@
|
||||
package sprig
|
||||
|
||||
import (
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/aokoli/goutils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSubstr(t *testing.T) {
|
||||
tpl := `{{"fooo" | substr 0 3 }}`
|
||||
if err := runt(tpl, "foo"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrunc(t *testing.T) {
|
||||
tpl := `{{ "foooooo" | trunc 3 }}`
|
||||
if err := runt(tpl, "foo"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuote(t *testing.T) {
|
||||
tpl := `{{quote "a" "b" "c"}}`
|
||||
if err := runt(tpl, `"a" "b" "c"`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{quote "\"a\"" "b" "c"}}`
|
||||
if err := runt(tpl, `"\"a\"" "b" "c"`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{quote 1 2 3 }}`
|
||||
if err := runt(tpl, `"1" "2" "3"`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestSquote(t *testing.T) {
|
||||
tpl := `{{squote "a" "b" "c"}}`
|
||||
if err := runt(tpl, `'a' 'b' 'c'`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{squote 1 2 3 }}`
|
||||
if err := runt(tpl, `'1' '2' '3'`); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
// Mainly, we're just verifying the paramater order swap.
|
||||
tests := []string{
|
||||
`{{if contains "cat" "fair catch"}}1{{end}}`,
|
||||
`{{if hasPrefix "cat" "catch"}}1{{end}}`,
|
||||
`{{if hasSuffix "cat" "ducat"}}1{{end}}`,
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if err := runt(tt, "1"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrim(t *testing.T) {
|
||||
tests := []string{
|
||||
`{{trim " 5.00 "}}`,
|
||||
`{{trimAll "$" "$5.00$"}}`,
|
||||
`{{trimPrefix "$" "$5.00"}}`,
|
||||
`{{trimSuffix "$" "5.00$"}}`,
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if err := runt(tt, "5.00"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplit(t *testing.T) {
|
||||
tpl := `{{$v := "foo$bar$baz" | split "$"}}{{$v._0}}`
|
||||
if err := runt(tpl, "foo"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToString(t *testing.T) {
|
||||
tpl := `{{ toString 1 | kindOf }}`
|
||||
assert.NoError(t, runt(tpl, "string"))
|
||||
}
|
||||
|
||||
func TestToStrings(t *testing.T) {
|
||||
tpl := `{{ $s := list 1 2 3 | toStrings }}{{ index $s 1 | kindOf }}`
|
||||
assert.NoError(t, runt(tpl, "string"))
|
||||
}
|
||||
|
||||
func TestJoin(t *testing.T) {
|
||||
assert.NoError(t, runt(`{{ tuple "a" "b" "c" | join "-" }}`, "a-b-c"))
|
||||
assert.NoError(t, runt(`{{ tuple 1 2 3 | join "-" }}`, "1-2-3"))
|
||||
assert.NoError(t, runtv(`{{ join "-" .V }}`, "a-b-c", map[string]interface{}{"V": []string{"a", "b", "c"}}))
|
||||
assert.NoError(t, runtv(`{{ join "-" .V }}`, "abc", map[string]interface{}{"V": "abc"}))
|
||||
assert.NoError(t, runtv(`{{ join "-" .V }}`, "1-2-3", map[string]interface{}{"V": []int{1, 2, 3}}))
|
||||
}
|
||||
|
||||
func TestSortAlpha(t *testing.T) {
|
||||
// Named `append` in the function map
|
||||
tests := map[string]string{
|
||||
`{{ list "c" "a" "b" | sortAlpha | join "" }}`: "abc",
|
||||
`{{ list 2 1 4 3 | sortAlpha | join "" }}`: "1234",
|
||||
}
|
||||
for tpl, expect := range tests {
|
||||
assert.NoError(t, runt(tpl, expect))
|
||||
}
|
||||
}
|
||||
func TestBase64EncodeDecode(t *testing.T) {
|
||||
magicWord := "coffee"
|
||||
expect := base64.StdEncoding.EncodeToString([]byte(magicWord))
|
||||
|
||||
if expect == magicWord {
|
||||
t.Fatal("Encoder doesn't work.")
|
||||
}
|
||||
|
||||
tpl := `{{b64enc "coffee"}}`
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = fmt.Sprintf("{{b64dec %q}}", expect)
|
||||
if err := runt(tpl, magicWord); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestBase32EncodeDecode(t *testing.T) {
|
||||
magicWord := "coffee"
|
||||
expect := base32.StdEncoding.EncodeToString([]byte(magicWord))
|
||||
|
||||
if expect == magicWord {
|
||||
t.Fatal("Encoder doesn't work.")
|
||||
}
|
||||
|
||||
tpl := `{{b32enc "coffee"}}`
|
||||
if err := runt(tpl, expect); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = fmt.Sprintf("{{b32dec %q}}", expect)
|
||||
if err := runt(tpl, magicWord); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoutils(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
`{{abbrev 5 "hello world"}}`: "he...",
|
||||
`{{abbrevboth 5 10 "1234 5678 9123"}}`: "...5678...",
|
||||
`{{nospace "h e l l o "}}`: "hello",
|
||||
`{{untitle "First Try"}}`: "first try", //https://youtu.be/44-RsrF_V_w
|
||||
`{{initials "First Try"}}`: "FT",
|
||||
`{{wrap 5 "Hello World"}}`: "Hello\nWorld",
|
||||
`{{wrapWith 5 "\t" "Hello World"}}`: "Hello\tWorld",
|
||||
}
|
||||
for k, v := range tests {
|
||||
t.Log(k)
|
||||
if err := runt(k, v); err != nil {
|
||||
t.Errorf("Error on tpl %s: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandom(t *testing.T) {
|
||||
// One of the things I love about Go:
|
||||
goutils.RANDOM = rand.New(rand.NewSource(1))
|
||||
|
||||
// Because we're using a random number generator, we need these to go in
|
||||
// a predictable sequence:
|
||||
if err := runt(`{{randAlphaNum 5}}`, "9bzRv"); err != nil {
|
||||
t.Errorf("Error on tpl %s: %s", err)
|
||||
}
|
||||
if err := runt(`{{randAlpha 5}}`, "VjwGe"); err != nil {
|
||||
t.Errorf("Error on tpl %s: %s", err)
|
||||
}
|
||||
if err := runt(`{{randAscii 5}}`, "1KA5p"); err != nil {
|
||||
t.Errorf("Error on tpl %s: %s", err)
|
||||
}
|
||||
if err := runt(`{{randNumeric 5}}`, "26018"); err != nil {
|
||||
t.Errorf("Error on tpl %s: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCat(t *testing.T) {
|
||||
tpl := `{{$b := "b"}}{{"c" | cat "a" $b}}`
|
||||
if err := runt(tpl, "a b c"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndent(t *testing.T) {
|
||||
tpl := `{{indent 4 "a\nb\nc"}}`
|
||||
if err := runt(tpl, " a\n b\n c"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReplace(t *testing.T) {
|
||||
tpl := `{{"I Am Henry VIII" | replace " " "-"}}`
|
||||
if err := runt(tpl, "I-Am-Henry-VIII"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlural(t *testing.T) {
|
||||
tpl := `{{$num := len "two"}}{{$num}} {{$num | plural "1 char" "chars"}}`
|
||||
if err := runt(tpl, "3 chars"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
tpl = `{{len "t" | plural "cheese" "%d chars"}}`
|
||||
if err := runt(tpl, "cheese"); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
18
vendor/github.com/aokoli/goutils/.travis.yml
generated
vendored
18
vendor/github.com/aokoli/goutils/.travis.yml
generated
vendored
@ -1,18 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/06e3328629952dabe3e0
|
||||
on_success: change # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: never # options: [always|never|change] default: always
|
78
vendor/github.com/aokoli/goutils/randomstringutils_test.go
generated
vendored
78
vendor/github.com/aokoli/goutils/randomstringutils_test.go
generated
vendored
@ -1,78 +0,0 @@
|
||||
package goutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// ****************************** TESTS ********************************************
|
||||
|
||||
func TestRandomSeed(t *testing.T) {
|
||||
|
||||
// count, start, end, letters, numbers := 5, 0, 0, true, true
|
||||
random := rand.New(rand.NewSource(10))
|
||||
out := "3ip9v"
|
||||
|
||||
// Test 1: Simulating RandomAlphaNumeric(count int)
|
||||
if x, _ := RandomSeed(5, 0, 0, true, true, nil, random); x != out {
|
||||
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, true, true, nil, random, x, out)
|
||||
}
|
||||
|
||||
// Test 2: Simulating RandomAlphabetic(count int)
|
||||
out = "MBrbj"
|
||||
|
||||
if x, _ := RandomSeed(5, 0, 0, true, false, nil, random); x != out {
|
||||
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, true, false, nil, random, x, out)
|
||||
}
|
||||
|
||||
// Test 3: Simulating RandomNumeric(count int)
|
||||
out = "88935"
|
||||
|
||||
if x, _ := RandomSeed(5, 0, 0, false, true, nil, random); x != out {
|
||||
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, false, true, nil, random, x, out)
|
||||
}
|
||||
|
||||
// Test 4: Simulating RandomAscii(count int)
|
||||
out = "H_I;E"
|
||||
|
||||
if x, _ := RandomSeed(5, 32, 127, false, false, nil, random); x != out {
|
||||
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 32, 127, false, false, nil, random, x, out)
|
||||
}
|
||||
|
||||
// Test 5: Simulating RandomSeed(...) with custom chars
|
||||
chars := []rune{'1', '2', '3', 'a', 'b', 'c'}
|
||||
out = "2b2ca"
|
||||
|
||||
if x, _ := RandomSeed(5, 0, 0, false, false, chars, random); x != out {
|
||||
t.Errorf("RandomSeed(%v, %v, %v, %v, %v, %v, %v) = %v, want %v", 5, 0, 0, false, false, chars, random, x, out)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ****************************** EXAMPLES ********************************************
|
||||
|
||||
func ExampleRandomSeed() {
|
||||
|
||||
var seed int64 = 10 // If you change this seed #, the random sequence below will change
|
||||
random := rand.New(rand.NewSource(seed))
|
||||
chars := []rune{'1', '2', '3', 'a', 'b', 'c'}
|
||||
|
||||
rand1, _ := RandomSeed(5, 0, 0, true, true, nil, random) // RandomAlphaNumeric (Alphabets and numbers possible)
|
||||
rand2, _ := RandomSeed(5, 0, 0, true, false, nil, random) // RandomAlphabetic (Only alphabets)
|
||||
rand3, _ := RandomSeed(5, 0, 0, false, true, nil, random) // RandomNumeric (Only numbers)
|
||||
rand4, _ := RandomSeed(5, 32, 127, false, false, nil, random) // RandomAscii (Alphabets, numbers, and other ASCII chars)
|
||||
rand5, _ := RandomSeed(5, 0, 0, true, true, chars, random) // RandomSeed with custom characters
|
||||
|
||||
fmt.Println(rand1)
|
||||
fmt.Println(rand2)
|
||||
fmt.Println(rand3)
|
||||
fmt.Println(rand4)
|
||||
fmt.Println(rand5)
|
||||
// Output:
|
||||
// 3ip9v
|
||||
// MBrbj
|
||||
// 88935
|
||||
// H_I;E
|
||||
// 2b2ca
|
||||
}
|
309
vendor/github.com/aokoli/goutils/stringutils_test.go
generated
vendored
309
vendor/github.com/aokoli/goutils/stringutils_test.go
generated
vendored
@ -1,309 +0,0 @@
|
||||
package goutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// ****************************** TESTS ********************************************
|
||||
|
||||
func TestAbbreviate(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
in := "abcdefg"
|
||||
out := "abc..."
|
||||
maxWidth := 6
|
||||
|
||||
if x, _ := Abbreviate(in, maxWidth); x != out {
|
||||
t.Errorf("Abbreviate(%v, %v) = %v, want %v", in, maxWidth, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
out = "abcdefg"
|
||||
maxWidth = 7
|
||||
|
||||
if x, _ := Abbreviate(in, maxWidth); x != out {
|
||||
t.Errorf("Abbreviate(%v, %v) = %v, want %v", in, maxWidth, x, out)
|
||||
}
|
||||
|
||||
// Test 3
|
||||
out = "a..."
|
||||
maxWidth = 4
|
||||
|
||||
if x, _ := Abbreviate(in, maxWidth); x != out {
|
||||
t.Errorf("Abbreviate(%v, %v) = %v, want %v", in, maxWidth, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAbbreviateFull(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
in := "abcdefghijklmno"
|
||||
out := "abcdefg..."
|
||||
offset := -1
|
||||
maxWidth := 10
|
||||
|
||||
if x, _ := AbbreviateFull(in, offset, maxWidth); x != out {
|
||||
t.Errorf("AbbreviateFull(%v, %v, %v) = %v, want %v", in, offset, maxWidth, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
out = "...fghi..."
|
||||
offset = 5
|
||||
maxWidth = 10
|
||||
|
||||
if x, _ := AbbreviateFull(in, offset, maxWidth); x != out {
|
||||
t.Errorf("AbbreviateFull(%v, %v, %v) = %v, want %v", in, offset, maxWidth, x, out)
|
||||
}
|
||||
|
||||
// Test 3
|
||||
out = "...ijklmno"
|
||||
offset = 12
|
||||
maxWidth = 10
|
||||
|
||||
if x, _ := AbbreviateFull(in, offset, maxWidth); x != out {
|
||||
t.Errorf("AbbreviateFull(%v, %v, %v) = %v, want %v", in, offset, maxWidth, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexOf(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
str := "abcafgka"
|
||||
sub := "a"
|
||||
start := 0
|
||||
out := 0
|
||||
|
||||
if x := IndexOf(str, sub, start); x != out {
|
||||
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
start = 1
|
||||
out = 3
|
||||
|
||||
if x := IndexOf(str, sub, start); x != out {
|
||||
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
|
||||
}
|
||||
|
||||
// Test 3
|
||||
start = 4
|
||||
out = 7
|
||||
|
||||
if x := IndexOf(str, sub, start); x != out {
|
||||
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
|
||||
}
|
||||
|
||||
// Test 4
|
||||
sub = "z"
|
||||
out = -1
|
||||
|
||||
if x := IndexOf(str, sub, start); x != out {
|
||||
t.Errorf("IndexOf(%v, %v, %v) = %v, want %v", str, sub, start, x, out)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsBlank(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
str := ""
|
||||
out := true
|
||||
|
||||
if x := IsBlank(str); x != out {
|
||||
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
str = " "
|
||||
out = true
|
||||
|
||||
if x := IsBlank(str); x != out {
|
||||
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
|
||||
}
|
||||
|
||||
// Test 3
|
||||
str = " abc "
|
||||
out = false
|
||||
|
||||
if x := IsBlank(str); x != out {
|
||||
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteWhiteSpace(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
str := " a b c "
|
||||
out := "abc"
|
||||
|
||||
if x := DeleteWhiteSpace(str); x != out {
|
||||
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
str = " "
|
||||
out = ""
|
||||
|
||||
if x := DeleteWhiteSpace(str); x != out {
|
||||
t.Errorf("IndexOf(%v) = %v, want %v", str, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexOfDifference(t *testing.T) {
|
||||
|
||||
str1 := "abc"
|
||||
str2 := "a_c"
|
||||
out := 1
|
||||
|
||||
if x := IndexOfDifference(str1, str2); x != out {
|
||||
t.Errorf("IndexOfDifference(%v, %v) = %v, want %v", str1, str2, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************** EXAMPLES ********************************************
|
||||
|
||||
func ExampleAbbreviate() {
|
||||
|
||||
str := "abcdefg"
|
||||
out1, _ := Abbreviate(str, 6)
|
||||
out2, _ := Abbreviate(str, 7)
|
||||
out3, _ := Abbreviate(str, 8)
|
||||
out4, _ := Abbreviate(str, 4)
|
||||
_, err1 := Abbreviate(str, 3)
|
||||
|
||||
fmt.Println(out1)
|
||||
fmt.Println(out2)
|
||||
fmt.Println(out3)
|
||||
fmt.Println(out4)
|
||||
fmt.Println(err1)
|
||||
// Output:
|
||||
// abc...
|
||||
// abcdefg
|
||||
// abcdefg
|
||||
// a...
|
||||
// stringutils illegal argument: Minimum abbreviation width is 4
|
||||
}
|
||||
|
||||
func ExampleAbbreviateFull() {
|
||||
|
||||
str := "abcdefghijklmno"
|
||||
str2 := "abcdefghij"
|
||||
out1, _ := AbbreviateFull(str, -1, 10)
|
||||
out2, _ := AbbreviateFull(str, 0, 10)
|
||||
out3, _ := AbbreviateFull(str, 1, 10)
|
||||
out4, _ := AbbreviateFull(str, 4, 10)
|
||||
out5, _ := AbbreviateFull(str, 5, 10)
|
||||
out6, _ := AbbreviateFull(str, 6, 10)
|
||||
out7, _ := AbbreviateFull(str, 8, 10)
|
||||
out8, _ := AbbreviateFull(str, 10, 10)
|
||||
out9, _ := AbbreviateFull(str, 12, 10)
|
||||
_, err1 := AbbreviateFull(str2, 0, 3)
|
||||
_, err2 := AbbreviateFull(str2, 5, 6)
|
||||
|
||||
fmt.Println(out1)
|
||||
fmt.Println(out2)
|
||||
fmt.Println(out3)
|
||||
fmt.Println(out4)
|
||||
fmt.Println(out5)
|
||||
fmt.Println(out6)
|
||||
fmt.Println(out7)
|
||||
fmt.Println(out8)
|
||||
fmt.Println(out9)
|
||||
fmt.Println(err1)
|
||||
fmt.Println(err2)
|
||||
// Output:
|
||||
// abcdefg...
|
||||
// abcdefg...
|
||||
// abcdefg...
|
||||
// abcdefg...
|
||||
// ...fghi...
|
||||
// ...ghij...
|
||||
// ...ijklmno
|
||||
// ...ijklmno
|
||||
// ...ijklmno
|
||||
// stringutils illegal argument: Minimum abbreviation width is 4
|
||||
// stringutils illegal argument: Minimum abbreviation width with offset is 7
|
||||
}
|
||||
|
||||
func ExampleIsBlank() {
|
||||
|
||||
out1 := IsBlank("")
|
||||
out2 := IsBlank(" ")
|
||||
out3 := IsBlank("bob")
|
||||
out4 := IsBlank(" bob ")
|
||||
|
||||
fmt.Println(out1)
|
||||
fmt.Println(out2)
|
||||
fmt.Println(out3)
|
||||
fmt.Println(out4)
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleDeleteWhiteSpace() {
|
||||
|
||||
out1 := DeleteWhiteSpace(" ")
|
||||
out2 := DeleteWhiteSpace("bob")
|
||||
out3 := DeleteWhiteSpace("bob ")
|
||||
out4 := DeleteWhiteSpace(" b o b ")
|
||||
|
||||
fmt.Println(out1)
|
||||
fmt.Println(out2)
|
||||
fmt.Println(out3)
|
||||
fmt.Println(out4)
|
||||
// Output:
|
||||
//
|
||||
// bob
|
||||
// bob
|
||||
// bob
|
||||
}
|
||||
|
||||
func ExampleIndexOf() {
|
||||
|
||||
str := "abcdefgehije"
|
||||
out1 := IndexOf(str, "e", 0)
|
||||
out2 := IndexOf(str, "e", 5)
|
||||
out3 := IndexOf(str, "e", 8)
|
||||
out4 := IndexOf(str, "eh", 0)
|
||||
out5 := IndexOf(str, "eh", 22)
|
||||
out6 := IndexOf(str, "z", 0)
|
||||
out7 := IndexOf(str, "", 0)
|
||||
|
||||
fmt.Println(out1)
|
||||
fmt.Println(out2)
|
||||
fmt.Println(out3)
|
||||
fmt.Println(out4)
|
||||
fmt.Println(out5)
|
||||
fmt.Println(out6)
|
||||
fmt.Println(out7)
|
||||
// Output:
|
||||
// 4
|
||||
// 7
|
||||
// 11
|
||||
// 7
|
||||
// -1
|
||||
// -1
|
||||
// -1
|
||||
}
|
||||
|
||||
func ExampleIndexOfDifference() {
|
||||
|
||||
out1 := IndexOfDifference("abc", "abc")
|
||||
out2 := IndexOfDifference("ab", "abxyz")
|
||||
out3 := IndexOfDifference("", "abc")
|
||||
out4 := IndexOfDifference("abcde", "abxyz")
|
||||
|
||||
fmt.Println(out1)
|
||||
fmt.Println(out2)
|
||||
fmt.Println(out3)
|
||||
fmt.Println(out4)
|
||||
// Output:
|
||||
// -1
|
||||
// 2
|
||||
// 0
|
||||
// 2
|
||||
}
|
225
vendor/github.com/aokoli/goutils/wordutils_test.go
generated
vendored
225
vendor/github.com/aokoli/goutils/wordutils_test.go
generated
vendored
@ -1,225 +0,0 @@
|
||||
package goutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// ****************************** TESTS ********************************************
|
||||
|
||||
func TestWrapNormalWord(t *testing.T) {
|
||||
|
||||
in := "Bob Manuel Bob Manuel"
|
||||
out := "Bob Manuel\nBob Manuel"
|
||||
wrapLength := 10
|
||||
|
||||
if x := Wrap(in, wrapLength); x != out {
|
||||
t.Errorf("Wrap(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrapCustomLongWordFalse(t *testing.T) {
|
||||
|
||||
in := "BobManuelBob Bob"
|
||||
out := "BobManuelBob<br\\>Bob"
|
||||
wrapLength := 10
|
||||
newLineStr := "<br\\>"
|
||||
wrapLongWords := false
|
||||
|
||||
if x := WrapCustom(in, wrapLength, newLineStr, wrapLongWords); x != out {
|
||||
t.Errorf("Wrap(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrapCustomLongWordTrue(t *testing.T) {
|
||||
|
||||
in := "BobManuelBob Bob"
|
||||
out := "BobManuelB<br\\>ob Bob"
|
||||
wrapLength := 10
|
||||
newLineStr := "<br\\>"
|
||||
wrapLongWords := true
|
||||
|
||||
if x := WrapCustom(in, wrapLength, newLineStr, wrapLongWords); x != out {
|
||||
t.Errorf("WrapCustom(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapitalize(t *testing.T) {
|
||||
|
||||
// Test 1: Checks if function works with 1 parameter, and default whitespace delimiter
|
||||
in := "test is going.well.thank.you.for inquiring"
|
||||
out := "Test Is Going.well.thank.you.for Inquiring"
|
||||
|
||||
if x := Capitalize(in); x != out {
|
||||
t.Errorf("Capitalize(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
|
||||
// Test 2: Checks if function works with both parameters, with param 2 containing whitespace and '.'
|
||||
out = "Test Is Going.Well.Thank.You.For Inquiring"
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
if x := Capitalize(in, delimiters...); x != out {
|
||||
t.Errorf("Capitalize(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapitalizeFully(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
in := "tEsT iS goiNG.wELL.tHaNk.yOU.for inqUIrING"
|
||||
out := "Test Is Going.well.thank.you.for Inquiring"
|
||||
|
||||
if x := CapitalizeFully(in); x != out {
|
||||
t.Errorf("CapitalizeFully(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
out = "Test Is Going.Well.Thank.You.For Inquiring"
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
if x := CapitalizeFully(in, delimiters...); x != out {
|
||||
t.Errorf("CapitalizeFully(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUncapitalize(t *testing.T) {
|
||||
|
||||
// Test 1: Checks if function works with 1 parameter, and default whitespace delimiter
|
||||
in := "This Is A.Test"
|
||||
out := "this is a.Test"
|
||||
|
||||
if x := Uncapitalize(in); x != out {
|
||||
t.Errorf("Uncapitalize(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
|
||||
// Test 2: Checks if function works with both parameters, with param 2 containing whitespace and '.'
|
||||
out = "this is a.test"
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
if x := Uncapitalize(in, delimiters...); x != out {
|
||||
t.Errorf("Uncapitalize(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwapCase(t *testing.T) {
|
||||
|
||||
in := "This Is A.Test"
|
||||
out := "tHIS iS a.tEST"
|
||||
|
||||
if x := SwapCase(in); x != out {
|
||||
t.Errorf("SwapCase(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitials(t *testing.T) {
|
||||
|
||||
// Test 1
|
||||
in := "John Doe.Ray"
|
||||
out := "JD"
|
||||
|
||||
if x := Initials(in); x != out {
|
||||
t.Errorf("Initials(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
|
||||
// Test 2
|
||||
out = "JDR"
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
if x := Initials(in, delimiters...); x != out {
|
||||
t.Errorf("Initials(%v) = %v, want %v", in, x, out)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ****************************** EXAMPLES ********************************************
|
||||
|
||||
func ExampleWrap() {
|
||||
|
||||
in := "Bob Manuel Bob Manuel"
|
||||
wrapLength := 10
|
||||
|
||||
fmt.Println(Wrap(in, wrapLength))
|
||||
// Output:
|
||||
// Bob Manuel
|
||||
// Bob Manuel
|
||||
}
|
||||
|
||||
func ExampleWrapCustom_1() {
|
||||
|
||||
in := "BobManuelBob Bob"
|
||||
wrapLength := 10
|
||||
newLineStr := "<br\\>"
|
||||
wrapLongWords := false
|
||||
|
||||
fmt.Println(WrapCustom(in, wrapLength, newLineStr, wrapLongWords))
|
||||
// Output:
|
||||
// BobManuelBob<br\>Bob
|
||||
}
|
||||
|
||||
func ExampleWrapCustom_2() {
|
||||
|
||||
in := "BobManuelBob Bob"
|
||||
wrapLength := 10
|
||||
newLineStr := "<br\\>"
|
||||
wrapLongWords := true
|
||||
|
||||
fmt.Println(WrapCustom(in, wrapLength, newLineStr, wrapLongWords))
|
||||
// Output:
|
||||
// BobManuelB<br\>ob Bob
|
||||
}
|
||||
|
||||
func ExampleCapitalize() {
|
||||
|
||||
in := "test is going.well.thank.you.for inquiring" // Compare input to CapitalizeFully example
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
fmt.Println(Capitalize(in))
|
||||
fmt.Println(Capitalize(in, delimiters...))
|
||||
// Output:
|
||||
// Test Is Going.well.thank.you.for Inquiring
|
||||
// Test Is Going.Well.Thank.You.For Inquiring
|
||||
}
|
||||
|
||||
func ExampleCapitalizeFully() {
|
||||
|
||||
in := "tEsT iS goiNG.wELL.tHaNk.yOU.for inqUIrING" // Notice scattered capitalization
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
fmt.Println(CapitalizeFully(in))
|
||||
fmt.Println(CapitalizeFully(in, delimiters...))
|
||||
// Output:
|
||||
// Test Is Going.well.thank.you.for Inquiring
|
||||
// Test Is Going.Well.Thank.You.For Inquiring
|
||||
}
|
||||
|
||||
func ExampleUncapitalize() {
|
||||
|
||||
in := "This Is A.Test"
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
fmt.Println(Uncapitalize(in))
|
||||
fmt.Println(Uncapitalize(in, delimiters...))
|
||||
// Output:
|
||||
// this is a.Test
|
||||
// this is a.test
|
||||
}
|
||||
|
||||
func ExampleSwapCase() {
|
||||
|
||||
in := "This Is A.Test"
|
||||
fmt.Println(SwapCase(in))
|
||||
// Output:
|
||||
// tHIS iS a.tEST
|
||||
}
|
||||
|
||||
func ExampleInitials() {
|
||||
|
||||
in := "John Doe.Ray"
|
||||
delimiters := []rune{' ', '.'}
|
||||
|
||||
fmt.Println(Initials(in))
|
||||
fmt.Println(Initials(in, delimiters...))
|
||||
// Output:
|
||||
// JD
|
||||
// JDR
|
||||
}
|
4
vendor/github.com/dgrijalva/jwt-go/.gitignore
generated
vendored
4
vendor/github.com/dgrijalva/jwt-go/.gitignore
generated
vendored
@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
bin
|
||||
|
||||
|
8
vendor/github.com/dgrijalva/jwt-go/.travis.yml
generated
vendored
8
vendor/github.com/dgrijalva/jwt-go/.travis.yml
generated
vendored
@ -1,8 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- tip
|
13
vendor/github.com/dgrijalva/jwt-go/cmd/jwt/README.md
generated
vendored
13
vendor/github.com/dgrijalva/jwt-go/cmd/jwt/README.md
generated
vendored
@ -1,13 +0,0 @@
|
||||
`jwt` command-line tool
|
||||
=======================
|
||||
|
||||
This is a simple tool to sign, verify and show JSON Web Tokens from
|
||||
the command line.
|
||||
|
||||
The following will create and sign a token, then verify it and output the original claims:
|
||||
|
||||
echo {\"foo\":\"bar\"} | bin/jwt -key test/sample_key -alg RS256 -sign - | bin/jwt -key test/sample_key.pub -verify -
|
||||
|
||||
To simply display a token, use:
|
||||
|
||||
echo $JWT | jwt -show -
|
245
vendor/github.com/dgrijalva/jwt-go/cmd/jwt/app.go
generated
vendored
245
vendor/github.com/dgrijalva/jwt-go/cmd/jwt/app.go
generated
vendored
@ -1,245 +0,0 @@
|
||||
// A useful example app. You can use this to debug your tokens on the command line.
|
||||
// This is also a great place to look at how you might use this library.
|
||||
//
|
||||
// Example usage:
|
||||
// The following will create and sign a token, then verify it and output the original claims.
|
||||
// echo {\"foo\":\"bar\"} | bin/jwt -key test/sample_key -alg RS256 -sign - | bin/jwt -key test/sample_key.pub -verify -
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
var (
|
||||
// Options
|
||||
flagAlg = flag.String("alg", "", "signing algorithm identifier")
|
||||
flagKey = flag.String("key", "", "path to key file or '-' to read from stdin")
|
||||
flagCompact = flag.Bool("compact", false, "output compact JSON")
|
||||
flagDebug = flag.Bool("debug", false, "print out all kinds of debug data")
|
||||
|
||||
// Modes - exactly one of these is required
|
||||
flagSign = flag.String("sign", "", "path to claims object to sign or '-' to read from stdin")
|
||||
flagVerify = flag.String("verify", "", "path to JWT token to verify or '-' to read from stdin")
|
||||
flagShow = flag.String("show", "", "path to JWT file or '-' to read from stdin")
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Usage message if you ask for -help or if you mess up inputs.
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " One of the following flags is required: sign, verify\n")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
// Parse command line options
|
||||
flag.Parse()
|
||||
|
||||
// Do the thing. If something goes wrong, print error to stderr
|
||||
// and exit with a non-zero status code
|
||||
if err := start(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out which thing to do and then do that
|
||||
func start() error {
|
||||
if *flagSign != "" {
|
||||
return signToken()
|
||||
} else if *flagVerify != "" {
|
||||
return verifyToken()
|
||||
} else if *flagShow != "" {
|
||||
return showToken()
|
||||
} else {
|
||||
flag.Usage()
|
||||
return fmt.Errorf("None of the required flags are present. What do you want me to do?")
|
||||
}
|
||||
}
|
||||
|
||||
// Helper func: Read input from specified file or stdin
|
||||
func loadData(p string) ([]byte, error) {
|
||||
if p == "" {
|
||||
return nil, fmt.Errorf("No path specified")
|
||||
}
|
||||
|
||||
var rdr io.Reader
|
||||
if p == "-" {
|
||||
rdr = os.Stdin
|
||||
} else {
|
||||
if f, err := os.Open(p); err == nil {
|
||||
rdr = f
|
||||
defer f.Close()
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ioutil.ReadAll(rdr)
|
||||
}
|
||||
|
||||
// Print a json object in accordance with the prophecy (or the command line options)
|
||||
func printJSON(j interface{}) error {
|
||||
var out []byte
|
||||
var err error
|
||||
|
||||
if *flagCompact == false {
|
||||
out, err = json.MarshalIndent(j, "", " ")
|
||||
} else {
|
||||
out, err = json.Marshal(j)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
fmt.Println(string(out))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Verify a token and output the claims. This is a great example
|
||||
// of how to verify and view a token.
|
||||
func verifyToken() error {
|
||||
// get the token
|
||||
tokData, err := loadData(*flagVerify)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read token: %v", err)
|
||||
}
|
||||
|
||||
// trim possible whitespace from token
|
||||
tokData = regexp.MustCompile(`\s*$`).ReplaceAll(tokData, []byte{})
|
||||
if *flagDebug {
|
||||
fmt.Fprintf(os.Stderr, "Token len: %v bytes\n", len(tokData))
|
||||
}
|
||||
|
||||
// Parse the token. Load the key from command line option
|
||||
token, err := jwt.Parse(string(tokData), func(t *jwt.Token) (interface{}, error) {
|
||||
data, err := loadData(*flagKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isEs() {
|
||||
return jwt.ParseECPublicKeyFromPEM(data)
|
||||
}
|
||||
return data, nil
|
||||
})
|
||||
|
||||
// Print some debug data
|
||||
if *flagDebug && token != nil {
|
||||
fmt.Fprintf(os.Stderr, "Header:\n%v\n", token.Header)
|
||||
fmt.Fprintf(os.Stderr, "Claims:\n%v\n", token.Claims)
|
||||
}
|
||||
|
||||
// Print an error if we can't parse for some reason
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't parse token: %v", err)
|
||||
}
|
||||
|
||||
// Is token invalid?
|
||||
if !token.Valid {
|
||||
return fmt.Errorf("Token is invalid")
|
||||
}
|
||||
|
||||
// Print the token details
|
||||
if err := printJSON(token.Claims); err != nil {
|
||||
return fmt.Errorf("Failed to output claims: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create, sign, and output a token. This is a great, simple example of
|
||||
// how to use this library to create and sign a token.
|
||||
func signToken() error {
|
||||
// get the token data from command line arguments
|
||||
tokData, err := loadData(*flagSign)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read token: %v", err)
|
||||
} else if *flagDebug {
|
||||
fmt.Fprintf(os.Stderr, "Token: %v bytes", len(tokData))
|
||||
}
|
||||
|
||||
// parse the JSON of the claims
|
||||
var claims jwt.MapClaims
|
||||
if err := json.Unmarshal(tokData, &claims); err != nil {
|
||||
return fmt.Errorf("Couldn't parse claims JSON: %v", err)
|
||||
}
|
||||
|
||||
// get the key
|
||||
var key interface{}
|
||||
key, err = loadData(*flagKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read key: %v", err)
|
||||
}
|
||||
|
||||
// get the signing alg
|
||||
alg := jwt.GetSigningMethod(*flagAlg)
|
||||
if alg == nil {
|
||||
return fmt.Errorf("Couldn't find signing method: %v", *flagAlg)
|
||||
}
|
||||
|
||||
// create a new token
|
||||
token := jwt.NewWithClaims(alg, claims)
|
||||
|
||||
if isEs() {
|
||||
if k, ok := key.([]byte); !ok {
|
||||
return fmt.Errorf("Couldn't convert key data to key")
|
||||
} else {
|
||||
key, err = jwt.ParseECPrivateKeyFromPEM(k)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if out, err := token.SignedString(key); err == nil {
|
||||
fmt.Println(out)
|
||||
} else {
|
||||
return fmt.Errorf("Error signing token: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// showToken pretty-prints the token on the command line.
|
||||
func showToken() error {
|
||||
// get the token
|
||||
tokData, err := loadData(*flagShow)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read token: %v", err)
|
||||
}
|
||||
|
||||
// trim possible whitespace from token
|
||||
tokData = regexp.MustCompile(`\s*$`).ReplaceAll(tokData, []byte{})
|
||||
if *flagDebug {
|
||||
fmt.Fprintf(os.Stderr, "Token len: %v bytes\n", len(tokData))
|
||||
}
|
||||
|
||||
token, err := jwt.Parse(string(tokData), nil)
|
||||
if token == nil {
|
||||
return fmt.Errorf("malformed token: %v", err)
|
||||
}
|
||||
|
||||
// Print the token details
|
||||
fmt.Println("Header:")
|
||||
if err := printJSON(token.Header); err != nil {
|
||||
return fmt.Errorf("Failed to output header: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("Claims:")
|
||||
if err := printJSON(token.Claims); err != nil {
|
||||
return fmt.Errorf("Failed to output claims: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isEs() bool {
|
||||
return strings.HasPrefix(*flagAlg, "ES")
|
||||
}
|
100
vendor/github.com/dgrijalva/jwt-go/ecdsa_test.go
generated
vendored
100
vendor/github.com/dgrijalva/jwt-go/ecdsa_test.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
var ecdsaTestData = []struct {
|
||||
name string
|
||||
keys map[string]string
|
||||
tokenString string
|
||||
alg string
|
||||
claims map[string]interface{}
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
"Basic ES256",
|
||||
map[string]string{"private": "test/ec256-private.pem", "public": "test/ec256-public.pem"},
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJmb28iOiJiYXIifQ.feG39E-bn8HXAKhzDZq7yEAPWYDhZlwTn3sePJnU9VrGMmwdXAIEyoOnrjreYlVM_Z4N13eK9-TmMTWyfKJtHQ",
|
||||
"ES256",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic ES384",
|
||||
map[string]string{"private": "test/ec384-private.pem", "public": "test/ec384-public.pem"},
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzM4NCJ9.eyJmb28iOiJiYXIifQ.ngAfKMbJUh0WWubSIYe5GMsA-aHNKwFbJk_wq3lq23aPp8H2anb1rRILIzVR0gUf4a8WzDtrzmiikuPWyCS6CN4-PwdgTk-5nehC7JXqlaBZU05p3toM3nWCwm_LXcld",
|
||||
"ES384",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic ES512",
|
||||
map[string]string{"private": "test/ec512-private.pem", "public": "test/ec512-public.pem"},
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJmb28iOiJiYXIifQ.AAU0TvGQOcdg2OvrwY73NHKgfk26UDekh9Prz-L_iWuTBIBqOFCWwwLsRiHB1JOddfKAls5do1W0jR_F30JpVd-6AJeTjGKA4C1A1H6gIKwRY0o_tFDIydZCl_lMBMeG5VNFAjO86-WCSKwc3hqaGkq1MugPRq_qrF9AVbuEB4JPLyL5",
|
||||
"ES512",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"basic ES256 invalid: foo => bar",
|
||||
map[string]string{"private": "test/ec256-private.pem", "public": "test/ec256-public.pem"},
|
||||
"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.MEQCIHoSJnmGlPaVQDqacx_2XlXEhhqtWceVopjomc2PJLtdAiAUTeGPoNYxZw0z8mgOnnIcjoxRuNDVZvybRZF3wR1l8W",
|
||||
"ES256",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestECDSAVerify(t *testing.T) {
|
||||
for _, data := range ecdsaTestData {
|
||||
var err error
|
||||
|
||||
key, _ := ioutil.ReadFile(data.keys["public"])
|
||||
|
||||
var ecdsaKey *ecdsa.PublicKey
|
||||
if ecdsaKey, err = jwt.ParseECPublicKeyFromPEM(key); err != nil {
|
||||
t.Errorf("Unable to parse ECDSA public key: %v", err)
|
||||
}
|
||||
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
err = method.Verify(strings.Join(parts[0:2], "."), parts[2], ecdsaKey)
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
|
||||
}
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid key passed validation", data.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestECDSASign(t *testing.T) {
|
||||
for _, data := range ecdsaTestData {
|
||||
var err error
|
||||
key, _ := ioutil.ReadFile(data.keys["private"])
|
||||
|
||||
var ecdsaKey *ecdsa.PrivateKey
|
||||
if ecdsaKey, err = jwt.ParseECPrivateKeyFromPEM(key); err != nil {
|
||||
t.Errorf("Unable to parse ECDSA private key: %v", err)
|
||||
}
|
||||
|
||||
if data.valid {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
sig, err := method.Sign(strings.Join(parts[0:2], "."), ecdsaKey)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error signing token: %v", data.name, err)
|
||||
}
|
||||
if sig == parts[2] {
|
||||
t.Errorf("[%v] Identical signatures\nbefore:\n%v\nafter:\n%v", data.name, parts[2], sig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
114
vendor/github.com/dgrijalva/jwt-go/example_test.go
generated
vendored
114
vendor/github.com/dgrijalva/jwt-go/example_test.go
generated
vendored
@ -1,114 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Example (atypical) using the StandardClaims type by itself to parse a token.
|
||||
// The StandardClaims type is designed to be embedded into your custom types
|
||||
// to provide standard validation features. You can use it alone, but there's
|
||||
// no way to retrieve other fields after parsing.
|
||||
// See the CustomClaimsType example for intended usage.
|
||||
func ExampleNewWithClaims_standardClaims() {
|
||||
mySigningKey := []byte("AllYourBase")
|
||||
|
||||
// Create the Claims
|
||||
claims := &jwt.StandardClaims{
|
||||
ExpiresAt: 15000,
|
||||
Issuer: "test",
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
ss, err := token.SignedString(mySigningKey)
|
||||
fmt.Printf("%v %v", ss, err)
|
||||
//Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.QsODzZu3lUZMVdhbO76u3Jv02iYCvEHcYVUI1kOWEU0 <nil>
|
||||
}
|
||||
|
||||
// Example creating a token using a custom claims type. The StandardClaim is embedded
|
||||
// in the custom type to allow for easy encoding, parsing and validation of standard claims.
|
||||
func ExampleNewWithClaims_customClaimsType() {
|
||||
mySigningKey := []byte("AllYourBase")
|
||||
|
||||
type MyCustomClaims struct {
|
||||
Foo string `json:"foo"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
// Create the Claims
|
||||
claims := MyCustomClaims{
|
||||
"bar",
|
||||
jwt.StandardClaims{
|
||||
ExpiresAt: 15000,
|
||||
Issuer: "test",
|
||||
},
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
ss, err := token.SignedString(mySigningKey)
|
||||
fmt.Printf("%v %v", ss, err)
|
||||
//Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c <nil>
|
||||
}
|
||||
|
||||
// Example creating a token using a custom claims type. The StandardClaim is embedded
|
||||
// in the custom type to allow for easy encoding, parsing and validation of standard claims.
|
||||
func ExampleParseWithClaims_customClaimsType() {
|
||||
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"
|
||||
|
||||
type MyCustomClaims struct {
|
||||
Foo string `json:"foo"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
// sample token is expired. override time so it parses as valid
|
||||
at(time.Unix(0, 0), func() {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte("AllYourBase"), nil
|
||||
})
|
||||
|
||||
if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
|
||||
fmt.Printf("%v %v", claims.Foo, claims.StandardClaims.ExpiresAt)
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
})
|
||||
|
||||
// Output: bar 15000
|
||||
}
|
||||
|
||||
// Override time value for tests. Restore default value after.
|
||||
func at(t time.Time, f func()) {
|
||||
jwt.TimeFunc = func() time.Time {
|
||||
return t
|
||||
}
|
||||
f()
|
||||
jwt.TimeFunc = time.Now
|
||||
}
|
||||
|
||||
// An example of parsing the error types using bitfield checks
|
||||
func ExampleParse_errorChecking() {
|
||||
// Token from another example. This token is expired
|
||||
var tokenString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"
|
||||
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte("AllYourBase"), nil
|
||||
})
|
||||
|
||||
if token.Valid {
|
||||
fmt.Println("You look nice today")
|
||||
} else if ve, ok := err.(*jwt.ValidationError); ok {
|
||||
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
|
||||
fmt.Println("That's not even a token")
|
||||
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
|
||||
// Token is either expired or not active yet
|
||||
fmt.Println("Timing is everything")
|
||||
} else {
|
||||
fmt.Println("Couldn't handle this token:", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Couldn't handle this token:", err)
|
||||
}
|
||||
|
||||
// Output: Timing is everything
|
||||
}
|
64
vendor/github.com/dgrijalva/jwt-go/hmac_example_test.go
generated
vendored
64
vendor/github.com/dgrijalva/jwt-go/hmac_example_test.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
// For HMAC signing method, the key can be any []byte. It is recommended to generate
|
||||
// a key using crypto/rand or something equivalent. You need the same key for signing
|
||||
// and validating.
|
||||
var hmacSampleSecret []byte
|
||||
|
||||
func init() {
|
||||
// Load sample key data
|
||||
if keyData, e := ioutil.ReadFile("test/hmacTestKey"); e == nil {
|
||||
hmacSampleSecret = keyData
|
||||
} else {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
// Example creating, signing, and encoding a JWT token using the HMAC signing method
|
||||
func ExampleNew_hmac() {
|
||||
// Create a new token object, specifying signing method and the claims
|
||||
// you would like it to contain.
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"foo": "bar",
|
||||
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
|
||||
})
|
||||
|
||||
// Sign and get the complete encoded token as a string using the secret
|
||||
tokenString, err := token.SignedString(hmacSampleSecret)
|
||||
|
||||
fmt.Println(tokenString, err)
|
||||
// Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58Br-Zk-bh7vLiRIsrpU <nil>
|
||||
}
|
||||
|
||||
// Example parsing and validating a token using the HMAC signing method
|
||||
func ExampleParse_hmac() {
|
||||
// sample token string taken from the New example
|
||||
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58Br-Zk-bh7vLiRIsrpU"
|
||||
|
||||
// Parse takes the token string and a function for looking up the key. The latter is especially
|
||||
// useful if you use multiple keys for your application. The standard is to use 'kid' in the
|
||||
// head of the token to identify which key to use, but the parsed token (head and claims) is provided
|
||||
// to the callback, providing flexibility.
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
// Don't forget to validate the alg is what you expect:
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return hmacSampleSecret, nil
|
||||
})
|
||||
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
fmt.Println(claims["foo"], claims["nbf"])
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Output: bar 1.4444784e+09
|
||||
}
|
91
vendor/github.com/dgrijalva/jwt-go/hmac_test.go
generated
vendored
91
vendor/github.com/dgrijalva/jwt-go/hmac_test.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var hmacTestData = []struct {
|
||||
name string
|
||||
tokenString string
|
||||
alg string
|
||||
claims map[string]interface{}
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
"web sample",
|
||||
"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
|
||||
"HS256",
|
||||
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"HS384",
|
||||
"eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.KWZEuOD5lbBxZ34g7F-SlVLAQ_r5KApWNWlZIIMyQVz5Zs58a7XdNzj5_0EcNoOy",
|
||||
"HS384",
|
||||
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"HS512",
|
||||
"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.CN7YijRX6Aw1n2jyI2Id1w90ja-DEMYiWixhYCyHnrZ1VfJRaFQz1bEbjjA5Fn4CLYaUG432dEYmSbS4Saokmw",
|
||||
"HS512",
|
||||
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"web sample: invalid",
|
||||
"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXo",
|
||||
"HS256",
|
||||
map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
// Sample data from http://tools.ietf.org/html/draft-jones-json-web-signature-04#appendix-A.1
|
||||
var hmacTestKey, _ = ioutil.ReadFile("test/hmacTestKey")
|
||||
|
||||
func TestHMACVerify(t *testing.T) {
|
||||
for _, data := range hmacTestData {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], hmacTestKey)
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
|
||||
}
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid key passed validation", data.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHMACSign(t *testing.T) {
|
||||
for _, data := range hmacTestData {
|
||||
if data.valid {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
sig, err := method.Sign(strings.Join(parts[0:2], "."), hmacTestKey)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error signing token: %v", data.name, err)
|
||||
}
|
||||
if sig != parts[2] {
|
||||
t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHS256Signing(b *testing.B) {
|
||||
benchmarkSigning(b, jwt.SigningMethodHS256, hmacTestKey)
|
||||
}
|
||||
|
||||
func BenchmarkHS384Signing(b *testing.B) {
|
||||
benchmarkSigning(b, jwt.SigningMethodHS384, hmacTestKey)
|
||||
}
|
||||
|
||||
func BenchmarkHS512Signing(b *testing.B) {
|
||||
benchmarkSigning(b, jwt.SigningMethodHS512, hmacTestKey)
|
||||
}
|
216
vendor/github.com/dgrijalva/jwt-go/http_example_test.go
generated
vendored
216
vendor/github.com/dgrijalva/jwt-go/http_example_test.go
generated
vendored
@ -1,216 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
// Example HTTP auth using asymmetric crypto/RSA keys
|
||||
// This is based on a (now outdated) example at https://gist.github.com/cryptix/45c33ecf0ae54828e63b
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/dgrijalva/jwt-go/request"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// location of the files used for signing and verification
|
||||
const (
|
||||
privKeyPath = "test/sample_key" // openssl genrsa -out app.rsa keysize
|
||||
pubKeyPath = "test/sample_key.pub" // openssl rsa -in app.rsa -pubout > app.rsa.pub
|
||||
)
|
||||
|
||||
var (
|
||||
verifyKey *rsa.PublicKey
|
||||
signKey *rsa.PrivateKey
|
||||
serverPort int
|
||||
// storing sample username/password pairs
|
||||
// don't do this on a real server
|
||||
users = map[string]string{
|
||||
"test": "known",
|
||||
}
|
||||
)
|
||||
|
||||
// read the key files before starting http handlers
|
||||
func init() {
|
||||
signBytes, err := ioutil.ReadFile(privKeyPath)
|
||||
fatal(err)
|
||||
|
||||
signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
|
||||
fatal(err)
|
||||
|
||||
verifyBytes, err := ioutil.ReadFile(pubKeyPath)
|
||||
fatal(err)
|
||||
|
||||
verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
|
||||
fatal(err)
|
||||
|
||||
http.HandleFunc("/authenticate", authHandler)
|
||||
http.HandleFunc("/restricted", restrictedHandler)
|
||||
|
||||
// Setup listener
|
||||
listener, err := net.ListenTCP("tcp", &net.TCPAddr{})
|
||||
serverPort = listener.Addr().(*net.TCPAddr).Port
|
||||
|
||||
log.Println("Listening...")
|
||||
go func() {
|
||||
fatal(http.Serve(listener, nil))
|
||||
}()
|
||||
}
|
||||
|
||||
var start func()
|
||||
|
||||
func fatal(err error) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Define some custom types were going to use within our tokens
|
||||
type CustomerInfo struct {
|
||||
Name string
|
||||
Kind string
|
||||
}
|
||||
|
||||
type CustomClaimsExample struct {
|
||||
*jwt.StandardClaims
|
||||
TokenType string
|
||||
CustomerInfo
|
||||
}
|
||||
|
||||
func Example_getTokenViaHTTP() {
|
||||
// See func authHandler for an example auth handler that produces a token
|
||||
res, err := http.PostForm(fmt.Sprintf("http://localhost:%v/authenticate", serverPort), url.Values{
|
||||
"user": {"test"},
|
||||
"pass": {"known"},
|
||||
})
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
fmt.Println("Unexpected status code", res.StatusCode)
|
||||
}
|
||||
|
||||
// Read the token out of the response body
|
||||
buf := new(bytes.Buffer)
|
||||
io.Copy(buf, res.Body)
|
||||
res.Body.Close()
|
||||
tokenString := strings.TrimSpace(buf.String())
|
||||
|
||||
// Parse the token
|
||||
token, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
|
||||
// since we only use the one private key to sign the tokens,
|
||||
// we also only use its public counter part to verify
|
||||
return verifyKey, nil
|
||||
})
|
||||
fatal(err)
|
||||
|
||||
claims := token.Claims.(*CustomClaimsExample)
|
||||
fmt.Println(claims.CustomerInfo.Name)
|
||||
|
||||
//Output: test
|
||||
}
|
||||
|
||||
func Example_useTokenViaHTTP() {
|
||||
|
||||
// Make a sample token
|
||||
// In a real world situation, this token will have been acquired from
|
||||
// some other API call (see Example_getTokenViaHTTP)
|
||||
token, err := createToken("foo")
|
||||
fatal(err)
|
||||
|
||||
// Make request. See func restrictedHandler for example request processor
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost:%v/restricted", serverPort), nil)
|
||||
fatal(err)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", token))
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
fatal(err)
|
||||
|
||||
// Read the response body
|
||||
buf := new(bytes.Buffer)
|
||||
io.Copy(buf, res.Body)
|
||||
res.Body.Close()
|
||||
fmt.Println(buf.String())
|
||||
|
||||
// Output: Welcome, foo
|
||||
}
|
||||
|
||||
func createToken(user string) (string, error) {
|
||||
// create a signer for rsa 256
|
||||
t := jwt.New(jwt.GetSigningMethod("RS256"))
|
||||
|
||||
// set our claims
|
||||
t.Claims = &CustomClaimsExample{
|
||||
&jwt.StandardClaims{
|
||||
// set the expire time
|
||||
// see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4
|
||||
ExpiresAt: time.Now().Add(time.Minute * 1).Unix(),
|
||||
},
|
||||
"level1",
|
||||
CustomerInfo{user, "human"},
|
||||
}
|
||||
|
||||
// Creat token string
|
||||
return t.SignedString(signKey)
|
||||
}
|
||||
|
||||
// reads the form values, checks them and creates the token
|
||||
func authHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// make sure its post
|
||||
if r.Method != "POST" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprintln(w, "No POST", r.Method)
|
||||
return
|
||||
}
|
||||
|
||||
user := r.FormValue("user")
|
||||
pass := r.FormValue("pass")
|
||||
|
||||
log.Printf("Authenticate: user[%s] pass[%s]\n", user, pass)
|
||||
|
||||
// check values
|
||||
if user != "test" || pass != "known" {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
fmt.Fprintln(w, "Wrong info")
|
||||
return
|
||||
}
|
||||
|
||||
tokenString, err := createToken(user)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprintln(w, "Sorry, error while Signing Token!")
|
||||
log.Printf("Token Signing error: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/jwt")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintln(w, tokenString)
|
||||
}
|
||||
|
||||
// only accessible with a valid token
|
||||
func restrictedHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Get token from request
|
||||
token, err := request.ParseFromRequestWithClaims(r, request.OAuth2Extractor, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
|
||||
// since we only use the one private key to sign the tokens,
|
||||
// we also only use its public counter part to verify
|
||||
return verifyKey, nil
|
||||
})
|
||||
|
||||
// If the token is missing or invalid, return error
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
fmt.Fprintln(w, "Invalid token:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Token is valid
|
||||
fmt.Fprintln(w, "Welcome,", token.Claims.(*CustomClaimsExample).Name)
|
||||
return
|
||||
}
|
72
vendor/github.com/dgrijalva/jwt-go/none_test.go
generated
vendored
72
vendor/github.com/dgrijalva/jwt-go/none_test.go
generated
vendored
@ -1,72 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var noneTestData = []struct {
|
||||
name string
|
||||
tokenString string
|
||||
alg string
|
||||
key interface{}
|
||||
claims map[string]interface{}
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
"Basic",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.",
|
||||
"none",
|
||||
jwt.UnsafeAllowNoneSignatureType,
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic - no key",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.",
|
||||
"none",
|
||||
nil,
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Signed",
|
||||
"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw",
|
||||
"none",
|
||||
jwt.UnsafeAllowNoneSignatureType,
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestNoneVerify(t *testing.T) {
|
||||
for _, data := range noneTestData {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], data.key)
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
|
||||
}
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid key passed validation", data.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoneSign(t *testing.T) {
|
||||
for _, data := range noneTestData {
|
||||
if data.valid {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
sig, err := method.Sign(strings.Join(parts[0:2], "."), data.key)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error signing token: %v", data.name, err)
|
||||
}
|
||||
if sig != parts[2] {
|
||||
t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
261
vendor/github.com/dgrijalva/jwt-go/parser_test.go
generated
vendored
261
vendor/github.com/dgrijalva/jwt-go/parser_test.go
generated
vendored
@ -1,261 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/dgrijalva/jwt-go/test"
|
||||
)
|
||||
|
||||
var keyFuncError error = fmt.Errorf("error loading key")
|
||||
|
||||
var (
|
||||
jwtTestDefaultKey *rsa.PublicKey
|
||||
defaultKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil }
|
||||
emptyKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil }
|
||||
errorKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, keyFuncError }
|
||||
nilKeyFunc jwt.Keyfunc = nil
|
||||
)
|
||||
|
||||
func init() {
|
||||
jwtTestDefaultKey = test.LoadRSAPublicKeyFromDisk("test/sample_key.pub")
|
||||
}
|
||||
|
||||
var jwtTestData = []struct {
|
||||
name string
|
||||
tokenString string
|
||||
keyfunc jwt.Keyfunc
|
||||
claims jwt.Claims
|
||||
valid bool
|
||||
errors uint32
|
||||
parser *jwt.Parser
|
||||
}{
|
||||
{
|
||||
"basic",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
true,
|
||||
0,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"basic expired",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "exp": float64(time.Now().Unix() - 100)},
|
||||
false,
|
||||
jwt.ValidationErrorExpired,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"basic nbf",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "nbf": float64(time.Now().Unix() + 100)},
|
||||
false,
|
||||
jwt.ValidationErrorNotValidYet,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"expired and nbf",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "nbf": float64(time.Now().Unix() + 100), "exp": float64(time.Now().Unix() - 100)},
|
||||
false,
|
||||
jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"basic invalid",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
false,
|
||||
jwt.ValidationErrorSignatureInvalid,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"basic nokeyfunc",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
nilKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
false,
|
||||
jwt.ValidationErrorUnverifiable,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"basic nokey",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
emptyKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
false,
|
||||
jwt.ValidationErrorSignatureInvalid,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"basic errorkey",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
errorKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
false,
|
||||
jwt.ValidationErrorUnverifiable,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"invalid signing method",
|
||||
"",
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
false,
|
||||
jwt.ValidationErrorSignatureInvalid,
|
||||
&jwt.Parser{ValidMethods: []string{"HS256"}},
|
||||
},
|
||||
{
|
||||
"valid signing method",
|
||||
"",
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
true,
|
||||
0,
|
||||
&jwt.Parser{ValidMethods: []string{"RS256", "HS256"}},
|
||||
},
|
||||
{
|
||||
"JSON Number",
|
||||
"",
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": json.Number("123.4")},
|
||||
true,
|
||||
0,
|
||||
&jwt.Parser{UseJSONNumber: true},
|
||||
},
|
||||
{
|
||||
"Standard Claims",
|
||||
"",
|
||||
defaultKeyFunc,
|
||||
&jwt.StandardClaims{
|
||||
ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
|
||||
},
|
||||
true,
|
||||
0,
|
||||
&jwt.Parser{UseJSONNumber: true},
|
||||
},
|
||||
{
|
||||
"JSON Number - basic expired",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "exp": json.Number(fmt.Sprintf("%v", time.Now().Unix()-100))},
|
||||
false,
|
||||
jwt.ValidationErrorExpired,
|
||||
&jwt.Parser{UseJSONNumber: true},
|
||||
},
|
||||
{
|
||||
"JSON Number - basic nbf",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "nbf": json.Number(fmt.Sprintf("%v", time.Now().Unix()+100))},
|
||||
false,
|
||||
jwt.ValidationErrorNotValidYet,
|
||||
&jwt.Parser{UseJSONNumber: true},
|
||||
},
|
||||
{
|
||||
"JSON Number - expired and nbf",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "nbf": json.Number(fmt.Sprintf("%v", time.Now().Unix()+100)), "exp": json.Number(fmt.Sprintf("%v", time.Now().Unix()-100))},
|
||||
false,
|
||||
jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired,
|
||||
&jwt.Parser{UseJSONNumber: true},
|
||||
},
|
||||
{
|
||||
"SkipClaimsValidation during token parsing",
|
||||
"", // autogen
|
||||
defaultKeyFunc,
|
||||
jwt.MapClaims{"foo": "bar", "nbf": json.Number(fmt.Sprintf("%v", time.Now().Unix()+100))},
|
||||
true,
|
||||
0,
|
||||
&jwt.Parser{UseJSONNumber: true, SkipClaimsValidation: true},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParser_Parse(t *testing.T) {
|
||||
privateKey := test.LoadRSAPrivateKeyFromDisk("test/sample_key")
|
||||
|
||||
// Iterate over test data set and run tests
|
||||
for _, data := range jwtTestData {
|
||||
// If the token string is blank, use helper function to generate string
|
||||
if data.tokenString == "" {
|
||||
data.tokenString = test.MakeSampleToken(data.claims, privateKey)
|
||||
}
|
||||
|
||||
// Parse the token
|
||||
var token *jwt.Token
|
||||
var err error
|
||||
var parser = data.parser
|
||||
if parser == nil {
|
||||
parser = new(jwt.Parser)
|
||||
}
|
||||
// Figure out correct claims type
|
||||
switch data.claims.(type) {
|
||||
case jwt.MapClaims:
|
||||
token, err = parser.ParseWithClaims(data.tokenString, jwt.MapClaims{}, data.keyfunc)
|
||||
case *jwt.StandardClaims:
|
||||
token, err = parser.ParseWithClaims(data.tokenString, &jwt.StandardClaims{}, data.keyfunc)
|
||||
}
|
||||
|
||||
// Verify result matches expectation
|
||||
if !reflect.DeepEqual(data.claims, token.Claims) {
|
||||
t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims)
|
||||
}
|
||||
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying token: %T:%v", data.name, err, err)
|
||||
}
|
||||
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid token passed validation", data.name)
|
||||
}
|
||||
|
||||
if (err == nil && !token.Valid) || (err != nil && token.Valid) {
|
||||
t.Errorf("[%v] Inconsistent behavior between returned error and token.Valid")
|
||||
}
|
||||
|
||||
if data.errors != 0 {
|
||||
if err == nil {
|
||||
t.Errorf("[%v] Expecting error. Didn't get one.", data.name)
|
||||
} else {
|
||||
|
||||
ve := err.(*jwt.ValidationError)
|
||||
// compare the bitfield part of the error
|
||||
if e := ve.Errors; e != data.errors {
|
||||
t.Errorf("[%v] Errors don't match expectation. %v != %v", data.name, e, data.errors)
|
||||
}
|
||||
|
||||
if err.Error() == keyFuncError.Error() && ve.Inner != keyFuncError {
|
||||
t.Errorf("[%v] Inner error does not match expectation. %v != %v", data.name, ve.Inner, keyFuncError)
|
||||
}
|
||||
}
|
||||
}
|
||||
if data.valid && token.Signature == "" {
|
||||
t.Errorf("[%v] Signature is left unpopulated after parsing", data.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method for benchmarking various methods
|
||||
func benchmarkSigning(b *testing.B, method jwt.SigningMethod, key interface{}) {
|
||||
t := jwt.New(method)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
if _, err := t.SignedString(key); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
7
vendor/github.com/dgrijalva/jwt-go/request/doc.go
generated
vendored
7
vendor/github.com/dgrijalva/jwt-go/request/doc.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
// Utility package for extracting JWT tokens from
|
||||
// HTTP requests.
|
||||
//
|
||||
// The main function is ParseFromRequest and it's WithClaims variant.
|
||||
// See examples for how to use the various Extractor implementations
|
||||
// or roll your own.
|
||||
package request
|
81
vendor/github.com/dgrijalva/jwt-go/request/extractor.go
generated
vendored
81
vendor/github.com/dgrijalva/jwt-go/request/extractor.go
generated
vendored
@ -1,81 +0,0 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
ErrNoTokenInRequest = errors.New("no token present in request")
|
||||
)
|
||||
|
||||
// Interface for extracting a token from an HTTP request.
|
||||
// The ExtractToken method should return a token string or an error.
|
||||
// If no token is present, you must return ErrNoTokenInRequest.
|
||||
type Extractor interface {
|
||||
ExtractToken(*http.Request) (string, error)
|
||||
}
|
||||
|
||||
// Extractor for finding a token in a header. Looks at each specified
|
||||
// header in order until there's a match
|
||||
type HeaderExtractor []string
|
||||
|
||||
func (e HeaderExtractor) ExtractToken(req *http.Request) (string, error) {
|
||||
// loop over header names and return the first one that contains data
|
||||
for _, header := range e {
|
||||
if ah := req.Header.Get(header); ah != "" {
|
||||
return ah, nil
|
||||
}
|
||||
}
|
||||
return "", ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
// Extract token from request arguments. This includes a POSTed form or
|
||||
// GET URL arguments. Argument names are tried in order until there's a match.
|
||||
// This extractor calls `ParseMultipartForm` on the request
|
||||
type ArgumentExtractor []string
|
||||
|
||||
func (e ArgumentExtractor) ExtractToken(req *http.Request) (string, error) {
|
||||
// Make sure form is parsed
|
||||
req.ParseMultipartForm(10e6)
|
||||
|
||||
// loop over arg names and return the first one that contains data
|
||||
for _, arg := range e {
|
||||
if ah := req.Form.Get(arg); ah != "" {
|
||||
return ah, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
// Tries Extractors in order until one returns a token string or an error occurs
|
||||
type MultiExtractor []Extractor
|
||||
|
||||
func (e MultiExtractor) ExtractToken(req *http.Request) (string, error) {
|
||||
// loop over header names and return the first one that contains data
|
||||
for _, extractor := range e {
|
||||
if tok, err := extractor.ExtractToken(req); tok != "" {
|
||||
return tok, nil
|
||||
} else if err != ErrNoTokenInRequest {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return "", ErrNoTokenInRequest
|
||||
}
|
||||
|
||||
// Wrap an Extractor in this to post-process the value before it's handed off.
|
||||
// See AuthorizationHeaderExtractor for an example
|
||||
type PostExtractionFilter struct {
|
||||
Extractor
|
||||
Filter func(string) (string, error)
|
||||
}
|
||||
|
||||
func (e *PostExtractionFilter) ExtractToken(req *http.Request) (string, error) {
|
||||
if tok, err := e.Extractor.ExtractToken(req); tok != "" {
|
||||
return e.Filter(tok)
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
}
|
32
vendor/github.com/dgrijalva/jwt-go/request/extractor_example_test.go
generated
vendored
32
vendor/github.com/dgrijalva/jwt-go/request/extractor_example_test.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
exampleTokenA = "A"
|
||||
)
|
||||
|
||||
func ExampleHeaderExtractor() {
|
||||
req := makeExampleRequest("GET", "/", map[string]string{"Token": exampleTokenA}, nil)
|
||||
tokenString, err := HeaderExtractor{"Token"}.ExtractToken(req)
|
||||
if err == nil {
|
||||
fmt.Println(tokenString)
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//Output: A
|
||||
}
|
||||
|
||||
func ExampleArgumentExtractor() {
|
||||
req := makeExampleRequest("GET", "/", nil, url.Values{"token": {extractorTestTokenA}})
|
||||
tokenString, err := ArgumentExtractor{"token"}.ExtractToken(req)
|
||||
if err == nil {
|
||||
fmt.Println(tokenString)
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//Output: A
|
||||
}
|
91
vendor/github.com/dgrijalva/jwt-go/request/extractor_test.go
generated
vendored
91
vendor/github.com/dgrijalva/jwt-go/request/extractor_test.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var extractorTestTokenA = "A"
|
||||
var extractorTestTokenB = "B"
|
||||
|
||||
var extractorTestData = []struct {
|
||||
name string
|
||||
extractor Extractor
|
||||
headers map[string]string
|
||||
query url.Values
|
||||
token string
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "simple header",
|
||||
extractor: HeaderExtractor{"Foo"},
|
||||
headers: map[string]string{"Foo": extractorTestTokenA},
|
||||
query: nil,
|
||||
token: extractorTestTokenA,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "simple argument",
|
||||
extractor: ArgumentExtractor{"token"},
|
||||
headers: map[string]string{},
|
||||
query: url.Values{"token": {extractorTestTokenA}},
|
||||
token: extractorTestTokenA,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "multiple extractors",
|
||||
extractor: MultiExtractor{
|
||||
HeaderExtractor{"Foo"},
|
||||
ArgumentExtractor{"token"},
|
||||
},
|
||||
headers: map[string]string{"Foo": extractorTestTokenA},
|
||||
query: url.Values{"token": {extractorTestTokenB}},
|
||||
token: extractorTestTokenA,
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "simple miss",
|
||||
extractor: HeaderExtractor{"This-Header-Is-Not-Set"},
|
||||
headers: map[string]string{"Foo": extractorTestTokenA},
|
||||
query: nil,
|
||||
token: "",
|
||||
err: ErrNoTokenInRequest,
|
||||
},
|
||||
{
|
||||
name: "filter",
|
||||
extractor: AuthorizationHeaderExtractor,
|
||||
headers: map[string]string{"Authorization": "Bearer " + extractorTestTokenA},
|
||||
query: nil,
|
||||
token: extractorTestTokenA,
|
||||
err: nil,
|
||||
},
|
||||
}
|
||||
|
||||
func TestExtractor(t *testing.T) {
|
||||
// Bearer token request
|
||||
for _, data := range extractorTestData {
|
||||
// Make request from test struct
|
||||
r := makeExampleRequest("GET", "/", data.headers, data.query)
|
||||
|
||||
// Test extractor
|
||||
token, err := data.extractor.ExtractToken(r)
|
||||
if token != data.token {
|
||||
t.Errorf("[%v] Expected token '%v'. Got '%v'", data.name, data.token, token)
|
||||
continue
|
||||
}
|
||||
if err != data.err {
|
||||
t.Errorf("[%v] Expected error '%v'. Got '%v'", data.name, data.err, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeExampleRequest(method, path string, headers map[string]string, urlArgs url.Values) *http.Request {
|
||||
r, _ := http.NewRequest(method, fmt.Sprintf("%v?%v", path, urlArgs.Encode()), nil)
|
||||
for k, v := range headers {
|
||||
r.Header.Set(k, v)
|
||||
}
|
||||
return r
|
||||
}
|
28
vendor/github.com/dgrijalva/jwt-go/request/oauth2.go
generated
vendored
28
vendor/github.com/dgrijalva/jwt-go/request/oauth2.go
generated
vendored
@ -1,28 +0,0 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Strips 'Bearer ' prefix from bearer token string
|
||||
func stripBearerPrefixFromTokenString(tok string) (string, error) {
|
||||
// Should be a bearer token
|
||||
if len(tok) > 6 && strings.ToUpper(tok[0:7]) == "BEARER " {
|
||||
return tok[7:], nil
|
||||
}
|
||||
return tok, nil
|
||||
}
|
||||
|
||||
// Extract bearer token from Authorization header
|
||||
// Uses PostExtractionFilter to strip "Bearer " prefix from header
|
||||
var AuthorizationHeaderExtractor = &PostExtractionFilter{
|
||||
HeaderExtractor{"Authorization"},
|
||||
stripBearerPrefixFromTokenString,
|
||||
}
|
||||
|
||||
// Extractor for OAuth2 access tokens. Looks in 'Authorization'
|
||||
// header then 'access_token' argument for a token.
|
||||
var OAuth2Extractor = &MultiExtractor{
|
||||
AuthorizationHeaderExtractor,
|
||||
ArgumentExtractor{"access_token"},
|
||||
}
|
24
vendor/github.com/dgrijalva/jwt-go/request/request.go
generated
vendored
24
vendor/github.com/dgrijalva/jwt-go/request/request.go
generated
vendored
@ -1,24 +0,0 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Extract and parse a JWT token from an HTTP request.
|
||||
// This behaves the same as Parse, but accepts a request and an extractor
|
||||
// instead of a token string. The Extractor interface allows you to define
|
||||
// the logic for extracting a token. Several useful implementations are provided.
|
||||
func ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) {
|
||||
return ParseFromRequestWithClaims(req, extractor, jwt.MapClaims{}, keyFunc)
|
||||
}
|
||||
|
||||
// ParseFromRequest but with custom Claims type
|
||||
func ParseFromRequestWithClaims(req *http.Request, extractor Extractor, claims jwt.Claims, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) {
|
||||
// Extract token from request
|
||||
if tokStr, err := extractor.ExtractToken(req); err == nil {
|
||||
return jwt.ParseWithClaims(tokStr, claims, keyFunc)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
103
vendor/github.com/dgrijalva/jwt-go/request/request_test.go
generated
vendored
103
vendor/github.com/dgrijalva/jwt-go/request/request_test.go
generated
vendored
@ -1,103 +0,0 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/dgrijalva/jwt-go/test"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var requestTestData = []struct {
|
||||
name string
|
||||
claims jwt.MapClaims
|
||||
extractor Extractor
|
||||
headers map[string]string
|
||||
query url.Values
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
"authorization bearer token",
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
AuthorizationHeaderExtractor,
|
||||
map[string]string{"Authorization": "Bearer %v"},
|
||||
url.Values{},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"oauth bearer token - header",
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
OAuth2Extractor,
|
||||
map[string]string{"Authorization": "Bearer %v"},
|
||||
url.Values{},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"oauth bearer token - url",
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
OAuth2Extractor,
|
||||
map[string]string{},
|
||||
url.Values{"access_token": {"%v"}},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"url token",
|
||||
jwt.MapClaims{"foo": "bar"},
|
||||
ArgumentExtractor{"token"},
|
||||
map[string]string{},
|
||||
url.Values{"token": {"%v"}},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
func TestParseRequest(t *testing.T) {
|
||||
// load keys from disk
|
||||
privateKey := test.LoadRSAPrivateKeyFromDisk("../test/sample_key")
|
||||
publicKey := test.LoadRSAPublicKeyFromDisk("../test/sample_key.pub")
|
||||
keyfunc := func(*jwt.Token) (interface{}, error) {
|
||||
return publicKey, nil
|
||||
}
|
||||
|
||||
// Bearer token request
|
||||
for _, data := range requestTestData {
|
||||
// Make token from claims
|
||||
tokenString := test.MakeSampleToken(data.claims, privateKey)
|
||||
|
||||
// Make query string
|
||||
for k, vv := range data.query {
|
||||
for i, v := range vv {
|
||||
if strings.Contains(v, "%v") {
|
||||
data.query[k][i] = fmt.Sprintf(v, tokenString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make request from test struct
|
||||
r, _ := http.NewRequest("GET", fmt.Sprintf("/?%v", data.query.Encode()), nil)
|
||||
for k, v := range data.headers {
|
||||
if strings.Contains(v, "%v") {
|
||||
r.Header.Set(k, fmt.Sprintf(v, tokenString))
|
||||
} else {
|
||||
r.Header.Set(k, tokenString)
|
||||
}
|
||||
}
|
||||
token, err := ParseFromRequestWithClaims(r, data.extractor, jwt.MapClaims{}, keyfunc)
|
||||
|
||||
if token == nil {
|
||||
t.Errorf("[%v] Token was not found: %v", data.name, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(data.claims, token.Claims) {
|
||||
t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims)
|
||||
}
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying token: %v", data.name, err)
|
||||
}
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid token passed validation", data.name)
|
||||
}
|
||||
}
|
||||
}
|
96
vendor/github.com/dgrijalva/jwt-go/rsa_pss_test.go
generated
vendored
96
vendor/github.com/dgrijalva/jwt-go/rsa_pss_test.go
generated
vendored
@ -1,96 +0,0 @@
|
||||
// +build go1.4
|
||||
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
var rsaPSSTestData = []struct {
|
||||
name string
|
||||
tokenString string
|
||||
alg string
|
||||
claims map[string]interface{}
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
"Basic PS256",
|
||||
"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9w",
|
||||
"PS256",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic PS384",
|
||||
"eyJhbGciOiJQUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.w7-qqgj97gK4fJsq_DCqdYQiylJjzWONvD0qWWWhqEOFk2P1eDULPnqHRnjgTXoO4HAw4YIWCsZPet7nR3Xxq4ZhMqvKW8b7KlfRTb9cH8zqFvzMmybQ4jv2hKc3bXYqVow3AoR7hN_CWXI3Dv6Kd2X5xhtxRHI6IL39oTVDUQ74LACe-9t4c3QRPuj6Pq1H4FAT2E2kW_0KOc6EQhCLWEhm2Z2__OZskDC8AiPpP8Kv4k2vB7l0IKQu8Pr4RcNBlqJdq8dA5D3hk5TLxP8V5nG1Ib80MOMMqoS3FQvSLyolFX-R_jZ3-zfq6Ebsqr0yEb0AH2CfsECF7935Pa0FKQ",
|
||||
"PS384",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic PS512",
|
||||
"eyJhbGciOiJQUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.GX1HWGzFaJevuSLavqqFYaW8_TpvcjQ8KfC5fXiSDzSiT9UD9nB_ikSmDNyDILNdtjZLSvVKfXxZJqCfefxAtiozEDDdJthZ-F0uO4SPFHlGiXszvKeodh7BuTWRI2wL9-ZO4mFa8nq3GMeQAfo9cx11i7nfN8n2YNQ9SHGovG7_T_AvaMZB_jT6jkDHpwGR9mz7x1sycckEo6teLdHRnH_ZdlHlxqknmyTu8Odr5Xh0sJFOL8BepWbbvIIn-P161rRHHiDWFv6nhlHwZnVzjx7HQrWSGb6-s2cdLie9QL_8XaMcUpjLkfOMKkDOfHo6AvpL7Jbwi83Z2ZTHjJWB-A",
|
||||
"PS512",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"basic PS256 invalid: foo => bar",
|
||||
"eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9W",
|
||||
"PS256",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestRSAPSSVerify(t *testing.T) {
|
||||
var err error
|
||||
|
||||
key, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||
var rsaPSSKey *rsa.PublicKey
|
||||
if rsaPSSKey, err = jwt.ParseRSAPublicKeyFromPEM(key); err != nil {
|
||||
t.Errorf("Unable to parse RSA public key: %v", err)
|
||||
}
|
||||
|
||||
for _, data := range rsaPSSTestData {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], rsaPSSKey)
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
|
||||
}
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid key passed validation", data.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSAPSSSign(t *testing.T) {
|
||||
var err error
|
||||
|
||||
key, _ := ioutil.ReadFile("test/sample_key")
|
||||
var rsaPSSKey *rsa.PrivateKey
|
||||
if rsaPSSKey, err = jwt.ParseRSAPrivateKeyFromPEM(key); err != nil {
|
||||
t.Errorf("Unable to parse RSA private key: %v", err)
|
||||
}
|
||||
|
||||
for _, data := range rsaPSSTestData {
|
||||
if data.valid {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
sig, err := method.Sign(strings.Join(parts[0:2], "."), rsaPSSKey)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error signing token: %v", data.name, err)
|
||||
}
|
||||
if sig == parts[2] {
|
||||
t.Errorf("[%v] Signatures shouldn't match\nnew:\n%v\noriginal:\n%v", data.name, sig, parts[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
176
vendor/github.com/dgrijalva/jwt-go/rsa_test.go
generated
vendored
176
vendor/github.com/dgrijalva/jwt-go/rsa_test.go
generated
vendored
@ -1,176 +0,0 @@
|
||||
package jwt_test
|
||||
|
||||
import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var rsaTestData = []struct {
|
||||
name string
|
||||
tokenString string
|
||||
alg string
|
||||
claims map[string]interface{}
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
"Basic RS256",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
"RS256",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic RS384",
|
||||
"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw",
|
||||
"RS384",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Basic RS512",
|
||||
"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.zBlLlmRrUxx4SJPUbV37Q1joRcI9EW13grnKduK3wtYKmDXbgDpF1cZ6B-2Jsm5RB8REmMiLpGms-EjXhgnyh2TSHE-9W2gA_jvshegLWtwRVDX40ODSkTb7OVuaWgiy9y7llvcknFBTIg-FnVPVpXMmeV_pvwQyhaz1SSwSPrDyxEmksz1hq7YONXhXPpGaNbMMeDTNP_1oj8DZaqTIL9TwV8_1wb2Odt_Fy58Ke2RVFijsOLdnyEAjt2n9Mxihu9i3PhNBkkxa2GbnXBfq3kzvZ_xxGGopLdHhJjcGWXO-NiwI9_tiu14NRv4L2xC0ItD9Yz68v2ZIZEp_DuzwRQ",
|
||||
"RS512",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"basic invalid: foo => bar",
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||
"RS256",
|
||||
map[string]interface{}{"foo": "bar"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestRSAVerify(t *testing.T) {
|
||||
keyData, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||
key, _ := jwt.ParseRSAPublicKeyFromPEM(keyData)
|
||||
|
||||
for _, data := range rsaTestData {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], key)
|
||||
if data.valid && err != nil {
|
||||
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
|
||||
}
|
||||
if !data.valid && err == nil {
|
||||
t.Errorf("[%v] Invalid key passed validation", data.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSASign(t *testing.T) {
|
||||
keyData, _ := ioutil.ReadFile("test/sample_key")
|
||||
key, _ := jwt.ParseRSAPrivateKeyFromPEM(keyData)
|
||||
|
||||
for _, data := range rsaTestData {
|
||||
if data.valid {
|
||||
parts := strings.Split(data.tokenString, ".")
|
||||
method := jwt.GetSigningMethod(data.alg)
|
||||
sig, err := method.Sign(strings.Join(parts[0:2], "."), key)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error signing token: %v", data.name, err)
|
||||
}
|
||||
if sig != parts[2] {
|
||||
t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) {
|
||||
key, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||
parsedKey, err := jwt.ParseRSAPublicKeyFromPEM(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testData := rsaTestData[0]
|
||||
parts := strings.Split(testData.tokenString, ".")
|
||||
err = jwt.SigningMethodRS256.Verify(strings.Join(parts[0:2], "."), parts[2], parsedKey)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error while verifying key: %v", testData.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSAWithPreParsedPrivateKey(t *testing.T) {
|
||||
key, _ := ioutil.ReadFile("test/sample_key")
|
||||
parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testData := rsaTestData[0]
|
||||
parts := strings.Split(testData.tokenString, ".")
|
||||
sig, err := jwt.SigningMethodRS256.Sign(strings.Join(parts[0:2], "."), parsedKey)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Error signing token: %v", testData.name, err)
|
||||
}
|
||||
if sig != parts[2] {
|
||||
t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", testData.name, sig, parts[2])
|
||||
}
|
||||
}
|
||||
|
||||
func TestRSAKeyParsing(t *testing.T) {
|
||||
key, _ := ioutil.ReadFile("test/sample_key")
|
||||
pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||
badKey := []byte("All your base are belong to key")
|
||||
|
||||
// Test parsePrivateKey
|
||||
if _, e := jwt.ParseRSAPrivateKeyFromPEM(key); e != nil {
|
||||
t.Errorf("Failed to parse valid private key: %v", e)
|
||||
}
|
||||
|
||||
if k, e := jwt.ParseRSAPrivateKeyFromPEM(pubKey); e == nil {
|
||||
t.Errorf("Parsed public key as valid private key: %v", k)
|
||||
}
|
||||
|
||||
if k, e := jwt.ParseRSAPrivateKeyFromPEM(badKey); e == nil {
|
||||
t.Errorf("Parsed invalid key as valid private key: %v", k)
|
||||
}
|
||||
|
||||
// Test parsePublicKey
|
||||
if _, e := jwt.ParseRSAPublicKeyFromPEM(pubKey); e != nil {
|
||||
t.Errorf("Failed to parse valid public key: %v", e)
|
||||
}
|
||||
|
||||
if k, e := jwt.ParseRSAPublicKeyFromPEM(key); e == nil {
|
||||
t.Errorf("Parsed private key as valid public key: %v", k)
|
||||
}
|
||||
|
||||
if k, e := jwt.ParseRSAPublicKeyFromPEM(badKey); e == nil {
|
||||
t.Errorf("Parsed invalid key as valid private key: %v", k)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkRS256Signing(b *testing.B) {
|
||||
key, _ := ioutil.ReadFile("test/sample_key")
|
||||
parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
benchmarkSigning(b, jwt.SigningMethodRS256, parsedKey)
|
||||
}
|
||||
|
||||
func BenchmarkRS384Signing(b *testing.B) {
|
||||
key, _ := ioutil.ReadFile("test/sample_key")
|
||||
parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
benchmarkSigning(b, jwt.SigningMethodRS384, parsedKey)
|
||||
}
|
||||
|
||||
func BenchmarkRS512Signing(b *testing.B) {
|
||||
key, _ := ioutil.ReadFile("test/sample_key")
|
||||
parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
benchmarkSigning(b, jwt.SigningMethodRS512, parsedKey)
|
||||
}
|
5
vendor/github.com/dgrijalva/jwt-go/test/ec256-private.pem
generated
vendored
5
vendor/github.com/dgrijalva/jwt-go/test/ec256-private.pem
generated
vendored
@ -1,5 +0,0 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIAh5qA3rmqQQuu0vbKV/+zouz/y/Iy2pLpIcWUSyImSwoAoGCCqGSM49
|
||||
AwEHoUQDQgAEYD54V/vp+54P9DXarYqx4MPcm+HKRIQzNasYSoRQHQ/6S6Ps8tpM
|
||||
cT+KvIIC8W/e9k0W7Cm72M1P9jU7SLf/vg==
|
||||
-----END EC PRIVATE KEY-----
|
4
vendor/github.com/dgrijalva/jwt-go/test/ec256-public.pem
generated
vendored
4
vendor/github.com/dgrijalva/jwt-go/test/ec256-public.pem
generated
vendored
@ -1,4 +0,0 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYD54V/vp+54P9DXarYqx4MPcm+HK
|
||||
RIQzNasYSoRQHQ/6S6Ps8tpMcT+KvIIC8W/e9k0W7Cm72M1P9jU7SLf/vg==
|
||||
-----END PUBLIC KEY-----
|
6
vendor/github.com/dgrijalva/jwt-go/test/ec384-private.pem
generated
vendored
6
vendor/github.com/dgrijalva/jwt-go/test/ec384-private.pem
generated
vendored
@ -1,6 +0,0 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDCaCvMHKhcG/qT7xsNLYnDT7sE/D+TtWIol1ROdaK1a564vx5pHbsRy
|
||||
SEKcIxISi1igBwYFK4EEACKhZANiAATYa7rJaU7feLMqrAx6adZFNQOpaUH/Uylb
|
||||
ZLriOLON5YFVwtVUpO1FfEXZUIQpptRPtc5ixIPY658yhBSb6irfIJUSP9aYTflJ
|
||||
GKk/mDkK4t8mWBzhiD5B6jg9cEGhGgA=
|
||||
-----END EC PRIVATE KEY-----
|
5
vendor/github.com/dgrijalva/jwt-go/test/ec384-public.pem
generated
vendored
5
vendor/github.com/dgrijalva/jwt-go/test/ec384-public.pem
generated
vendored
@ -1,5 +0,0 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2Gu6yWlO33izKqwMemnWRTUDqWlB/1Mp
|
||||
W2S64jizjeWBVcLVVKTtRXxF2VCEKabUT7XOYsSD2OufMoQUm+oq3yCVEj/WmE35
|
||||
SRipP5g5CuLfJlgc4Yg+Qeo4PXBBoRoA
|
||||
-----END PUBLIC KEY-----
|
7
vendor/github.com/dgrijalva/jwt-go/test/ec512-private.pem
generated
vendored
7
vendor/github.com/dgrijalva/jwt-go/test/ec512-private.pem
generated
vendored
@ -1,7 +0,0 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIHcAgEBBEIB0pE4uFaWRx7t03BsYlYvF1YvKaBGyvoakxnodm9ou0R9wC+sJAjH
|
||||
QZZJikOg4SwNqgQ/hyrOuDK2oAVHhgVGcYmgBwYFK4EEACOhgYkDgYYABAAJXIuw
|
||||
12MUzpHggia9POBFYXSxaOGKGbMjIyDI+6q7wi7LMw3HgbaOmgIqFG72o8JBQwYN
|
||||
4IbXHf+f86CRY1AA2wHzbHvt6IhkCXTNxBEffa1yMUgu8n9cKKF2iLgyQKcKqW33
|
||||
8fGOw/n3Rm2Yd/EB56u2rnD29qS+nOM9eGS+gy39OQ==
|
||||
-----END EC PRIVATE KEY-----
|
6
vendor/github.com/dgrijalva/jwt-go/test/ec512-public.pem
generated
vendored
6
vendor/github.com/dgrijalva/jwt-go/test/ec512-public.pem
generated
vendored
@ -1,6 +0,0 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQACVyLsNdjFM6R4IImvTzgRWF0sWjh
|
||||
ihmzIyMgyPuqu8IuyzMNx4G2jpoCKhRu9qPCQUMGDeCG1x3/n/OgkWNQANsB82x7
|
||||
7eiIZAl0zcQRH32tcjFILvJ/XCihdoi4MkCnCqlt9/HxjsP590ZtmHfxAeertq5w
|
||||
9vakvpzjPXhkvoMt/Tk=
|
||||
-----END PUBLIC KEY-----
|
42
vendor/github.com/dgrijalva/jwt-go/test/helpers.go
generated
vendored
42
vendor/github.com/dgrijalva/jwt-go/test/helpers.go
generated
vendored
@ -1,42 +0,0 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func LoadRSAPrivateKeyFromDisk(location string) *rsa.PrivateKey {
|
||||
keyData, e := ioutil.ReadFile(location)
|
||||
if e != nil {
|
||||
panic(e.Error())
|
||||
}
|
||||
key, e := jwt.ParseRSAPrivateKeyFromPEM(keyData)
|
||||
if e != nil {
|
||||
panic(e.Error())
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func LoadRSAPublicKeyFromDisk(location string) *rsa.PublicKey {
|
||||
keyData, e := ioutil.ReadFile(location)
|
||||
if e != nil {
|
||||
panic(e.Error())
|
||||
}
|
||||
key, e := jwt.ParseRSAPublicKeyFromPEM(keyData)
|
||||
if e != nil {
|
||||
panic(e.Error())
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func MakeSampleToken(c jwt.Claims, key interface{}) string {
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, c)
|
||||
s, e := token.SignedString(key)
|
||||
|
||||
if e != nil {
|
||||
panic(e.Error())
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
1
vendor/github.com/dgrijalva/jwt-go/test/hmacTestKey
generated
vendored
1
vendor/github.com/dgrijalva/jwt-go/test/hmacTestKey
generated
vendored
@ -1 +0,0 @@
|
||||
#5K+・シミew{ヲ住ウ(跼Tノ(ゥ┫メP.ソモ燾辻G<>感テwb="=.!r.Oタヘ奎gミ」
|
27
vendor/github.com/dgrijalva/jwt-go/test/sample_key
generated
vendored
27
vendor/github.com/dgrijalva/jwt-go/test/sample_key
generated
vendored
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA4f5wg5l2hKsTeNem/V41fGnJm6gOdrj8ym3rFkEU/wT8RDtn
|
||||
SgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7mCpz9Er5qLaMXJwZxzHzAahlfA0i
|
||||
cqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBpHssPnpYGIn20ZZuNlX2BrClciHhC
|
||||
PUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2XrHhR+1DcKJzQBSTAGnpYVaqpsAR
|
||||
ap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3bODIRe1AuTyHceAbewn8b462yEWKA
|
||||
Rdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy7wIDAQABAoIBAQCwia1k7+2oZ2d3
|
||||
n6agCAbqIE1QXfCmh41ZqJHbOY3oRQG3X1wpcGH4Gk+O+zDVTV2JszdcOt7E5dAy
|
||||
MaomETAhRxB7hlIOnEN7WKm+dGNrKRvV0wDU5ReFMRHg31/Lnu8c+5BvGjZX+ky9
|
||||
POIhFFYJqwCRlopGSUIxmVj5rSgtzk3iWOQXr+ah1bjEXvlxDOWkHN6YfpV5ThdE
|
||||
KdBIPGEVqa63r9n2h+qazKrtiRqJqGnOrHzOECYbRFYhexsNFz7YT02xdfSHn7gM
|
||||
IvabDDP/Qp0PjE1jdouiMaFHYnLBbgvlnZW9yuVf/rpXTUq/njxIXMmvmEyyvSDn
|
||||
FcFikB8pAoGBAPF77hK4m3/rdGT7X8a/gwvZ2R121aBcdPwEaUhvj/36dx596zvY
|
||||
mEOjrWfZhF083/nYWE2kVquj2wjs+otCLfifEEgXcVPTnEOPO9Zg3uNSL0nNQghj
|
||||
FuD3iGLTUBCtM66oTe0jLSslHe8gLGEQqyMzHOzYxNqibxcOZIe8Qt0NAoGBAO+U
|
||||
I5+XWjWEgDmvyC3TrOSf/KCGjtu0TSv30ipv27bDLMrpvPmD/5lpptTFwcxvVhCs
|
||||
2b+chCjlghFSWFbBULBrfci2FtliClOVMYrlNBdUSJhf3aYSG2Doe6Bgt1n2CpNn
|
||||
/iu37Y3NfemZBJA7hNl4dYe+f+uzM87cdQ214+jrAoGAXA0XxX8ll2+ToOLJsaNT
|
||||
OvNB9h9Uc5qK5X5w+7G7O998BN2PC/MWp8H+2fVqpXgNENpNXttkRm1hk1dych86
|
||||
EunfdPuqsX+as44oCyJGFHVBnWpm33eWQw9YqANRI+pCJzP08I5WK3osnPiwshd+
|
||||
hR54yjgfYhBFNI7B95PmEQkCgYBzFSz7h1+s34Ycr8SvxsOBWxymG5zaCsUbPsL0
|
||||
4aCgLScCHb9J+E86aVbbVFdglYa5Id7DPTL61ixhl7WZjujspeXZGSbmq0Kcnckb
|
||||
mDgqkLECiOJW2NHP/j0McAkDLL4tysF8TLDO8gvuvzNC+WQ6drO2ThrypLVZQ+ry
|
||||
eBIPmwKBgEZxhqa0gVvHQG/7Od69KWj4eJP28kq13RhKay8JOoN0vPmspXJo1HY3
|
||||
CKuHRG+AP579dncdUnOMvfXOtkdM4vk0+hWASBQzM9xzVcztCa+koAugjVaLS9A+
|
||||
9uQoqEeVNTckxx0S2bYevRy7hGQmUJTyQm3j1zEUR5jpdbL83Fbq
|
||||
-----END RSA PRIVATE KEY-----
|
9
vendor/github.com/dgrijalva/jwt-go/test/sample_key.pub
generated
vendored
9
vendor/github.com/dgrijalva/jwt-go/test/sample_key.pub
generated
vendored
@ -1,9 +0,0 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4f5wg5l2hKsTeNem/V41
|
||||
fGnJm6gOdrj8ym3rFkEU/wT8RDtnSgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7
|
||||
mCpz9Er5qLaMXJwZxzHzAahlfA0icqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBp
|
||||
HssPnpYGIn20ZZuNlX2BrClciHhCPUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2
|
||||
XrHhR+1DcKJzQBSTAGnpYVaqpsARap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3b
|
||||
ODIRe1AuTyHceAbewn8b462yEWKARdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy
|
||||
7wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
45
vendor/github.com/go-kit/kit/.gitignore
generated
vendored
45
vendor/github.com/go-kit/kit/.gitignore
generated
vendored
@ -1,45 +0,0 @@
|
||||
examples/addsvc/addsvc
|
||||
examples/addsvc/client/client
|
||||
examples/apigateway/apigateway
|
||||
examples/profilesvc/profilesvc
|
||||
examples/stringsvc1/stringsvc1
|
||||
examples/stringsvc2/stringsvc2
|
||||
examples/stringsvc3/stringsvc3
|
||||
gover.coverprofile
|
||||
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
_old*
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
|
||||
# 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
|
||||
|
9
vendor/github.com/go-kit/kit/.travis.yml
generated
vendored
9
vendor/github.com/go-kit/kit/.travis.yml
generated
vendored
@ -1,9 +0,0 @@
|
||||
language: go
|
||||
|
||||
script: go test -race -v ./...
|
||||
|
||||
go:
|
||||
- 1.5.4
|
||||
- 1.6.3
|
||||
- 1.7.1
|
||||
- tip
|
106
vendor/github.com/go-kit/kit/auth/jwt/middleware_test.go
generated
vendored
106
vendor/github.com/go-kit/kit/auth/jwt/middleware_test.go
generated
vendored
@ -1,106 +0,0 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
kid = "kid"
|
||||
key = []byte("test_signing_key")
|
||||
method = jwt.SigningMethodHS256
|
||||
invalidMethod = jwt.SigningMethodRS256
|
||||
claims = Claims{"user": "go-kit"}
|
||||
// Signed tokens generated at https://jwt.io/
|
||||
signedKey = "eyJhbGciOiJIUzI1NiIsImtpZCI6ImtpZCIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ28ta2l0In0.14M2VmYyApdSlV_LZ88ajjwuaLeIFplB8JpyNy0A19E"
|
||||
invalidKey = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.vKVCKto-Wn6rgz3vBdaZaCBGfCBDTXOENSo_X2Gq7qA"
|
||||
)
|
||||
|
||||
func TestSigner(t *testing.T) {
|
||||
e := func(ctx context.Context, i interface{}) (interface{}, error) { return ctx, nil }
|
||||
|
||||
signer := NewSigner(kid, key, method, claims)(e)
|
||||
ctx, err := signer(context.Background(), struct{}{})
|
||||
if err != nil {
|
||||
t.Fatalf("Signer returned error: %s", err)
|
||||
}
|
||||
|
||||
token, ok := ctx.(context.Context).Value(JWTTokenContextKey).(string)
|
||||
if !ok {
|
||||
t.Fatal("Token did not exist in context")
|
||||
}
|
||||
|
||||
if token != signedKey {
|
||||
t.Fatalf("JWT tokens did not match: expecting %s got %s", signedKey, token)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWTParser(t *testing.T) {
|
||||
e := func(ctx context.Context, i interface{}) (interface{}, error) { return ctx, nil }
|
||||
|
||||
keys := func(token *jwt.Token) (interface{}, error) {
|
||||
return key, nil
|
||||
}
|
||||
|
||||
parser := NewParser(keys, method)(e)
|
||||
|
||||
// No Token is passed into the parser
|
||||
_, err := parser(context.Background(), struct{}{})
|
||||
if err == nil {
|
||||
t.Error("Parser should have returned an error")
|
||||
}
|
||||
|
||||
if err != ErrTokenContextMissing {
|
||||
t.Errorf("unexpected error returned, expected: %s got: %s", ErrTokenContextMissing, err)
|
||||
}
|
||||
|
||||
// Invalid Token is passed into the parser
|
||||
ctx := context.WithValue(context.Background(), JWTTokenContextKey, invalidKey)
|
||||
_, err = parser(ctx, struct{}{})
|
||||
if err == nil {
|
||||
t.Error("Parser should have returned an error")
|
||||
}
|
||||
|
||||
// Invalid Method is used in the parser
|
||||
badParser := NewParser(keys, invalidMethod)(e)
|
||||
ctx = context.WithValue(context.Background(), JWTTokenContextKey, signedKey)
|
||||
_, err = badParser(ctx, struct{}{})
|
||||
if err == nil {
|
||||
t.Error("Parser should have returned an error")
|
||||
}
|
||||
|
||||
if err != ErrUnexpectedSigningMethod {
|
||||
t.Errorf("unexpected error returned, expected: %s got: %s", ErrUnexpectedSigningMethod, err)
|
||||
}
|
||||
|
||||
// Invalid key is used in the parser
|
||||
invalidKeys := func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte("bad"), nil
|
||||
}
|
||||
|
||||
badParser = NewParser(invalidKeys, method)(e)
|
||||
ctx = context.WithValue(context.Background(), JWTTokenContextKey, signedKey)
|
||||
_, err = badParser(ctx, struct{}{})
|
||||
if err == nil {
|
||||
t.Error("Parser should have returned an error")
|
||||
}
|
||||
|
||||
// Correct token is passed into the parser
|
||||
ctx = context.WithValue(context.Background(), JWTTokenContextKey, signedKey)
|
||||
ctx1, err := parser(ctx, struct{}{})
|
||||
if err != nil {
|
||||
t.Fatalf("Parser returned error: %s", err)
|
||||
}
|
||||
|
||||
cl, ok := ctx1.(context.Context).Value(JWTClaimsContextKey).(Claims)
|
||||
if !ok {
|
||||
t.Fatal("Claims were not passed into context correctly")
|
||||
}
|
||||
|
||||
if cl["user"] != claims["user"] {
|
||||
t.Fatalf("JWT Claims.user did not match: expecting %s got %s", claims["user"], cl["user"])
|
||||
}
|
||||
}
|
126
vendor/github.com/go-kit/kit/auth/jwt/transport_test.go
generated
vendored
126
vendor/github.com/go-kit/kit/auth/jwt/transport_test.go
generated
vendored
@ -1,126 +0,0 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestToHTTPContext(t *testing.T) {
|
||||
reqFunc := ToHTTPContext()
|
||||
|
||||
// When the header doesn't exist
|
||||
ctx := reqFunc(context.Background(), &http.Request{})
|
||||
|
||||
if ctx.Value(JWTTokenContextKey) != nil {
|
||||
t.Error("Context shouldn't contain the encoded JWT")
|
||||
}
|
||||
|
||||
// Authorization header value has invalid format
|
||||
header := http.Header{}
|
||||
header.Set("Authorization", "no expected auth header format value")
|
||||
ctx = reqFunc(context.Background(), &http.Request{Header: header})
|
||||
|
||||
if ctx.Value(JWTTokenContextKey) != nil {
|
||||
t.Error("Context shouldn't contain the encoded JWT")
|
||||
}
|
||||
|
||||
// Authorization header is correct
|
||||
header.Set("Authorization", generateAuthHeaderFromToken(signedKey))
|
||||
ctx = reqFunc(context.Background(), &http.Request{Header: header})
|
||||
|
||||
token := ctx.Value(JWTTokenContextKey).(string)
|
||||
if token != signedKey {
|
||||
t.Errorf("Context doesn't contain the expected encoded token value; expected: %s, got: %s", signedKey, token)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromHTTPContext(t *testing.T) {
|
||||
reqFunc := FromHTTPContext()
|
||||
|
||||
// No JWT Token is passed in the context
|
||||
ctx := context.Background()
|
||||
r := http.Request{}
|
||||
reqFunc(ctx, &r)
|
||||
|
||||
token := r.Header.Get("Authorization")
|
||||
if token != "" {
|
||||
t.Error("authorization key should not exist in metadata")
|
||||
}
|
||||
|
||||
// Correct JWT Token is passed in the context
|
||||
ctx = context.WithValue(context.Background(), JWTTokenContextKey, signedKey)
|
||||
r = http.Request{Header: http.Header{}}
|
||||
reqFunc(ctx, &r)
|
||||
|
||||
token = r.Header.Get("Authorization")
|
||||
expected := generateAuthHeaderFromToken(signedKey)
|
||||
|
||||
if token != expected {
|
||||
t.Errorf("Authorization header does not contain the expected JWT token; expected %s, got %s", expected, token)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToGRPCContext(t *testing.T) {
|
||||
md := metadata.MD{}
|
||||
reqFunc := ToGRPCContext()
|
||||
|
||||
// No Authorization header is passed
|
||||
ctx := reqFunc(context.Background(), &md)
|
||||
token := ctx.Value(JWTTokenContextKey)
|
||||
if token != nil {
|
||||
t.Error("Context should not contain a JWT Token")
|
||||
}
|
||||
|
||||
// Invalid Authorization header is passed
|
||||
md["authorization"] = []string{fmt.Sprintf("%s", signedKey)}
|
||||
ctx = reqFunc(context.Background(), &md)
|
||||
token = ctx.Value(JWTTokenContextKey)
|
||||
if token != nil {
|
||||
t.Error("Context should not contain a JWT Token")
|
||||
}
|
||||
|
||||
// Authorization header is correct
|
||||
md["authorization"] = []string{fmt.Sprintf("Bearer %s", signedKey)}
|
||||
ctx = reqFunc(context.Background(), &md)
|
||||
token, ok := ctx.Value(JWTTokenContextKey).(string)
|
||||
if !ok {
|
||||
t.Fatal("JWT Token not passed to context correctly")
|
||||
}
|
||||
|
||||
if token != signedKey {
|
||||
t.Errorf("JWT tokens did not match: expecting %s got %s", signedKey, token)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromGRPCContext(t *testing.T) {
|
||||
reqFunc := FromGRPCContext()
|
||||
|
||||
// No JWT Token is passed in the context
|
||||
ctx := context.Background()
|
||||
md := metadata.MD{}
|
||||
reqFunc(ctx, &md)
|
||||
|
||||
_, ok := md["authorization"]
|
||||
if ok {
|
||||
t.Error("authorization key should not exist in metadata")
|
||||
}
|
||||
|
||||
// Correct JWT Token is passed in the context
|
||||
ctx = context.WithValue(context.Background(), JWTTokenContextKey, signedKey)
|
||||
md = metadata.MD{}
|
||||
reqFunc(ctx, &md)
|
||||
|
||||
token, ok := md["authorization"]
|
||||
if !ok {
|
||||
t.Fatal("JWT Token not passed to metadata correctly")
|
||||
}
|
||||
|
||||
if token[0] != generateAuthHeaderFromToken(signedKey) {
|
||||
t.Errorf("JWT tokens did not match: expecting %s got %s", signedKey, token[0])
|
||||
}
|
||||
}
|
10
vendor/github.com/go-kit/kit/circuitbreaker/doc.go
generated
vendored
10
vendor/github.com/go-kit/kit/circuitbreaker/doc.go
generated
vendored
@ -1,10 +0,0 @@
|
||||
// Package circuitbreaker implements the circuit breaker pattern.
|
||||
//
|
||||
// Circuit breakers prevent thundering herds, and improve resiliency against
|
||||
// intermittent errors. Every client-side endpoint should be wrapped in a
|
||||
// circuit breaker.
|
||||
//
|
||||
// We provide several implementations in this package, but if you're looking
|
||||
// for guidance, Gobreaker is probably the best place to start. It has a
|
||||
// simple and intuitive API, and is well-tested.
|
||||
package circuitbreaker
|
21
vendor/github.com/go-kit/kit/circuitbreaker/gobreaker.go
generated
vendored
21
vendor/github.com/go-kit/kit/circuitbreaker/gobreaker.go
generated
vendored
@ -1,21 +0,0 @@
|
||||
package circuitbreaker
|
||||
|
||||
import (
|
||||
"github.com/sony/gobreaker"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
// Gobreaker returns an endpoint.Middleware that implements the circuit
|
||||
// breaker pattern using the sony/gobreaker package. Only errors returned by
|
||||
// the wrapped endpoint count against the circuit breaker's error count.
|
||||
//
|
||||
// See http://godoc.org/github.com/sony/gobreaker for more information.
|
||||
func Gobreaker(cb *gobreaker.CircuitBreaker) endpoint.Middleware {
|
||||
return func(next endpoint.Endpoint) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return cb.Execute(func() (interface{}, error) { return next(ctx, request) })
|
||||
}
|
||||
}
|
||||
}
|
19
vendor/github.com/go-kit/kit/circuitbreaker/gobreaker_test.go
generated
vendored
19
vendor/github.com/go-kit/kit/circuitbreaker/gobreaker_test.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
package circuitbreaker_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sony/gobreaker"
|
||||
|
||||
"github.com/go-kit/kit/circuitbreaker"
|
||||
)
|
||||
|
||||
func TestGobreaker(t *testing.T) {
|
||||
var (
|
||||
breaker = circuitbreaker.Gobreaker(gobreaker.NewCircuitBreaker(gobreaker.Settings{}))
|
||||
primeWith = 100
|
||||
shouldPass = func(n int) bool { return n <= 5 } // https://github.com/sony/gobreaker/blob/bfa846d/gobreaker.go#L76
|
||||
circuitOpenError = "circuit breaker is open"
|
||||
)
|
||||
testFailingEndpoint(t, breaker, primeWith, shouldPass, 0, circuitOpenError)
|
||||
}
|
38
vendor/github.com/go-kit/kit/circuitbreaker/handy_breaker.go
generated
vendored
38
vendor/github.com/go-kit/kit/circuitbreaker/handy_breaker.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
package circuitbreaker
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/streadway/handy/breaker"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
// HandyBreaker returns an endpoint.Middleware that implements the circuit
|
||||
// breaker pattern using the streadway/handy/breaker package. Only errors
|
||||
// returned by the wrapped endpoint count against the circuit breaker's error
|
||||
// count.
|
||||
//
|
||||
// See http://godoc.org/github.com/streadway/handy/breaker for more
|
||||
// information.
|
||||
func HandyBreaker(cb breaker.Breaker) endpoint.Middleware {
|
||||
return func(next endpoint.Endpoint) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
if !cb.Allow() {
|
||||
return nil, breaker.ErrCircuitOpen
|
||||
}
|
||||
|
||||
defer func(begin time.Time) {
|
||||
if err == nil {
|
||||
cb.Success(time.Since(begin))
|
||||
} else {
|
||||
cb.Failure(time.Since(begin))
|
||||
}
|
||||
}(time.Now())
|
||||
|
||||
response, err = next(ctx, request)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
20
vendor/github.com/go-kit/kit/circuitbreaker/handy_breaker_test.go
generated
vendored
20
vendor/github.com/go-kit/kit/circuitbreaker/handy_breaker_test.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
package circuitbreaker_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
handybreaker "github.com/streadway/handy/breaker"
|
||||
|
||||
"github.com/go-kit/kit/circuitbreaker"
|
||||
)
|
||||
|
||||
func TestHandyBreaker(t *testing.T) {
|
||||
var (
|
||||
failureRatio = 0.05
|
||||
breaker = circuitbreaker.HandyBreaker(handybreaker.NewBreaker(failureRatio))
|
||||
primeWith = handybreaker.DefaultMinObservations * 10
|
||||
shouldPass = func(n int) bool { return (float64(n) / float64(primeWith+n)) <= failureRatio }
|
||||
openCircuitError = handybreaker.ErrCircuitOpen.Error()
|
||||
)
|
||||
testFailingEndpoint(t, breaker, primeWith, shouldPass, 0, openCircuitError)
|
||||
}
|
30
vendor/github.com/go-kit/kit/circuitbreaker/hystrix.go
generated
vendored
30
vendor/github.com/go-kit/kit/circuitbreaker/hystrix.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
package circuitbreaker
|
||||
|
||||
import (
|
||||
"github.com/afex/hystrix-go/hystrix"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
// Hystrix returns an endpoint.Middleware that implements the circuit
|
||||
// breaker pattern using the afex/hystrix-go package.
|
||||
//
|
||||
// When using this circuit breaker, please configure your commands separately.
|
||||
//
|
||||
// See https://godoc.org/github.com/afex/hystrix-go/hystrix for more
|
||||
// information.
|
||||
func Hystrix(commandName string) endpoint.Middleware {
|
||||
return func(next endpoint.Endpoint) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
|
||||
var resp interface{}
|
||||
if err := hystrix.Do(commandName, func() (err error) {
|
||||
resp, err = next(ctx, request)
|
||||
return err
|
||||
}, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
}
|
40
vendor/github.com/go-kit/kit/circuitbreaker/hystrix_test.go
generated
vendored
40
vendor/github.com/go-kit/kit/circuitbreaker/hystrix_test.go
generated
vendored
@ -1,40 +0,0 @@
|
||||
package circuitbreaker_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
stdlog "log"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/afex/hystrix-go/hystrix"
|
||||
|
||||
"github.com/go-kit/kit/circuitbreaker"
|
||||
)
|
||||
|
||||
func TestHystrix(t *testing.T) {
|
||||
stdlog.SetOutput(ioutil.Discard)
|
||||
|
||||
const (
|
||||
commandName = "my-endpoint"
|
||||
errorPercent = 5
|
||||
maxConcurrent = 1000
|
||||
)
|
||||
hystrix.ConfigureCommand(commandName, hystrix.CommandConfig{
|
||||
ErrorPercentThreshold: errorPercent,
|
||||
MaxConcurrentRequests: maxConcurrent,
|
||||
})
|
||||
|
||||
var (
|
||||
breaker = circuitbreaker.Hystrix(commandName)
|
||||
primeWith = hystrix.DefaultVolumeThreshold * 2
|
||||
shouldPass = func(n int) bool { return (float64(n) / float64(primeWith+n)) <= (float64(errorPercent-1) / 100.0) }
|
||||
openCircuitError = hystrix.ErrCircuitOpen.Error()
|
||||
)
|
||||
|
||||
// hystrix-go uses buffered channels to receive reports on request success/failure,
|
||||
// and so is basically impossible to test deterministically. We have to make sure
|
||||
// the report buffer is emptied, by injecting a sleep between each invocation.
|
||||
requestDelay := 5 * time.Millisecond
|
||||
|
||||
testFailingEndpoint(t, breaker, primeWith, shouldPass, requestDelay, openCircuitError)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user