diff --git a/.gitignore b/.gitignore index bb381fc672c6..3eaeb89a5981 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /.idea/ /test/path /golangci-lint +/tools/ diff --git a/.travis.yml b/.travis.yml index e23dec5a5701..bf593a692c60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,6 @@ go: - 1.11.x - 1.12.x -before_script: - - go get github.com/valyala/quicktemplate - script: make check_generated test after_success: diff --git a/Makefile b/Makefile index 29aca2b66097..6c34319d1650 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,17 @@ +.DEFAULT_GOAL = test +.PHONY: FORCE +export GO111MODULE = on + +# Build + +build: golangci-lint +clean: + rm -f golangci-lint test/path + rm -rf tools +.PHONY: build clean + +# Test + test: build GL_TEST_RUN=1 ./golangci-lint run -v GL_TEST_RUN=1 ./golangci-lint run --fast --no-config -v --skip-dirs 'test/testdata_etc,pkg/golinters/goanalysis/(checker|passes)' @@ -6,34 +20,81 @@ test: build build: go build -o golangci-lint ./cmd/golangci-lint +.PHONY: test test_race: go build -race -o golangci-lint ./cmd/golangci-lint GL_TEST_RUN=1 ./golangci-lint run -v --deadline=5m +.PHONY: test_race test_linters: GL_TEST_RUN=1 go test -v ./test -count 1 -run TestSourcesFromTestdataWithIssuesDir/$T +.PHONY: test_linters -assets: - svg-term --cast=183662 --out docs/demo.svg --window --width 110 --height 30 --from 2000 --to 20000 --profile Dracula --term iterm2 - -readme: - go run ./scripts/gen_readme/main.go +# Maintenance -gen: - go generate ./... +generate: docs/demo.svg README.md install.sh pkg/logutils/log_mock.go vendor +maintainer-clean: clean + rm -f docs/demo.svg README.md install.sh pkg/logutils/log_mock.go + rm -rf vendor +.PHONY: generate maintainer-clean check_generated: - make readme && git diff --exit-code # check no changes + $(MAKE) --always-make generate + git diff --exit-code # check no changes +.PHONY: check_generated release: rm -rf dist curl -sL https://git.io/goreleaser | bash +.PHONY: release -update_deps: - GO111MODULE=on go mod verify - GO111MODULE=on go mod tidy - rm -rf vendor - GO111MODULE=on go mod vendor +# Non-PHONY targets (real files) -.PHONY: test +golangci-lint: FORCE pkg/logutils/log_mock.go + go build -o $@ ./cmd/golangci-lint + +tools/mockgen: go.mod go.sum + GOBIN=$(CURDIR)/tools go install github.com/golang/mock/mockgen + +tools/goimports: go.mod go.sum + GOBIN=$(CURDIR)/tools go install golang.org/x/tools/cmd/goimports + +tools/go.mod: + @mkdir -p tools + @rm -f $@ + cd tools && go mod init local-tools + +tools/godownloader: Makefile tools/go.mod + cd tools && GOBIN=$(CURDIR)/tools go get github.com/goreleaser/godownloader@3b90d248ba30307915288f08ab3f2fc2d9f6710c + +tools/svg-term: + @mkdir -p tools + cd tools && npm install svg-term-cli + ln -sf node_modules/.bin/svg-term $@ + +tools/Dracula.itermcolors: + @mkdir -p tools + curl -fL -o $@ https://raw.githubusercontent.com/dracula/iterm/master/Dracula.itermcolors + +docs/demo.svg: tools/svg-term tools/Dracula.itermcolors + PATH=$(CURDIR)/tools:$${PATH} svg-term --cast=183662 --out docs/demo.svg --window --width 110 --height 30 --from 2000 --to 20000 --profile ./tools/Dracula.itermcolors --term iterm2 + +install.sh: tools/godownloader .goreleaser.yml + PATH=$(CURDIR)/tools:$${PATH} tools/godownloader .goreleaser.yml | sed '/DO NOT EDIT/s/ on [0-9TZ:-]*//' > $@ + +README.md: FORCE golangci-lint + go run ./scripts/gen_readme/main.go + +pkg/logutils/log_mock.go: tools/mockgen tools/goimports pkg/logutils/log.go + @rm -f $@ + PATH=$(CURDIR)/tools:$${PATH} go generate ./... + +go.mod: FORCE + go mod verify + go mod tidy +go.sum: go.mod + +vendor: go.mod go.sum + rm -rf vendor + go mod vendor diff --git a/go.mod b/go.mod index db0ed1cc5e51..c2486e955132 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/go-lintpack/lintpack v0.5.2 github.com/go-ole/go-ole v1.2.1 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/golang/mock v1.1.1 + github.com/golang/mock v1.0.0 github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a github.com/golangci/errcheck v0.0.0-20181003203344-ef45e06d44b6 @@ -49,6 +49,7 @@ require ( github.com/spf13/pflag v1.0.1 github.com/spf13/viper v1.0.2 github.com/stretchr/testify v1.2.2 + github.com/valyala/quicktemplate v1.1.1 github.com/timakin/bodyclose v0.0.0-20190407043127-4a873e97b2bb golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect golang.org/x/net v0.0.0-20190313220215-9f648a60d977 // indirect diff --git a/go.sum b/go.sum index a6184e29ce2d..d08aa2d4265d 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.0.0 h1:HzcpUG60pfl43n9d2qbdi/3l1uKpAmxlfWEPWtV/QxM= +github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= @@ -88,6 +88,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -152,6 +156,12 @@ github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso= github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= +github.com/valyala/quicktemplate v1.1.1 h1:C58y/wN0FMTi2PR0n3onltemfFabany53j7M6SDDB8k= +github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/timakin/bodyclose v0.0.0-20190407043127-4a873e97b2bb h1:lI9ufgFfvuqRctP9Ny8lDDLbSWCMxBPletcSqrnyFYM= github.com/timakin/bodyclose v0.0.0-20190407043127-4a873e97b2bb/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -160,6 +170,7 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= diff --git a/install.sh b/install.sh index 9446c441ab28..dc993a8a4559 100644 --- a/install.sh +++ b/install.sh @@ -1,6 +1,6 @@ #!/bin/sh set -e -# Code generated by godownloader on 2018-06-05T12:04:55Z. DO NOT EDIT. +# Code generated by godownloader. DO NOT EDIT. # usage() { diff --git a/pkg/logutils/log.go b/pkg/logutils/log.go index 178075bc4645..944c26329a4e 100644 --- a/pkg/logutils/log.go +++ b/pkg/logutils/log.go @@ -1,6 +1,7 @@ package logutils //go:generate mockgen -package logutils -source log.go -destination log_mock.go +//go:generate goimports -w log_mock.go type Log interface { Fatalf(format string, args ...interface{}) diff --git a/scripts/gen_readme/main.go b/scripts/gen_readme/main.go index b0db3fd9ebb7..f649dfab9652 100644 --- a/scripts/gen_readme/main.go +++ b/scripts/gen_readme/main.go @@ -53,18 +53,18 @@ func buildTemplateContext() (map[string]interface{}, error) { return nil, fmt.Errorf("can't read .golangci.example.yml: %s", err) } - if err = exec.Command("go", "install", "./cmd/...").Run(); err != nil { + if err = exec.Command("make", "build").Run(); err != nil { return nil, fmt.Errorf("can't run go install: %s", err) } - lintersOut, err := exec.Command("golangci-lint", "help", "linters").Output() + lintersOut, err := exec.Command("./golangci-lint", "help", "linters").Output() if err != nil { return nil, fmt.Errorf("can't run linters cmd: %s", err) } lintersOutParts := bytes.Split(lintersOut, []byte("\n\n")) - helpCmd := exec.Command("golangci-lint", "run", "-h") + helpCmd := exec.Command("./golangci-lint", "run", "-h") helpCmd.Env = append(helpCmd.Env, os.Environ()...) helpCmd.Env = append(helpCmd.Env, "HELP_RUN=1") // make default concurrency stable: don't depend on machine CPU number help, err := helpCmd.Output() diff --git a/test/data.go b/test/data.go index 710e3914b7eb..e5320b3bbb20 100644 --- a/test/data.go +++ b/test/data.go @@ -3,7 +3,7 @@ package test import "path/filepath" const testdataDir = "testdata" -const binName = "golangci-lint" +const binName = "../golangci-lint" func getProjectRoot() string { return filepath.Join("..", "...") diff --git a/test/run_test.go b/test/run_test.go index a191341dab79..0f8a79073f85 100644 --- a/test/run_test.go +++ b/test/run_test.go @@ -10,6 +10,8 @@ import ( "github.com/golangci/golangci-lint/test/testshared" "github.com/golangci/golangci-lint/pkg/exitcodes" + + _ "github.com/valyala/quicktemplate" ) func getCommonRunArgs() []string { @@ -25,13 +27,13 @@ func TestAutogeneratedNoIssues(t *testing.T) { } func TestEmptyDirRun(t *testing.T) { - testshared.NewLintRunner(t).Run(getTestDataDir("nogofiles")). + testshared.NewLintRunner(t, "GO111MODULE=off").Run(getTestDataDir("nogofiles")). ExpectExitCode(exitcodes.NoGoFiles). ExpectOutputContains(": no go files to analyze") } func TestNotExistingDirRun(t *testing.T) { - testshared.NewLintRunner(t).Run(getTestDataDir("no_such_dir")). + testshared.NewLintRunner(t, "GO111MODULE=off").Run(getTestDataDir("no_such_dir")). ExpectExitCode(exitcodes.Failure). ExpectOutputContains(`cannot find package \"./testdata/no_such_dir\"`) } diff --git a/test/testshared/testshared.go b/test/testshared/testshared.go index 1ea716528dd9..18eff223a48d 100644 --- a/test/testshared/testshared.go +++ b/test/testshared/testshared.go @@ -4,7 +4,6 @@ import ( "io/ioutil" "os" "os/exec" - "path/filepath" "strings" "syscall" @@ -17,27 +16,26 @@ import ( type LintRunner struct { t assert.TestingT log logutils.Log - - installed bool + env []string } -func NewLintRunner(t assert.TestingT) *LintRunner { +func NewLintRunner(t assert.TestingT, environ ...string) *LintRunner { log := logutils.NewStderrLog("test") log.SetLevel(logutils.LogLevelInfo) return &LintRunner{ t: t, log: log, + env: environ, } } func (r *LintRunner) Install() { - if r.installed { + if _, err := os.Stat("../golangci-lint"); err == nil { return } - cmd := exec.Command("go", "install", filepath.Join("..", "cmd", "golangci-lint")) + cmd := exec.Command("make", "-C", "..", "build") assert.NoError(r.t, cmd.Run(), "Can't go install golangci-lint") - r.installed = true } type RunResult struct { @@ -82,7 +80,8 @@ func (r *LintRunner) Run(args ...string) *RunResult { runArgs := append([]string{"run"}, args...) r.log.Infof("golangci-lint %s", strings.Join(runArgs, " ")) - cmd := exec.Command("golangci-lint", runArgs...) + cmd := exec.Command("../golangci-lint", runArgs...) + cmd.Env = append(os.Environ(), r.env...) out, err := cmd.CombinedOutput() if err != nil { if exitError, ok := err.(*exec.ExitError); ok { diff --git a/vendor/github.com/golang/mock/gomock/call.go b/vendor/github.com/golang/mock/gomock/call.go index a3fa1ae419d1..cc8dfffeb6c1 100644 --- a/vendor/github.com/golang/mock/gomock/call.go +++ b/vendor/github.com/golang/mock/gomock/call.go @@ -17,7 +17,6 @@ package gomock import ( "fmt" "reflect" - "strconv" "strings" ) @@ -25,11 +24,11 @@ import ( type Call struct { t TestReporter // for triggering test failures on invalid call setup - receiver interface{} // the receiver of the method call - method string // the name of the method - methodType reflect.Type // the type of the method - args []Matcher // the args - origin string // file and line number of call setup + receiver interface{} // the receiver of the method call + method string // the name of the method + methodType reflect.Type // the type of the method + args []Matcher // the args + rets []interface{} // the return values (if any) preReqs []*Call // prerequisite calls @@ -38,44 +37,9 @@ type Call struct { numCalls int // actual number made - // actions are called when this Call is called. Each action gets the args and - // can set the return values by returning a non-nil slice. Actions run in the - // order they are created. - actions []func([]interface{}) []interface{} -} - -// newCall creates a *Call. It requires the method type in order to support -// unexported methods. -func newCall(t TestReporter, receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { - if h, ok := t.(testHelper); ok { - h.Helper() - } - - // TODO: check arity, types. - margs := make([]Matcher, len(args)) - for i, arg := range args { - if m, ok := arg.(Matcher); ok { - margs[i] = m - } else if arg == nil { - // Handle nil specially so that passing a nil interface value - // will match the typed nils of concrete args. - margs[i] = Nil() - } else { - margs[i] = Eq(arg) - } - } - - origin := callerInfo(3) - actions := []func([]interface{}) []interface{}{func([]interface{}) []interface{} { - // Synthesize the zero value for each of the return args' types. - rets := make([]interface{}, methodType.NumOut()) - for i := 0; i < methodType.NumOut(); i++ { - rets[i] = reflect.Zero(methodType.Out(i)).Interface() - } - return rets - }} - return &Call{t: t, receiver: receiver, method: method, methodType: methodType, - args: margs, origin: origin, minCalls: 1, maxCalls: 1, actions: actions} + // Actions + doFunc reflect.Value + setArgs map[int]reflect.Value } // AnyTimes allows the expectation to be called 0 or more times @@ -104,69 +68,19 @@ func (c *Call) MaxTimes(n int) *Call { return c } -// DoAndReturn declares the action to run when the call is matched. -// The return values from this function are returned by the mocked function. -// It takes an interface{} argument to support n-arity functions. -func (c *Call) DoAndReturn(f interface{}) *Call { - // TODO: Check arity and types here, rather than dying badly elsewhere. - v := reflect.ValueOf(f) - - c.addAction(func(args []interface{}) []interface{} { - vargs := make([]reflect.Value, len(args)) - ft := v.Type() - for i := 0; i < len(args); i++ { - if args[i] != nil { - vargs[i] = reflect.ValueOf(args[i]) - } else { - // Use the zero value for the arg. - vargs[i] = reflect.Zero(ft.In(i)) - } - } - vrets := v.Call(vargs) - rets := make([]interface{}, len(vrets)) - for i, ret := range vrets { - rets[i] = ret.Interface() - } - return rets - }) - return c -} - -// Do declares the action to run when the call is matched. The function's -// return values are ignored to retain backward compatibility. To use the -// return values call DoAndReturn. +// Do declares the action to run when the call is matched. // It takes an interface{} argument to support n-arity functions. func (c *Call) Do(f interface{}) *Call { // TODO: Check arity and types here, rather than dying badly elsewhere. - v := reflect.ValueOf(f) - - c.addAction(func(args []interface{}) []interface{} { - vargs := make([]reflect.Value, len(args)) - ft := v.Type() - for i := 0; i < len(args); i++ { - if args[i] != nil { - vargs[i] = reflect.ValueOf(args[i]) - } else { - // Use the zero value for the arg. - vargs[i] = reflect.Zero(ft.In(i)) - } - } - v.Call(vargs) - return nil - }) + c.doFunc = reflect.ValueOf(f) return c } -// Return declares the values to be returned by the mocked function call. func (c *Call) Return(rets ...interface{}) *Call { - if h, ok := c.t.(testHelper); ok { - h.Helper() - } - mt := c.methodType if len(rets) != mt.NumOut() { - c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d [%s]", - c.receiver, c.method, len(rets), mt.NumOut(), c.origin) + c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d", + c.receiver, c.method, len(rets), mt.NumOut()) } for i, ret := range rets { if got, want := reflect.TypeOf(ret), mt.Out(i); got == want { @@ -177,8 +91,8 @@ func (c *Call) Return(rets ...interface{}) *Call { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: // ok default: - c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable [%s]", - i, c.receiver, c.method, want, c.origin) + c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable", + i, c.receiver, c.method, want) } } else if got.AssignableTo(want) { // Assignable type relation. Make the assignment now so that the generated code @@ -187,38 +101,31 @@ func (c *Call) Return(rets ...interface{}) *Call { v.Set(reflect.ValueOf(ret)) rets[i] = v.Interface() } else { - c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v [%s]", - i, c.receiver, c.method, got, want, c.origin) + c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v", + i, c.receiver, c.method, got, want) } } - c.addAction(func([]interface{}) []interface{} { - return rets - }) - + c.rets = rets return c } -// Times declares the exact number of times a function call is expected to be executed. func (c *Call) Times(n int) *Call { c.minCalls, c.maxCalls = n, n return c } // SetArg declares an action that will set the nth argument's value, -// indirected through a pointer. Or, in the case of a slice, SetArg -// will copy value's elements into the nth argument. +// indirected through a pointer. func (c *Call) SetArg(n int, value interface{}) *Call { - if h, ok := c.t.(testHelper); ok { - h.Helper() + if c.setArgs == nil { + c.setArgs = make(map[int]reflect.Value) } - mt := c.methodType // TODO: This will break on variadic methods. // We will need to check those at invocation time. if n < 0 || n >= mt.NumIn() { - c.t.Fatalf("SetArg(%d, ...) called for a method with %d args [%s]", - n, mt.NumIn(), c.origin) + c.t.Fatalf("SetArg(%d, ...) called for a method with %d args", n, mt.NumIn()) } // Permit setting argument through an interface. // In the interface case, we don't (nay, can't) check the type here. @@ -227,28 +134,14 @@ func (c *Call) SetArg(n int, value interface{}) *Call { case reflect.Ptr: dt := at.Elem() if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) { - c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v [%s]", - n, vt, dt, c.origin) + c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v", n, vt, dt) } case reflect.Interface: // nothing to do - case reflect.Slice: - // nothing to do default: - c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice type %v [%s]", - n, at, c.origin) + c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v", n, at) } - - c.addAction(func(args []interface{}) []interface{} { - v := reflect.ValueOf(value) - switch reflect.TypeOf(args[n]).Kind() { - case reflect.Slice: - setSlice(args[n], v) - default: - reflect.ValueOf(args[n]).Elem().Set(v) - } - return nil - }) + c.setArgs[n] = reflect.ValueOf(value) return c } @@ -264,12 +157,8 @@ func (c *Call) isPreReq(other *Call) bool { // After declares that the call may only match after preReq has been exhausted. func (c *Call) After(preReq *Call) *Call { - if h, ok := c.t.(testHelper); ok { - h.Helper() - } - if c == preReq { - c.t.Fatalf("A call isn't allowed to be its own prerequisite") + c.t.Fatalf("A call isn't allowed to be it's own prerequisite") } if preReq.isPreReq(c) { c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq) @@ -279,7 +168,7 @@ func (c *Call) After(preReq *Call) *Call { return c } -// Returns true if the minimum number of calls have been made. +// Returns true iff the minimum number of calls have been made. func (c *Call) satisfied() bool { return c.numCalls >= c.minCalls } @@ -295,108 +184,31 @@ func (c *Call) String() string { args[i] = arg.String() } arguments := strings.Join(args, ", ") - return fmt.Sprintf("%T.%v(%s) %s", c.receiver, c.method, arguments, c.origin) + return fmt.Sprintf("%T.%v(%s)", c.receiver, c.method, arguments) } // Tests if the given call matches the expected call. -// If yes, returns nil. If no, returns error with message explaining why it does not match. -func (c *Call) matches(args []interface{}) error { - if !c.methodType.IsVariadic() { - if len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", - c.origin, len(args), len(c.args)) - } - - for i, m := range c.args { - if !m.Matches(args[i]) { - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", - c.origin, strconv.Itoa(i), args[i], m) - } - } - } else { - if len(c.args) < c.methodType.NumIn()-1 { - return fmt.Errorf("Expected call at %s has the wrong number of matchers. Got: %d, want: %d", - c.origin, len(c.args), c.methodType.NumIn()-1) - } - if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: %d", - c.origin, len(args), len(c.args)) - } - if len(args) < len(c.args)-1 { - return fmt.Errorf("Expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d", - c.origin, len(args), len(c.args)-1) - } - - for i, m := range c.args { - if i < c.methodType.NumIn()-1 { - // Non-variadic args - if !m.Matches(args[i]) { - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", - c.origin, strconv.Itoa(i), args[i], m) - } - continue - } - // The last arg has a possibility of a variadic argument, so let it branch - - // sample: Foo(a int, b int, c ...int) - if i < len(c.args) && i < len(args) { - if m.Matches(args[i]) { - // Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any()) - // Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher) - // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC) - // Got Foo(a, b) want Foo(matcherA, matcherB) - // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD) - continue - } - } - - // The number of actual args don't match the number of matchers, - // or the last matcher is a slice and the last arg is not. - // If this function still matches it is because the last matcher - // matches all the remaining arguments or the lack of any. - // Convert the remaining arguments, if any, into a slice of the - // expected type. - vargsType := c.methodType.In(c.methodType.NumIn() - 1) - vargs := reflect.MakeSlice(vargsType, 0, len(args)-i) - for _, arg := range args[i:] { - vargs = reflect.Append(vargs, reflect.ValueOf(arg)) - } - if m.Matches(vargs.Interface()) { - // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any()) - // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher) - // Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any()) - // Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher) - break - } - // Wrong number of matchers or not match. Fail. - // Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD) - // Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD) - // Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE) - // Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD) - // Got Foo(a, b, c) want Foo(matcherA, matcherB) - return fmt.Errorf("Expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v", - c.origin, strconv.Itoa(i), args[i:], c.args[i]) - +func (c *Call) matches(args []interface{}) bool { + if len(args) != len(c.args) { + return false + } + for i, m := range c.args { + if !m.Matches(args[i]) { + return false } } // Check that all prerequisite calls have been satisfied. for _, preReqCall := range c.preReqs { if !preReqCall.satisfied() { - return fmt.Errorf("Expected call at %s doesn't have a prerequisite call satisfied:\n%v\nshould be called before:\n%v", - c.origin, preReqCall, c) + return false } } - // Check that the call is not exhausted. - if c.exhausted() { - return fmt.Errorf("Expected call at %s has already been called the max number of times.", c.origin) - } - - return nil + return true } -// dropPrereqs tells the expected Call to not re-check prerequisite calls any +// dropPrereqs tells the expected Call to not re-check prerequite calls any // longer, and to return its current set. func (c *Call) dropPrereqs() (preReqs []*Call) { preReqs = c.preReqs @@ -404,9 +216,38 @@ func (c *Call) dropPrereqs() (preReqs []*Call) { return } -func (c *Call) call(args []interface{}) []func([]interface{}) []interface{} { +func (c *Call) call(args []interface{}) (rets []interface{}, action func()) { c.numCalls++ - return c.actions + + // Actions + if c.doFunc.IsValid() { + doArgs := make([]reflect.Value, len(args)) + ft := c.doFunc.Type() + for i := 0; i < len(args); i++ { + if args[i] != nil { + doArgs[i] = reflect.ValueOf(args[i]) + } else { + // Use the zero value for the arg. + doArgs[i] = reflect.Zero(ft.In(i)) + } + } + action = func() { c.doFunc.Call(doArgs) } + } + for n, v := range c.setArgs { + reflect.ValueOf(args[n]).Elem().Set(v) + } + + rets = c.rets + if rets == nil { + // Synthesize the zero value for each of the return args' types. + mt := c.methodType + rets = make([]interface{}, mt.NumOut()) + for i := 0; i < mt.NumOut(); i++ { + rets[i] = reflect.Zero(mt.Out(i)).Interface() + } + } + + return } // InOrder declares that the given calls should occur in order. @@ -415,14 +256,3 @@ func InOrder(calls ...*Call) { calls[i].After(calls[i-1]) } } - -func setSlice(arg interface{}, v reflect.Value) { - va := reflect.ValueOf(arg) - for i := 0; i < v.Len(); i++ { - va.Index(i).Set(v.Index(i)) - } -} - -func (c *Call) addAction(action func([]interface{}) []interface{}) { - c.actions = append(c.actions, action) -} diff --git a/vendor/github.com/golang/mock/gomock/callset.go b/vendor/github.com/golang/mock/gomock/callset.go index c44a8a585b32..1b7de4c0b327 100644 --- a/vendor/github.com/golang/mock/gomock/callset.go +++ b/vendor/github.com/golang/mock/gomock/callset.go @@ -14,95 +14,63 @@ package gomock -import ( - "bytes" - "fmt" -) - // callSet represents a set of expected calls, indexed by receiver and method // name. -type callSet struct { - // Calls that are still expected. - expected map[callSetKey][]*Call - // Calls that have been exhausted. - exhausted map[callSetKey][]*Call -} - -// callSetKey is the key in the maps in callSet -type callSetKey struct { - receiver interface{} - fname string -} - -func newCallSet() *callSet { - return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)} -} +type callSet map[interface{}]map[string][]*Call // Add adds a new expected call. func (cs callSet) Add(call *Call) { - key := callSetKey{call.receiver, call.method} - m := cs.expected - if call.exhausted() { - m = cs.exhausted + methodMap, ok := cs[call.receiver] + if !ok { + methodMap = make(map[string][]*Call) + cs[call.receiver] = methodMap } - m[key] = append(m[key], call) + methodMap[call.method] = append(methodMap[call.method], call) } // Remove removes an expected call. func (cs callSet) Remove(call *Call) { - key := callSetKey{call.receiver, call.method} - calls := cs.expected[key] - for i, c := range calls { + methodMap, ok := cs[call.receiver] + if !ok { + return + } + sl := methodMap[call.method] + for i, c := range sl { if c == call { - // maintain order for remaining calls - cs.expected[key] = append(calls[:i], calls[i+1:]...) - cs.exhausted[key] = append(cs.exhausted[key], call) + // quick removal; we don't need to maintain call order + if len(sl) > 1 { + sl[i] = sl[len(sl)-1] + } + methodMap[call.method] = sl[:len(sl)-1] break } } } -// FindMatch searches for a matching call. Returns error with explanation message if no call matched. -func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) (*Call, error) { - key := callSetKey{receiver, method} - - // Search through the expected calls. - expected := cs.expected[key] - var callsErrors bytes.Buffer - for _, call := range expected { - err := call.matches(args) - if err != nil { - fmt.Fprintf(&callsErrors, "\n%v", err) - } else { - return call, nil - } +// FindMatch searches for a matching call. Returns nil if no call matched. +func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) *Call { + methodMap, ok := cs[receiver] + if !ok { + return nil } - - // If we haven't found a match then search through the exhausted calls so we - // get useful error messages. - exhausted := cs.exhausted[key] - for _, call := range exhausted { - if err := call.matches(args); err != nil { - fmt.Fprintf(&callsErrors, "\n%v", err) - } + calls, ok := methodMap[method] + if !ok { + return nil } - if len(expected)+len(exhausted) == 0 { - fmt.Fprintf(&callsErrors, "there are no expected calls of the method %q for that receiver", method) - } - - return nil, fmt.Errorf(callsErrors.String()) -} - -// Failures returns the calls that are not satisfied. -func (cs callSet) Failures() []*Call { - failures := make([]*Call, 0, len(cs.expected)) - for _, calls := range cs.expected { - for _, call := range calls { - if !call.satisfied() { - failures = append(failures, call) - } + // Search through the unordered set of calls expected on a method on a + // receiver. + for _, call := range calls { + // A call should not normally still be here if exhausted, + // but it can happen if, for instance, .Times(0) was used. + // Pretend the call doesn't match. + if call.exhausted() { + continue + } + if call.matches(args) { + return call } } - return failures + + return nil } diff --git a/vendor/github.com/golang/mock/gomock/controller.go b/vendor/github.com/golang/mock/gomock/controller.go index a7b79188bc8c..6bff78d1dce1 100644 --- a/vendor/github.com/golang/mock/gomock/controller.go +++ b/vendor/github.com/golang/mock/gomock/controller.go @@ -57,9 +57,7 @@ package gomock import ( "fmt" - "golang.org/x/net/context" "reflect" - "runtime" "sync" ) @@ -76,40 +74,17 @@ type TestReporter interface { type Controller struct { mu sync.Mutex t TestReporter - expectedCalls *callSet - finished bool + expectedCalls callSet } func NewController(t TestReporter) *Controller { return &Controller{ t: t, - expectedCalls: newCallSet(), + expectedCalls: make(callSet), } } -type cancelReporter struct { - t TestReporter - cancel func() -} - -func (r *cancelReporter) Errorf(format string, args ...interface{}) { r.t.Errorf(format, args...) } -func (r *cancelReporter) Fatalf(format string, args ...interface{}) { - defer r.cancel() - r.t.Fatalf(format, args...) -} - -// WithContext returns a new Controller and a Context, which is cancelled on any -// fatal failure. -func WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) { - ctx, cancel := context.WithCancel(ctx) - return NewController(&cancelReporter{t, cancel}), ctx -} - func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call { - if h, ok := ctrl.t.(testHelper); ok { - h.Helper() - } - recv := reflect.ValueOf(receiver) for i := 0; i < recv.Type().NumMethod(); i++ { if recv.Type().Method(i).Name == method { @@ -117,77 +92,73 @@ func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ... } } ctrl.t.Fatalf("gomock: failed finding method %s on %T", method, receiver) - panic("unreachable") + // In case t.Fatalf does not panic. + panic(fmt.Sprintf("gomock: failed finding method %s on %T", method, receiver)) } func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { - if h, ok := ctrl.t.(testHelper); ok { - h.Helper() + // TODO: check arity, types. + margs := make([]Matcher, len(args)) + for i, arg := range args { + if m, ok := arg.(Matcher); ok { + margs[i] = m + } else if arg == nil { + // Handle nil specially so that passing a nil interface value + // will match the typed nils of concrete args. + margs[i] = Nil() + } else { + margs[i] = Eq(arg) + } } - call := newCall(ctrl.t, receiver, method, methodType, args...) - ctrl.mu.Lock() defer ctrl.mu.Unlock() - ctrl.expectedCalls.Add(call) + call := &Call{t: ctrl.t, receiver: receiver, method: method, methodType: methodType, args: margs, minCalls: 1, maxCalls: 1} + + ctrl.expectedCalls.Add(call) return call } func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} { - if h, ok := ctrl.t.(testHelper); ok { - h.Helper() - } - - // Nest this code so we can use defer to make sure the lock is released. - actions := func() []func([]interface{}) []interface{} { - ctrl.mu.Lock() - defer ctrl.mu.Unlock() + ctrl.mu.Lock() + defer ctrl.mu.Unlock() - expected, err := ctrl.expectedCalls.FindMatch(receiver, method, args) - if err != nil { - origin := callerInfo(2) - ctrl.t.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err) - } + expected := ctrl.expectedCalls.FindMatch(receiver, method, args) + if expected == nil { + ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args) + } - // Two things happen here: - // * the matching call no longer needs to check prerequite calls, - // * and the prerequite calls are no longer expected, so remove them. - preReqCalls := expected.dropPrereqs() - for _, preReqCall := range preReqCalls { - ctrl.expectedCalls.Remove(preReqCall) - } + // Two things happen here: + // * the matching call no longer needs to check prerequite calls, + // * and the prerequite calls are no longer expected, so remove them. + preReqCalls := expected.dropPrereqs() + for _, preReqCall := range preReqCalls { + ctrl.expectedCalls.Remove(preReqCall) + } - actions := expected.call(args) - if expected.exhausted() { - ctrl.expectedCalls.Remove(expected) - } - return actions - }() + rets, action := expected.call(args) + if expected.exhausted() { + ctrl.expectedCalls.Remove(expected) + } - var rets []interface{} - for _, action := range actions { - if r := action(args); r != nil { - rets = r - } + // Don't hold the lock while doing the call's action (if any) + // so that actions may execute concurrently. + // We use the deferred Unlock to capture any panics that happen above; + // here we add a deferred Lock to balance it. + ctrl.mu.Unlock() + defer ctrl.mu.Lock() + if action != nil { + action() } return rets } func (ctrl *Controller) Finish() { - if h, ok := ctrl.t.(testHelper); ok { - h.Helper() - } - ctrl.mu.Lock() defer ctrl.mu.Unlock() - if ctrl.finished { - ctrl.t.Fatalf("Controller.Finish was called more than once. It has to be called exactly once.") - } - ctrl.finished = true - // If we're currently panicking, probably because this is a deferred call, // pass through the panic. if err := recover(); err != nil { @@ -195,23 +166,18 @@ func (ctrl *Controller) Finish() { } // Check that all remaining expected calls are satisfied. - failures := ctrl.expectedCalls.Failures() - for _, call := range failures { - ctrl.t.Errorf("missing call(s) to %v", call) + failures := false + for _, methodMap := range ctrl.expectedCalls { + for _, calls := range methodMap { + for _, call := range calls { + if !call.satisfied() { + ctrl.t.Errorf("missing call(s) to %v", call) + failures = true + } + } + } } - if len(failures) != 0 { + if failures { ctrl.t.Fatalf("aborting test due to missing call(s)") } } - -func callerInfo(skip int) string { - if _, file, line, ok := runtime.Caller(skip + 1); ok { - return fmt.Sprintf("%s:%d", file, line) - } - return "unknown file" -} - -type testHelper interface { - TestReporter - Helper() -} diff --git a/vendor/github.com/valyala/bytebufferpool/.travis.yml b/vendor/github.com/valyala/bytebufferpool/.travis.yml new file mode 100644 index 000000000000..6a6ec2eb0691 --- /dev/null +++ b/vendor/github.com/valyala/bytebufferpool/.travis.yml @@ -0,0 +1,15 @@ +language: go + +go: + - 1.6 + +script: + # build test for supported platforms + - GOOS=linux go build + - GOOS=darwin go build + - GOOS=freebsd go build + - GOOS=windows go build + - GOARCH=386 go build + + # run tests on a standard platform + - go test -v ./... diff --git a/vendor/github.com/valyala/bytebufferpool/LICENSE b/vendor/github.com/valyala/bytebufferpool/LICENSE new file mode 100644 index 000000000000..f7c935c201b0 --- /dev/null +++ b/vendor/github.com/valyala/bytebufferpool/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Aliaksandr Valialkin, VertaMedia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/valyala/bytebufferpool/README.md b/vendor/github.com/valyala/bytebufferpool/README.md new file mode 100644 index 000000000000..061357e833d9 --- /dev/null +++ b/vendor/github.com/valyala/bytebufferpool/README.md @@ -0,0 +1,21 @@ +[![Build Status](https://travis-ci.org/valyala/bytebufferpool.svg)](https://travis-ci.org/valyala/bytebufferpool) +[![GoDoc](https://godoc.org/github.com/valyala/bytebufferpool?status.svg)](http://godoc.org/github.com/valyala/bytebufferpool) +[![Go Report](http://goreportcard.com/badge/valyala/bytebufferpool)](http://goreportcard.com/report/valyala/bytebufferpool) + +# bytebufferpool + +An implementation of a pool of byte buffers with anti-memory-waste protection. + +The pool may waste limited amount of memory due to fragmentation. +This amount equals to the maximum total size of the byte buffers +in concurrent use. + +# Benchmark results +Currently bytebufferpool is fastest and most effective buffer pool written in Go. + +You can find results [here](https://omgnull.github.io/go-benchmark/buffer/). + +# bytebufferpool users + +* [fasthttp](https://github.com/valyala/fasthttp) +* [quicktemplate](https://github.com/valyala/quicktemplate) diff --git a/vendor/github.com/valyala/bytebufferpool/bytebuffer.go b/vendor/github.com/valyala/bytebufferpool/bytebuffer.go new file mode 100644 index 000000000000..07a055a2df79 --- /dev/null +++ b/vendor/github.com/valyala/bytebufferpool/bytebuffer.go @@ -0,0 +1,111 @@ +package bytebufferpool + +import "io" + +// ByteBuffer provides byte buffer, which can be used for minimizing +// memory allocations. +// +// ByteBuffer may be used with functions appending data to the given []byte +// slice. See example code for details. +// +// Use Get for obtaining an empty byte buffer. +type ByteBuffer struct { + + // B is a byte buffer to use in append-like workloads. + // See example code for details. + B []byte +} + +// Len returns the size of the byte buffer. +func (b *ByteBuffer) Len() int { + return len(b.B) +} + +// ReadFrom implements io.ReaderFrom. +// +// The function appends all the data read from r to b. +func (b *ByteBuffer) ReadFrom(r io.Reader) (int64, error) { + p := b.B + nStart := int64(len(p)) + nMax := int64(cap(p)) + n := nStart + if nMax == 0 { + nMax = 64 + p = make([]byte, nMax) + } else { + p = p[:nMax] + } + for { + if n == nMax { + nMax *= 2 + bNew := make([]byte, nMax) + copy(bNew, p) + p = bNew + } + nn, err := r.Read(p[n:]) + n += int64(nn) + if err != nil { + b.B = p[:n] + n -= nStart + if err == io.EOF { + return n, nil + } + return n, err + } + } +} + +// WriteTo implements io.WriterTo. +func (b *ByteBuffer) WriteTo(w io.Writer) (int64, error) { + n, err := w.Write(b.B) + return int64(n), err +} + +// Bytes returns b.B, i.e. all the bytes accumulated in the buffer. +// +// The purpose of this function is bytes.Buffer compatibility. +func (b *ByteBuffer) Bytes() []byte { + return b.B +} + +// Write implements io.Writer - it appends p to ByteBuffer.B +func (b *ByteBuffer) Write(p []byte) (int, error) { + b.B = append(b.B, p...) + return len(p), nil +} + +// WriteByte appends the byte c to the buffer. +// +// The purpose of this function is bytes.Buffer compatibility. +// +// The function always returns nil. +func (b *ByteBuffer) WriteByte(c byte) error { + b.B = append(b.B, c) + return nil +} + +// WriteString appends s to ByteBuffer.B. +func (b *ByteBuffer) WriteString(s string) (int, error) { + b.B = append(b.B, s...) + return len(s), nil +} + +// Set sets ByteBuffer.B to p. +func (b *ByteBuffer) Set(p []byte) { + b.B = append(b.B[:0], p...) +} + +// SetString sets ByteBuffer.B to s. +func (b *ByteBuffer) SetString(s string) { + b.B = append(b.B[:0], s...) +} + +// String returns string representation of ByteBuffer.B. +func (b *ByteBuffer) String() string { + return string(b.B) +} + +// Reset makes ByteBuffer.B empty. +func (b *ByteBuffer) Reset() { + b.B = b.B[:0] +} diff --git a/vendor/github.com/valyala/bytebufferpool/doc.go b/vendor/github.com/valyala/bytebufferpool/doc.go new file mode 100644 index 000000000000..e511b7c59323 --- /dev/null +++ b/vendor/github.com/valyala/bytebufferpool/doc.go @@ -0,0 +1,7 @@ +// Package bytebufferpool implements a pool of byte buffers +// with anti-fragmentation protection. +// +// The pool may waste limited amount of memory due to fragmentation. +// This amount equals to the maximum total size of the byte buffers +// in concurrent use. +package bytebufferpool diff --git a/vendor/github.com/valyala/bytebufferpool/pool.go b/vendor/github.com/valyala/bytebufferpool/pool.go new file mode 100644 index 000000000000..8bb4134dd0d3 --- /dev/null +++ b/vendor/github.com/valyala/bytebufferpool/pool.go @@ -0,0 +1,151 @@ +package bytebufferpool + +import ( + "sort" + "sync" + "sync/atomic" +) + +const ( + minBitSize = 6 // 2**6=64 is a CPU cache line size + steps = 20 + + minSize = 1 << minBitSize + maxSize = 1 << (minBitSize + steps - 1) + + calibrateCallsThreshold = 42000 + maxPercentile = 0.95 +) + +// Pool represents byte buffer pool. +// +// Distinct pools may be used for distinct types of byte buffers. +// Properly determined byte buffer types with their own pools may help reducing +// memory waste. +type Pool struct { + calls [steps]uint64 + calibrating uint64 + + defaultSize uint64 + maxSize uint64 + + pool sync.Pool +} + +var defaultPool Pool + +// Get returns an empty byte buffer from the pool. +// +// Got byte buffer may be returned to the pool via Put call. +// This reduces the number of memory allocations required for byte buffer +// management. +func Get() *ByteBuffer { return defaultPool.Get() } + +// Get returns new byte buffer with zero length. +// +// The byte buffer may be returned to the pool via Put after the use +// in order to minimize GC overhead. +func (p *Pool) Get() *ByteBuffer { + v := p.pool.Get() + if v != nil { + return v.(*ByteBuffer) + } + return &ByteBuffer{ + B: make([]byte, 0, atomic.LoadUint64(&p.defaultSize)), + } +} + +// Put returns byte buffer to the pool. +// +// ByteBuffer.B mustn't be touched after returning it to the pool. +// Otherwise data races will occur. +func Put(b *ByteBuffer) { defaultPool.Put(b) } + +// Put releases byte buffer obtained via Get to the pool. +// +// The buffer mustn't be accessed after returning to the pool. +func (p *Pool) Put(b *ByteBuffer) { + idx := index(len(b.B)) + + if atomic.AddUint64(&p.calls[idx], 1) > calibrateCallsThreshold { + p.calibrate() + } + + maxSize := int(atomic.LoadUint64(&p.maxSize)) + if maxSize == 0 || cap(b.B) <= maxSize { + b.Reset() + p.pool.Put(b) + } +} + +func (p *Pool) calibrate() { + if !atomic.CompareAndSwapUint64(&p.calibrating, 0, 1) { + return + } + + a := make(callSizes, 0, steps) + var callsSum uint64 + for i := uint64(0); i < steps; i++ { + calls := atomic.SwapUint64(&p.calls[i], 0) + callsSum += calls + a = append(a, callSize{ + calls: calls, + size: minSize << i, + }) + } + sort.Sort(a) + + defaultSize := a[0].size + maxSize := defaultSize + + maxSum := uint64(float64(callsSum) * maxPercentile) + callsSum = 0 + for i := 0; i < steps; i++ { + if callsSum > maxSum { + break + } + callsSum += a[i].calls + size := a[i].size + if size > maxSize { + maxSize = size + } + } + + atomic.StoreUint64(&p.defaultSize, defaultSize) + atomic.StoreUint64(&p.maxSize, maxSize) + + atomic.StoreUint64(&p.calibrating, 0) +} + +type callSize struct { + calls uint64 + size uint64 +} + +type callSizes []callSize + +func (ci callSizes) Len() int { + return len(ci) +} + +func (ci callSizes) Less(i, j int) bool { + return ci[i].calls > ci[j].calls +} + +func (ci callSizes) Swap(i, j int) { + ci[i], ci[j] = ci[j], ci[i] +} + +func index(n int) int { + n-- + n >>= minBitSize + idx := 0 + for n > 0 { + n >>= 1 + idx++ + } + if idx >= steps { + idx = steps - 1 + } + return idx +} diff --git a/vendor/github.com/valyala/quicktemplate/.gitignore b/vendor/github.com/valyala/quicktemplate/.gitignore new file mode 100644 index 000000000000..6e92f57d4647 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/.gitignore @@ -0,0 +1 @@ +tags diff --git a/vendor/github.com/valyala/quicktemplate/.travis.yml b/vendor/github.com/valyala/quicktemplate/.travis.yml new file mode 100644 index 000000000000..4a1c677366de --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/.travis.yml @@ -0,0 +1,19 @@ +language: go + +go: + - 1.11.x + - 1.12.x + - tip + +before_install: + - go get -u github.com/valyala/quicktemplate/qtc + - go generate + +script: + # build test for supported platforms + - GOOS=linux go build + - GOOS=darwin go build + - GOOS=freebsd go build + + # run tests on a standard platform + - go test -v ./... diff --git a/vendor/github.com/valyala/quicktemplate/LICENSE b/vendor/github.com/valyala/quicktemplate/LICENSE new file mode 100644 index 000000000000..f7c935c201b0 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Aliaksandr Valialkin, VertaMedia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/valyala/quicktemplate/QuickTemplate.xml b/vendor/github.com/valyala/quicktemplate/QuickTemplate.xml new file mode 100644 index 000000000000..700d55e816e2 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/QuickTemplate.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/github.com/valyala/quicktemplate/README.md b/vendor/github.com/valyala/quicktemplate/README.md new file mode 100644 index 000000000000..3c104f40fc3b --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/README.md @@ -0,0 +1,621 @@ +[![Build Status](https://travis-ci.org/valyala/quicktemplate.svg)](https://travis-ci.org/valyala/quicktemplate) +[![GoDoc](https://godoc.org/github.com/valyala/quicktemplate?status.svg)](http://godoc.org/github.com/valyala/quicktemplate) +[![Go Report Card](https://goreportcard.com/badge/github.com/valyala/quicktemplate)](https://goreportcard.com/report/github.com/valyala/quicktemplate) + +# quicktemplate + +A fast, powerful, yet easy to use template engine for Go. +Inspired by the [Mako templates](http://www.makotemplates.org/) philosophy. + +# Features + + * [Extremely fast](#performance-comparison-with-htmltemplate). + Templates are converted into Go code and then compiled. + * Quicktemplate syntax is very close to Go - there is no need to learn + yet another template language before starting to use quicktemplate. + * Almost all bugs are caught during template compilation, so production + suffers less from template-related bugs. + * Easy to use. See [quickstart](#quick-start) and [examples](https://github.com/valyala/quicktemplate/tree/master/examples) + for details. + * Powerful. Arbitrary Go code may be embedded into and mixed with templates. + Be careful with this power - do not query the database and/or external resources from + templates unless you miss the PHP way in Go :) This power is mostly for + arbitrary data transformations. + * Easy to use template inheritance powered by [Go interfaces](https://golang.org/doc/effective_go.html#interfaces). + See [this example](https://github.com/valyala/quicktemplate/tree/master/examples/basicserver) for details. + * Templates are compiled into a single binary, so there is no need to copy + template files to the server. + +# Drawbacks + + * Templates cannot be updated on the fly on the server, since they + are compiled into a single binary. + Take a look at [fasttemplate](https://github.com/valyala/fasttemplate) + if you need a fast template engine for simple dynamically updated templates. + +# Performance comparison with html/template + +Quicktemplate is more than 20x faster than [html/template](https://golang.org/pkg/html/template/). +The following simple template is used in the benchmark: + + * [html/template version](https://github.com/valyala/quicktemplate/blob/master/testdata/templates/bench.tpl) + * [quicktemplate version](https://github.com/valyala/quicktemplate/blob/master/testdata/templates/bench.qtpl) + +Benchmark results: + +``` +$ go test -bench='Benchmark(Quick|HTML)Template' -benchmem github.com/valyala/quicktemplate/tests +BenchmarkQuickTemplate1-4 10000000 120 ns/op 0 B/op 0 allocs/op +BenchmarkQuickTemplate10-4 3000000 441 ns/op 0 B/op 0 allocs/op +BenchmarkQuickTemplate100-4 300000 3945 ns/op 0 B/op 0 allocs/op +BenchmarkHTMLTemplate1-4 500000 2501 ns/op 752 B/op 23 allocs/op +BenchmarkHTMLTemplate10-4 100000 12442 ns/op 3521 B/op 117 allocs/op +BenchmarkHTMLTemplate100-4 10000 123392 ns/op 34498 B/op 1152 allocs/op +``` + +[goTemplateBenchmark](https://github.com/SlinSo/goTemplateBenchmark) compares QuickTemplate with numerous Go templating packages. QuickTemplate performs favorably. + +# Security + + * All template placeholders are HTML-escaped by default. + * Template placeholders for JSON strings prevent from ``-based + XSS attacks: + + ```qtpl + {% func FailedXSS() %} + + {% endfunc %} + ``` + +# Examples + +See [examples](https://github.com/valyala/quicktemplate/tree/master/examples). + +# Quick start + +First of all, install the `quicktemplate` package +and [quicktemplate compiler](https://github.com/valyala/quicktemplate/tree/master/qtc) (`qtc`): + +``` +go get -u github.com/valyala/quicktemplate +go get -u github.com/valyala/quicktemplate/qtc +``` + +Let's start with a minimal template example: + +```qtpl +All text outside function templates is treated as comments, +i.e. it is just ignored by quicktemplate compiler (`qtc`). It is for humans. + +Hello is a simple template function. +{% func Hello(name string) %} + Hello, {%s name %}! +{% endfunc %} +``` + +Save this file into a `templates` folder under the name `hello.qtpl` +and run `qtc` inside this folder. + +If everything went OK, `hello.qtpl.go` file should appear in the `templates` folder. +This file contains Go code for `hello.qtpl`. Let's use it! + +Create a file main.go outside `templates` folder and put the following +code there: + +```go +package main + +import ( + "fmt" + + "./templates" +) + +func main() { + fmt.Printf("%s\n", templates.Hello("Foo")) + fmt.Printf("%s\n", templates.Hello("Bar")) +} +``` + +Then issue `go run`. If everything went OK, you'll see something like this: + +``` + + Hello, Foo! + + + Hello, Bar! + +``` + +Let's create more a complex template which calls other template functions, +contains loops, conditions, breaks, continues and returns. +Put the following template into `templates/greetings.qtpl`: + +```qtpl + +Greetings greets up to 42 names. +It also greets John differently comparing to others. +{% func Greetings(names []string) %} + {% if len(names) == 0 %} + Nobody to greet :( + {% return %} + {% endif %} + + {% for i, name := range names %} + {% if i == 42 %} + I'm tired to greet so many people... + {% break %} + {% elseif name == "John" %} + {%= sayHi("Mr. " + name) %} + {% continue %} + {% else %} + {%= Hello(name) %} + {% endif %} + {% endfor %} +{% endfunc %} + +sayHi is unexported, since it starts with lowercase letter. +{% func sayHi(name string) %} + Hi, {%s name %} +{% endfunc %} + +Note that every template file may contain an arbitrary number +of template functions. For instance, this file contains Greetings and sayHi +functions. +``` + +Run `qtc` inside `templates` folder. Now the folder should contain +two files with Go code: `hello.qtpl.go` and `greetings.qtpl.go`. These files +form a single `templates` Go package. Template functions and other template +stuff is shared between template files located in the same folder. +So `Hello` template function may be used inside `greetings.qtpl` while +it is defined in `hello.qtpl`. +Moreover, the folder may contain ordinary Go files, so its contents may +be used inside templates and vice versa. +The package name inside template files may be overriden +with `{% package packageName %}`. + +Now put the following code into `main.go`: + +```go +package main + +import ( + "bytes" + "fmt" + + "./templates" +) + +func main() { + names := []string{"Kate", "Go", "John", "Brad"} + + // qtc creates Write* function for each template function. + // Such functions accept io.Writer as first parameter: + var buf bytes.Buffer + templates.WriteGreetings(&buf, names) + + fmt.Printf("buf=\n%s", buf.Bytes()) +} +``` + +Careful readers may notice different output tags were used in these +templates: `{%s name %}` and `{%= Hello(name) %}`. What's the difference? +The `{%s x %}` is used for printing HTML-safe strings, while `{%= F() %}` +is used for embedding template function calls. Quicktemplate supports also +other output tags: + + * `{%d num %}` for integers. + * `{%f float %}` for float64. + Floating point precision may be set via `{%f.precision float %}`. + For example, `{%f.2 1.2345 %}` outputs `1.23`. + * `{%z bytes %}` for byte slices. + * `{%q str %}` and `{%qz bytes %}` for JSON-compatible quoted strings. + * `{%j str %}` and `{%jz bytes %}` for embedding str into a JSON string. Unlike `{%q str %}`, + it doesn't quote the string. + * `{%u str %}` and `{%uz bytes %}` for [URL encoding](https://en.wikipedia.org/wiki/Percent-encoding) + the given str. + * `{%v anything %}` is equivalent to `%v` in [printf-like functions](https://golang.org/pkg/fmt/). + +All the output tags except `{%= F() %}` produce HTML-safe output, i.e. they +escape `<` to `<`, `>` to `>`, etc. If you don't want HTML-safe output, +then just put `=` after the tag. For example: `{%s= "

This h1 won't be escaped

" %}`. + +As you may notice `{%= F() %}` and `{%s= F() %}` produce the same output for `{% func F() %}`. +But the first one is optimized for speed - it avoids memory allocations and copies. +It is therefore recommended to stick to it when embedding template function calls. + +Additionally, the following extensions are supported for `{%= F() %}`: + + * `{%=h F() %}` produces html-escaped output. + * `{%=u F() %}` produces [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding) output. + * `{%=q F() %}` produces quoted json string. + * `{%=j F() %}` produces json string without quotes. + * `{%=uh F() %}` produces html-safe URL-encoded output. + * `{%=qh F() %}` produces html-safe quoted json string. + * `{%=jh F() %}` produces html-safe json string without quotes. + +All output tags except `{%= F() %}` family may contain arbitrary valid +Go expressions instead of just an identifier. For example: + +```qtpl +Import fmt for fmt.Sprintf() +{% import "fmt" %} + +FmtFunc uses fmt.Sprintf() inside output tag +{% func FmtFunc(s string) %} + {%s fmt.Sprintf("FmtFunc accepted %q string", s) %} +{% endfunc %} +``` + +There are other useful tags supported by quicktemplate: + + * `{% comment %}` + + ```qtpl + {% comment %} + This is a comment. It won't trap into the output. + It may contain {% arbitrary tags %}. They are just ignored. + {% endcomment %} + ``` + + * `{% plain %}` + + ```qtpl + {% plain %} + Tags will {% trap into %} the output {% unmodified %}. + Plain block may contain invalid and {% incomplete tags. + {% endplain %} + ``` + + * `{% collapsespace %}` + + ```qtpl + {% collapsespace %} +
+
space between lines
+ and {%s "tags" %} +
is collapsed into a single space + unless{% newline %}or{% space %}is used
+
+ {% endcollapsespace %} + ``` + + Is converted into: + + ``` +
space between lines
and tags
is collapsed into a single space unless + or is used
+ ``` + + * `{% stripspace %}` + + ```qtpl + {% stripspace %} +
+
space between lines
+ and {%s " tags" %} +
is removed unless{% newline %}or{% space %}is used
+
+ {% endstripspace %} + ``` + + Is converted into: + + ``` +
space between lines
and tags
is removed unless + or is used
+ ``` + + * `{% switch %}`, `{% case %}` and `{% default %}`: + + + ```qtpl + 1 + 1 = + {% switch 1+1 %} + {% case 2 %} + 2? + {% case 42 %} + 42! + {% default %} + I don't know :( + {% endswitch %} + ``` + + * `{% code %}`: + + ```qtpl + {% code + // arbitrary Go code may be embedded here! + type FooArg struct { + Name string + Age int + } + %} + ``` + + * `{% package %}`: + + ```qtpl + Override default package name with the custom name + {% package customPackageName %} + ``` + + * `{% import %}`: + + ```qtpl + Import external packages. + {% import "foo/bar" %} + {% import ( + "foo" + bar "baz/baa" + ) %} + ``` + + * `{% cat "/path/to/file" %}`: + + ```qtpl + Cat emits the given file contents as a plaintext: + {% func passwords() %} + /etc/passwd contents: + {% cat "/etc/passwd" %} + {% endfunc %} + ``` + + * `{% interface %}`: + + ```qtpl + Interfaces allow powerful templates' inheritance + {% + interface Page { + Title() + Body(s string, n int) + Footer() + } + %} + + PrintPage prints Page + {% func PrintPage(p Page) %} + + {%= p.Title() %} + +
{%= p.Body("foo", 42) %}
+
{%= p.Footer() %}
+ + + {% endfunc %} + + Base page implementation + {% code + type BasePage struct { + TitleStr string + FooterStr string + } + %} + {% func (bp *BasePage) Title() %}{%s bp.TitleStr %}{% endfunc %} + {% func (bp *BasePage) Body(s string, n int) %} + s={%q s %}, n={%d n %} + {% endfunc %} + {% func (bp *BasePage) Footer() %}{%s bp.FooterStr %}{% endfunc %} + + Main page implementation + {% code + type MainPage struct { + // inherit from BasePage + BasePage + + // real body for main page + BodyStr string + } + %} + + Override only Body + Title and Footer are used from BasePage. + {% func (mp *MainPage) Body(s string, n int) %} +
+ main body: {%s mp.BodyStr %} +
+
+ base body: {%= mp.BasePage.Body(s, n) %} +
+ {% endfunc %} + ``` + + See [basicserver example](https://github.com/valyala/quicktemplate/tree/master/examples/basicserver) + for more details. + +# Performance optimization tips + + * Prefer calling `WriteFoo` instead of `Foo` when generating template output + for `{% func Foo() %}`. This avoids unnesessary memory allocation and a copy + for a `string` returned from `Foo()`. + + * Prefer `{%= Foo() %}` instead of `{%s= Foo() %}` when embedding + a function template `{% func Foo() %}`. Though both approaches generate + identical output, the first approach is optimized for speed. + + * Prefer using existing output tags instead of passing `fmt.Sprintf` + to `{%s %}`. For instance, use `{%d num %}` instead + of `{%s fmt.Sprintf("%d", num) %}`, because the first approach is optimized + for speed. + + * Prefer using specific output tags instead of generic output tag + `{%v %}`. For example, use `{%s str %}` instead of `{%v str %}`, since + specific output tags are optimized for speed. + + * Prefer creating custom function templates instead of composing complex + strings by hands before passing them to `{%s %}`. + For instance, the first approach is slower than the second one: + + ```qtpl + {% func Foo(n int) %} + {% code + // construct complex string + complexStr := "" + for i := 0; i < n; i++ { + complexStr += fmt.Sprintf("num %d,", i) + } + %} + complex string = {%s= complexStr %} + {% endfunc %} + ``` + + ```qtpl + {% func Foo(n int) %} + complex string = {%= complexStr(n) %} + {% endfunc %} + + // Wrap complexStr func into stripspace for stripping unnesessary space + // between tags and lines. + {% stripspace %} + {% func complexStr(n int) %} + {% for i := 0; i < n; i++ %} + num{% space %}{%d i %}{% newline %} + {% endfor %} + {% endfunc %} + {% endstripspace %} + ``` + + * Make sure that the `io.Writer` passed to `Write*` functions + is [buffered](https://golang.org/pkg/bufio/#Writer). + This will minimize the number of `write` + [syscalls](https://en.wikipedia.org/wiki/System_call), + which may be quite expensive. + + Note: There is no need to wrap [fasthttp.RequestCtx](https://godoc.org/github.com/valyala/fasthttp#RequestCtx) + into [bufio.Writer](https://golang.org/pkg/bufio/#Writer), since it is already buffered. + + * [Profile](http://blog.golang.org/profiling-go-programs) your programs + for memory allocations and fix the most demanding functions based on + the output of `go tool pprof --alloc_objects`. + +# Use cases + +While the main quicktemplate purpose is generating HTML, it may be used +for generating other data too. For example, JSON and XML marshalling may +be easily implemented with quicktemplate: + +```qtpl +{% code +type MarshalRow struct { + Msg string + N int +} + +type MarshalData struct { + Foo int + Bar string + Rows []MarshalRow +} +%} + +// JSON marshaling +{% stripspace %} +{% func (d *MarshalData) JSON() %} +{ + "Foo": {%d d.Foo %}, + "Bar": {%q= d.Bar %}, + "Rows":[ + {% for i, r := range d.Rows %} + { + "Msg": {%q= r.Msg %}, + "N": {%d r.N %} + } + {% if i + 1 < len(d.Rows) %},{% endif %} + {% endfor %} + ] +} +{% endfunc %} +{% endstripspace %} + +// XML marshalling +{% stripspace %} +{% func (d *MarshalData) XML() %} + + {%d d.Foo %} + {%s d.Bar %} + + {% for _, r := range d.Rows %} + + {%s r.Msg %} + {%d r.N %} + + {% endfor %} + + +{% endfunc %} +{% endstripspace %} +``` + +Usually, marshalling built with quicktemplate works faster than the marshalling +implemented via standard [encoding/json](https://golang.org/pkg/encoding/json/) +and [encoding/xml](https://golang.org/pkg/encoding/xml/). +See the corresponding benchmark results: + +``` +go test -bench=Marshal -benchmem github.com/valyala/quicktemplate/tests +BenchmarkMarshalJSONStd1-4 3000000 480 ns/op 8 B/op 1 allocs/op +BenchmarkMarshalJSONStd10-4 1000000 1842 ns/op 8 B/op 1 allocs/op +BenchmarkMarshalJSONStd100-4 100000 15820 ns/op 8 B/op 1 allocs/op +BenchmarkMarshalJSONStd1000-4 10000 159327 ns/op 59 B/op 1 allocs/op +BenchmarkMarshalJSONQuickTemplate1-4 10000000 162 ns/op 0 B/op 0 allocs/op +BenchmarkMarshalJSONQuickTemplate10-4 2000000 748 ns/op 0 B/op 0 allocs/op +BenchmarkMarshalJSONQuickTemplate100-4 200000 6572 ns/op 0 B/op 0 allocs/op +BenchmarkMarshalJSONQuickTemplate1000-4 20000 66784 ns/op 29 B/op 0 allocs/op +BenchmarkMarshalXMLStd1-4 1000000 1652 ns/op 2 B/op 2 allocs/op +BenchmarkMarshalXMLStd10-4 200000 7533 ns/op 11 B/op 11 allocs/op +BenchmarkMarshalXMLStd100-4 20000 65763 ns/op 195 B/op 101 allocs/op +BenchmarkMarshalXMLStd1000-4 2000 663373 ns/op 3522 B/op 1002 allocs/op +BenchmarkMarshalXMLQuickTemplate1-4 10000000 145 ns/op 0 B/op 0 allocs/op +BenchmarkMarshalXMLQuickTemplate10-4 3000000 597 ns/op 0 B/op 0 allocs/op +BenchmarkMarshalXMLQuickTemplate100-4 300000 5833 ns/op 0 B/op 0 allocs/op +BenchmarkMarshalXMLQuickTemplate1000-4 30000 53000 ns/op 32 B/op 0 allocs/op +``` + +# FAQ + + * *Why is the quicktemplate syntax incompatible with [html/template](https://golang.org/pkg/html/template/)?* + + Because `html/template` syntax isn't expressive enough for `quicktemplate`. + + * *What's the difference between quicktemplate and [ego](https://github.com/benbjohnson/ego)?* + + `Ego` is similar to `quicktemplate` in the sense it converts templates into Go code. + But it misses the following stuff, which makes `quicktemplate` so powerful + and easy to use: + + * Defining multiple function templates in a single template file. + * Embedding function templates inside other function templates. + * Template interfaces, inheritance and overriding. + See [this example](https://github.com/valyala/quicktemplate/tree/master/examples/basicserver) + for details. + * Top-level comments outside function templates. + * Template packages. + * Combining arbitrary Go files with template files in template packages. + * Performance optimizations. + + * *What's the difference between quicktemplate and [gorazor](https://github.com/sipin/gorazor)?* + + `Gorazor` is similar to `quicktemplate` in the sense it converts templates into Go code. + But it misses the following useful features: + + * Clear syntax insead of hard-to-understand magic stuff related + to template arguments, template inheritance and embedding function + templates into other templates. + * Performance optimizations. + +* *Is there a syntax highlighting for qtpl files?* + + Yes - see [this issue](https://github.com/valyala/quicktemplate/issues/19) for details. + If you are using JetBrains products (syntax highlighting and autocomplete): + * cd [JetBrains settings directory](https://intellij-support.jetbrains.com/hc/en-us/articles/206544519-Directories-used-by-the-IDE-to-store-settings-caches-plugins-and-logs) + * mkdir -p filetypes && cd filetypes + * curl https://raw.githubusercontent.com/valyala/quicktemplate/master/QuickTemplate.xml >> QuickTemplate.xml + * Restart your IDE + +* *I didn't find an answer for my question here.* + + Try exploring [these questions](https://github.com/valyala/quicktemplate/issues?q=label%3Aquestion). diff --git a/vendor/github.com/valyala/quicktemplate/bytebuffer.go b/vendor/github.com/valyala/quicktemplate/bytebuffer.go new file mode 100644 index 000000000000..47d88f78e707 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/bytebuffer.go @@ -0,0 +1,45 @@ +package quicktemplate + +import ( + "github.com/valyala/bytebufferpool" +) + +// ByteBuffer implements io.Writer on top of byte slice. +// +// Recycle byte buffers via AcquireByteBuffer and ReleaseByteBuffer +// in order to reduce memory allocations. +// +// Deprecated: use github.com/valyala/bytebufferpool instead. +type ByteBuffer bytebufferpool.ByteBuffer + +// Write implements io.Writer. +func (b *ByteBuffer) Write(p []byte) (int, error) { + return bb(b).Write(p) +} + +// Reset resets the byte buffer. +func (b *ByteBuffer) Reset() { + bb(b).Reset() +} + +// AcquireByteBuffer returns new ByteBuffer from the pool. +// +// Return unneeded buffers to the pool by calling ReleaseByteBuffer +// in order to reduce memory allocations. +func AcquireByteBuffer() *ByteBuffer { + return (*ByteBuffer)(byteBufferPool.Get()) +} + +// ReleaseByteBuffer retruns byte buffer to the pool. +// +// Do not access byte buffer after returning it to the pool, +// otherwise data races may occur. +func ReleaseByteBuffer(b *ByteBuffer) { + byteBufferPool.Put(bb(b)) +} + +func bb(b *ByteBuffer) *bytebufferpool.ByteBuffer { + return (*bytebufferpool.ByteBuffer)(b) +} + +var byteBufferPool bytebufferpool.Pool diff --git a/vendor/github.com/valyala/quicktemplate/doc.go b/vendor/github.com/valyala/quicktemplate/doc.go new file mode 100644 index 000000000000..14cb5ffb7641 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/doc.go @@ -0,0 +1,6 @@ +/* +Package quicktemplate provides fast and powerful template engine. + +See https://github.com/valyala/quicktemplate for details. +*/ +package quicktemplate diff --git a/vendor/github.com/valyala/quicktemplate/go.mod b/vendor/github.com/valyala/quicktemplate/go.mod new file mode 100644 index 000000000000..ab6fd16ea0a9 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/go.mod @@ -0,0 +1,8 @@ +module github.com/valyala/quicktemplate + +require ( + github.com/klauspost/compress v1.4.1 // indirect + github.com/klauspost/cpuid v1.2.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 + github.com/valyala/fasthttp v1.2.0 +) diff --git a/vendor/github.com/valyala/quicktemplate/go.sum b/vendor/github.com/valyala/quicktemplate/go.sum new file mode 100644 index 000000000000..c868cd17f8b9 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/go.sum @@ -0,0 +1,12 @@ +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.2.0 h1:dzZJf2IuMiclVjdw0kkT+f9u4YdrapbNyGAN47E/qnk= +github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/vendor/github.com/valyala/quicktemplate/htmlescapewriter.go b/vendor/github.com/valyala/quicktemplate/htmlescapewriter.go new file mode 100644 index 000000000000..77560b41138b --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/htmlescapewriter.go @@ -0,0 +1,62 @@ +package quicktemplate + +import ( + "bytes" + "io" +) + +type htmlEscapeWriter struct { + w io.Writer +} + +func (w *htmlEscapeWriter) Write(b []byte) (int, error) { + if bytes.IndexByte(b, '<') < 0 && + bytes.IndexByte(b, '>') < 0 && + bytes.IndexByte(b, '"') < 0 && + bytes.IndexByte(b, '\'') < 0 && + bytes.IndexByte(b, '&') < 0 { + + // fast path - nothing to escape + return w.w.Write(b) + } + + // slow path + write := w.w.Write + j := 0 + for i, c := range b { + switch c { + case '<': + write(b[j:i]) + write(strLT) + j = i + 1 + case '>': + write(b[j:i]) + write(strGT) + j = i + 1 + case '"': + write(b[j:i]) + write(strQuot) + j = i + 1 + case '\'': + write(b[j:i]) + write(strApos) + j = i + 1 + case '&': + write(b[j:i]) + write(strAmp) + j = i + 1 + } + } + if n, err := write(b[j:]); err != nil { + return j + n, err + } + return len(b), nil +} + +var ( + strLT = []byte("<") + strGT = []byte(">") + strQuot = []byte(""") + strApos = []byte("'") + strAmp = []byte("&") +) diff --git a/vendor/github.com/valyala/quicktemplate/jsonstring.go b/vendor/github.com/valyala/quicktemplate/jsonstring.go new file mode 100644 index 000000000000..dac862c8afa5 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/jsonstring.go @@ -0,0 +1,93 @@ +package quicktemplate + +import ( + "io" + "strings" +) + +func writeJSONString(w io.Writer, s string) { + if len(s) > 24 && + strings.IndexByte(s, '"') < 0 && + strings.IndexByte(s, '\\') < 0 && + strings.IndexByte(s, '\n') < 0 && + strings.IndexByte(s, '\r') < 0 && + strings.IndexByte(s, '\t') < 0 && + strings.IndexByte(s, '\f') < 0 && + strings.IndexByte(s, '\b') < 0 && + strings.IndexByte(s, '<') < 0 && + strings.IndexByte(s, '\'') < 0 && + strings.IndexByte(s, 0) < 0 { + + // fast path - nothing to escape + w.Write(unsafeStrToBytes(s)) + return + } + + // slow path + write := w.Write + b := unsafeStrToBytes(s) + j := 0 + n := len(b) + if n > 0 { + // Hint the compiler to remove bounds checks in the loop below. + _ = b[n-1] + } + for i := 0; i < n; i++ { + switch b[i] { + case '"': + write(b[j:i]) + write(strBackslashQuote) + j = i + 1 + case '\\': + write(b[j:i]) + write(strBackslashBackslash) + j = i + 1 + case '\n': + write(b[j:i]) + write(strBackslashN) + j = i + 1 + case '\r': + write(b[j:i]) + write(strBackslashR) + j = i + 1 + case '\t': + write(b[j:i]) + write(strBackslashT) + j = i + 1 + case '\f': + write(b[j:i]) + write(strBackslashF) + j = i + 1 + case '\b': + write(b[j:i]) + write(strBackslashB) + j = i + 1 + case '<': + write(b[j:i]) + write(strBackslashLT) + j = i + 1 + case '\'': + write(b[j:i]) + write(strBackslashQ) + j = i + 1 + case 0: + write(b[j:i]) + write(strBackslashZero) + j = i + 1 + } + } + write(b[j:]) +} + +var ( + strBackslashQuote = []byte(`\"`) + strBackslashBackslash = []byte(`\\`) + strBackslashN = []byte(`\n`) + strBackslashR = []byte(`\r`) + strBackslashT = []byte(`\t`) + strBackslashF = []byte(`\u000c`) + strBackslashB = []byte(`\u0008`) + strBackslashLT = []byte(`\u003c`) + strBackslashQ = []byte(`\u0027`) + strBackslashZero = []byte(`\u0000`) +) diff --git a/vendor/github.com/valyala/quicktemplate/urlencode.go b/vendor/github.com/valyala/quicktemplate/urlencode.go new file mode 100644 index 000000000000..33113ba17e88 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/urlencode.go @@ -0,0 +1,32 @@ +package quicktemplate + +func appendURLEncode(dst []byte, src string) []byte { + n := len(src) + if n > 0 { + // Hint the compiler to remove bounds checks in the loop below. + _ = src[n-1] + } + for i := 0; i < n; i++ { + c := src[i] + + // See http://www.w3.org/TR/html5/forms.html#form-submission-algorithm + if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || + c == '-' || c == '.' || c == '_' { + dst = append(dst, c) + } else { + if c == ' ' { + dst = append(dst, '+') + } else { + dst = append(dst, '%', hexCharUpper(c>>4), hexCharUpper(c&15)) + } + } + } + return dst +} + +func hexCharUpper(c byte) byte { + if c < 10 { + return '0' + c + } + return c - 10 + 'A' +} diff --git a/vendor/github.com/valyala/quicktemplate/util.go b/vendor/github.com/valyala/quicktemplate/util.go new file mode 100644 index 000000000000..8476ff552fb4 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/util.go @@ -0,0 +1,3 @@ +package quicktemplate + +//go:generate qtc -dir=testdata/templates diff --git a/vendor/github.com/valyala/quicktemplate/util_appengine.go b/vendor/github.com/valyala/quicktemplate/util_appengine.go new file mode 100644 index 000000000000..7642bf7df086 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/util_appengine.go @@ -0,0 +1,11 @@ +// +build appengine appenginevm + +package quicktemplate + +func unsafeStrToBytes(s string) []byte { + return []byte(s) +} + +func unsafeBytesToStr(z []byte) string { + return string(z) +} diff --git a/vendor/github.com/valyala/quicktemplate/util_noappengine.go b/vendor/github.com/valyala/quicktemplate/util_noappengine.go new file mode 100644 index 000000000000..166396ea8262 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/util_noappengine.go @@ -0,0 +1,22 @@ +// +build !appengine,!appenginevm + +package quicktemplate + +import ( + "reflect" + "unsafe" +) + +func unsafeStrToBytes(s string) []byte { + sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) + bh := reflect.SliceHeader{ + Data: sh.Data, + Len: sh.Len, + Cap: sh.Len, + } + return *(*[]byte)(unsafe.Pointer(&bh)) +} + +func unsafeBytesToStr(z []byte) string { + return *(*string)(unsafe.Pointer(&z)) +} diff --git a/vendor/github.com/valyala/quicktemplate/writer.go b/vendor/github.com/valyala/quicktemplate/writer.go new file mode 100644 index 000000000000..0a83a43e1333 --- /dev/null +++ b/vendor/github.com/valyala/quicktemplate/writer.go @@ -0,0 +1,188 @@ +package quicktemplate + +import ( + "fmt" + "io" + "strconv" + "sync" +) + +// Writer implements auxiliary writer used by quicktemplate functions. +// +// Use AcquireWriter for creating new writers. +type Writer struct { + e QWriter + n QWriter +} + +// W returns the underlying writer passed to AcquireWriter. +func (qw *Writer) W() io.Writer { + return qw.n.w +} + +// E returns QWriter with enabled html escaping. +func (qw *Writer) E() *QWriter { + return &qw.e +} + +// N returns QWriter without html escaping. +func (qw *Writer) N() *QWriter { + return &qw.n +} + +// AcquireWriter returns new writer from the pool. +// +// Return unneeded writer to the pool by calling ReleaseWriter +// in order to reduce memory allocations. +func AcquireWriter(w io.Writer) *Writer { + v := writerPool.Get() + if v == nil { + qw := &Writer{} + qw.e.w = &htmlEscapeWriter{} + v = qw + } + qw := v.(*Writer) + qw.e.w.(*htmlEscapeWriter).w = w + qw.n.w = w + return qw +} + +// ReleaseWriter returns the writer to the pool. +// +// Do not access released writer, otherwise data races may occur. +func ReleaseWriter(qw *Writer) { + hw := qw.e.w.(*htmlEscapeWriter) + hw.w = nil + qw.e.Reset() + qw.e.w = hw + + qw.n.Reset() + + writerPool.Put(qw) +} + +var writerPool sync.Pool + +// QWriter is auxiliary writer used by Writer. +type QWriter struct { + w io.Writer + err error + b []byte +} + +// Write implements io.Writer. +func (w *QWriter) Write(p []byte) (int, error) { + if w.err != nil { + return 0, w.err + } + n, err := w.w.Write(p) + if err != nil { + w.err = err + } + return n, err +} + +// Reset resets QWriter to the original state. +func (w *QWriter) Reset() { + w.w = nil + w.err = nil +} + +// S writes s to w. +func (w *QWriter) S(s string) { + w.Write(unsafeStrToBytes(s)) +} + +// Z writes z to w. +func (w *QWriter) Z(z []byte) { + w.Write(z) +} + +// SZ is a synonym to Z. +func (w *QWriter) SZ(z []byte) { + w.Write(z) +} + +// D writes n to w. +func (w *QWriter) D(n int) { + bb, ok := w.w.(*ByteBuffer) + if ok { + bb.B = strconv.AppendInt(bb.B, int64(n), 10) + } else { + w.b = strconv.AppendInt(w.b[:0], int64(n), 10) + w.Write(w.b) + } +} + +// F writes f to w. +func (w *QWriter) F(f float64) { + n := int(f) + if float64(n) == f { + // Fast path - just int. + w.D(n) + return + } + + // Slow path. + w.FPrec(f, -1) +} + +// FPrec writes f to w using the given floating point precision. +func (w *QWriter) FPrec(f float64, prec int) { + bb, ok := w.w.(*ByteBuffer) + if ok { + bb.B = strconv.AppendFloat(bb.B, f, 'f', prec, 64) + } else { + w.b = strconv.AppendFloat(w.b[:0], f, 'f', prec, 64) + w.Write(w.b) + } +} + +// Q writes quoted json-safe s to w. +func (w *QWriter) Q(s string) { + w.Write(strQuote) + writeJSONString(w, s) + w.Write(strQuote) +} + +var strQuote = []byte(`"`) + +// QZ writes quoted json-safe z to w. +func (w *QWriter) QZ(z []byte) { + w.Q(unsafeBytesToStr(z)) +} + +// J writes json-safe s to w. +// +// Unlike Q it doesn't qoute resulting s. +func (w *QWriter) J(s string) { + writeJSONString(w, s) +} + +// JZ writes json-safe z to w. +// +// Unlike Q it doesn't qoute resulting z. +func (w *QWriter) JZ(z []byte) { + w.J(unsafeBytesToStr(z)) +} + +// V writes v to w. +func (w *QWriter) V(v interface{}) { + fmt.Fprintf(w, "%v", v) +} + +// U writes url-encoded s to w. +func (w *QWriter) U(s string) { + bb, ok := w.w.(*ByteBuffer) + if ok { + bb.B = appendURLEncode(bb.B, s) + } else { + w.b = appendURLEncode(w.b[:0], s) + w.Write(w.b) + } +} + +// UZ writes url-encoded z to w. +func (w *QWriter) UZ(z []byte) { + w.U(unsafeBytesToStr(z)) +} diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS deleted file mode 100644 index 15167cd746c5..000000000000 --- a/vendor/golang.org/x/net/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS deleted file mode 100644 index 1c4577e96806..000000000000 --- a/vendor/golang.org/x/net/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE deleted file mode 100644 index 6a66aea5eafe..000000000000 --- a/vendor/golang.org/x/net/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/net/PATENTS b/vendor/golang.org/x/net/PATENTS deleted file mode 100644 index 733099041f84..000000000000 --- a/vendor/golang.org/x/net/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go deleted file mode 100644 index a3c021d3f88e..000000000000 --- a/vendor/golang.org/x/net/context/context.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package context defines the Context type, which carries deadlines, -// cancelation signals, and other request-scoped values across API boundaries -// and between processes. -// As of Go 1.7 this package is available in the standard library under the -// name context. https://golang.org/pkg/context. -// -// Incoming requests to a server should create a Context, and outgoing calls to -// servers should accept a Context. The chain of function calls between must -// propagate the Context, optionally replacing it with a modified copy created -// using WithDeadline, WithTimeout, WithCancel, or WithValue. -// -// Programs that use Contexts should follow these rules to keep interfaces -// consistent across packages and enable static analysis tools to check context -// propagation: -// -// Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. The Context should be the first -// parameter, typically named ctx: -// -// func DoSomething(ctx context.Context, arg Arg) error { -// // ... use ctx ... -// } -// -// Do not pass a nil Context, even if a function permits it. Pass context.TODO -// if you are unsure about which Context to use. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -// -// The same Context may be passed to functions running in different goroutines; -// Contexts are safe for simultaneous use by multiple goroutines. -// -// See http://blog.golang.org/context for example code for a server that uses -// Contexts. -package context // import "golang.org/x/net/context" - -// Background returns a non-nil, empty Context. It is never canceled, has no -// values, and has no deadline. It is typically used by the main function, -// initialization, and tests, and as the top-level Context for incoming -// requests. -func Background() Context { - return background -} - -// TODO returns a non-nil, empty Context. Code should use context.TODO when -// it's unclear which Context to use or it is not yet available (because the -// surrounding function has not yet been extended to accept a Context -// parameter). TODO is recognized by static analysis tools that determine -// whether Contexts are propagated correctly in a program. -func TODO() Context { - return todo -} diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go deleted file mode 100644 index d20f52b7de93..000000000000 --- a/vendor/golang.org/x/net/context/go17.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.7 - -package context - -import ( - "context" // standard library's context, as of Go 1.7 - "time" -) - -var ( - todo = context.TODO() - background = context.Background() -) - -// Canceled is the error returned by Context.Err when the context is canceled. -var Canceled = context.Canceled - -// DeadlineExceeded is the error returned by Context.Err when the context's -// deadline passes. -var DeadlineExceeded = context.DeadlineExceeded - -// WithCancel returns a copy of parent with a new Done channel. The returned -// context's Done channel is closed when the returned cancel function is called -// or when the parent context's Done channel is closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { - ctx, f := context.WithCancel(parent) - return ctx, CancelFunc(f) -} - -// WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned -// context's Done channel is closed when the deadline expires, when the returned -// cancel function is called, or when the parent context's Done channel is -// closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { - ctx, f := context.WithDeadline(parent, deadline) - return ctx, CancelFunc(f) -} - -// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete: -// -// func slowOperationWithTimeout(ctx context.Context) (Result, error) { -// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) -// defer cancel() // releases resources if slowOperation completes before timeout elapses -// return slowOperation(ctx) -// } -func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { - return WithDeadline(parent, time.Now().Add(timeout)) -} - -// WithValue returns a copy of parent in which the value associated with key is -// val. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -func WithValue(parent Context, key interface{}, val interface{}) Context { - return context.WithValue(parent, key, val) -} diff --git a/vendor/golang.org/x/net/context/go19.go b/vendor/golang.org/x/net/context/go19.go deleted file mode 100644 index d88bd1db127d..000000000000 --- a/vendor/golang.org/x/net/context/go19.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.9 - -package context - -import "context" // standard library's context, as of Go 1.7 - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context = context.Context - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc = context.CancelFunc diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go deleted file mode 100644 index 0f35592df518..000000000000 --- a/vendor/golang.org/x/net/context/pre_go17.go +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.7 - -package context - -import ( - "errors" - "fmt" - "sync" - "time" -) - -// An emptyCtx is never canceled, has no values, and has no deadline. It is not -// struct{}, since vars of this type must have distinct addresses. -type emptyCtx int - -func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { - return -} - -func (*emptyCtx) Done() <-chan struct{} { - return nil -} - -func (*emptyCtx) Err() error { - return nil -} - -func (*emptyCtx) Value(key interface{}) interface{} { - return nil -} - -func (e *emptyCtx) String() string { - switch e { - case background: - return "context.Background" - case todo: - return "context.TODO" - } - return "unknown empty Context" -} - -var ( - background = new(emptyCtx) - todo = new(emptyCtx) -) - -// Canceled is the error returned by Context.Err when the context is canceled. -var Canceled = errors.New("context canceled") - -// DeadlineExceeded is the error returned by Context.Err when the context's -// deadline passes. -var DeadlineExceeded = errors.New("context deadline exceeded") - -// WithCancel returns a copy of parent with a new Done channel. The returned -// context's Done channel is closed when the returned cancel function is called -// or when the parent context's Done channel is closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { - c := newCancelCtx(parent) - propagateCancel(parent, c) - return c, func() { c.cancel(true, Canceled) } -} - -// newCancelCtx returns an initialized cancelCtx. -func newCancelCtx(parent Context) *cancelCtx { - return &cancelCtx{ - Context: parent, - done: make(chan struct{}), - } -} - -// propagateCancel arranges for child to be canceled when parent is. -func propagateCancel(parent Context, child canceler) { - if parent.Done() == nil { - return // parent is never canceled - } - if p, ok := parentCancelCtx(parent); ok { - p.mu.Lock() - if p.err != nil { - // parent has already been canceled - child.cancel(false, p.err) - } else { - if p.children == nil { - p.children = make(map[canceler]bool) - } - p.children[child] = true - } - p.mu.Unlock() - } else { - go func() { - select { - case <-parent.Done(): - child.cancel(false, parent.Err()) - case <-child.Done(): - } - }() - } -} - -// parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this -// package represents its parent. -func parentCancelCtx(parent Context) (*cancelCtx, bool) { - for { - switch c := parent.(type) { - case *cancelCtx: - return c, true - case *timerCtx: - return c.cancelCtx, true - case *valueCtx: - parent = c.Context - default: - return nil, false - } - } -} - -// removeChild removes a context from its parent. -func removeChild(parent Context, child canceler) { - p, ok := parentCancelCtx(parent) - if !ok { - return - } - p.mu.Lock() - if p.children != nil { - delete(p.children, child) - } - p.mu.Unlock() -} - -// A canceler is a context type that can be canceled directly. The -// implementations are *cancelCtx and *timerCtx. -type canceler interface { - cancel(removeFromParent bool, err error) - Done() <-chan struct{} -} - -// A cancelCtx can be canceled. When canceled, it also cancels any children -// that implement canceler. -type cancelCtx struct { - Context - - done chan struct{} // closed by the first cancel call. - - mu sync.Mutex - children map[canceler]bool // set to nil by the first cancel call - err error // set to non-nil by the first cancel call -} - -func (c *cancelCtx) Done() <-chan struct{} { - return c.done -} - -func (c *cancelCtx) Err() error { - c.mu.Lock() - defer c.mu.Unlock() - return c.err -} - -func (c *cancelCtx) String() string { - return fmt.Sprintf("%v.WithCancel", c.Context) -} - -// cancel closes c.done, cancels each of c's children, and, if -// removeFromParent is true, removes c from its parent's children. -func (c *cancelCtx) cancel(removeFromParent bool, err error) { - if err == nil { - panic("context: internal error: missing cancel error") - } - c.mu.Lock() - if c.err != nil { - c.mu.Unlock() - return // already canceled - } - c.err = err - close(c.done) - for child := range c.children { - // NOTE: acquiring the child's lock while holding parent's lock. - child.cancel(false, err) - } - c.children = nil - c.mu.Unlock() - - if removeFromParent { - removeChild(c.Context, c) - } -} - -// WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned -// context's Done channel is closed when the deadline expires, when the returned -// cancel function is called, or when the parent context's Done channel is -// closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { - if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { - // The current deadline is already sooner than the new one. - return WithCancel(parent) - } - c := &timerCtx{ - cancelCtx: newCancelCtx(parent), - deadline: deadline, - } - propagateCancel(parent, c) - d := deadline.Sub(time.Now()) - if d <= 0 { - c.cancel(true, DeadlineExceeded) // deadline has already passed - return c, func() { c.cancel(true, Canceled) } - } - c.mu.Lock() - defer c.mu.Unlock() - if c.err == nil { - c.timer = time.AfterFunc(d, func() { - c.cancel(true, DeadlineExceeded) - }) - } - return c, func() { c.cancel(true, Canceled) } -} - -// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to -// implement Done and Err. It implements cancel by stopping its timer then -// delegating to cancelCtx.cancel. -type timerCtx struct { - *cancelCtx - timer *time.Timer // Under cancelCtx.mu. - - deadline time.Time -} - -func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { - return c.deadline, true -} - -func (c *timerCtx) String() string { - return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) -} - -func (c *timerCtx) cancel(removeFromParent bool, err error) { - c.cancelCtx.cancel(false, err) - if removeFromParent { - // Remove this timerCtx from its parent cancelCtx's children. - removeChild(c.cancelCtx.Context, c) - } - c.mu.Lock() - if c.timer != nil { - c.timer.Stop() - c.timer = nil - } - c.mu.Unlock() -} - -// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete: -// -// func slowOperationWithTimeout(ctx context.Context) (Result, error) { -// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) -// defer cancel() // releases resources if slowOperation completes before timeout elapses -// return slowOperation(ctx) -// } -func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { - return WithDeadline(parent, time.Now().Add(timeout)) -} - -// WithValue returns a copy of parent in which the value associated with key is -// val. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -func WithValue(parent Context, key interface{}, val interface{}) Context { - return &valueCtx{parent, key, val} -} - -// A valueCtx carries a key-value pair. It implements Value for that key and -// delegates all other calls to the embedded Context. -type valueCtx struct { - Context - key, val interface{} -} - -func (c *valueCtx) String() string { - return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) -} - -func (c *valueCtx) Value(key interface{}) interface{} { - if c.key == key { - return c.val - } - return c.Context.Value(key) -} diff --git a/vendor/golang.org/x/net/context/pre_go19.go b/vendor/golang.org/x/net/context/pre_go19.go deleted file mode 100644 index b105f80be4fe..000000000000 --- a/vendor/golang.org/x/net/context/pre_go19.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.9 - -package context - -import "time" - -// A Context carries a deadline, a cancelation signal, and other values across -// API boundaries. -// -// Context's methods may be called by multiple goroutines simultaneously. -type Context interface { - // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. - Deadline() (deadline time.Time, ok bool) - - // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. - // - // WithCancel arranges for Done to be closed when cancel is called; - // WithDeadline arranges for Done to be closed when the deadline - // expires; WithTimeout arranges for Done to be closed when the timeout - // elapses. - // - // Done is provided for use in select statements: - // - // // Stream generates values with DoSomething and sends them to out - // // until DoSomething returns an error or ctx.Done is closed. - // func Stream(ctx context.Context, out chan<- Value) error { - // for { - // v, err := DoSomething(ctx) - // if err != nil { - // return err - // } - // select { - // case <-ctx.Done(): - // return ctx.Err() - // case out <- v: - // } - // } - // } - // - // See http://blog.golang.org/pipelines for more examples of how to use - // a Done channel for cancelation. - Done() <-chan struct{} - - // Err returns a non-nil error value after Done is closed. Err returns - // Canceled if the context was canceled or DeadlineExceeded if the - // context's deadline passed. No other values for Err are defined. - // After Done is closed, successive calls to Err return the same value. - Err() error - - // Value returns the value associated with this context for key, or nil - // if no value is associated with key. Successive calls to Value with - // the same key returns the same result. - // - // Use context values only for request-scoped data that transits - // processes and API boundaries, not for passing optional parameters to - // functions. - // - // A key identifies a specific value in a Context. Functions that wish - // to store values in Context typically allocate a key in a global - // variable then use that key as the argument to context.WithValue and - // Context.Value. A key can be any type that supports equality; - // packages should define keys as an unexported type to avoid - // collisions. - // - // Packages that define a Context key should provide type-safe accessors - // for the values stores using that key: - // - // // Package user defines a User type that's stored in Contexts. - // package user - // - // import "golang.org/x/net/context" - // - // // User is the type of value stored in the Contexts. - // type User struct {...} - // - // // key is an unexported type for keys defined in this package. - // // This prevents collisions with keys defined in other packages. - // type key int - // - // // userKey is the key for user.User values in Contexts. It is - // // unexported; clients use user.NewContext and user.FromContext - // // instead of using this key directly. - // var userKey key = 0 - // - // // NewContext returns a new Context that carries value u. - // func NewContext(ctx context.Context, u *User) context.Context { - // return context.WithValue(ctx, userKey, u) - // } - // - // // FromContext returns the User value stored in ctx, if any. - // func FromContext(ctx context.Context) (*User, bool) { - // u, ok := ctx.Value(userKey).(*User) - // return u, ok - // } - Value(key interface{}) interface{} -} - -// A CancelFunc tells an operation to abandon its work. -// A CancelFunc does not wait for the work to stop. -// After the first call, subsequent calls to a CancelFunc do nothing. -type CancelFunc func() diff --git a/vendor/modules.txt b/vendor/modules.txt index cc1dff308aab..1ed4a3ab0a7f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -44,7 +44,7 @@ github.com/gobwas/glob/syntax/lexer github.com/gobwas/glob/util/strings # github.com/gogo/protobuf v1.1.1 github.com/gogo/protobuf/proto -# github.com/golang/mock v1.1.1 +# github.com/golang/mock v1.0.0 github.com/golang/mock/gomock # github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 github.com/golangci/check/cmd/structcheck @@ -181,12 +181,14 @@ github.com/spf13/viper # github.com/stretchr/testify v1.2.2 github.com/stretchr/testify/assert github.com/stretchr/testify/require +# github.com/valyala/bytebufferpool v1.0.0 +github.com/valyala/bytebufferpool +# github.com/valyala/quicktemplate v1.1.1 +github.com/valyala/quicktemplate # github.com/timakin/bodyclose v0.0.0-20190407043127-4a873e97b2bb github.com/timakin/bodyclose/passes/bodyclose # golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a golang.org/x/crypto/ssh/terminal -# golang.org/x/net v0.0.0-20190313220215-9f648a60d977 -golang.org/x/net/context # golang.org/x/sys v0.0.0-20190312061237-fead79001313 golang.org/x/sys/unix golang.org/x/sys/windows