diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..d85c6373 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 412274a3..8142982a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v1 + - uses: actions/stale@v3.0.19 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is inactive for a long time.' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..7ebaddd1 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,124 @@ +name: Test +on: + push: + branches: + - master + - develop + paths: + - "**/*.go" + - "go.mod" + - "go.sum" + - ".github/workflows/test.yml" + pull_request: + types: [opened, synchronize, reopened] + branches: + - master + - develop + paths: + - "**/*.go" + - "go.mod" + - "go.sum" + - ".github/workflows/test.yml" + +jobs: + test: + strategy: + fail-fast: false + matrix: + go-version: [1.14, 1.15, 1.16] + runs-on: ubuntu-latest + services: + redis: + image: redis:latest + ports: + - 6379:6379 + memcached: + image: memcached:latest + ports: + - 11211:11211 + ssdb: + image: wendal/ssdb:latest + ports: + - 8888:8888 + postgres: + image: postgres:latest + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: orm_test + ports: + - 5432/tcp + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + steps: + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + + - name: Checkout codebase + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Run etcd + env: + ETCD_VERSION: v3.4.16 + run: | + rm -rf /tmp/etcd-data.tmp + mkdir -p /tmp/etcd-data.tmp + docker rmi gcr.io/etcd-development/etcd:${ETCD_VERSION} || true && \ + docker run -d \ + -p 2379:2379 \ + -p 2380:2380 \ + --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data \ + --name etcd-gcr-${ETCD_VERSION} \ + gcr.io/etcd-development/etcd:${ETCD_VERSION} \ + /usr/local/bin/etcd \ + --name s1 \ + --data-dir /etcd-data \ + --listen-client-urls http://0.0.0.0:2379 \ + --advertise-client-urls http://0.0.0.0:2379 \ + --listen-peer-urls http://0.0.0.0:2380 \ + --initial-advertise-peer-urls http://0.0.0.0:2380 \ + --initial-cluster s1=http://0.0.0.0:2380 \ + --initial-cluster-token tkn \ + --initial-cluster-state new + docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23" + docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true" + docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11" + docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello" + docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test" + docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key" + + - name: Run ORM tests on sqlite3 + env: + GOPATH: /home/runner/go + ORM_DRIVER: sqlite3 + ORM_SOURCE: /tmp/sqlite3/orm_test.db + run: | + mkdir -p /tmp/sqlite3 && touch /tmp/sqlite3/orm_test.db + go test -coverprofile=coverage_sqlite3.txt -covermode=atomic $(go list ./... | grep client/orm) + + - name: Run ORM tests on postgres + env: + GOPATH: /home/runner/go + ORM_DRIVER: postgres + ORM_SOURCE: host=localhost port=${{ job.services.postgres.ports[5432] }} user=postgres password=postgres dbname=orm_test sslmode=disable + run: | + go test -coverprofile=coverage_postgres.txt -covermode=atomic $(go list ./... | grep client/orm) + + - name: Run tests on mysql + env: + GOPATH: /home/runner/go + ORM_DRIVER: mysql + ORM_SOURCE: root:root@/orm_test?charset=utf8 + run: | + sudo systemctl start mysql + mysql -u root -proot -e 'create database orm_test;' + go test -coverprofile=coverage.txt -covermode=atomic ./... + + - name: Upload codecov + env: + CODECOV_TOKEN: 4f4bc484-32a8-43b7-9f48-20966bd48ceb + run: bash <(curl -s https://codecov.io/bash) diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5ccd3645..00000000 --- a/.travis.yml +++ /dev/null @@ -1,75 +0,0 @@ -language: go - -go: - - "1.14.x" -services: - - redis-server - - mysql - - postgresql - - memcached - - docker -env: - global: - - GO_REPO_FULLNAME="github.com/beego/beego/v2" - matrix: - - ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db - - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" - - ORM_DRIVER=mysql export ORM_SOURCE="root:@/orm_test?charset=utf8" -before_install: - - export CODECOV_TOKEN="4f4bc484-32a8-43b7-9f48-20966bd48ceb" - # link the local repo with ${GOPATH}/src// - - GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*} - # relies on GOPATH to contain only one directory... - - mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE} - - ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME} - - cd ${GOPATH}/src/${GO_REPO_FULLNAME} - # get and build ssdb - - git clone git://github.com/ideawu/ssdb.git - - cd ssdb - - make - - cd .. - # - prepare etcd - # - prepare for etcd unit tests - - rm -rf /tmp/etcd-data.tmp - - mkdir -p /tmp/etcd-data.tmp - - docker rmi gcr.io/etcd-development/etcd:v3.3.25 || true && - docker run -d - -p 2379:2379 - -p 2380:2380 - --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data - --name etcd-gcr-v3.3.25 - gcr.io/etcd-development/etcd:v3.3.25 - /usr/local/bin/etcd - --name s1 - --data-dir /etcd-data - --listen-client-urls http://0.0.0.0:2379 - --advertise-client-urls http://0.0.0.0:2379 - --listen-peer-urls http://0.0.0.0:2380 - --initial-advertise-peer-urls http://0.0.0.0:2380 - --initial-cluster s1=http://0.0.0.0:2380 - --initial-cluster-token tkn - --initial-cluster-state new - - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23" - - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true" - - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11" - - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello" - - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test" - - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key" -before_script: - - psql --version - # - prepare for orm unit tests - - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" - - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi" - - sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi" - - sh -c "go list ./... | grep -v vendor | xargs go vet -v" - - mkdir -p res/var - - ./ssdb/ssdb-server ./ssdb/ssdb.conf -d -after_script: - - killall -w ssdb-server - - rm -rf ./res/var/* -after_success: - - bash <(curl -s https://codecov.io/bash) -script: - - GO111MODULE=on go test -coverprofile=coverage.txt -covermode=atomic ./... -addons: - postgresql: "9.6" diff --git a/CHANGELOG.md b/CHANGELOG.md index 5749cf07..58e0e8ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,13 @@ # developing + - Add template functions eq,lt to support uint and int compare. [4607](https://github.com/beego/beego/pull/4607) +- Migrate tests to GitHub Actions. [4663](https://github.com/beego/beego/issues/4663) +- Add http client and option func. [4455](https://github.com/beego/beego/issues/4455) +- Add: Convenient way to generate mock object [4620](https://github.com/beego/beego/issues/4620) +- Infra: use dependabot to update dependencies. [4623](https://github.com/beego/beego/pull/4623) - Lint: use golangci-lint. [4619](https://github.com/beego/beego/pull/4619) - Chore: format code. [4615](https://github.com/beego/beego/pull/4615) +- Test on Go v1.15.x & v1.16.x. [4614](https://github.com/beego/beego/pull/4614) - Env: non-empty GOBIN & GOPATH. [4613](https://github.com/beego/beego/pull/4613) - Chore: update dependencies. [4611](https://github.com/beego/beego/pull/4611) - Update orm_test.go/TestInsertOrUpdate with table-driven. [4609](https://github.com/beego/beego/pull/4609) @@ -45,10 +51,29 @@ - Optimize AddAutoPrefix: only register one router in case-insensitive mode. [4582](https://github.com/beego/beego/pull/4582) - Init exceptMethod by using reflection. [4583](https://github.com/beego/beego/pull/4583) - Deprecated BeeMap and replace all usage with `sync.map` [4616](https://github.com/beego/beego/pull/4616) +- TaskManager support graceful shutdown [4635](https://github.com/beego/beego/pull/4635) ## Fix Sonar +- [4624](https://github.com/beego/beego/pull/4624) - [4608](https://github.com/beego/beego/pull/4608) - [4473](https://github.com/beego/beego/pull/4473) - [4474](https://github.com/beego/beego/pull/4474) - [4479](https://github.com/beego/beego/pull/4479) +- [4639](https://github.com/beego/beego/pull/4639) + +## Fix lint and format code + +- [4644](https://github.com/beego/beego/pull/4644) +- [4645](https://github.com/beego/beego/pull/4645) +- [4646](https://github.com/beego/beego/pull/4646) +- [4647](https://github.com/beego/beego/pull/4647) +- [4648](https://github.com/beego/beego/pull/4648) +- [4649](https://github.com/beego/beego/pull/4649) +- [4651](https://github.com/beego/beego/pull/4651) +- [4652](https://github.com/beego/beego/pull/4652) +- [4653](https://github.com/beego/beego/pull/4653) +- [4654](https://github.com/beego/beego/pull/4654) +- [4655](https://github.com/beego/beego/pull/4655) +- [4656](https://github.com/beego/beego/pull/4656) +- [4660](https://github.com/beego/beego/pull/4660) diff --git a/README.md b/README.md index aa023fc7..0133510f 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ -# Beego [![Build Status](https://travis-ci.org/beego/beego.svg?branch=master)](https://travis-ci.org/beego/beego) [![GoDoc](http://godoc.org/github.com/beego/beego?status.svg)](http://godoc.org/github.com/beego/beego) [![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org) [![Go Report Card](https://goreportcard.com/badge/github.com/beego/beego)](https://goreportcard.com/report/github.com/beego/beego) +# Beego [![Test](https://github.com/beego/beego/actions/workflows/test.yml/badge.svg?branch=develop)](https://github.com/beego/beego/actions/workflows/test.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/beego/beego)](https://goreportcard.com/report/github.com/beego/beego) [![Go Reference](https://pkg.go.dev/badge/github.com/beego/beego/v2.svg)](https://pkg.go.dev/github.com/beego/beego/v2) -Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend -services. +Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. -It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct -embedding. +It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding. ![architecture](https://cdn.nlark.com/yuque/0/2020/png/755700/1607857489109-1e267fce-d65f-4c5e-b915-5c475df33c58.png) -Beego is compos of four parts: +Beego is composed of four parts: 1. Base modules: including log module, config module, governor module; 2. Task: is used for running timed tasks or periodic tasks; @@ -90,11 +88,11 @@ Congratulations! You've just built your first **beego** app. ## Community * [http://beego.me/community](http://beego.me/community) -* Welcome to join us in Slack: [https://beego.slack.com invite](https://join.slack.com/t/beego/shared_invite/zt-fqlfjaxs-_CRmiITCSbEqQG9NeBqXKA), +* Welcome to join us in Slack: [https://beego.slack.com invite](https://join.slack.com/t/beego/shared_invite/zt-fqlfjaxs-_CRmiITCSbEqQG9NeBqXKA), * QQ Group Group ID:523992905 * [Contribution Guide](https://github.com/beego/beedoc/blob/master/en-US/intro/contributing.md). ## License beego source code is licensed under the Apache Licence, Version 2.0 -(http://www.apache.org/licenses/LICENSE-2.0.html). +([https://www.apache.org/licenses/LICENSE-2.0.html](https://www.apache.org/licenses/LICENSE-2.0.html)). diff --git a/adapter/app.go b/adapter/app.go index 8502256b..2a5ff123 100644 --- a/adapter/app.go +++ b/adapter/app.go @@ -22,10 +22,8 @@ import ( "github.com/beego/beego/v2/server/web/context" ) -var ( - // BeeApp is an application instance - BeeApp *App -) +// BeeApp is an application instance +var BeeApp *App func init() { // create beego application diff --git a/adapter/beego.go b/adapter/beego.go index 331aa786..08eb1e72 100644 --- a/adapter/beego.go +++ b/adapter/beego.go @@ -36,10 +36,6 @@ type M web.M // Hook function to run type hookfunc func() error -var ( - hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc -) - // AddAPPStartHook is used to register the hookfunc // The hookfuncs will run in beego.Run() // such as initiating session , starting middleware , building template, starting admin control and so on. diff --git a/adapter/cache/conv_test.go b/adapter/cache/conv_test.go index b90e224a..af49e92c 100644 --- a/adapter/cache/conv_test.go +++ b/adapter/cache/conv_test.go @@ -19,15 +19,15 @@ import ( ) func TestGetString(t *testing.T) { - var t1 = "test1" + t1 := "test1" if "test1" != GetString(t1) { t.Error("get string from string error") } - var t2 = []byte("test2") + t2 := []byte("test2") if "test2" != GetString(t2) { t.Error("get string from byte array error") } - var t3 = 1 + t3 := 1 if "1" != GetString(t3) { t.Error("get string from int error") } @@ -35,7 +35,7 @@ func TestGetString(t *testing.T) { if "1" != GetString(t4) { t.Error("get string from int64 error") } - var t5 = 1.1 + t5 := 1.1 if "1.1" != GetString(t5) { t.Error("get string from float64 error") } @@ -46,7 +46,7 @@ func TestGetString(t *testing.T) { } func TestGetInt(t *testing.T) { - var t1 = 1 + t1 := 1 if 1 != GetInt(t1) { t.Error("get int from int error") } @@ -58,7 +58,7 @@ func TestGetInt(t *testing.T) { if 64 != GetInt(t3) { t.Error("get int from int64 error") } - var t4 = "128" + t4 := "128" if 128 != GetInt(t4) { t.Error("get int from num string error") } @@ -69,7 +69,7 @@ func TestGetInt(t *testing.T) { func TestGetInt64(t *testing.T) { var i int64 = 1 - var t1 = 1 + t1 := 1 if i != GetInt64(t1) { t.Error("get int64 from int error") } @@ -81,7 +81,7 @@ func TestGetInt64(t *testing.T) { if i != GetInt64(t3) { t.Error("get int64 from int64 error") } - var t4 = "1" + t4 := "1" if i != GetInt64(t4) { t.Error("get int64 from num string error") } @@ -91,22 +91,22 @@ func TestGetInt64(t *testing.T) { } func TestGetFloat64(t *testing.T) { - var f = 1.11 + f := 1.11 var t1 float32 = 1.11 if f != GetFloat64(t1) { t.Error("get float64 from float32 error") } - var t2 = 1.11 + t2 := 1.11 if f != GetFloat64(t2) { t.Error("get float64 from float64 error") } - var t3 = "1.11" + t3 := "1.11" if f != GetFloat64(t3) { t.Error("get float64 from string error") } var f2 float64 = 1 - var t4 = 1 + t4 := 1 if f2 != GetFloat64(t4) { t.Error("get float64 from int error") } @@ -117,11 +117,11 @@ func TestGetFloat64(t *testing.T) { } func TestGetBool(t *testing.T) { - var t1 = true + t1 := true if !GetBool(t1) { t.Error("get bool from bool error") } - var t2 = "true" + t2 := "true" if !GetBool(t2) { t.Error("get bool from string error") } diff --git a/adapter/cache/redis/redis.go b/adapter/cache/redis/redis.go index 003bc6b1..a511f53a 100644 --- a/adapter/cache/redis/redis.go +++ b/adapter/cache/redis/redis.go @@ -34,10 +34,8 @@ import ( redis2 "github.com/beego/beego/v2/client/cache/redis" ) -var ( - // DefaultKey the collection name of redis for cache adapter. - DefaultKey = "beecacheRedis" -) +// DefaultKey the collection name of redis for cache adapter. +var DefaultKey = "beecacheRedis" // NewRedisCache create new redis cache with default collection name. func NewRedisCache() cache.Cache { diff --git a/adapter/config/config_test.go b/adapter/config/config_test.go index 15d6ffa6..86d3a2c5 100644 --- a/adapter/config/config_test.go +++ b/adapter/config/config_test.go @@ -20,7 +20,6 @@ import ( ) func TestExpandValueEnv(t *testing.T) { - testCases := []struct { item string want string @@ -51,5 +50,4 @@ func TestExpandValueEnv(t *testing.T) { t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got) } } - } diff --git a/adapter/config/ini_test.go b/adapter/config/ini_test.go index 07992ba7..997d3f68 100644 --- a/adapter/config/ini_test.go +++ b/adapter/config/ini_test.go @@ -23,7 +23,6 @@ import ( ) func TestIni(t *testing.T) { - var ( inicontext = ` ;comment one @@ -129,11 +128,9 @@ password = ${GOPATH} if iniconf.String("name") != "astaxie" { t.Fatal("get name error") } - } func TestIniSave(t *testing.T) { - const ( inicontext = ` app = app diff --git a/adapter/config/json_test.go b/adapter/config/json_test.go index c73b5772..2f2c27c3 100644 --- a/adapter/config/json_test.go +++ b/adapter/config/json_test.go @@ -23,7 +23,6 @@ import ( ) func TestJsonStartsWithArray(t *testing.T) { - const jsoncontextwitharray = `[ { "url": "user", @@ -71,7 +70,6 @@ func TestJsonStartsWithArray(t *testing.T) { } func TestJson(t *testing.T) { - var ( jsoncontext = `{ "appname": "beeapi", diff --git a/adapter/config/xml/xml_test.go b/adapter/config/xml/xml_test.go index 95b21fd9..48424ef9 100644 --- a/adapter/config/xml/xml_test.go +++ b/adapter/config/xml/xml_test.go @@ -23,7 +23,6 @@ import ( ) func TestXML(t *testing.T) { - var ( // xml parse should incluce in tags xmlcontext = ` diff --git a/adapter/config/yaml/yaml_test.go b/adapter/config/yaml/yaml_test.go index 323b5e87..ac0245dd 100644 --- a/adapter/config/yaml/yaml_test.go +++ b/adapter/config/yaml/yaml_test.go @@ -23,7 +23,6 @@ import ( ) func TestYaml(t *testing.T) { - var ( yamlcontext = ` "appname": beeapi @@ -112,5 +111,4 @@ func TestYaml(t *testing.T) { if yamlconf.String("name") != "astaxie" { t.Fatal("get name error") } - } diff --git a/adapter/context/param/conv_test.go b/adapter/context/param/conv_test.go index 8428ed89..b31a8afc 100644 --- a/adapter/context/param/conv_test.go +++ b/adapter/context/param/conv_test.go @@ -25,7 +25,6 @@ import ( // Demo is used to test, it's empty func Demo(i int) { - } func TestConvertParams(t *testing.T) { diff --git a/adapter/controller.go b/adapter/controller.go index 840abb48..6d2d5f64 100644 --- a/adapter/controller.go +++ b/adapter/controller.go @@ -48,9 +48,11 @@ type ControllerCommentsSlice web.ControllerCommentsSlice func (p ControllerCommentsSlice) Len() int { return (web.ControllerCommentsSlice)(p).Len() } + func (p ControllerCommentsSlice) Less(i, j int) bool { return (web.ControllerCommentsSlice)(p).Less(i, j) } + func (p ControllerCommentsSlice) Swap(i, j int) { (web.ControllerCommentsSlice)(p).Swap(i, j) } diff --git a/adapter/httplib/httplib_test.go b/adapter/httplib/httplib_test.go index 298d84f9..41018c19 100644 --- a/adapter/httplib/httplib_test.go +++ b/adapter/httplib/httplib_test.go @@ -26,11 +26,13 @@ import ( "time" ) -const getUrl = "http://httpbin.org/get" -const ipUrl = "http://httpbin.org/ip" +const ( + getURL = "http://httpbin.org/get" + ipURL = "http://httpbin.org/ip" +) func TestResponse(t *testing.T) { - req := Get(getUrl) + req := Get(getURL) resp, err := req.Response() if err != nil { t.Fatal(err) @@ -63,12 +65,10 @@ func TestDoRequest(t *testing.T) { if elapsedTime < delayedTime { t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime) } - } func TestGet(t *testing.T) { - - req := Get(getUrl) + req := Get(getURL) b, err := req.Bytes() if err != nil { t.Fatal(err) @@ -210,7 +210,7 @@ func TestWithSetting(t *testing.T) { setting.ReadWriteTimeout = 5 * time.Second SetDefaultSetting(setting) - str, err := Get(getUrl).String() + str, err := Get(getURL).String() if err != nil { t.Fatal(err) } @@ -223,8 +223,7 @@ func TestWithSetting(t *testing.T) { } func TestToJson(t *testing.T) { - - req := Get(ipUrl) + req := Get(ipURL) resp, err := req.Response() if err != nil { t.Fatal(err) @@ -250,12 +249,11 @@ func TestToJson(t *testing.T) { t.Fatal("response is not valid ip") } } - } func TestToFile(t *testing.T) { f := "beego_testfile" - req := Get(ipUrl) + req := Get(ipURL) err := req.ToFile(f) if err != nil { t.Fatal(err) @@ -269,7 +267,7 @@ func TestToFile(t *testing.T) { func TestToFileDir(t *testing.T) { f := "./files/beego_testfile" - req := Get(ipUrl) + req := Get(ipURL) err := req.ToFile(f) if err != nil { t.Fatal(err) diff --git a/adapter/orm/db.go b/adapter/orm/db.go index 3cdd33cd..c1d1fe92 100644 --- a/adapter/orm/db.go +++ b/adapter/orm/db.go @@ -18,7 +18,5 @@ import ( "github.com/beego/beego/v2/client/orm" ) -var ( - // ErrMissPK missing pk error - ErrMissPK = orm.ErrMissPK -) +// ErrMissPK missing pk error +var ErrMissPK = orm.ErrMissPK diff --git a/adapter/orm/query_setter_adapter.go b/adapter/orm/query_setter_adapter.go deleted file mode 100644 index edea0a15..00000000 --- a/adapter/orm/query_setter_adapter.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2020 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package orm - -import ( - "github.com/beego/beego/v2/client/orm" -) - -type baseQuerySetter struct { -} - -const shouldNotInvoke = "you should not invoke this method." - -func (b *baseQuerySetter) ForceIndex(indexes ...string) orm.QuerySeter { - panic(shouldNotInvoke) -} - -func (b *baseQuerySetter) UseIndex(indexes ...string) orm.QuerySeter { - panic(shouldNotInvoke) -} - -func (b *baseQuerySetter) IgnoreIndex(indexes ...string) orm.QuerySeter { - panic(shouldNotInvoke) -} diff --git a/adapter/session/redis_sentinel/sess_redis_sentinel_test.go b/adapter/session/redis_sentinel/sess_redis_sentinel_test.go index b08d0256..2d381af6 100644 --- a/adapter/session/redis_sentinel/sess_redis_sentinel_test.go +++ b/adapter/session/redis_sentinel/sess_redis_sentinel_test.go @@ -72,5 +72,4 @@ func TestRedisSentinel(t *testing.T) { assert.Nil(t, password) sess.SessionRelease(w) - } diff --git a/adapter/session/sess_file_test.go b/adapter/session/sess_file_test.go index 4cec8341..a3e3d0b9 100644 --- a/adapter/session/sess_file_test.go +++ b/adapter/session/sess_file_test.go @@ -22,14 +22,14 @@ import ( "time" ) -const sid = "Session_id" -const sidNew = "Session_id_new" -const sessionPath = "./_session_runtime" - -var ( - mutex sync.Mutex +const ( + sid = "Session_id" + sidNew = "Session_id_new" + sessionPath = "./_session_runtime" ) +var mutex sync.Mutex + func TestFileProviderSessionExist(t *testing.T) { mutex.Lock() defer mutex.Unlock() diff --git a/adapter/templatefunc.go b/adapter/templatefunc.go index 808539e7..c5574d32 100644 --- a/adapter/templatefunc.go +++ b/adapter/templatefunc.go @@ -118,7 +118,6 @@ func AssetsJs(text string) template.HTML { // AssetsCSS returns stylesheet link tag with src string. func AssetsCSS(text string) template.HTML { - text = "" return template.HTML(text) diff --git a/adapter/templatefunc_test.go b/adapter/templatefunc_test.go index c12efd7e..b3d5e968 100644 --- a/adapter/templatefunc_test.go +++ b/adapter/templatefunc_test.go @@ -79,7 +79,6 @@ func TestHtmlunquote(t *testing.T) { h := `<' ”“&">` s := `<' ”“&">` assert.Equal(t, s, Htmlunquote(h)) - } func TestParseForm(t *testing.T) { @@ -234,5 +233,4 @@ func TestMapGet(t *testing.T) { res, err = MapGet(m5, 5, 4, 3, 2, 1) assert.Nil(t, err) assert.Nil(t, res) - } diff --git a/adapter/testing/client.go b/adapter/testing/client.go index 356a0f68..a773c9a6 100644 --- a/adapter/testing/client.go +++ b/adapter/testing/client.go @@ -14,12 +14,7 @@ package testing -import ( - "github.com/beego/beego/v2/client/httplib/testing" -) - -var port = "" -var baseURL = "http://localhost:" +import "github.com/beego/beego/v2/client/httplib/testing" // TestHTTPRequest beego test request client type TestHTTPRequest testing.TestHTTPRequest diff --git a/adapter/toolbox/profile.go b/adapter/toolbox/profile.go index 15d7010a..00b0eef7 100644 --- a/adapter/toolbox/profile.go +++ b/adapter/toolbox/profile.go @@ -16,19 +16,10 @@ package toolbox import ( "io" - "os" - "time" "github.com/beego/beego/v2/core/admin" ) -var startTime = time.Now() -var pid int - -func init() { - pid = os.Getpid() -} - // ProcessInput parse input command string func ProcessInput(input string, w io.Writer) { admin.ProcessInput(input, w) diff --git a/adapter/toolbox/task.go b/adapter/toolbox/task.go index 7b7cd68a..199956f8 100644 --- a/adapter/toolbox/task.go +++ b/adapter/toolbox/task.go @@ -80,7 +80,6 @@ type Task struct { // NewTask add new task with name, time and func func NewTask(tname string, spec string, f TaskFunc) *Task { - task := task.NewTask(tname, spec, func(ctx context.Context) error { return f() }) @@ -98,7 +97,6 @@ func (t *Task) GetSpec() string { // GetStatus get current task status func (t *Task) GetStatus() string { - t.initDelegate() return t.delegate.GetStatus(context.Background()) @@ -222,7 +220,6 @@ type MapSorter task.MapSorter // NewMapSorter create new tasker map func NewMapSorter(m map[string]Tasker) *MapSorter { - newTaskerMap := make(map[string]task.Tasker, len(m)) for key, value := range m { @@ -249,6 +246,7 @@ func (ms *MapSorter) Less(i, j int) bool { } return ms.Vals[i].GetNext(context.Background()).Before(ms.Vals[j].GetNext(context.Background())) } + func (ms *MapSorter) Swap(i, j int) { ms.Vals[i], ms.Vals[j] = ms.Vals[j], ms.Vals[i] ms.Keys[i], ms.Keys[j] = ms.Keys[j], ms.Keys[i] diff --git a/adapter/utils/captcha/captcha.go b/adapter/utils/captcha/captcha.go index 741be9a5..7cdcab2d 100644 --- a/adapter/utils/captcha/captcha.go +++ b/adapter/utils/captcha/captcha.go @@ -69,9 +69,7 @@ import ( beecontext "github.com/beego/beego/v2/server/web/context" ) -var ( - defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} -) +var defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} const ( // default captcha attributes diff --git a/adapter/utils/debug_test.go b/adapter/utils/debug_test.go index efb8924e..a748d20a 100644 --- a/adapter/utils/debug_test.go +++ b/adapter/utils/debug_test.go @@ -28,8 +28,8 @@ func TestPrint(t *testing.T) { } func TestPrintPoint(t *testing.T) { - var v1 = new(mytype) - var v2 = new(mytype) + v1 := new(mytype) + v2 := new(mytype) v1.prev = nil v1.next = v2 diff --git a/adapter/utils/slice.go b/adapter/utils/slice.go index cdbfcca8..082b22ce 100644 --- a/adapter/utils/slice.go +++ b/adapter/utils/slice.go @@ -19,6 +19,7 @@ import ( ) type reducetype func(interface{}) interface{} + type filtertype func(interface{}) bool // InSlice checks given string in string slice or not. diff --git a/adapter/validation/util.go b/adapter/validation/util.go index 502be750..5ff43ebc 100644 --- a/adapter/validation/util.go +++ b/adapter/validation/util.go @@ -27,9 +27,7 @@ const ( LabelTag = validation.LabelTag ) -var ( - ErrInt64On32 = validation.ErrInt64On32 -) +var ErrInt64On32 = validation.ErrInt64On32 // CustomFunc is for custom validate function type CustomFunc func(v *Validation, obj interface{}, key string) diff --git a/adapter/validation/validation_test.go b/adapter/validation/validation_test.go index 2e29b641..547e8635 100644 --- a/adapter/validation/validation_test.go +++ b/adapter/validation/validation_test.go @@ -50,7 +50,6 @@ func TestMin(t *testing.T) { assert.False(t, valid.Min(-1, 0, "min0").Ok) assert.True(t, valid.Min(1, 0, "min0").Ok) - } func TestMax(t *testing.T) { @@ -502,5 +501,4 @@ func TestCanSkipAlso(t *testing.T) { assert.Nil(t, err) assert.True(t, b) - } diff --git a/client/cache/calc_utils.go b/client/cache/calc_utils.go index 417f8337..f8b7f24a 100644 --- a/client/cache/calc_utils.go +++ b/client/cache/calc_utils.go @@ -12,6 +12,11 @@ var ( ErrNotIntegerType = berror.Error(NotIntegerType, "item val is not (u)int (u)int32 (u)int64") ) +const ( + MinUint32 uint32 = 0 + MinUint64 uint64 = 0 +) + func incr(originVal interface{}) (interface{}, error) { switch val := originVal.(type) { case int: @@ -75,12 +80,12 @@ func decr(originVal interface{}) (interface{}, error) { } return val - 1, nil case uint32: - if val == 0 { + if val == MinUint32 { return nil, ErrDecrementOverflow } return val - 1, nil case uint64: - if val == 0 { + if val == MinUint64 { return nil, ErrDecrementOverflow } return val - 1, nil diff --git a/client/cache/conv_test.go b/client/cache/conv_test.go index 523150d1..c261c440 100644 --- a/client/cache/conv_test.go +++ b/client/cache/conv_test.go @@ -21,29 +21,29 @@ import ( ) func TestGetString(t *testing.T) { - var t1 = "test1" + t1 := "test1" assert.Equal(t, "test1", GetString(t1)) - var t2 = []byte("test2") + t2 := []byte("test2") assert.Equal(t, "test2", GetString(t2)) - var t3 = 1 + t3 := 1 assert.Equal(t, "1", GetString(t3)) var t4 int64 = 1 assert.Equal(t, "1", GetString(t4)) - var t5 = 1.1 + t5 := 1.1 assert.Equal(t, "1.1", GetString(t5)) assert.Equal(t, "", GetString(nil)) } func TestGetInt(t *testing.T) { - var t1 = 1 + t1 := 1 assert.Equal(t, 1, GetInt(t1)) var t2 int32 = 32 assert.Equal(t, 32, GetInt(t2)) var t3 int64 = 64 assert.Equal(t, 64, GetInt(t3)) - var t4 = "128" + t4 := "128" assert.Equal(t, 128, GetInt(t4)) assert.Equal(t, 0, GetInt(nil)) @@ -51,38 +51,38 @@ func TestGetInt(t *testing.T) { func TestGetInt64(t *testing.T) { var i int64 = 1 - var t1 = 1 + t1 := 1 assert.Equal(t, i, GetInt64(t1)) var t2 int32 = 1 assert.Equal(t, i, GetInt64(t2)) var t3 int64 = 1 assert.Equal(t, i, GetInt64(t3)) - var t4 = "1" + t4 := "1" assert.Equal(t, i, GetInt64(t4)) assert.Equal(t, int64(0), GetInt64(nil)) } func TestGetFloat64(t *testing.T) { - var f = 1.11 + f := 1.11 var t1 float32 = 1.11 assert.Equal(t, f, GetFloat64(t1)) - var t2 = 1.11 + t2 := 1.11 assert.Equal(t, f, GetFloat64(t2)) - var t3 = "1.11" + t3 := "1.11" assert.Equal(t, f, GetFloat64(t3)) var f2 float64 = 1 - var t4 = 1 + t4 := 1 assert.Equal(t, f2, GetFloat64(t4)) assert.Equal(t, float64(0), GetFloat64(nil)) } func TestGetBool(t *testing.T) { - var t1 = true + t1 := true assert.True(t, GetBool(t1)) - var t2 = "true" + t2 := "true" assert.True(t, GetBool(t2)) assert.False(t, GetBool(nil)) diff --git a/client/cache/error_code.go b/client/cache/error_code.go index 3981af43..5611f065 100644 --- a/client/cache/error_code.go +++ b/client/cache/error_code.go @@ -170,5 +170,7 @@ The reponse from SSDB server is invalid. Usually it indicates something wrong on server side. `) -var ErrKeyExpired = berror.Error(KeyExpired, "the key is expired") -var ErrKeyNotExist = berror.Error(KeyNotExist, "the key isn't exist") +var ( + ErrKeyExpired = berror.Error(KeyExpired, "the key is expired") + ErrKeyNotExist = berror.Error(KeyNotExist, "the key isn't exist") +) diff --git a/client/cache/file.go b/client/cache/file.go index 1f2e64d6..ae2bc7cf 100644 --- a/client/cache/file.go +++ b/client/cache/file.go @@ -67,7 +67,6 @@ func NewFileCache() Cache { // StartAndGC starts gc for file cache. // config must be in the format {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"} func (fc *FileCache) StartAndGC(config string) error { - cfg := make(map[string]string) err := json.Unmarshal([]byte(config), &cfg) if err != nil { diff --git a/client/cache/memory.go b/client/cache/memory.go index f294595d..c1d1a2e5 100644 --- a/client/cache/memory.go +++ b/client/cache/memory.go @@ -25,10 +25,8 @@ import ( "github.com/beego/beego/v2/core/berror" ) -var ( - // Timer for how often to recycle the expired cache items in memory (in seconds) - DefaultEvery = 60 // 1 minute -) +// DefaultEvery sets a timer for how often to recycle the expired cache items in memory (in seconds) +var DefaultEvery = 60 // 1 minute // MemoryItem stores memory cache item. type MemoryItem struct { diff --git a/client/cache/redis/redis.go b/client/cache/redis/redis.go index 7e70af2e..bd244223 100644 --- a/client/cache/redis/redis.go +++ b/client/cache/redis/redis.go @@ -43,10 +43,8 @@ import ( "github.com/beego/beego/v2/core/berror" ) -var ( - // The collection name of redis for the cache adapter. - DefaultKey = "beecacheRedis" -) +// DefaultKey defines the collection name of redis for the cache adapter. +var DefaultKey = "beecacheRedis" // Cache is Redis cache adapter. type Cache struct { diff --git a/client/cache/redis/redis_test.go b/client/cache/redis/redis_test.go index 89ee9243..305e5423 100644 --- a/client/cache/redis/redis_test.go +++ b/client/cache/redis/redis_test.go @@ -28,7 +28,6 @@ import ( ) func TestRedisCache(t *testing.T) { - redisAddr := os.Getenv("REDIS_ADDR") if redisAddr == "" { redisAddr = "127.0.0.1:6379" diff --git a/client/cache/ssdb/ssdb.go b/client/cache/ssdb/ssdb.go index e715d07f..54558ea3 100644 --- a/client/cache/ssdb/ssdb.go +++ b/client/cache/ssdb/ssdb.go @@ -124,7 +124,6 @@ func (rc *Cache) IsExist(ctx context.Context, key string) (bool, error) { return true, nil } return false, nil - } // ClearAll clears all cached items in ssdb. diff --git a/client/cache/ssdb/ssdb_test.go b/client/cache/ssdb/ssdb_test.go index 41271e9b..0a38b2de 100644 --- a/client/cache/ssdb/ssdb_test.go +++ b/client/cache/ssdb/ssdb_test.go @@ -15,7 +15,6 @@ import ( ) func TestSsdbcacheCache(t *testing.T) { - ssdbAddr := os.Getenv("SSDB_ADDR") if ssdbAddr == "" { ssdbAddr = "127.0.0.1:8888" diff --git a/client/httplib/README.md b/client/httplib/README.md index 1d22f341..a5723c6d 100644 --- a/client/httplib/README.md +++ b/client/httplib/README.md @@ -9,7 +9,7 @@ httplib is an libs help you to curl remote url. you can use Get to crawl data. import "github.com/beego/beego/v2/client/httplib" - + str, err := httplib.Get("http://beego.me/").String() if err != nil { // error @@ -39,7 +39,7 @@ Example: // GET httplib.Get("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second) - + // POST httplib.Post("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second) diff --git a/client/httplib/client_option.go b/client/httplib/client_option.go new file mode 100644 index 00000000..f970e67d --- /dev/null +++ b/client/httplib/client_option.go @@ -0,0 +1,155 @@ +// Copyright 2020 beego +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package httplib + +import ( + "crypto/tls" + "net/http" + "net/url" + "time" +) + +type ( + ClientOption func(client *Client) + BeegoHTTPRequestOption func(request *BeegoHTTPRequest) +) + +// WithEnableCookie will enable cookie in all subsequent request +func WithEnableCookie(enable bool) ClientOption { + return func(client *Client) { + client.Setting.EnableCookie = enable + } +} + +// WithEnableCookie will adds UA in all subsequent request +func WithUserAgent(userAgent string) ClientOption { + return func(client *Client) { + client.Setting.UserAgent = userAgent + } +} + +// WithTLSClientConfig will adds tls config in all subsequent request +func WithTLSClientConfig(config *tls.Config) ClientOption { + return func(client *Client) { + client.Setting.TLSClientConfig = config + } +} + +// WithTransport will set transport field in all subsequent request +func WithTransport(transport http.RoundTripper) ClientOption { + return func(client *Client) { + client.Setting.Transport = transport + } +} + +// WithProxy will set http proxy field in all subsequent request +func WithProxy(proxy func(*http.Request) (*url.URL, error)) ClientOption { + return func(client *Client) { + client.Setting.Proxy = proxy + } +} + +// WithCheckRedirect will specifies the policy for handling redirects in all subsequent request +func WithCheckRedirect(redirect func(req *http.Request, via []*http.Request) error) ClientOption { + return func(client *Client) { + client.Setting.CheckRedirect = redirect + } +} + +// WithHTTPSetting can replace beegoHTTPSeting +func WithHTTPSetting(setting BeegoHTTPSettings) ClientOption { + return func(client *Client) { + client.Setting = setting + } +} + +// WithEnableGzip will enable gzip in all subsequent request +func WithEnableGzip(enable bool) ClientOption { + return func(client *Client) { + client.Setting.Gzip = enable + } +} + +// BeegoHttpRequestOption + +// WithTimeout sets connect time out and read-write time out for BeegoRequest. +func WithTimeout(connectTimeout, readWriteTimeout time.Duration) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.SetTimeout(connectTimeout, readWriteTimeout) + } +} + +// WithHeader adds header item string in request. +func WithHeader(key, value string) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.Header(key, value) + } +} + +// WithCookie adds a cookie to the request. +func WithCookie(cookie *http.Cookie) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.Header("Cookie", cookie.String()) + } +} + +// Withtokenfactory adds a custom function to set Authorization +func WithTokenFactory(tokenFactory func() string) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + t := tokenFactory() + + request.Header("Authorization", t) + } +} + +// WithBasicAuth adds a custom function to set basic auth +func WithBasicAuth(basicAuth func() (string, string)) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + username, password := basicAuth() + request.SetBasicAuth(username, password) + } +} + +// WithFilters will use the filter as the invocation filters +func WithFilters(fcs ...FilterChain) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.SetFilters(fcs...) + } +} + +// WithContentType adds ContentType in header +func WithContentType(contentType string) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.Header(contentTypeKey, contentType) + } +} + +// WithParam adds query param in to request. +func WithParam(key, value string) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.Param(key, value) + } +} + +// WithRetry set retry times and delay for the request +// default is 0 (never retry) +// -1 retry indefinitely (forever) +// Other numbers specify the exact retry amount +func WithRetry(times int, delay time.Duration) BeegoHTTPRequestOption { + return func(request *BeegoHTTPRequest) { + request.Retries(times) + request.RetryDelay(delay) + } +} diff --git a/client/httplib/client_option_test.go b/client/httplib/client_option_test.go new file mode 100644 index 00000000..79e5103f --- /dev/null +++ b/client/httplib/client_option_test.go @@ -0,0 +1,261 @@ +// Copyright 2020 beego +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package httplib + +import ( + "errors" + "net" + "net/http" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +type respCarrier struct { + bytes []byte +} + +func (r *respCarrier) SetBytes(bytes []byte) { + r.bytes = bytes +} + +func (r *respCarrier) String() string { + return string(r.bytes) +} + +func TestOption_WithEnableCookie(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/", + WithEnableCookie(true)) + if err != nil { + t.Fatal(err) + } + + v := "smallfish" + resp := &respCarrier{} + err = client.Get(resp, "/cookies/set?k1="+v) + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + err = client.Get(resp, "/cookies") + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), v) + if n == -1 { + t.Fatal(v + " not found in cookie") + } +} + +func TestOption_WithUserAgent(t *testing.T) { + v := "beego" + client, err := NewClient("test", "http://httpbin.org/", + WithUserAgent(v)) + if err != nil { + t.Fatal(err) + } + + resp := &respCarrier{} + err = client.Get(resp, "/headers") + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), v) + if n == -1 { + t.Fatal(v + " not found in user-agent") + } +} + +func TestOption_WithCheckRedirect(t *testing.T) { + client, err := NewClient("test", "https://goolnk.com/33BD2j", + WithCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error { + return errors.New("Redirect triggered") + })) + if err != nil { + t.Fatal(err) + } + err = client.Get(nil, "") + assert.NotNil(t, err) +} + +func TestOption_WithHTTPSetting(t *testing.T) { + v := "beego" + var setting BeegoHTTPSettings + setting.EnableCookie = true + setting.UserAgent = v + setting.Transport = &http.Transport{ + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 50, + IdleConnTimeout: 90 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } + setting.ReadWriteTimeout = 5 * time.Second + + client, err := NewClient("test", "http://httpbin.org/", + WithHTTPSetting(setting)) + if err != nil { + t.Fatal(err) + } + + resp := &respCarrier{} + err = client.Get(resp, "/get") + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), v) + if n == -1 { + t.Fatal(v + " not found in user-agent") + } +} + +func TestOption_WithHeader(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/") + if err != nil { + t.Fatal(err) + } + client.CommonOpts = append(client.CommonOpts, WithHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36")) + + resp := &respCarrier{} + err = client.Get(resp, "/headers") + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), "Mozilla/5.0") + if n == -1 { + t.Fatal("Mozilla/5.0 not found in user-agent") + } +} + +func TestOption_WithTokenFactory(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/") + if err != nil { + t.Fatal(err) + } + client.CommonOpts = append(client.CommonOpts, + WithTokenFactory(func() string { + return "testauth" + })) + + resp := &respCarrier{} + err = client.Get(resp, "/headers") + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), "testauth") + if n == -1 { + t.Fatal("Auth is not set in request") + } +} + +func TestOption_WithBasicAuth(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/") + if err != nil { + t.Fatal(err) + } + + resp := &respCarrier{} + err = client.Get(resp, "/basic-auth/user/passwd", + WithBasicAuth(func() (string, string) { + return "user", "passwd" + })) + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + n := strings.Index(resp.String(), "authenticated") + if n == -1 { + t.Fatal("authenticated not found in response") + } +} + +func TestOption_WithContentType(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/") + if err != nil { + t.Fatal(err) + } + + v := "application/json" + resp := &respCarrier{} + err = client.Get(resp, "/headers", WithContentType(v)) + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), v) + if n == -1 { + t.Fatal(v + " not found in header") + } +} + +func TestOption_WithParam(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/") + if err != nil { + t.Fatal(err) + } + + v := "smallfish" + resp := &respCarrier{} + err = client.Get(resp, "/get", WithParam("username", v)) + if err != nil { + t.Fatal(err) + } + t.Log(resp.String()) + + n := strings.Index(resp.String(), v) + if n == -1 { + t.Fatal(v + " not found in header") + } +} + +func TestOption_WithRetry(t *testing.T) { + client, err := NewClient("test", "https://goolnk.com/33BD2j", + WithCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error { + return errors.New("Redirect triggered") + })) + if err != nil { + t.Fatal(err) + } + + retryAmount := 1 + retryDelay := 800 * time.Millisecond + startTime := time.Now().UnixNano() / int64(time.Millisecond) + + _ = client.Get(nil, "", WithRetry(retryAmount, retryDelay)) + + endTime := time.Now().UnixNano() / int64(time.Millisecond) + elapsedTime := endTime - startTime + delayedTime := int64(retryAmount) * retryDelay.Milliseconds() + if elapsedTime < delayedTime { + t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime) + } +} diff --git a/client/httplib/error_code.go b/client/httplib/error_code.go index bd349a34..177419ad 100644 --- a/client/httplib/error_code.go +++ b/client/httplib/error_code.go @@ -124,3 +124,11 @@ Make sure that: 1. You pass valid structure pointer to the function; 2. The body is valid YAML document `) + +var UnmarshalResponseToObjectFailed = berror.DefineCode(5001011, moduleName, + "UnmarshalResponseToObjectFailed", ` +Beego trying to unmarshal response's body to structure but failed. +There are several cases that cause this error: +1. You pass valid structure pointer to the function; +2. The body is valid json, Yaml or XML document +`) diff --git a/client/httplib/filter/opentracing/filter.go b/client/httplib/filter/opentracing/filter.go index a46effc8..aef20e66 100644 --- a/client/httplib/filter/opentracing/filter.go +++ b/client/httplib/filter/opentracing/filter.go @@ -35,9 +35,7 @@ type FilterChainBuilder struct { } func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filter { - return func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) { - method := req.GetRequest().Method operationName := method + "#" + req.GetRequest().URL.String() diff --git a/client/httplib/filter/prometheus/filter.go b/client/httplib/filter/prometheus/filter.go index 5761eb7e..e93b2298 100644 --- a/client/httplib/filter/prometheus/filter.go +++ b/client/httplib/filter/prometheus/filter.go @@ -32,11 +32,12 @@ type FilterChainBuilder struct { RunMode string } -var summaryVec prometheus.ObserverVec -var initSummaryVec sync.Once +var ( + summaryVec prometheus.ObserverVec + initSummaryVec sync.Once +) func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filter { - initSummaryVec.Do(func() { summaryVec = prometheus.NewSummaryVec(prometheus.SummaryOpts{ Name: "beego", diff --git a/client/httplib/httpclient.go b/client/httplib/httpclient.go new file mode 100644 index 00000000..c2a61fcf --- /dev/null +++ b/client/httplib/httpclient.go @@ -0,0 +1,174 @@ +// Copyright 2020 beego +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package httplib + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" +) + +// Client provides an HTTP client supporting chain call +type Client struct { + Name string + Endpoint string + CommonOpts []BeegoHTTPRequestOption + + Setting BeegoHTTPSettings +} + +// HTTPResponseCarrier If value implement HTTPResponseCarrier. http.Response will pass to SetHTTPResponse +type HTTPResponseCarrier interface { + SetHTTPResponse(resp *http.Response) +} + +// HTTPBodyCarrier If value implement HTTPBodyCarrier. http.Response.Body will pass to SetReader +type HTTPBodyCarrier interface { + SetReader(r io.ReadCloser) +} + +// HTTPBytesCarrier If value implement HTTPBytesCarrier. +// All the byte in http.Response.Body will pass to SetBytes +type HTTPBytesCarrier interface { + SetBytes(bytes []byte) +} + +// HTTPStatusCarrier If value implement HTTPStatusCarrier. http.Response.StatusCode will pass to SetStatusCode +type HTTPStatusCarrier interface { + SetStatusCode(status int) +} + +// HttpHeaderCarrier If value implement HttpHeaderCarrier. http.Response.Header will pass to SetHeader +type HTTPHeadersCarrier interface { + SetHeader(header map[string][]string) +} + +// NewClient return a new http client +func NewClient(name string, endpoint string, opts ...ClientOption) (*Client, error) { + res := &Client{ + Name: name, + Endpoint: endpoint, + } + setting := GetDefaultSetting() + res.Setting = setting + for _, o := range opts { + o(res) + } + return res, nil +} + +func (c *Client) customReq(req *BeegoHTTPRequest, opts []BeegoHTTPRequestOption) { + req.Setting(c.Setting) + opts = append(c.CommonOpts, opts...) + for _, o := range opts { + o(req) + } +} + +// handleResponse try to parse body to meaningful value +func (c *Client) handleResponse(value interface{}, req *BeegoHTTPRequest) error { + // make sure req.resp is not nil + _, err := req.Bytes() + if err != nil { + return err + } + + err = c.handleCarrier(value, req) + if err != nil { + return err + } + + return req.ToValue(value) +} + +// handleCarrier set http data to value +func (c *Client) handleCarrier(value interface{}, req *BeegoHTTPRequest) error { + if value == nil { + return nil + } + + if carrier, ok := value.(HTTPResponseCarrier); ok { + b, err := req.Bytes() + if err != nil { + return err + } + req.resp.Body = ioutil.NopCloser(bytes.NewReader(b)) + carrier.SetHTTPResponse(req.resp) + } + if carrier, ok := value.(HTTPBodyCarrier); ok { + b, err := req.Bytes() + if err != nil { + return err + } + reader := ioutil.NopCloser(bytes.NewReader(b)) + carrier.SetReader(reader) + } + if carrier, ok := value.(HTTPBytesCarrier); ok { + b, err := req.Bytes() + if err != nil { + return err + } + carrier.SetBytes(b) + } + if carrier, ok := value.(HTTPStatusCarrier); ok { + carrier.SetStatusCode(req.resp.StatusCode) + } + if carrier, ok := value.(HTTPHeadersCarrier); ok { + carrier.SetHeader(req.resp.Header) + } + return nil +} + +// Get Send a GET request and try to give its result value +func (c *Client) Get(value interface{}, path string, opts ...BeegoHTTPRequestOption) error { + req := Get(c.Endpoint + path) + c.customReq(req, opts) + return c.handleResponse(value, req) +} + +// Post Send a POST request and try to give its result value +func (c *Client) Post(value interface{}, path string, body interface{}, opts ...BeegoHTTPRequestOption) error { + req := Post(c.Endpoint + path) + c.customReq(req, opts) + if body != nil { + req = req.Body(body) + } + return c.handleResponse(value, req) +} + +// Put Send a Put request and try to give its result value +func (c *Client) Put(value interface{}, path string, body interface{}, opts ...BeegoHTTPRequestOption) error { + req := Put(c.Endpoint + path) + c.customReq(req, opts) + if body != nil { + req = req.Body(body) + } + return c.handleResponse(value, req) +} + +// Delete Send a Delete request and try to give its result value +func (c *Client) Delete(value interface{}, path string, opts ...BeegoHTTPRequestOption) error { + req := Delete(c.Endpoint + path) + c.customReq(req, opts) + return c.handleResponse(value, req) +} + +// Head Send a Head request and try to give its result value +func (c *Client) Head(value interface{}, path string, opts ...BeegoHTTPRequestOption) error { + req := Head(c.Endpoint + path) + c.customReq(req, opts) + return c.handleResponse(value, req) +} diff --git a/client/httplib/httpclient_test.go b/client/httplib/httpclient_test.go new file mode 100644 index 00000000..6bb00258 --- /dev/null +++ b/client/httplib/httpclient_test.go @@ -0,0 +1,220 @@ +// Copyright 2020 beego +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package httplib + +import ( + "encoding/xml" + "io" + "io/ioutil" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewClient(t *testing.T) { + client, err := NewClient("test1", "http://beego.me", WithEnableCookie(true)) + assert.NoError(t, err) + assert.NotNil(t, client) + assert.Equal(t, true, client.Setting.EnableCookie) +} + +type slideShowResponse struct { + Resp *http.Response + bytes []byte + StatusCode int + Body io.ReadCloser + Header map[string][]string + + Slideshow slideshow `json:"slideshow" yaml:"slideshow"` +} + +func (r *slideShowResponse) SetHTTPResponse(resp *http.Response) { + r.Resp = resp +} + +func (r *slideShowResponse) SetBytes(bytes []byte) { + r.bytes = bytes +} + +func (r *slideShowResponse) SetReader(reader io.ReadCloser) { + r.Body = reader +} + +func (r *slideShowResponse) SetStatusCode(status int) { + r.StatusCode = status +} + +func (r *slideShowResponse) SetHeader(header map[string][]string) { + r.Header = header +} + +func (r *slideShowResponse) String() string { + return string(r.bytes) +} + +type slideshow struct { + XMLName xml.Name `xml:"slideshow"` + + Title string `json:"title" yaml:"title" xml:"title,attr"` + Author string `json:"author" yaml:"author" xml:"author,attr"` + Date string `json:"date" yaml:"date" xml:"date,attr"` + Slides []slide `json:"slides" yaml:"slides" xml:"slide"` +} + +type slide struct { + XMLName xml.Name `xml:"slide"` + + Title string `json:"title" yaml:"title" xml:"title"` +} + +func TestClient_handleCarrier(t *testing.T) { + v := "beego" + client, err := NewClient("test", "http://httpbin.org/", + WithUserAgent(v)) + if err != nil { + t.Fatal(err) + } + + s := &slideShowResponse{} + err = client.Get(s, "/json") + if err != nil { + t.Fatal(err) + } + defer s.Body.Close() + + assert.NotNil(t, s.Resp) + assert.NotNil(t, s.Body) + assert.Equal(t, "429", s.Header["Content-Length"][0]) + assert.Equal(t, 200, s.StatusCode) + + b, err := ioutil.ReadAll(s.Body) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, 429, len(b)) + assert.Equal(t, s.String(), string(b)) +} + +func TestClient_Get(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org/") + if err != nil { + t.Fatal(err) + } + + // json + var s *slideShowResponse + err = client.Get(&s, "/json") + if err != nil { + t.Fatal(err) + } + assert.Equal(t, "Sample Slide Show", s.Slideshow.Title) + assert.Equal(t, 2, len(s.Slideshow.Slides)) + assert.Equal(t, "Overview", s.Slideshow.Slides[1].Title) + + // xml + var ssp *slideshow + err = client.Get(&ssp, "/base64/PD94bWwgPz48c2xpZGVzaG93CnRpdGxlPSJTYW1wbGUgU2xpZGUgU2hvdyIKZGF0ZT0iRGF0ZSBvZiBwdWJsaWNhdGlvbiIKYXV0aG9yPSJZb3VycyBUcnVseSI+PHNsaWRlIHR5cGU9ImFsbCI+PHRpdGxlPldha2UgdXAgdG8gV29uZGVyV2lkZ2V0cyE8L3RpdGxlPjwvc2xpZGU+PHNsaWRlIHR5cGU9ImFsbCI+PHRpdGxlPk92ZXJ2aWV3PC90aXRsZT48aXRlbT5XaHkgPGVtPldvbmRlcldpZGdldHM8L2VtPiBhcmUgZ3JlYXQ8L2l0ZW0+PGl0ZW0vPjxpdGVtPldobyA8ZW0+YnV5czwvZW0+IFdvbmRlcldpZGdldHM8L2l0ZW0+PC9zbGlkZT48L3NsaWRlc2hvdz4=") + if err != nil { + t.Fatal(err) + } + assert.Equal(t, "Sample Slide Show", ssp.Title) + assert.Equal(t, 2, len(ssp.Slides)) + assert.Equal(t, "Overview", ssp.Slides[1].Title) + + // yaml + s = nil + err = client.Get(&s, "/base64/c2xpZGVzaG93OgogIGF1dGhvcjogWW91cnMgVHJ1bHkKICBkYXRlOiBkYXRlIG9mIHB1YmxpY2F0aW9uCiAgc2xpZGVzOgogIC0gdGl0bGU6IFdha2UgdXAgdG8gV29uZGVyV2lkZ2V0cyEKICAgIHR5cGU6IGFsbAogIC0gaXRlbXM6CiAgICAtIFdoeSA8ZW0+V29uZGVyV2lkZ2V0czwvZW0+IGFyZSBncmVhdAogICAgLSBXaG8gPGVtPmJ1eXM8L2VtPiBXb25kZXJXaWRnZXRzCiAgICB0aXRsZTogT3ZlcnZpZXcKICAgIHR5cGU6IGFsbAogIHRpdGxlOiBTYW1wbGUgU2xpZGUgU2hvdw==") + if err != nil { + t.Fatal(err) + } + assert.Equal(t, "Sample Slide Show", s.Slideshow.Title) + assert.Equal(t, 2, len(s.Slideshow.Slides)) + assert.Equal(t, "Overview", s.Slideshow.Slides[1].Title) +} + +func TestClient_Post(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org") + if err != nil { + t.Fatal(err) + } + + resp := &slideShowResponse{} + err = client.Get(resp, "/json") + if err != nil { + t.Fatal(err) + } + + jsonStr := resp.String() + err = client.Post(resp, "/post", jsonStr) + if err != nil { + t.Fatal(err) + } + assert.NotNil(t, resp) + assert.Equal(t, http.MethodPost, resp.Resp.Request.Method) +} + +func TestClient_Put(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org") + if err != nil { + t.Fatal(err) + } + + resp := &slideShowResponse{} + err = client.Get(resp, "/json") + if err != nil { + t.Fatal(err) + } + + jsonStr := resp.String() + err = client.Put(resp, "/put", jsonStr) + if err != nil { + t.Fatal(err) + } + assert.NotNil(t, resp) + assert.Equal(t, http.MethodPut, resp.Resp.Request.Method) +} + +func TestClient_Delete(t *testing.T) { + client, err := NewClient("test", "http://httpbin.org") + if err != nil { + t.Fatal(err) + } + + resp := &slideShowResponse{} + err = client.Delete(resp, "/delete") + if err != nil { + t.Fatal(err) + } + defer resp.Resp.Body.Close() + assert.NotNil(t, resp) + assert.Equal(t, http.MethodDelete, resp.Resp.Request.Method) +} + +func TestClient_Head(t *testing.T) { + client, err := NewClient("test", "http://beego.me") + if err != nil { + t.Fatal(err) + } + + resp := &slideShowResponse{} + err = client.Head(resp, "") + if err != nil { + t.Fatal(err) + } + defer resp.Resp.Body.Close() + assert.NotNil(t, resp) + assert.Equal(t, http.MethodHead, resp.Resp.Request.Method) +} diff --git a/client/httplib/httplib.go b/client/httplib/httplib.go index 434d74c1..ca643b33 100644 --- a/client/httplib/httplib.go +++ b/client/httplib/httplib.go @@ -124,7 +124,6 @@ type BeegoHTTPRequest struct { setting BeegoHTTPSettings resp *http.Response body []byte - dump []byte } // GetRequest returns the request object @@ -199,7 +198,7 @@ func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest { // SetProtocolVersion sets the protocol version for incoming requests. // Client requests always use HTTP/1.1 func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest { - if len(vers) == 0 { + if vers == "" { vers = "HTTP/1.1" } @@ -401,7 +400,6 @@ func (b *BeegoHTTPRequest) handleFileToBody(bodyWriter *multipart.Writer, formna "could not create form file, formname: %s, filename: %s", formname, filename)) } fh, err := os.Open(filename) - if err != nil { logs.Error(errFmt, berror.Wrapf(err, ReadFileFailed, "could not open this file %s", filename)) } @@ -511,18 +509,16 @@ func (b *BeegoHTTPRequest) buildTrans() http.RoundTripper { DialContext: TimeoutDialerCtx(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout), MaxIdleConnsPerHost: 100, } - } else { + } else if t, ok := trans.(*http.Transport); ok { // if b.transport is *http.Transport then set the settings. - if t, ok := trans.(*http.Transport); ok { - if t.TLSClientConfig == nil { - t.TLSClientConfig = b.setting.TLSClientConfig - } - if t.Proxy == nil { - t.Proxy = b.setting.Proxy - } - if t.DialContext == nil { - t.DialContext = TimeoutDialerCtx(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout) - } + if t.TLSClientConfig == nil { + t.TLSClientConfig = b.setting.TLSClientConfig + } + if t.Proxy == nil { + t.Proxy = b.setting.Proxy + } + if t.DialContext == nil { + t.DialContext = TimeoutDialerCtx(b.setting.ConnectTimeout, b.setting.ReadWriteTimeout) } } return trans @@ -656,6 +652,40 @@ func (b *BeegoHTTPRequest) ToYAML(v interface{}) error { UnmarshalYAMLResponseToObjectFailed, "unmarshal yaml body to object failed.") } +// ToValue attempts to resolve the response body to value using an existing method. +// Calls Response inner. +// If response header contain Content-Type, func will call ToJSON\ToXML\ToYAML. +// Else it will try to parse body as json\yaml\xml, If all attempts fail, an error will be returned +func (b *BeegoHTTPRequest) ToValue(value interface{}) error { + if value == nil { + return nil + } + + contentType := strings.Split(b.resp.Header.Get(contentTypeKey), ";")[0] + // try to parse it as content type + switch contentType { + case "application/json": + return b.ToJSON(value) + case "text/xml", "application/xml": + return b.ToXML(value) + case "text/yaml", "application/x-yaml", "application/x+yaml": + return b.ToYAML(value) + } + + // try to parse it anyway + if err := b.ToJSON(value); err == nil { + return nil + } + if err := b.ToYAML(value); err == nil { + return nil + } + if err := b.ToXML(value); err == nil { + return nil + } + + return berror.Error(UnmarshalResponseToObjectFailed, "unmarshal body to object failed.") +} + // Response executes request client gets response manually. func (b *BeegoHTTPRequest) Response() (*http.Response, error) { return b.getResponse() diff --git a/client/httplib/httplib_test.go b/client/httplib/httplib_test.go index be702fb6..4be9fd43 100644 --- a/client/httplib/httplib_test.go +++ b/client/httplib/httplib_test.go @@ -63,7 +63,6 @@ func TestDoRequest(t *testing.T) { if elapsedTime < delayedTime { t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime) } - } func TestGet(t *testing.T) { @@ -248,7 +247,6 @@ func TestToJson(t *testing.T) { t.Fatal("response is not valid ip") } } - } func TestToFile(t *testing.T) { @@ -433,3 +431,7 @@ func TestBeegoHTTPRequestXMLBody(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, req.req.GetBody) } + +// TODO +func TestBeegoHTTPRequest_ResponseForValue(t *testing.T) { +} diff --git a/client/httplib/mock/mock_condition.go b/client/httplib/mock/mock_condition.go index 53d3d703..912699ff 100644 --- a/client/httplib/mock/mock_condition.go +++ b/client/httplib/mock/mock_condition.go @@ -57,7 +57,7 @@ func NewSimpleCondition(path string, opts ...simpleConditionOption) *SimpleCondi } func (sc *SimpleCondition) Match(ctx context.Context, req *httplib.BeegoHTTPRequest) bool { - res := true + var res bool if len(sc.path) > 0 { res = sc.matchPath(ctx, req) } else if len(sc.pathReg) > 0 { diff --git a/client/httplib/mock/mock_condition_test.go b/client/httplib/mock/mock_condition_test.go index 4fc6d377..9ebdab70 100644 --- a/client/httplib/mock/mock_condition_test.go +++ b/client/httplib/mock/mock_condition_test.go @@ -23,10 +23,6 @@ import ( "github.com/beego/beego/v2/client/httplib" ) -func init() { - -} - func TestSimpleCondition_MatchPath(t *testing.T) { sc := NewSimpleCondition("/abc/s") res := sc.Match(context.Background(), httplib.Get("http://localhost:8080/abc/s")) @@ -72,7 +68,6 @@ func TestSimpleCondition_MatchHeader(t *testing.T) { } func TestSimpleCondition_MatchBodyField(t *testing.T) { - sc := NewSimpleCondition("/abc/s") req := httplib.Post("http://localhost:8080/abc/s") diff --git a/client/httplib/mock/mock_test.go b/client/httplib/mock/mock_test.go index 2972cf8f..754841c3 100644 --- a/client/httplib/mock/mock_test.go +++ b/client/httplib/mock/mock_test.go @@ -26,7 +26,6 @@ import ( ) func TestStartMock(t *testing.T) { - // httplib.defaultSetting.FilterChains = []httplib.FilterChain{mockFilter.FilterChain} stub := StartMock() @@ -41,7 +40,6 @@ func TestStartMock(t *testing.T) { assert.Equal(t, expectedErr, err) assert.Equal(t, expectedResp, resp) - } // TestStartMock_Isolation Test StartMock that diff --git a/client/httplib/setting.go b/client/httplib/setting.go index df8eff4b..fa034413 100644 --- a/client/httplib/setting.go +++ b/client/httplib/setting.go @@ -55,6 +55,11 @@ func SetDefaultSetting(setting BeegoHTTPSettings) { defaultSetting = setting } +// GetDefaultSetting return current default setting +func GetDefaultSetting() BeegoHTTPSettings { + return defaultSetting +} + var defaultSetting = BeegoHTTPSettings{ UserAgent: "beegoServer", ConnectTimeout: 60 * time.Second, @@ -63,8 +68,10 @@ var defaultSetting = BeegoHTTPSettings{ FilterChains: make([]FilterChain, 0, 4), } -var defaultCookieJar http.CookieJar -var settingMutex sync.Mutex +var ( + defaultCookieJar http.CookieJar + settingMutex sync.Mutex +) // AddDefaultFilter add a new filter into defaultSetting // Be careful about using this method if you invoke SetDefaultSetting somewhere diff --git a/client/httplib/testing/client.go b/client/httplib/testing/client.go index 517e0722..43e2e968 100644 --- a/client/httplib/testing/client.go +++ b/client/httplib/testing/client.go @@ -18,8 +18,10 @@ import ( "github.com/beego/beego/v2/client/httplib" ) -var port = "" -var baseURL = "http://localhost:" +var ( + port = "" + baseURL = "http://localhost:" +) // TestHTTPRequest beego test request client type TestHTTPRequest struct { diff --git a/client/orm/clauses/order_clause/order_test.go b/client/orm/clauses/order_clause/order_test.go index 172e7492..757abb3a 100644 --- a/client/orm/clauses/order_clause/order_test.go +++ b/client/orm/clauses/order_clause/order_test.go @@ -5,9 +5,7 @@ import ( ) func TestClause(t *testing.T) { - var ( - column = `a` - ) + column := `a` o := Clause( Column(column), @@ -108,7 +106,6 @@ func TestParseOrder(t *testing.T) { if orders[2].GetColumn() != `user.status` { t.Error() } - } func TestOrder_GetColumn(t *testing.T) { @@ -120,25 +117,21 @@ func TestOrder_GetColumn(t *testing.T) { } } -func TestOrder_GetSort(t *testing.T) { - o := Clause( - SortDescending(), - ) - if o.GetSort() != Descending { - t.Error() - } -} +func TestSortString(t *testing.T) { + template := "got: %s, want: %s" -func TestOrder_IsRaw(t *testing.T) { - o1 := Clause() - if o1.IsRaw() { - t.Error() + o1 := Clause(sort(Sort(1))) + if o1.SortString() != "ASC" { + t.Errorf(template, o1.SortString(), "ASC") } - o2 := Clause( - Raw(), - ) - if !o2.IsRaw() { - t.Error() + o2 := Clause(sort(Sort(2))) + if o2.SortString() != "DESC" { + t.Errorf(template, o2.SortString(), "DESC") + } + + o3 := Clause(sort(Sort(3))) + if o3.SortString() != `` { + t.Errorf(template, o3.SortString(), ``) } } diff --git a/client/orm/cmd.go b/client/orm/cmd.go index b377a5f2..432785d6 100644 --- a/client/orm/cmd.go +++ b/client/orm/cmd.go @@ -27,9 +27,7 @@ type commander interface { Run() error } -var ( - commands = make(map[string]commander) -) +var commands = make(map[string]commander) // print help. func printHelp(errs ...string) { diff --git a/client/orm/cmd_utils.go b/client/orm/cmd_utils.go index 8d6c0c33..7b795b22 100644 --- a/client/orm/cmd_utils.go +++ b/client/orm/cmd_utils.go @@ -126,9 +126,7 @@ func getColumnAddQuery(al *alias, fi *fieldInfo) string { // Get string value for the attribute "DEFAULT" for the CREATE, ALTER commands func getColumnDefault(fi *fieldInfo) string { - var ( - v, t, d string - ) + var v, t, d string // Skip default attribute if field is in relations if fi.rel || fi.reverse { diff --git a/client/orm/db.go b/client/orm/db.go index a49d6df7..48987ab8 100644 --- a/client/orm/db.go +++ b/client/orm/db.go @@ -32,41 +32,37 @@ const ( formatDateTime = "2006-01-02 15:04:05" ) -var ( - // ErrMissPK missing pk error - ErrMissPK = errors.New("missed pk value") -) +// ErrMissPK missing pk error +var ErrMissPK = errors.New("missed pk value") -var ( - operators = map[string]bool{ - "exact": true, - "iexact": true, - "strictexact": true, - "contains": true, - "icontains": true, - // "regex": true, - // "iregex": true, - "gt": true, - "gte": true, - "lt": true, - "lte": true, - "eq": true, - "nq": true, - "ne": true, - "startswith": true, - "endswith": true, - "istartswith": true, - "iendswith": true, - "in": true, - "between": true, - // "year": true, - // "month": true, - // "day": true, - // "week_day": true, - "isnull": true, - // "search": true, - } -) +var operators = map[string]bool{ + "exact": true, + "iexact": true, + "strictexact": true, + "contains": true, + "icontains": true, + // "regex": true, + // "iregex": true, + "gt": true, + "gte": true, + "lt": true, + "lte": true, + "eq": true, + "nq": true, + "ne": true, + "startswith": true, + "endswith": true, + "istartswith": true, + "iendswith": true, + "in": true, + "between": true, + // "year": true, + // "month": true, + // "day": true, + // "week_day": true, + "isnull": true, + // "search": true, +} // an instance of dbBaser interface/ type dbBase struct { @@ -537,7 +533,6 @@ func (d *dbBase) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *modelInfo, names := make([]string, 0, len(mi.fields.dbcols)-1) Q := d.ins.TableQuote() values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, a.TZ) - if err != nil { return 0, err } @@ -934,7 +929,6 @@ func (d *dbBase) DeleteBatch(ctx context.Context, q dbQuerier, qs *querySet, mi // read related records. func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location, cols []string) (int64, error) { - val := reflect.ValueOf(container) ind := reflect.Indirect(val) @@ -1435,12 +1429,10 @@ end: } return value, nil - } // set one value to struct column field. func (d *dbBase) setFieldValue(fi *fieldInfo, value interface{}, field reflect.Value) (interface{}, error) { - fieldType := fi.fieldType isNative := !fi.isFielder @@ -1632,7 +1624,6 @@ setValue: // query sql, read values , save to *[]ParamList. func (d *dbBase) ReadValues(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) { - var ( maps []Params lists []ParamsList diff --git a/client/orm/db_alias.go b/client/orm/db_alias.go index 72c447b3..c3b867c3 100644 --- a/client/orm/db_alias.go +++ b/client/orm/db_alias.go @@ -112,8 +112,10 @@ type DB struct { stmtDecoratorsLimit int } -var _ dbQuerier = new(DB) -var _ txer = new(DB) +var ( + _ dbQuerier = new(DB) + _ txer = new(DB) +) func (d *DB) Begin() (*sql.Tx, error) { return d.DB.Begin() @@ -221,8 +223,10 @@ type TxDB struct { tx *sql.Tx } -var _ dbQuerier = new(TxDB) -var _ txEnder = new(TxDB) +var ( + _ dbQuerier = new(TxDB) + _ txEnder = new(TxDB) +) func (t *TxDB) Commit() error { return t.tx.Commit() @@ -240,8 +244,10 @@ func (t *TxDB) RollbackUnlessCommit() error { return nil } -var _ dbQuerier = new(TxDB) -var _ txEnder = new(TxDB) +var ( + _ dbQuerier = new(TxDB) + _ txEnder = new(TxDB) +) func (t *TxDB) Prepare(query string) (*sql.Stmt, error) { return t.PrepareContext(context.Background(), query) @@ -365,7 +371,6 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) } func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) { - al := &alias{} al.DB = &DB{ RWMutex: new(sync.RWMutex), diff --git a/client/orm/db_mysql.go b/client/orm/db_mysql.go index c89b1e52..5b3333e0 100644 --- a/client/orm/db_mysql.go +++ b/client/orm/db_mysql.go @@ -124,7 +124,6 @@ func (d *dbBaseMysql) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *model names := make([]string, 0, len(mi.fields.dbcols)-1) Q := d.ins.TableQuote() values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, a.TZ) - if err != nil { return 0, err } diff --git a/client/orm/db_tables.go b/client/orm/db_tables.go index f81651ff..a0b355ca 100644 --- a/client/orm/db_tables.go +++ b/client/orm/db_tables.go @@ -106,7 +106,6 @@ func (t *dbTables) loopDepth(depth int, prefix string, fi *fieldInfo, related [] // parse related fields. func (t *dbTables) parseRelated(rels []string, depth int) { - relsNum := len(rels) related := make([]string, relsNum) copy(related, rels) diff --git a/client/orm/db_utils.go b/client/orm/db_utils.go index 7ae10ca5..dbe49ae5 100644 --- a/client/orm/db_utils.go +++ b/client/orm/db_utils.go @@ -55,7 +55,6 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac // get fields description as flatted string. func getFlatParams(fi *fieldInfo, args []interface{}, tz *time.Location) (params []interface{}) { - outFor: for _, arg := range args { val := reflect.ValueOf(arg) diff --git a/client/orm/do_nothing_orm.go b/client/orm/do_nothing_orm.go index 59ffe877..d9e574a5 100644 --- a/client/orm/do_nothing_orm.go +++ b/client/orm/do_nothing_orm.go @@ -27,8 +27,7 @@ import ( var _ Ormer = new(DoNothingOrm) -type DoNothingOrm struct { -} +type DoNothingOrm struct{} func (d *DoNothingOrm) Read(md interface{}, cols ...string) error { return nil diff --git a/client/orm/filter/bean/default_value_filter_test.go b/client/orm/filter/bean/default_value_filter_test.go index 871d5539..580c7036 100644 --- a/client/orm/filter/bean/default_value_filter_test.go +++ b/client/orm/filter/bean/default_value_filter_test.go @@ -57,7 +57,6 @@ func TestDefaultValueFilterChainBuilder_FilterChain(t *testing.T) { _, _ = o.InsertMulti(3, []*DefaultValueTestEntity{entity}) assert.Equal(t, 12, entity.Age) assert.Equal(t, 13, entity.AgeInOldStyle) - } type defaultValueTestOrm struct { diff --git a/client/orm/filter/prometheus/filter.go b/client/orm/filter/prometheus/filter.go index b2c83dcf..f525cebc 100644 --- a/client/orm/filter/prometheus/filter.go +++ b/client/orm/filter/prometheus/filter.go @@ -39,11 +39,12 @@ type FilterChainBuilder struct { RunMode string } -var summaryVec prometheus.ObserverVec -var initSummaryVec sync.Once +var ( + summaryVec prometheus.ObserverVec + initSummaryVec sync.Once +) func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter { - initSummaryVec.Do(func() { summaryVec = prometheus.NewSummaryVec(prometheus.SummaryOpts{ Name: "beego", diff --git a/client/orm/filter/prometheus/filter_test.go b/client/orm/filter/prometheus/filter_test.go index a25515a7..060088f4 100644 --- a/client/orm/filter/prometheus/filter_test.go +++ b/client/orm/filter/prometheus/filter_test.go @@ -58,5 +58,4 @@ func TestFilterChainBuilder_FilterChain1(t *testing.T) { inv.Method = "Update" builder.report(ctx, inv, time.Second) - } diff --git a/client/orm/filter_orm_decorator.go b/client/orm/filter_orm_decorator.go index 6a9ecc53..a4a215f1 100644 --- a/client/orm/filter_orm_decorator.go +++ b/client/orm/filter_orm_decorator.go @@ -28,8 +28,10 @@ const ( TxNameKey = "TxName" ) -var _ Ormer = new(filterOrmDecorator) -var _ TxOrmer = new(filterOrmDecorator) +var ( + _ Ormer = new(filterOrmDecorator) + _ TxOrmer = new(filterOrmDecorator) +) type filterOrmDecorator struct { ormer @@ -120,7 +122,6 @@ func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...s } func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) { - mi, _ := modelCache.getByMd(md) inv := &Invocation{ Method: "ReadOrCreateWithCtx", @@ -143,7 +144,6 @@ func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...ut } func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) { - mi, _ := modelCache.getByMd(md) inv := &Invocation{ Method: "LoadRelatedWithCtx", @@ -162,7 +162,6 @@ func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interfac } func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer { - mi, _ := modelCache.getByMd(md) inv := &Invocation{ Method: "QueryM2M", diff --git a/client/orm/filter_orm_decorator_test.go b/client/orm/filter_orm_decorator_test.go index a4b3f488..d1776cc8 100644 --- a/client/orm/filter_orm_decorator_test.go +++ b/client/orm/filter_orm_decorator_test.go @@ -27,7 +27,6 @@ import ( ) func TestFilterOrmDecorator_Read(t *testing.T) { - register() o := &filterMockOrm{} diff --git a/client/orm/migration/ddl.go b/client/orm/migration/ddl.go index ec6dc2e7..ab452b49 100644 --- a/client/orm/migration/ddl.go +++ b/client/orm/migration/ddl.go @@ -116,7 +116,6 @@ func (m *Migration) UniCol(uni, name string) *Column { // ForeignCol creates a new foreign column and returns the instance of column func (m *Migration) ForeignCol(colname, foreigncol, foreigntable string) (foreign *Foreign) { - foreign = &Foreign{ForeignColumn: foreigncol, ForeignTable: foreigntable} foreign.Name = colname m.AddForeign(foreign) @@ -153,7 +152,6 @@ func (c *Column) SetAuto(inc bool) *Column { func (c *Column) SetNullable(null bool) *Column { if null { c.Null = "" - } else { c.Null = "NOT NULL" } @@ -184,7 +182,6 @@ func (c *Column) SetDataType(dataType string) *Column { func (c *RenameColumn) SetOldNullable(null bool) *RenameColumn { if null { c.OldNull = "" - } else { c.OldNull = "NOT NULL" } @@ -219,7 +216,6 @@ func (c *Column) SetPrimary(m *Migration) *Column { // AddColumnsToUnique adds the columns to Unique Struct func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique { - unique.Columns = append(unique.Columns, columns...) return unique @@ -227,7 +223,6 @@ func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique { // AddColumns adds columns to m struct func (m *Migration) AddColumns(columns ...*Column) *Migration { - m.Columns = append(m.Columns, columns...) return m diff --git a/client/orm/migration/migration.go b/client/orm/migration/migration.go index 86d6f590..dda7737d 100644 --- a/client/orm/migration/migration.go +++ b/client/orm/migration/migration.go @@ -72,9 +72,7 @@ type Migration struct { RemoveForeigns []*Foreign } -var ( - migrationMap map[string]Migrationer -) +var migrationMap map[string]Migrationer func init() { migrationMap = make(map[string]Migrationer) @@ -82,7 +80,6 @@ func init() { // Up implement in the Inheritance struct for upgrade func (m *Migration) Up() { - switch m.ModifyType { case "reverse": m.ModifyType = "alter" @@ -94,7 +91,6 @@ func (m *Migration) Up() { // Down implement in the Inheritance struct for down func (m *Migration) Down() { - switch m.ModifyType { case "alter": m.ModifyType = "reverse" @@ -311,6 +307,7 @@ func isRollBack(name string) bool { } return false } + func getAllMigrations() (map[string]string, error) { o := orm.NewOrm() var maps []orm.Params diff --git a/client/orm/mock/mock.go b/client/orm/mock/mock.go index 072488b2..7aca914c 100644 --- a/client/orm/mock/mock.go +++ b/client/orm/mock/mock.go @@ -55,7 +55,6 @@ func (o *OrmStub) Clear() { func (o *OrmStub) FilterChain(next orm.Filter) orm.Filter { return func(ctx context.Context, inv *orm.Invocation) []interface{} { - ms := mockFromCtx(ctx) ms = append(ms, o.ms...) diff --git a/client/orm/mock/mock_orm_test.go b/client/orm/mock/mock_orm_test.go index b6dc82f7..29d9ea01 100644 --- a/client/orm/mock/mock_orm_test.go +++ b/client/orm/mock/mock_orm_test.go @@ -247,7 +247,7 @@ func TestTransactionRollbackUnlessCommit(t *testing.T) { mock := errors.New(mockErrorMsg) s.Mock(MockRollbackUnlessCommit(mock)) - //u := &User{} + // u := &User{} o := orm.NewOrm() txOrm, _ := o.Begin() err := txOrm.RollbackUnlessCommit() diff --git a/client/orm/mock/mock_queryM2Mer.go b/client/orm/mock/mock_queryM2Mer.go index a58f10ae..732e27b6 100644 --- a/client/orm/mock/mock_queryM2Mer.go +++ b/client/orm/mock/mock_queryM2Mer.go @@ -22,8 +22,7 @@ import ( // DoNothingQueryM2Mer do nothing // use it to build mock orm.QueryM2Mer -type DoNothingQueryM2Mer struct { -} +type DoNothingQueryM2Mer struct{} func (d *DoNothingQueryM2Mer) AddWithCtx(ctx context.Context, i ...interface{}) (int64, error) { return 0, nil diff --git a/client/orm/mock/mock_querySetter.go b/client/orm/mock/mock_querySetter.go index 074b6211..5bbf9888 100644 --- a/client/orm/mock/mock_querySetter.go +++ b/client/orm/mock/mock_querySetter.go @@ -23,8 +23,7 @@ import ( // DoNothingQuerySetter do nothing // usually you use this to build your mock QuerySetter -type DoNothingQuerySetter struct { -} +type DoNothingQuerySetter struct{} func (d *DoNothingQuerySetter) OrderClauses(orders ...*order_clause.Order) orm.QuerySeter { return d diff --git a/client/orm/mock/mock_rawSetter.go b/client/orm/mock/mock_rawSetter.go index 00311e80..f4768cc8 100644 --- a/client/orm/mock/mock_rawSetter.go +++ b/client/orm/mock/mock_rawSetter.go @@ -20,8 +20,7 @@ import ( "github.com/beego/beego/v2/client/orm" ) -type DoNothingRawSetter struct { -} +type DoNothingRawSetter struct{} func (d *DoNothingRawSetter) Exec() (sql.Result, error) { return nil, nil diff --git a/client/orm/models.go b/client/orm/models.go index 31cdc4a1..c78bcf69 100644 --- a/client/orm/models.go +++ b/client/orm/models.go @@ -32,9 +32,7 @@ const ( defaultStructTagDelim = ";" ) -var ( - modelCache = NewModelCacheHandler() -) +var modelCache = NewModelCacheHandler() // model info collection type _modelCache struct { @@ -332,7 +330,6 @@ end: // register register models to model cache func (mc *_modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, models ...interface{}) (err error) { - for _, model := range models { val := reflect.ValueOf(model) typ := reflect.Indirect(val).Type() diff --git a/client/orm/models_info_f.go b/client/orm/models_info_f.go index 6d1263e2..6a9e7a99 100644 --- a/client/orm/models_info_f.go +++ b/client/orm/models_info_f.go @@ -387,7 +387,6 @@ checkType: fi.timePrecision = &v } } - } if attrs["auto_now"] { diff --git a/client/orm/models_test.go b/client/orm/models_test.go index 54712f48..421ff3de 100644 --- a/client/orm/models_test.go +++ b/client/orm/models_test.go @@ -193,22 +193,24 @@ type DataNull struct { DateTimePtr *time.Time `orm:"null"` } -type String string -type Boolean bool -type Byte byte -type Rune rune -type Int int -type Int8 int8 -type Int16 int16 -type Int32 int32 -type Int64 int64 -type Uint uint -type Uint8 uint8 -type Uint16 uint16 -type Uint32 uint32 -type Uint64 uint64 -type Float32 float64 -type Float64 float64 +type ( + String string + Boolean bool + Byte byte + Rune rune + Int int + Int8 int8 + Int16 int16 + Int32 int32 + Int64 int64 + Uint uint + Uint8 uint8 + Uint16 uint16 + Uint32 uint32 + Uint64 uint64 + Float32 float64 + Float64 float64 +) type DataCustom struct { ID int `orm:"column(id)"` @@ -486,8 +488,7 @@ var ( dDbBaser dbBaser ) -var ( - helpinfo = `need driver and source! +var helpinfo = `need driver and source! Default DB Drivers. @@ -530,7 +531,6 @@ var ( go test -v github.com/beego/beego/v2/pgk/orm ` -) func init() { // Debug, _ = StrTo(DBARGS.Debug).Bool() @@ -542,7 +542,6 @@ func init() { } err := RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, MaxIdleConnections(20)) - if err != nil { panic(fmt.Sprintf("can not register database: %v", err)) } @@ -551,5 +550,4 @@ func init() { if alias.Driver == DRMySQL { alias.Engine = "INNODB" } - } diff --git a/client/orm/orm.go b/client/orm/orm.go index e168e9ec..003937d9 100644 --- a/client/orm/orm.go +++ b/client/orm/orm.go @@ -101,9 +101,11 @@ type ormBase struct { db dbQuerier } -var _ DQL = new(ormBase) -var _ DML = new(ormBase) -var _ DriverGetter = new(ormBase) +var ( + _ DQL = new(ormBase) + _ DML = new(ormBase) + _ DriverGetter = new(ormBase) +) // get model info and model reflect value func (o *ormBase) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) { @@ -133,6 +135,7 @@ func (o *ormBase) getFieldInfo(mi *modelInfo, name string) *fieldInfo { func (o *ormBase) Read(md interface{}, cols ...string) error { return o.ReadWithCtx(context.Background(), md, cols...) } + func (o *ormBase) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error { mi, ind := o.getMiInd(md, true) return o.alias.DbBaser.Read(ctx, o.db, mi, ind, o.alias.TZ, cols, false) @@ -142,6 +145,7 @@ func (o *ormBase) ReadWithCtx(ctx context.Context, md interface{}, cols ...strin func (o *ormBase) ReadForUpdate(md interface{}, cols ...string) error { return o.ReadForUpdateWithCtx(context.Background(), md, cols...) } + func (o *ormBase) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error { mi, ind := o.getMiInd(md, true) return o.alias.DbBaser.Read(ctx, o.db, mi, ind, o.alias.TZ, cols, true) @@ -151,6 +155,7 @@ func (o *ormBase) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols func (o *ormBase) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) { return o.ReadOrCreateWithCtx(context.Background(), md, col1, cols...) } + func (o *ormBase) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) { cols = append([]string{col1}, cols...) mi, ind := o.getMiInd(md, true) @@ -177,6 +182,7 @@ func (o *ormBase) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 func (o *ormBase) Insert(md interface{}) (int64, error) { return o.InsertWithCtx(context.Background(), md) } + func (o *ormBase) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) { mi, ind := o.getMiInd(md, true) id, err := o.alias.DbBaser.Insert(ctx, o.db, mi, ind, o.alias.TZ) @@ -204,6 +210,7 @@ func (o *ormBase) setPk(mi *modelInfo, ind reflect.Value, id int64) { func (o *ormBase) InsertMulti(bulk int, mds interface{}) (int64, error) { return o.InsertMultiWithCtx(context.Background(), bulk, mds) } + func (o *ormBase) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) { var cnt int64 @@ -242,6 +249,7 @@ func (o *ormBase) InsertMultiWithCtx(ctx context.Context, bulk int, mds interfac func (o *ormBase) InsertOrUpdate(md interface{}, colConflictAndArgs ...string) (int64, error) { return o.InsertOrUpdateWithCtx(context.Background(), md, colConflictAndArgs...) } + func (o *ormBase) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) { mi, ind := o.getMiInd(md, true) id, err := o.alias.DbBaser.InsertOrUpdate(ctx, o.db, mi, ind, o.alias, colConflitAndArgs...) @@ -259,6 +267,7 @@ func (o *ormBase) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, col func (o *ormBase) Update(md interface{}, cols ...string) (int64, error) { return o.UpdateWithCtx(context.Background(), md, cols...) } + func (o *ormBase) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { mi, ind := o.getMiInd(md, true) return o.alias.DbBaser.Update(ctx, o.db, mi, ind, o.alias.TZ, cols) @@ -269,6 +278,7 @@ func (o *ormBase) UpdateWithCtx(ctx context.Context, md interface{}, cols ...str func (o *ormBase) Delete(md interface{}, cols ...string) (int64, error) { return o.DeleteWithCtx(context.Background(), md, cols...) } + func (o *ormBase) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { mi, ind := o.getMiInd(md, true) num, err := o.alias.DbBaser.Delete(ctx, o.db, mi, ind, o.alias.TZ, cols) @@ -313,6 +323,7 @@ func (o *ormBase) QueryM2MWithCtx(_ context.Context, md interface{}, name string func (o *ormBase) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) { return o.LoadRelatedWithCtx(context.Background(), md, name, args...) } + func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) { _, fi, ind, qs := o.queryRelated(md, name) @@ -482,6 +493,7 @@ func (o *ormBase) QueryTableWithCtx(_ context.Context, ptrStructOrTableName inte func (o *ormBase) Raw(query string, args ...interface{}) RawSeter { return o.RawWithCtx(context.Background(), query, args...) } + func (o *ormBase) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter { return newRawSet(o, query, args) } @@ -571,7 +583,7 @@ func doTxTemplate(o TxBeginner, ctx context.Context, opts *sql.TxOptions, } } }() - var taskTxOrm = _txOrm + taskTxOrm := _txOrm err = task(ctx, taskTxOrm) panicked = false return err diff --git a/client/orm/orm_conds.go b/client/orm/orm_conds.go index eeb5538a..7d6eabe2 100644 --- a/client/orm/orm_conds.go +++ b/client/orm/orm_conds.go @@ -78,7 +78,6 @@ func (c Condition) AndNot(expr string, args ...interface{}) *Condition { // AndCond combine a condition to current condition func (c *Condition) AndCond(cond *Condition) *Condition { - if c == cond { panic(fmt.Errorf(" cannot use self as sub cond")) } diff --git a/client/orm/orm_log.go b/client/orm/orm_log.go index da3ef732..e6f8bc83 100644 --- a/client/orm/orm_log.go +++ b/client/orm/orm_log.go @@ -40,7 +40,7 @@ func NewLog(out io.Writer) *Log { } func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) { - var logMap = make(map[string]interface{}) + logMap := make(map[string]interface{}) sub := time.Since(t) / 1e5 elsp := float64(int(sub)) / 10.0 logMap["cost_time"] = elsp @@ -94,6 +94,7 @@ func (d *stmtQueryLog) ExecContext(ctx context.Context, args ...interface{}) (sq debugLogQueies(d.alias, "st.Exec", d.query, a, err, args...) return res, err } + func (d *stmtQueryLog) Query(args ...interface{}) (*sql.Rows, error) { return d.QueryContext(context.Background(), args...) } @@ -133,9 +134,11 @@ type dbQueryLog struct { txe txEnder } -var _ dbQuerier = new(dbQueryLog) -var _ txer = new(dbQueryLog) -var _ txEnder = new(dbQueryLog) +var ( + _ dbQuerier = new(dbQueryLog) + _ txer = new(dbQueryLog) + _ txEnder = new(dbQueryLog) +) func (d *dbQueryLog) Prepare(query string) (*sql.Stmt, error) { return d.PrepareContext(context.Background(), query) diff --git a/client/orm/orm_raw.go b/client/orm/orm_raw.go index af9c00cc..25452660 100644 --- a/client/orm/orm_raw.go +++ b/client/orm/orm_raw.go @@ -253,7 +253,6 @@ func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr } cur++ } - } else { value := reflect.ValueOf(refs[cur]).Elem().Interface() if isPtr && value == nil { @@ -437,7 +436,6 @@ func (o *rawSet) QueryRow(containers ...interface{}) error { sInd.Set(nInd) } } - } else { return ErrNoRows } @@ -606,7 +604,6 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { } if cnt > 0 { - if structMode { sInds[0].Set(sInd) } else { diff --git a/client/orm/orm_test.go b/client/orm/orm_test.go index 58f2a597..12fb9492 100644 --- a/client/orm/orm_test.go +++ b/client/orm/orm_test.go @@ -842,7 +842,6 @@ The program—and web server—godoc processes Go source files to extract docume throwFailNow(t, AssertIs(nums, num)) } } - } func TestCustomField(t *testing.T) { @@ -1235,7 +1234,6 @@ func TestOne(t *testing.T) { err = qs.Filter("user_name", "nothing").One(&user) throwFail(t, AssertIs(err, ErrNoRows)) - } func TestValues(t *testing.T) { @@ -1285,8 +1283,8 @@ func TestValuesList(t *testing.T) { throwFail(t, err) throwFail(t, AssertIs(num, 3)) if num == 3 { - throwFail(t, AssertIs(list[0][1], "slene")) //username - throwFail(t, AssertIs(list[2][10], nil)) //profile + throwFail(t, AssertIs(list[0][1], "slene")) // username + throwFail(t, AssertIs(list[2][10], nil)) // profile } num, err = qs.OrderBy("Id").ValuesList(&list, "UserName", "Profile__Age") @@ -1845,17 +1843,12 @@ func TestRawQueryRow(t *testing.T) { case "id": throwFail(t, AssertIs(id, 1)) break - case "time": + case "time", "datetime": v = v.(time.Time).In(DefaultTimeLoc) value := dataValues[col].(time.Time).In(DefaultTimeLoc) assert.True(t, v.(time.Time).Sub(value) <= time.Second) break case "date": - case "datetime": - v = v.(time.Time).In(DefaultTimeLoc) - value := dataValues[col].(time.Time).In(DefaultTimeLoc) - assert.True(t, v.(time.Time).Sub(value) <= time.Second) - break default: throwFail(t, AssertIs(v, dataValues[col])) } @@ -2224,7 +2217,7 @@ func TestTransaction(t *testing.T) { to, err := o.Begin() throwFail(t, err) - var names = []string{"1", "2", "3"} + names := []string{"1", "2", "3"} var tag Tag tag.Name = names[0] @@ -2267,7 +2260,6 @@ func TestTransaction(t *testing.T) { num, err = o.QueryTable("tag").Filter("name", "commit").Delete() assert.Nil(t, err) assert.Equal(t, int64(1), num) - } func TestTxOrmRollbackUnlessCommit(t *testing.T) { @@ -2768,7 +2760,9 @@ func TestStrPkInsert(t *testing.T) { if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + return } else if err == ErrLastInsertIdUnavailable { + return } else { throwFailNow(t, err) } diff --git a/client/orm/qb_postgres.go b/client/orm/qb_postgres.go index eec784df..d7f21692 100644 --- a/client/orm/qb_postgres.go +++ b/client/orm/qb_postgres.go @@ -21,7 +21,6 @@ func processingStr(str []string) string { // Select will join the fields func (qb *PostgresQueryBuilder) Select(fields ...string) QueryBuilder { - var str string n := len(fields) @@ -80,7 +79,6 @@ func (qb *PostgresQueryBuilder) RightJoin(table string) QueryBuilder { // On join with on cond func (qb *PostgresQueryBuilder) On(cond string) QueryBuilder { - var str string cond = strings.Replace(cond, " ", "", -1) slice := strings.Split(cond, "=") diff --git a/client/orm/types.go b/client/orm/types.go index b30c218f..145f2897 100644 --- a/client/orm/types.go +++ b/client/orm/types.go @@ -246,7 +246,7 @@ type ormer interface { DriverGetter } -//QueryExecutor wrapping for ormer +// QueryExecutor wrapping for ormer type QueryExecutor interface { ormer } diff --git a/core/admin/profile.go b/core/admin/profile.go index 6162a2d4..bd9eff4d 100644 --- a/core/admin/profile.go +++ b/core/admin/profile.go @@ -29,8 +29,10 @@ import ( "github.com/beego/beego/v2/core/utils" ) -var startTime = time.Now() -var pid int +var ( + startTime = time.Now() + pid int +) func init() { pid = os.Getpid() @@ -105,7 +107,6 @@ func PrintGCSummary(w io.Writer) { } func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats, w io.Writer) { - if gcstats.NumGC > 0 { lastPause := gcstats.Pause[0] elapsed := time.Since(startTime) diff --git a/core/bean/context.go b/core/bean/context.go index 7cee2c7e..78666437 100644 --- a/core/bean/context.go +++ b/core/bean/context.go @@ -16,5 +16,4 @@ package bean // ApplicationContext define for future // when we decide to support DI, IoC, this will be core API -type ApplicationContext interface { -} +type ApplicationContext interface{} diff --git a/core/bean/mock.go b/core/bean/mock.go new file mode 100644 index 00000000..0a8d3e29 --- /dev/null +++ b/core/bean/mock.go @@ -0,0 +1,142 @@ +package bean + +import ( + "fmt" + "reflect" + "strconv" + "strings" +) + +// the mock object must be pointer of struct +// the element in mock object can be slices, structures, basic data types, pointers and interface +func Mock(v interface{}) (err error) { + pv := reflect.ValueOf(v) + // the input must be pointer of struct + if pv.Kind() != reflect.Ptr || pv.IsNil() { + err = fmt.Errorf("not a pointer of struct") + return + } + err = mock(pv) + return +} + +func mock(pv reflect.Value) (err error) { + pt := pv.Type() + for i := 0; i < pt.Elem().NumField(); i++ { + ptt := pt.Elem().Field(i) + pvv := pv.Elem().FieldByName(ptt.Name) + if !pvv.CanSet() { + continue + } + kt := ptt.Type.Kind() + tagValue := ptt.Tag.Get("mock") + switch kt { + case reflect.Map: + continue + case reflect.Interface: + if pvv.IsNil() { // when interface is nil,can not sure the type + continue + } + pvv.Set(reflect.New(pvv.Elem().Type().Elem())) + err = mock(pvv.Elem()) + case reflect.Ptr: + err = mockPtr(pvv, ptt.Type.Elem()) + case reflect.Struct: + err = mock(pvv.Addr()) + case reflect.Array, reflect.Slice: + err = mockSlice(tagValue, pvv) + case reflect.String: + pvv.SetString(tagValue) + case reflect.Bool: + err = mockBool(tagValue, pvv) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + value, e := strconv.ParseInt(tagValue, 10, 64) + if e != nil || pvv.OverflowInt(value) { + err = fmt.Errorf("the value:%s is invalid", tagValue) + } + pvv.SetInt(value) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + value, e := strconv.ParseUint(tagValue, 10, 64) + if e != nil || pvv.OverflowUint(value) { + err = fmt.Errorf("the value:%s is invalid", tagValue) + } + pvv.SetUint(value) + case reflect.Float32, reflect.Float64: + value, e := strconv.ParseFloat(tagValue, pvv.Type().Bits()) + if e != nil || pvv.OverflowFloat(value) { + err = fmt.Errorf("the value:%s is invalid", tagValue) + } + pvv.SetFloat(value) + default: + } + if err != nil { + return + } + } + return +} + +// mock slice value +func mockSlice(tagValue string, pvv reflect.Value) (err error) { + if tagValue == "" { + return + } + sliceMetas := strings.Split(tagValue, ":") + if len(sliceMetas) != 2 || sliceMetas[0] != "length" { + err = fmt.Errorf("the value:%s is invalid", tagValue) + return + } + length, e := strconv.Atoi(sliceMetas[1]) + if e != nil { + return e + } + + sliceType := reflect.SliceOf(pvv.Type().Elem()) // get slice type + itemType := sliceType.Elem() // get the type of item in slice + value := reflect.MakeSlice(sliceType, 0, length) + newSliceValue := make([]reflect.Value, 0, length) + for k := 0; k < length; k++ { + itemValue := reflect.New(itemType).Elem() + // if item in slice is struct or pointer,must set zero value + switch itemType.Kind() { + case reflect.Struct: + err = mock(itemValue.Addr()) + case reflect.Ptr: + if itemValue.IsNil() { + itemValue.Set(reflect.New(itemType.Elem())) + if e := mock(itemValue); e != nil { + return e + } + } + } + newSliceValue = append(newSliceValue, itemValue) + if err != nil { + return + } + } + value = reflect.Append(value, newSliceValue...) + pvv.Set(value) + return +} + +// mock bool value +func mockBool(tagValue string, pvv reflect.Value) (err error) { + switch tagValue { + case "true": + pvv.SetBool(true) + case "false": + pvv.SetBool(false) + default: + err = fmt.Errorf("the value:%s is invalid", tagValue) + } + return +} + +// mock pointer +func mockPtr(pvv reflect.Value, ptt reflect.Type) (err error) { + if pvv.IsNil() { + pvv.Set(reflect.New(ptt)) // must set nil value to zero value + } + err = mock(pvv) + return +} diff --git a/core/bean/mock_test.go b/core/bean/mock_test.go new file mode 100644 index 00000000..0fe81f43 --- /dev/null +++ b/core/bean/mock_test.go @@ -0,0 +1,74 @@ +package bean + +import ( + "fmt" + "testing" +) + +func TestMock(t *testing.T) { + type MockSubSubObject struct { + A int `mock:"20"` + } + type MockSubObjectAnoy struct { + Anoy int `mock:"20"` + } + type MockSubObject struct { + A bool `mock:"true"` + B MockSubSubObject + } + type MockObject struct { + A string `mock:"aaaaa"` + B int8 `mock:"10"` + C []*MockSubObject `mock:"length:2"` + D bool `mock:"true"` + E *MockSubObject + F []int `mock:"length:3"` + G InterfaceA + H InterfaceA + MockSubObjectAnoy + } + m := &MockObject{G: &ImplA{}} + err := Mock(m) + if err != nil { + t.Fatalf("mock failed: %v", err) + } + if m.A != "aaaaa" || m.B != 10 || m.C[1].B.A != 20 || + !m.E.A || m.E.B.A != 20 || !m.D || len(m.F) != 3 { + t.Fail() + } + _, ok := m.G.(*ImplA) + if !ok { + t.Fail() + } + _, ok = m.G.(*ImplB) + if ok { + t.Fail() + } + _, ok = m.H.(*ImplA) + if ok { + t.Fail() + } + if m.Anoy != 20 { + t.Fail() + } +} + +type InterfaceA interface { + Item() +} + +type ImplA struct { + A string `mock:"aaa"` +} + +func (i *ImplA) Item() { + fmt.Println("implA") +} + +type ImplB struct { + B string `mock:"bbb"` +} + +func (i *ImplB) Item() { + fmt.Println("implB") +} diff --git a/core/berror/pre_define_code.go b/core/berror/pre_define_code.go index 275f86c1..ff8eb46b 100644 --- a/core/berror/pre_define_code.go +++ b/core/berror/pre_define_code.go @@ -46,6 +46,7 @@ func init() { func goCodeBlock(code string) string { return codeBlock("go", code) } + func codeBlock(lan string, code string) string { return fmt.Sprintf("```%s\n%s\n```", lan, code) } diff --git a/core/config/base_config_test.go b/core/config/base_config_test.go index 74a669a7..340d05db 100644 --- a/core/config/base_config_test.go +++ b/core/config/base_config_test.go @@ -66,7 +66,6 @@ func newBaseConfier(str1 string) *BaseConfiger { } else { return "", errors.New("mock error") } - }, } } diff --git a/core/config/config.go b/core/config/config.go index 98080fe3..5c931995 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -165,6 +165,7 @@ func (c *BaseConfiger) DefaultBool(key string, defaultVal bool) bool { } return defaultVal } + func (c *BaseConfiger) DefaultFloat(key string, defaultVal float64) float64 { if res, err := c.Float(key); err == nil { return res @@ -370,5 +371,4 @@ func ToString(x interface{}) string { type DecodeOption func(options decodeOptions) -type decodeOptions struct { -} +type decodeOptions struct{} diff --git a/core/config/config_test.go b/core/config/config_test.go index 15d6ffa6..86d3a2c5 100644 --- a/core/config/config_test.go +++ b/core/config/config_test.go @@ -20,7 +20,6 @@ import ( ) func TestExpandValueEnv(t *testing.T) { - testCases := []struct { item string want string @@ -51,5 +50,4 @@ func TestExpandValueEnv(t *testing.T) { t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got) } } - } diff --git a/core/config/etcd/config.go b/core/config/etcd/config.go index 0f7d81c8..fb12b065 100644 --- a/core/config/etcd/config.go +++ b/core/config/etcd/config.go @@ -119,7 +119,6 @@ func (e *EtcdConfiger) Sub(key string) (config.Configer, error) { // TODO remove this before release v2.0.0 func (e *EtcdConfiger) OnChange(key string, fn func(value string)) { - buildOptsFunc := func() []clientv3.OpOption { return []clientv3.OpOption{} } @@ -144,11 +143,9 @@ func (e *EtcdConfiger) OnChange(key string, fn func(value string)) { rch = e.client.Watch(context.Background(), e.prefix+key, buildOptsFunc()...) } }() - } -type EtcdConfigerProvider struct { -} +type EtcdConfigerProvider struct{} // Parse = ParseData([]byte(key)) // key must be json diff --git a/core/config/etcd/config_test.go b/core/config/etcd/config_test.go index 6907fd26..ffaf2727 100644 --- a/core/config/etcd/config_test.go +++ b/core/config/etcd/config_test.go @@ -32,7 +32,6 @@ func TestEtcdConfigerProvider_Parse(t *testing.T) { } func TestEtcdConfiger(t *testing.T) { - provider := &EtcdConfigerProvider{} cfger, _ := provider.Parse(readEtcdConfig()) diff --git a/core/config/global.go b/core/config/global.go index d0b74253..3a334cb6 100644 --- a/core/config/global.go +++ b/core/config/global.go @@ -42,15 +42,19 @@ func String(key string) (string, error) { func Strings(key string) ([]string, error) { return globalInstance.Strings(key) } + func Int(key string) (int, error) { return globalInstance.Int(key) } + func Int64(key string) (int64, error) { return globalInstance.Int64(key) } + func Bool(key string) (bool, error) { return globalInstance.Bool(key) } + func Float(key string) (float64, error) { return globalInstance.Float(key) } @@ -64,15 +68,19 @@ func DefaultString(key string, defaultVal string) string { func DefaultStrings(key string, defaultVal []string) []string { return globalInstance.DefaultStrings(key, defaultVal) } + func DefaultInt(key string, defaultVal int) int { return globalInstance.DefaultInt(key, defaultVal) } + func DefaultInt64(key string, defaultVal int64) int64 { return globalInstance.DefaultInt64(key, defaultVal) } + func DefaultBool(key string, defaultVal bool) bool { return globalInstance.DefaultBool(key, defaultVal) } + func DefaultFloat(key string, defaultVal float64) float64 { return globalInstance.DefaultFloat(key, defaultVal) } @@ -89,6 +97,7 @@ func GetSection(section string) (map[string]string, error) { func Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error { return globalInstance.Unmarshaler(prefix, obj, opt...) } + func Sub(key string) (Configer, error) { return globalInstance.Sub(key) } diff --git a/core/config/ini.go b/core/config/ini.go index 205760c2..4d80fbbf 100644 --- a/core/config/ini.go +++ b/core/config/ini.go @@ -46,8 +46,7 @@ var ( ) // IniConfig implements Config to parse ini file. -type IniConfig struct { -} +type IniConfig struct{} // Parse creates a new Config and parses the file configuration from the named file. func (ini *IniConfig) Parse(name string) (Configer, error) { diff --git a/core/config/ini_test.go b/core/config/ini_test.go index b7a03aa2..37ec7203 100644 --- a/core/config/ini_test.go +++ b/core/config/ini_test.go @@ -23,7 +23,6 @@ import ( ) func TestIni(t *testing.T) { - var ( inicontext = ` ;comment one @@ -129,11 +128,9 @@ password = ${GOPATH} if res != "astaxie" { t.Fatal("get name error") } - } func TestIniSave(t *testing.T) { - const ( inicontext = ` app = app diff --git a/core/config/json/json.go b/core/config/json/json.go index c1a29cad..098f0308 100644 --- a/core/config/json/json.go +++ b/core/config/json/json.go @@ -31,8 +31,7 @@ import ( ) // JSONConfig is a json config parser and implements Config interface. -type JSONConfig struct { -} +type JSONConfig struct{} // Parse returns a ConfigContainer with parsed json config map. func (js *JSONConfig) Parse(filename string) (config.Configer, error) { @@ -211,7 +210,6 @@ func (c *JSONConfigContainer) String(key string) (string, error) { // DefaultString returns the string value for a given key. // if err != nil return defaultval func (c *JSONConfigContainer) DefaultString(key string, defaultVal string) string { - // TODO FIXME should not use "" to replace non existence if v, err := c.String(key); v != "" && err == nil { return v } diff --git a/core/config/json/json_test.go b/core/config/json/json_test.go index 8f5b2c83..2d107183 100644 --- a/core/config/json/json_test.go +++ b/core/config/json/json_test.go @@ -25,7 +25,6 @@ import ( ) func TestJsonStartsWithArray(t *testing.T) { - const jsoncontextwitharray = `[ { "url": "user", @@ -72,7 +71,6 @@ func TestJsonStartsWithArray(t *testing.T) { } func TestJson(t *testing.T) { - var ( jsoncontext = `{ "appname": "beeapi", diff --git a/core/config/toml/toml.go b/core/config/toml/toml.go index 9261cd27..0c678164 100644 --- a/core/config/toml/toml.go +++ b/core/config/toml/toml.go @@ -47,7 +47,6 @@ func (c *Config) ParseData(data []byte) (config.Configer, error) { return &configContainer{ t: t, }, nil - } // configContainer support key looks like "a.b.c" @@ -70,7 +69,6 @@ func (c *configContainer) Set(key, val string) error { // return error if key not found or value is invalid type func (c *configContainer) String(key string) (string, error) { res, err := c.get(key) - if err != nil { return "", err } @@ -90,7 +88,6 @@ func (c *configContainer) String(key string) (string, error) { // return error if key not found or value is invalid type func (c *configContainer) Strings(key string) ([]string, error) { val, err := c.get(key) - if err != nil { return []string{}, err } @@ -141,9 +138,7 @@ func (c *configContainer) Int64(key string) (int64, error) { // bool return bool value // return error if key not found or value is invalid type func (c *configContainer) Bool(key string) (bool, error) { - res, err := c.get(key) - if err != nil { return false, err } @@ -330,7 +325,6 @@ func (c *configContainer) get(key string) (interface{}, error) { segs := strings.Split(key, keySeparator) t, err := subTree(c.t, segs[0:len(segs)-1]) - if err != nil { return nil, err } diff --git a/core/config/xml/xml.go b/core/config/xml/xml.go index 9eed2fa0..067d4811 100644 --- a/core/config/xml/xml.go +++ b/core/config/xml/xml.go @@ -102,7 +102,6 @@ func (c *ConfigContainer) Sub(key string) (config.Configer, error) { return &ConfigContainer{ data: sub, }, nil - } func (c *ConfigContainer) sub(key string) (map[string]interface{}, error) { @@ -170,7 +169,6 @@ func (c *ConfigContainer) DefaultInt64(key string, defaultVal int64) int64 { return defaultVal } return v - } // Float returns the float value for a given key. diff --git a/core/config/xml/xml_test.go b/core/config/xml/xml_test.go index 37c5fe7f..c71488fe 100644 --- a/core/config/xml/xml_test.go +++ b/core/config/xml/xml_test.go @@ -25,7 +25,6 @@ import ( ) func TestXML(t *testing.T) { - var ( // xml parse should incluce in tags xmlcontext = ` @@ -149,7 +148,6 @@ func TestXML(t *testing.T) { err = xmlconf.Unmarshaler("mysection", sec) assert.Nil(t, err) assert.Equal(t, "MySection", sec.Name) - } type Section struct { diff --git a/core/config/yaml/yaml.go b/core/config/yaml/yaml.go index 10335123..2dec5eb5 100644 --- a/core/config/yaml/yaml.go +++ b/core/config/yaml/yaml.go @@ -302,7 +302,6 @@ func (c *ConfigContainer) DefaultStrings(key string, defaultVal []string) []stri // GetSection returns map for the given section func (c *ConfigContainer) GetSection(section string) (map[string]string, error) { - if v, ok := c.data[section]; ok { return v.(map[string]string), nil } @@ -335,7 +334,6 @@ func (c *ConfigContainer) DIY(key string) (v interface{}, err error) { } func (c *ConfigContainer) getData(key string) (interface{}, error) { - if len(key) == 0 { return nil, errors.New("key is empty") } diff --git a/core/config/yaml/yaml_test.go b/core/config/yaml/yaml_test.go index cf889613..164abe9f 100644 --- a/core/config/yaml/yaml_test.go +++ b/core/config/yaml/yaml_test.go @@ -25,7 +25,6 @@ import ( ) func TestYaml(t *testing.T) { - var ( yamlcontext = ` "appname": beeapi diff --git a/core/logs/alils/alils.go b/core/logs/alils/alils.go index 7a3e4ddf..6fd8702a 100644 --- a/core/logs/alils/alils.go +++ b/core/logs/alils/alils.go @@ -180,7 +180,6 @@ func (c *aliLSWriter) WriteMsg(lm *logs.LogMsg) error { // Flush implementing method. empty. func (c *aliLSWriter) Flush() { - // flush all group for _, lg := range c.group { c.flush(lg) @@ -192,7 +191,6 @@ func (c *aliLSWriter) Destroy() { } func (c *aliLSWriter) flush(lg *LogGroup) { - c.lock.Lock() defer c.lock.Unlock() err := c.store.PutLogs(lg) diff --git a/core/logs/alils/log_project.go b/core/logs/alils/log_project.go index 7ede3fef..f993003e 100755 --- a/core/logs/alils/log_project.go +++ b/core/logs/alils/log_project.go @@ -128,7 +128,6 @@ func (p *LogProject) GetLogStore(name string) (s *LogStore, err error) { // and ttl is time-to-live(in day) of logs, // and shardCnt is the number of shards. func (p *LogProject) CreateLogStore(name string, ttl, shardCnt int) (err error) { - type Body struct { Name string `json:"logstoreName"` TTL int `json:"ttl"` @@ -212,7 +211,6 @@ func (p *LogProject) DeleteLogStore(name string) (err error) { // UpdateLogStore updates a logstore according by logstore name, // obviously we can't modify the logstore name itself. func (p *LogProject) UpdateLogStore(name string, ttl, shardCnt int) (err error) { - type Body struct { Name string `json:"logstoreName"` TTL int `json:"ttl"` @@ -355,7 +353,6 @@ func (p *LogProject) GetMachineGroup(name string) (m *MachineGroup, err error) { // CreateMachineGroup creates a new machine group in SLS. func (p *LogProject) CreateMachineGroup(m *MachineGroup) (err error) { - body, err := json.Marshal(m) if err != nil { return @@ -395,7 +392,6 @@ func (p *LogProject) CreateMachineGroup(m *MachineGroup) (err error) { // UpdateMachineGroup updates a machine group. func (p *LogProject) UpdateMachineGroup(m *MachineGroup) (err error) { - body, err := json.Marshal(m) if err != nil { return @@ -555,7 +551,6 @@ func (p *LogProject) GetConfig(name string) (c *LogConfig, err error) { // UpdateConfig updates a config. func (p *LogProject) UpdateConfig(c *LogConfig) (err error) { - body, err := json.Marshal(c) if err != nil { return @@ -595,7 +590,6 @@ func (p *LogProject) UpdateConfig(c *LogConfig) (err error) { // CreateConfig creates a new config in SLS. func (p *LogProject) CreateConfig(c *LogConfig) (err error) { - body, err := json.Marshal(c) if err != nil { return diff --git a/core/logs/alils/log_store.go b/core/logs/alils/log_store.go index d5ff25e2..fd9d9eaf 100755 --- a/core/logs/alils/log_store.go +++ b/core/logs/alils/log_store.go @@ -241,7 +241,6 @@ func (s *LogStore) GetLogsBytes(shardID int, cursor string, // LogsBytesDecode decodes logs binary data retruned by GetLogsBytes API func LogsBytesDecode(data []byte) (gl *LogGroupList, err error) { - gl = &LogGroupList{} err = proto.Unmarshal(data, gl) if err != nil { diff --git a/core/logs/conn.go b/core/logs/conn.go index 1fd71be7..cfeb3f91 100644 --- a/core/logs/conn.go +++ b/core/logs/conn.go @@ -95,7 +95,6 @@ func (c *connWriter) WriteMsg(lm *LogMsg) error { // Flush implementing method. empty. func (c *connWriter) Flush() { - } // Destroy destroy connection writer and close tcp listener. diff --git a/core/logs/conn_test.go b/core/logs/conn_test.go index ca9ea1c7..85b95c10 100644 --- a/core/logs/conn_test.go +++ b/core/logs/conn_test.go @@ -26,7 +26,6 @@ import ( // ConnTCPListener takes a TCP listener and accepts n TCP connections // Returns connections using connChan func connTCPListener(t *testing.T, n int, ln net.Listener, connChan chan<- net.Conn) { - // Listen and accept n incoming connections for i := 0; i < n; i++ { conn, err := ln.Accept() diff --git a/core/logs/console.go b/core/logs/console.go index 66e2c7ea..849e9c6e 100644 --- a/core/logs/console.go +++ b/core/logs/console.go @@ -88,7 +88,6 @@ func newConsole() *consoleWriter { // Init initianlizes the console logger. // jsonConfig must be in the format '{"level":LevelTrace}' func (c *consoleWriter) Init(config string) error { - if len(config) == 0 { return nil } @@ -116,12 +115,10 @@ func (c *consoleWriter) WriteMsg(lm *LogMsg) error { // Destroy implementing method. empty. func (c *consoleWriter) Destroy() { - } // Flush implementing method. empty. func (c *consoleWriter) Flush() { - } func init() { diff --git a/core/logs/es/es.go b/core/logs/es/es.go index 1140da97..2073ab3d 100644 --- a/core/logs/es/es.go +++ b/core/logs/es/es.go @@ -41,7 +41,6 @@ type esLogger struct { } func (el *esLogger) Format(lm *logs.LogMsg) string { - msg := lm.OldStyleFormat() idx := LogDocument{ Timestamp: lm.When.Format(time.RFC3339), @@ -60,7 +59,6 @@ func (el *esLogger) SetFormatter(f logs.LogFormatter) { // {"dsn":"http://localhost:9200/","level":1} func (el *esLogger) Init(config string) error { - err := json.Unmarshal([]byte(config), el) if err != nil { return err @@ -113,7 +111,6 @@ func (el *esLogger) Destroy() { // Flush is a empty method func (el *esLogger) Flush() { - } type LogDocument struct { diff --git a/core/logs/file.go b/core/logs/file.go index 97c4a72d..80114db2 100644 --- a/core/logs/file.go +++ b/core/logs/file.go @@ -117,7 +117,6 @@ func (w *fileLogWriter) SetFormatter(f LogFormatter) { // "perm":"0600" // } func (w *fileLogWriter) Init(config string) error { - err := json.Unmarshal([]byte(config), w) if err != nil { return err @@ -165,7 +164,6 @@ func (w *fileLogWriter) needRotateHourly(hour int) bool { return (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) || (w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) || (w.Hourly && hour != w.hourlyOpenDate) - } // WriteMsg writes logger message into file. diff --git a/core/logs/file_test.go b/core/logs/file_test.go index e9a8922b..16220936 100644 --- a/core/logs/file_test.go +++ b/core/logs/file_test.go @@ -42,7 +42,7 @@ func TestFilePerm(t *testing.T) { if err != nil { t.Fatal(err) } - if file.Mode() != 0666 { + if file.Mode() != 0o666 { t.Fatal("unexpected log file permission") } os.Remove("test.log") @@ -74,7 +74,7 @@ func TestFile1(t *testing.T) { lineNum++ } } - var expected = LevelDebug + 1 + expected := LevelDebug + 1 if lineNum != expected { t.Fatal(lineNum, "not "+strconv.Itoa(expected)+" lines") } @@ -107,7 +107,7 @@ func TestFile2(t *testing.T) { lineNum++ } } - var expected = LevelError + 1 + expected := LevelError + 1 if lineNum != expected { t.Fatal(lineNum, "not "+strconv.Itoa(expected)+" lines") } @@ -164,6 +164,7 @@ func TestFileDailyRotate_05(t *testing.T) { testFileDailyRotate(t, fn1, fn2) os.Remove(fn) } + func TestFileDailyRotate_06(t *testing.T) { // test file mode log := NewLogger(10000) log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`) @@ -177,7 +178,7 @@ func TestFileDailyRotate_06(t *testing.T) { // test file mode log.Emergency("emergency") rotateName := "test3" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) + ".log" s, _ := os.Lstat(rotateName) - if s.Mode() != 0440 { + if s.Mode() != 0o440 { os.Remove(rotateName) os.Remove("test3.log") t.Fatal("rotate file mode error") @@ -250,7 +251,7 @@ func TestFileHourlyRotate_06(t *testing.T) { // test file mode log.Emergency("emergency") rotateName := "test3" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006010215"), 1) + ".log" s, _ := os.Lstat(rotateName) - if s.Mode() != 0440 { + if s.Mode() != 0o440 { os.Remove(rotateName) os.Remove("test3.log") t.Fatal("rotate file mode error") @@ -369,6 +370,7 @@ func testFileHourlyRotate(t *testing.T, fn1, fn2 string) { } fw.Destroy() } + func exists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { diff --git a/core/logs/jianliao.go b/core/logs/jianliao.go index c82a0957..95835c06 100644 --- a/core/logs/jianliao.go +++ b/core/logs/jianliao.go @@ -31,7 +31,6 @@ func newJLWriter() Logger { // Init JLWriter with json config string func (s *JLWriter) Init(config string) error { - res := json.Unmarshal([]byte(config), s) if res == nil && len(s.Formatter) > 0 { fmtr, ok := GetFormatter(s.Formatter) diff --git a/core/logs/log.go b/core/logs/log.go index cf3ce8e0..aeb2d96b 100644 --- a/core/logs/log.go +++ b/core/logs/log.go @@ -92,8 +92,10 @@ type Logger interface { SetFormatter(f LogFormatter) } -var adapters = make(map[string]newLoggerFunc) -var levelPrefix = [LevelDebug + 1]string{"[M]", "[A]", "[C]", "[E]", "[W]", "[N]", "[I]", "[D]"} +var ( + adapters = make(map[string]newLoggerFunc) + levelPrefix = [LevelDebug + 1]string{"[M]", "[A]", "[C]", "[E]", "[W]", "[N]", "[I]", "[D]"} +) // Register makes a log provide available by the provided name. // If Register is called twice with the same name or if driver is nil, @@ -201,7 +203,6 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error { } err := lg.Init(config) - if err != nil { fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error()) return err @@ -519,49 +520,19 @@ func (bl *BeeLogger) Debug(format string, v ...interface{}) { // Warn Log WARN level message. // compatibility alias for Warning() func (bl *BeeLogger) Warn(format string, v ...interface{}) { - if LevelWarn > bl.level { - return - } - lm := &LogMsg{ - Level: LevelWarn, - Msg: format, - When: time.Now(), - Args: v, - } - - bl.writeMsg(lm) + bl.Warning(format, v...) } // Info Log INFO level message. // compatibility alias for Informational() func (bl *BeeLogger) Info(format string, v ...interface{}) { - if LevelInfo > bl.level { - return - } - lm := &LogMsg{ - Level: LevelInfo, - Msg: format, - When: time.Now(), - Args: v, - } - - bl.writeMsg(lm) + bl.Informational(format, v...) } // Trace Log TRACE level message. // compatibility alias for Debug() func (bl *BeeLogger) Trace(format string, v ...interface{}) { - if LevelDebug > bl.level { - return - } - lm := &LogMsg{ - Level: LevelDebug, - Msg: format, - When: time.Now(), - Args: v, - } - - bl.writeMsg(lm) + bl.Debug(format, v...) } // Flush flush all chan data. diff --git a/core/logs/logger.go b/core/logs/logger.go index 77e68ea2..29e33a82 100644 --- a/core/logs/logger.go +++ b/core/logs/logger.go @@ -112,8 +112,10 @@ var ( reset = string([]byte{27, 91, 48, 109}) ) -var once sync.Once -var colorMap map[string]string +var ( + once sync.Once + colorMap map[string]string +) func initColor() { if runtime.GOOS == "windows" { diff --git a/core/logs/multifile.go b/core/logs/multifile.go index 79178211..0ad8244f 100644 --- a/core/logs/multifile.go +++ b/core/logs/multifile.go @@ -45,7 +45,6 @@ var levelNames = [...]string{"emergency", "alert", "critical", "error", "warning // } func (f *multiFileLogWriter) Init(config string) error { - writer := newFileWriter().(*fileLogWriter) err := writer.Init(config) if err != nil { diff --git a/core/logs/multifile_test.go b/core/logs/multifile_test.go index 57b96094..8050bc6b 100644 --- a/core/logs/multifile_test.go +++ b/core/logs/multifile_test.go @@ -60,7 +60,7 @@ func TestFiles_1(t *testing.T) { lineNum++ } } - var expected = 1 + expected := 1 if fn == "" { expected = LevelDebug + 1 } @@ -74,5 +74,4 @@ func TestFiles_1(t *testing.T) { } os.Remove(file) } - } diff --git a/core/utils/debug.go b/core/utils/debug.go index 93c27b70..93279181 100644 --- a/core/utils/debug.go +++ b/core/utils/debug.go @@ -47,20 +47,20 @@ func GetDisplayString(data ...interface{}) string { } func display(displayed bool, data ...interface{}) string { - var pc, file, line, ok = runtime.Caller(2) + pc, file, line, ok := runtime.Caller(2) if !ok { return "" } - var buf = new(bytes.Buffer) + buf := new(bytes.Buffer) fmt.Fprintf(buf, "[Debug] at %s() [%s:%d]\n", function(pc), file, line) fmt.Fprintf(buf, "\n[Variables]\n") for i := 0; i < len(data); i += 2 { - var output = fomateinfo(len(data[i].(string))+3, data[i+1]) + output := fomateinfo(len(data[i].(string))+3, data[i+1]) fmt.Fprintf(buf, "%s = %s", data[i], output) } @@ -72,7 +72,7 @@ func display(displayed bool, data ...interface{}) string { // return data dump and format bytes func fomateinfo(headlen int, data ...interface{}) []byte { - var buf = new(bytes.Buffer) + buf := new(bytes.Buffer) if len(data) > 1 { fmt.Fprint(buf, " ") @@ -83,9 +83,9 @@ func fomateinfo(headlen int, data ...interface{}) []byte { } for k, v := range data { - var buf2 = new(bytes.Buffer) + buf2 := new(bytes.Buffer) var pointers *pointerInfo - var interfaces = make([]reflect.Value, 0, 10) + interfaces := make([]reflect.Value, 0, 10) printKeyValue(buf2, reflect.ValueOf(v), &pointers, &interfaces, nil, true, " ", 1) @@ -140,13 +140,13 @@ func isSimpleType(val reflect.Value, kind reflect.Kind, pointers **pointerInfo, return true } - var elem = val.Elem() + elem := val.Elem() if isSimpleType(elem, elem.Kind(), pointers, interfaces) { return true } - var addr = val.Elem().UnsafeAddr() + addr := val.Elem().UnsafeAddr() for p := *pointers; p != nil; p = p.prev { if addr == p.addr { @@ -162,7 +162,7 @@ func isSimpleType(val reflect.Value, kind reflect.Kind, pointers **pointerInfo, // dump value func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, interfaces *[]reflect.Value, structFilter func(string, string) bool, formatOutput bool, indent string, level int) { - var t = val.Kind() + t := val.Kind() switch t { case reflect.Bool: @@ -183,7 +183,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, return } - var addr = val.Elem().UnsafeAddr() + addr := val.Elem().UnsafeAddr() for p := *pointers; p != nil; p = p.prev { if addr == p.addr { @@ -206,7 +206,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, case reflect.String: fmt.Fprint(buf, "\"", val.String(), "\"") case reflect.Interface: - var value = val.Elem() + value := val.Elem() if !value.IsValid() { fmt.Fprint(buf, "nil") @@ -223,7 +223,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, printKeyValue(buf, value, pointers, interfaces, structFilter, formatOutput, indent, level+1) } case reflect.Struct: - var t = val.Type() + t := val.Type() fmt.Fprint(buf, t) fmt.Fprint(buf, "{") @@ -235,7 +235,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, fmt.Fprint(buf, " ") } - var name = t.Field(i).Name + name := t.Field(i).Name if formatOutput { for ind := 0; ind < level; ind++ { @@ -270,12 +270,12 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, fmt.Fprint(buf, val.Type()) fmt.Fprint(buf, "{") - var allSimple = true + allSimple := true for i := 0; i < val.Len(); i++ { - var elem = val.Index(i) + elem := val.Index(i) - var isSimple = isSimpleType(elem, elem.Kind(), pointers, interfaces) + isSimple := isSimpleType(elem, elem.Kind(), pointers, interfaces) if !isSimple { allSimple = false @@ -312,18 +312,18 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, fmt.Fprint(buf, "}") case reflect.Map: - var t = val.Type() - var keys = val.MapKeys() + t := val.Type() + keys := val.MapKeys() fmt.Fprint(buf, t) fmt.Fprint(buf, "{") - var allSimple = true + allSimple := true for i := 0; i < len(keys); i++ { - var elem = val.MapIndex(keys[i]) + elem := val.MapIndex(keys[i]) - var isSimple = isSimpleType(elem, elem.Kind(), pointers, interfaces) + isSimple := isSimpleType(elem, elem.Kind(), pointers, interfaces) if !isSimple { allSimple = false @@ -372,8 +372,8 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, // PrintPointerInfo dump pointer value func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) { - var anyused = false - var pointerNum = 0 + anyused := false + pointerNum := 0 for p := pointers; p != nil; p = p.prev { if len(p.used) > 0 { @@ -384,10 +384,10 @@ func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) { } if anyused { - var pointerBufs = make([][]rune, pointerNum+1) + pointerBufs := make([][]rune, pointerNum+1) for i := 0; i < len(pointerBufs); i++ { - var pointerBuf = make([]rune, buf.Len()+headlen) + pointerBuf := make([]rune, buf.Len()+headlen) for j := 0; j < len(pointerBuf); j++ { pointerBuf[j] = ' ' @@ -402,7 +402,7 @@ func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) { if pn == p.n { pointerBufs[pn][p.pos+headlen] = '└' - var maxpos = 0 + maxpos := 0 for i, pos := range p.used { if i < len(p.used)-1 { @@ -440,10 +440,10 @@ func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) { // Stack get stack bytes func Stack(skip int, indent string) []byte { - var buf = new(bytes.Buffer) + buf := new(bytes.Buffer) for i := skip; ; i++ { - var pc, file, line, ok = runtime.Caller(i) + pc, file, line, ok := runtime.Caller(i) if !ok { break diff --git a/core/utils/debug_test.go b/core/utils/debug_test.go index efb8924e..a748d20a 100644 --- a/core/utils/debug_test.go +++ b/core/utils/debug_test.go @@ -28,8 +28,8 @@ func TestPrint(t *testing.T) { } func TestPrintPoint(t *testing.T) { - var v1 = new(mytype) - var v2 = new(mytype) + v1 := new(mytype) + v2 := new(mytype) v1.prev = nil v1.next = v2 diff --git a/core/utils/kv_test.go b/core/utils/kv_test.go index 4c9643dc..cd0dc5c3 100644 --- a/core/utils/kv_test.go +++ b/core/utils/kv_test.go @@ -34,5 +34,4 @@ func TestKVs(t *testing.T) { v = kvs.GetValueOr(`key-not-exists`, 8546) assert.Equal(t, 8546, v) - } diff --git a/core/utils/rand.go b/core/utils/rand.go index 344d1cd5..f80dad7d 100644 --- a/core/utils/rand.go +++ b/core/utils/rand.go @@ -27,7 +27,7 @@ func RandomCreateBytes(n int, alphabets ...byte) []byte { if len(alphabets) == 0 { alphabets = alphaNum } - var bytes = make([]byte, n) + bytes := make([]byte, n) var randBy bool if num, err := rand.Read(bytes); num != n || err != nil { r.Seed(time.Now().UnixNano()) diff --git a/core/utils/safemap.go b/core/utils/safemap.go index 05763786..1f9923f1 100644 --- a/core/utils/safemap.go +++ b/core/utils/safemap.go @@ -18,8 +18,7 @@ import ( "sync" ) - -//deprecated +// deprecated type BeeMap struct { lock *sync.RWMutex bm map[interface{}]interface{} diff --git a/core/utils/slice.go b/core/utils/slice.go index 8f2cef98..0eda4670 100644 --- a/core/utils/slice.go +++ b/core/utils/slice.go @@ -20,6 +20,7 @@ import ( ) type reducetype func(interface{}) interface{} + type filtertype func(interface{}) bool // InSlice checks given string in string slice or not. diff --git a/core/utils/time.go b/core/utils/time.go index 579b292a..00d13861 100644 --- a/core/utils/time.go +++ b/core/utils/time.go @@ -21,7 +21,6 @@ import ( // short string format func ToShortTimeFormat(d time.Duration) string { - u := uint64(d) if u < uint64(time.Second) { switch { @@ -44,5 +43,4 @@ func ToShortTimeFormat(d time.Duration) string { return fmt.Sprintf("%.2fh", float64(u)/1000/1000/1000/60/60) } } - } diff --git a/core/validation/validation.go b/core/validation/validation.go index 6be10ef3..78a31f13 100644 --- a/core/validation/validation.go +++ b/core/validation/validation.go @@ -235,8 +235,11 @@ func (v *Validation) Tel(obj interface{}, key string) *Result { // Phone Test that the obj is chinese mobile or telephone number if type is string func (v *Validation) Phone(obj interface{}, key string) *Result { - return v.apply(Phone{Mobile{Match: Match{Regexp: mobilePattern}}, - Tel{Match: Match{Regexp: telPattern}}, key}, obj) + return v.apply(Phone{ + Mobile{Match: Match{Regexp: mobilePattern}}, + Tel{Match: Match{Regexp: telPattern}}, + key, + }, obj) } // ZipCode Test that the obj is chinese zip code if type is string diff --git a/core/validation/validation_test.go b/core/validation/validation_test.go index bca4f560..00a45a98 100644 --- a/core/validation/validation_test.go +++ b/core/validation/validation_test.go @@ -605,7 +605,6 @@ func TestCanSkipAlso(t *testing.T) { if !b { t.Fatal("validation should be passed") } - } func TestFieldNoEmpty(t *testing.T) { diff --git a/go.mod b/go.mod index 0305be1e..578d9f5b 100644 --- a/go.mod +++ b/go.mod @@ -26,15 +26,15 @@ require ( github.com/mattn/go-sqlite3 v1.14.7 github.com/mitchellh/mapstructure v1.4.1 github.com/opentracing/opentracing-go v1.2.0 - github.com/pelletier/go-toml v1.9.1 + github.com/pelletier/go-toml v1.9.2 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.10.0 + github.com/prometheus/client_golang v1.11.0 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec github.com/stretchr/testify v1.7.0 github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec // indirect - go.etcd.io/etcd/client/v3 v3.5.0-alpha.0 + go.etcd.io/etcd/client/v3 v3.5.0 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a - google.golang.org/grpc v1.37.1 + google.golang.org/grpc v1.38.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index c144e80d..2775eedb 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= @@ -56,8 +55,8 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/couchbase/go-couchbase v0.1.0 h1:g4bCvDwRL+ZL6HLhYeRlXxEYP31Wpy0VFxnFw6efEp8= github.com/couchbase/go-couchbase v0.1.0/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= @@ -67,7 +66,6 @@ github.com/couchbase/goutils v0.1.0 h1:0WLlKJilu7IBm98T8nS9+J36lBFVLRUSIUtyD/uWp github.com/couchbase/goutils v0.1.0/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ= github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -103,6 +101,7 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= @@ -114,12 +113,11 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -130,7 +128,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -138,8 +135,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -152,8 +151,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -169,7 +169,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -203,13 +203,12 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -286,8 +285,8 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.1 h1:a6qW1EVNZWH9WGI6CsYdD8WAylkoXBS5yv0XHlh17Tc= -github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.2 h1:7NiByeVF4jKSG1lDF3X8LTIkq2/bu+1uYbIm1eS5tzk= +github.com/pelletier/go-toml v1.9.2/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= @@ -304,10 +303,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -318,10 +316,9 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -354,7 +351,6 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec h1:q6XVwXmKvCRHRqesF3cSv6lNqqHi0QWOvgDlSohg8UA= github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -379,33 +375,33 @@ github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec/go.mod h1:Q12BUT7DqI github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0-alpha.0 h1:+e5nrluATIy3GP53znpkHMFzPTHGYyzvJGFCbuI6ZLc= -go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= -go.etcd.io/etcd/client/v3 v3.5.0-alpha.0 h1:dr1EOILak2pu4Nf5XbRIOCNIBjcz6UmkQd7hHRXwxaM= -go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= -go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0 h1:3yLUEC0nFCxw/RArImOyRUI4OAFbg4PFpBbAhSNzKNY= -go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY= +go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek= +go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -420,13 +416,13 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -444,12 +440,13 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -461,6 +458,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -479,27 +477,28 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -511,9 +510,10 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -529,8 +529,9 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -542,10 +543,9 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.37.1 h1:ARnQJNWxGyYJpdf/JXscNlQr/uv607ZPU9Z7ogHi+iI= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -554,8 +554,10 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -582,12 +584,12 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/server/web/admin.go b/server/web/admin.go index 3f665b09..f5a1afc8 100644 --- a/server/web/admin.go +++ b/server/web/admin.go @@ -45,9 +45,7 @@ var beeAdminApp *adminApp var FilterMonitorFunc func(string, string, time.Duration, string, int) bool func init() { - FilterMonitorFunc = func(string, string, time.Duration, string, int) bool { return true } - } func list(root string, p interface{}, m M) { @@ -84,7 +82,6 @@ type adminApp struct { // Route adds http.HandlerFunc to adminApp with url pattern. func (admin *adminApp) Run() { - // if len(task.AdminTaskList) > 0 { // task.StartTask() // } diff --git a/server/web/admin_controller.go b/server/web/admin_controller.go index 8ac0ccd4..ce77ecdb 100644 --- a/server/web/admin_controller.go +++ b/server/web/admin_controller.go @@ -79,7 +79,6 @@ func (a *adminController) PrometheusMetrics() { // TaskStatus is a http.Handler with running task status (task name, status and the last execution). // it's in "/task" pattern in admin module. func (a *adminController) TaskStatus() { - rw, req := a.Ctx.ResponseWriter, a.Ctx.Request data := make(map[interface{}]interface{}) @@ -91,11 +90,11 @@ func (a *adminController) TaskStatus() { cmd := admin.GetCommand("task", "run") res := cmd.Execute(taskname) if res.IsSuccess() { - - data["Message"] = []string{"success", + data["Message"] = []string{ + "success", template.HTMLEscapeString(fmt.Sprintf("%s run success,Now the Status is
%s", - taskname, res.Content.(string)))} - + taskname, res.Content.(string))), + } } else { data["Message"] = []string{"error", template.HTMLEscapeString(fmt.Sprintf("%s", res.Error))} } @@ -104,7 +103,7 @@ func (a *adminController) TaskStatus() { // List Tasks content := make(M) resultList := admin.GetCommand("task", "list").Execute().Content.([][]string) - var fields = []string{ + fields := []string{ "Task Name", "Task Spec", "Task Status", @@ -238,14 +237,12 @@ func (a *adminController) ListConf() { data["Title"] = "Routers" writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl) case "filter": - var ( - content = M{ - "Fields": []string{ - "Router Pattern", - "Filter Function", - }, - } - ) + content := M{ + "Fields": []string{ + "Router Pattern", + "Filter Function", + }, + } filterTypeData := BeeApp.reportFilter() @@ -287,7 +284,6 @@ func buildHealthCheckResponseList(healthCheckResults *[][]string) []map[string]i } return response - } // PrintTree print all routers diff --git a/server/web/admin_test.go b/server/web/admin_test.go index 04da4fab..60c067b0 100644 --- a/server/web/admin_test.go +++ b/server/web/admin_test.go @@ -14,11 +14,9 @@ import ( "github.com/beego/beego/v2/core/admin" ) -type SampleDatabaseCheck struct { -} +type SampleDatabaseCheck struct{} -type SampleCacheCheck struct { -} +type SampleCacheCheck struct{} func (dc *SampleDatabaseCheck) Check() error { return nil @@ -111,7 +109,6 @@ func TestWriteJSON(t *testing.T) { decodedBody := []int{} err := json.NewDecoder(w.Body).Decode(&decodedBody) - if err != nil { t.Fatal("Could not decode response body into slice.") } @@ -147,7 +144,6 @@ func TestHealthCheckHandlerDefault(t *testing.T) { if !strings.Contains(w.Body.String(), "database") { t.Errorf("Expected 'database' in generated template.") } - } func TestBuildHealthCheckResponseList(t *testing.T) { @@ -180,13 +176,10 @@ func TestBuildHealthCheckResponseList(t *testing.T) { t.Errorf("expected %s to be in the response %v", field, response) } } - } - } func TestHealthCheckHandlerReturnsJSON(t *testing.T) { - admin.AddHealthCheck("database", &SampleDatabaseCheck{}) admin.AddHealthCheck("cache", &SampleCacheCheck{}) @@ -245,5 +238,4 @@ func TestHealthCheckHandlerReturnsJSON(t *testing.T) { assert.Equal(t, expectedResponseBody[0], database) assert.Equal(t, expectedResponseBody[1], cache) - } diff --git a/server/web/beego.go b/server/web/beego.go index 17a7ea7b..cfe9a5dd 100644 --- a/server/web/beego.go +++ b/server/web/beego.go @@ -33,9 +33,7 @@ type M map[string]interface{} // Hook function to run type hookfunc func() error -var ( - hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc -) +var hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc // AddAPPStartHook is used to register the hookfunc // The hookfuncs will run in beego.Run() @@ -50,7 +48,6 @@ func AddAPPStartHook(hf ...hookfunc) { // beego.Run(":8089") // beego.Run("127.0.0.1:8089") func Run(params ...string) { - if len(params) > 0 && params[0] != "" { BeeApp.Run(params[0]) } diff --git a/server/web/captcha/captcha.go b/server/web/captcha/captcha.go index 2aca5e13..6d8c33b4 100644 --- a/server/web/captcha/captcha.go +++ b/server/web/captcha/captcha.go @@ -73,9 +73,7 @@ import ( "github.com/beego/beego/v2/server/web/context" ) -var ( - defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} -) +var defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} const ( // default captcha attributes @@ -199,7 +197,7 @@ func (c *Captcha) VerifyReq(req *http.Request) bool { // Verify direct verify id and challenge string func (c *Captcha) Verify(id string, challenge string) (success bool) { - if len(challenge) == 0 || len(id) == 0 { + if challenge == "" || id == "" { return } @@ -243,7 +241,7 @@ func NewCaptcha(urlPrefix string, store Storage) *Captcha { cpt.StdWidth = stdWidth cpt.StdHeight = stdHeight - if len(urlPrefix) == 0 { + if urlPrefix == "" { urlPrefix = defaultURLPrefix } diff --git a/server/web/config.go b/server/web/config.go index 9be0b163..3114a966 100644 --- a/server/web/config.go +++ b/server/web/config.go @@ -156,7 +156,7 @@ func init() { if err != nil { panic(err) } - var filename = "app.conf" + filename := "app.conf" if os.Getenv("BEEGO_RUNMODE") != "" { filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf" } @@ -304,7 +304,6 @@ func parseConfig(appConfigPath string) (err error) { // For 1.x, it use assignSingleConfig to parse the file // but for 2.x, we use Unmarshaler method func assignConfig(ac config.Configer) error { - parseConfigForV1(ac) err := ac.Unmarshaler("", BConfig) @@ -422,7 +421,6 @@ func assignSingleConfig(p interface{}, ac config.Configer) { // do nothing here } } - } // LoadAppConfig allow developer to apply a config file diff --git a/server/web/config_test.go b/server/web/config_test.go index 9f8f7a80..578457db 100644 --- a/server/web/config_test.go +++ b/server/web/config_test.go @@ -105,7 +105,6 @@ func TestAssignConfig_02(t *testing.T) { t.Log(_BConfig.Log.FileLineNum) t.FailNow() } - } func TestAssignConfig_03(t *testing.T) { diff --git a/server/web/context/acceptencoder.go b/server/web/context/acceptencoder.go index 312e50de..4181bfee 100644 --- a/server/web/context/acceptencoder.go +++ b/server/web/context/acceptencoder.go @@ -131,14 +131,12 @@ var ( } ) -var ( - encoderMap = map[string]acceptEncoder{ // all the other compress methods will ignore - "gzip": gzipCompressEncoder, - "deflate": deflateCompressEncoder, - "*": gzipCompressEncoder, // * means any compress will accept,we prefer gzip - "identity": noneCompressEncoder, // identity means none-compress - } -) +var encoderMap = map[string]acceptEncoder{ // all the other compress methods will ignore + "gzip": gzipCompressEncoder, + "deflate": deflateCompressEncoder, + "*": gzipCompressEncoder, // * means any compress will accept,we prefer gzip + "identity": noneCompressEncoder, // identity means none-compress +} // WriteFile reads from file and writes to writer by the specific encoding(gzip/deflate) func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string, error) { @@ -159,7 +157,7 @@ func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string, func writeLevel(encoding string, writer io.Writer, reader io.Reader, level int) (bool, string, error) { var outputWriter resetWriter var err error - var ce = noneCompressEncoder + ce := noneCompressEncoder if cf, ok := encoderMap[encoding]; ok { ce = cf diff --git a/server/web/context/input_test.go b/server/web/context/input_test.go index 3a6c2e7b..005ccd9a 100644 --- a/server/web/context/input_test.go +++ b/server/web/context/input_test.go @@ -203,8 +203,8 @@ func TestParams(t *testing.T) { if val := inp.Param("p2"); val != "val2_ver2" { t.Fatalf("Input.Param wrong value: %s, expected %s", val, "val1_ver2") } - } + func BenchmarkQuery(b *testing.B) { beegoInput := NewInput() beegoInput.Context = NewContext() diff --git a/server/web/context/output.go b/server/web/context/output.go index aba5e560..a981acfe 100644 --- a/server/web/context/output.go +++ b/server/web/context/output.go @@ -63,7 +63,7 @@ func (output *BeegoOutput) Header(key, val string) { // Sends out response body directly. func (output *BeegoOutput) Body(content []byte) error { var encoding string - var buf = &bytes.Buffer{} + buf := &bytes.Buffer{} if output.EnableGzip { encoding = ParseEncoding(output.Context.Request) } diff --git a/server/web/context/param/parsers.go b/server/web/context/param/parsers.go index fb4099f5..99ad9275 100644 --- a/server/web/context/param/parsers.go +++ b/server/web/context/param/parsers.go @@ -55,29 +55,25 @@ func (f parserFunc) parse(value string, toType reflect.Type) (interface{}, error return f(value, toType) } -type boolParser struct { -} +type boolParser struct{} func (p boolParser) parse(value string, toType reflect.Type) (interface{}, error) { return strconv.ParseBool(value) } -type stringParser struct { -} +type stringParser struct{} func (p stringParser) parse(value string, toType reflect.Type) (interface{}, error) { return value, nil } -type intParser struct { -} +type intParser struct{} func (p intParser) parse(value string, toType reflect.Type) (interface{}, error) { return strconv.Atoi(value) } -type floatParser struct { -} +type floatParser struct{} func (p floatParser) parse(value string, toType reflect.Type) (interface{}, error) { if toType.Kind() == reflect.Float32 { @@ -90,8 +86,7 @@ func (p floatParser) parse(value string, toType reflect.Type) (interface{}, erro return strconv.ParseFloat(value, 64) } -type timeParser struct { -} +type timeParser struct{} func (p timeParser) parse(value string, toType reflect.Type) (result interface{}, err error) { result, err = time.Parse(time.RFC3339, value) @@ -101,8 +96,7 @@ func (p timeParser) parse(value string, toType reflect.Type) (result interface{} return } -type jsonParser struct { -} +type jsonParser struct{} func (p jsonParser) parse(value string, toType reflect.Type) (interface{}, error) { pResult := reflect.New(toType) diff --git a/server/web/context/param/parsers_test.go b/server/web/context/param/parsers_test.go index 7d4c9661..931d88f6 100644 --- a/server/web/context/param/parsers_test.go +++ b/server/web/context/param/parsers_test.go @@ -13,7 +13,6 @@ type testDefinition struct { } func Test_Parsers(t *testing.T) { - // ints checkParser(testDefinition{"1", 1, intParser{}}, t) checkParser(testDefinition{"-1", int64(-1), intParser{}}, t) @@ -48,12 +47,11 @@ func Test_Parsers(t *testing.T) { checkParser(testDefinition{`["a","b"]`, []string{"a", "b"}, jsonParser{}}, t, MethodParam{in: body}) // pointers - var someInt = 1 + someInt := 1 checkParser(testDefinition{`1`, &someInt, ptrParser(intParser{})}, t) - var someStruct = struct{ X int }{5} + someStruct := struct{ X int }{5} checkParser(testDefinition{`{"X": 5}`, &someStruct, jsonParser{}}, t) - } func checkParser(def testDefinition, t *testing.T, methodParam ...MethodParam) { diff --git a/server/web/controller.go b/server/web/controller.go index a767fac4..103dd08f 100644 --- a/server/web/controller.go +++ b/server/web/controller.go @@ -51,7 +51,7 @@ var ( const ( bytePerKb = 1024 copyBufferKb = 32 - filePerm = 0666 + filePerm = 0o666 ) func init() { @@ -250,7 +250,8 @@ func (c *Controller) Bind(obj interface{}) error { return c.BindJson(obj) } i, l := 0, len(ct[0]) - for ; i < l && ct[0][i] != ';'; i++ { + for i < l && ct[0][i] != ';' { + i++ } switch ct[0][0:i] { case "application/json": diff --git a/server/web/controller_test.go b/server/web/controller_test.go index 09fdf1d8..dfd21713 100644 --- a/server/web/controller_test.go +++ b/server/web/controller_test.go @@ -141,7 +141,7 @@ func TestAdditionalViewPaths(t *testing.T) { dir2file := "file2.tpl" genFile := func(dir string, name string, content string) { - os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) + os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0o777) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) } else { @@ -149,7 +149,6 @@ func TestAdditionalViewPaths(t *testing.T) { f.WriteString(content) f.Close() } - } genFile(dir1, dir1file, `
{{.Content}}
`) genFile(dir2, dir2file, `{{.Content}}`) @@ -216,7 +215,6 @@ func TestBindNoContentType(t *testing.T) { } func TestBindXML(t *testing.T) { - var s struct { Foo string `xml:"foo"` } diff --git a/server/web/filter/prometheus/filter.go b/server/web/filter/prometheus/filter.go index 520170e0..2a26e2f1 100644 --- a/server/web/filter/prometheus/filter.go +++ b/server/web/filter/prometheus/filter.go @@ -33,15 +33,15 @@ const unknownRouterPattern = "UnknownRouterPattern" // FilterChainBuilder is an extension point, // when we want to support some configuration, // please use this structure -type FilterChainBuilder struct { -} +type FilterChainBuilder struct{} -var summaryVec prometheus.ObserverVec -var initSummaryVec sync.Once +var ( + summaryVec prometheus.ObserverVec + initSummaryVec sync.Once +) // FilterChain returns a FilterFunc. The filter will records some metrics func (builder *FilterChainBuilder) FilterChain(next web.FilterFunc) web.FilterFunc { - initSummaryVec.Do(func() { summaryVec = builder.buildVec() err := prometheus.Register(summaryVec) diff --git a/server/web/filter/prometheus/filter_test.go b/server/web/filter/prometheus/filter_test.go index 618ce5af..46ba3caf 100644 --- a/server/web/filter/prometheus/filter_test.go +++ b/server/web/filter/prometheus/filter_test.go @@ -42,7 +42,6 @@ func TestFilterChain(t *testing.T) { } func TestFilterChainBuilder_report(t *testing.T) { - ctx := context.NewContext() r, _ := http.NewRequest("GET", "/prometheus/user", nil) w := httptest.NewRecorder() diff --git a/server/web/filter/session/filter.go b/server/web/filter/session/filter.go index b26e4d53..40f3e198 100644 --- a/server/web/filter/session/filter.go +++ b/server/web/filter/session/filter.go @@ -9,8 +9,8 @@ import ( "github.com/beego/beego/v2/server/web/session" ) -//Session maintain session for web service -//Session new a session storage and store it into webContext.Context +// Session maintain session for web service +// Session new a session storage and store it into webContext.Context func Session(providerType session.ProviderType, options ...session.ManagerConfigOpt) web.FilterChain { sessionConfig := session.NewManagerConfig(options...) sessionManager, _ := session.NewManager(string(providerType), sessionConfig) @@ -25,7 +25,7 @@ func Session(providerType session.ProviderType, options ...session.ManagerConfig if sess, err := sessionManager.SessionStart(ctx.ResponseWriter, ctx.Request); err != nil { logs.Error(`init session error:%s`, err.Error()) } else { - //release session at the end of request + // release session at the end of request defer sess.SessionRelease(context.Background(), ctx.ResponseWriter) ctx.Input.CruSession = sess } diff --git a/server/web/filter_chain_test.go b/server/web/filter_chain_test.go index d76d8cbf..d102a9c8 100644 --- a/server/web/filter_chain_test.go +++ b/server/web/filter_chain_test.go @@ -28,7 +28,6 @@ import ( ) func TestControllerRegister_InsertFilterChain(t *testing.T) { - InsertFilterChain("/*", func(next FilterFunc) FilterFunc { return func(ctx *context.Context) { ctx.Output.Header("filter", "filter-chain") diff --git a/server/web/fs.go b/server/web/fs.go index 5457457a..4d65630a 100644 --- a/server/web/fs.go +++ b/server/web/fs.go @@ -6,8 +6,7 @@ import ( "path/filepath" ) -type FileSystem struct { -} +type FileSystem struct{} func (d FileSystem) Open(name string) (http.File, error) { return os.Open(name) @@ -17,7 +16,6 @@ func (d FileSystem) Open(name string) (http.File, error) { // directory in the tree, including root. All errors that arise visiting files // and directories are filtered by walkFn. func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error { - f, err := fs.Open(root) if err != nil { return err diff --git a/server/web/grace/server.go b/server/web/grace/server.go index 13fa6e34..5546546d 100644 --- a/server/web/grace/server.go +++ b/server/web/grace/server.go @@ -303,8 +303,8 @@ func (srv *Server) fork() (err error) { } runningServersForked = true - var files = make([]*os.File, len(runningServers)) - var orderArgs = make([]string, len(runningServers)) + files := make([]*os.File, len(runningServers)) + orderArgs := make([]string, len(runningServers)) for _, srvPtr := range runningServers { f, _ := srvPtr.ln.(*net.TCPListener).File() files[socketPtrOffsetMap[srvPtr.Server.Addr]] = f diff --git a/server/web/mock/session_test.go b/server/web/mock/session_test.go index b09881ef..f0abd167 100644 --- a/server/web/mock/session_test.go +++ b/server/web/mock/session_test.go @@ -25,7 +25,6 @@ import ( ) func TestSessionProvider(t *testing.T) { - sp := NewSessionProvider("file") assert.NotNil(t, sp) diff --git a/server/web/policy.go b/server/web/policy.go index 1b810520..41fb2669 100644 --- a/server/web/policy.go +++ b/server/web/policy.go @@ -25,7 +25,7 @@ type PolicyFunc func(*context.Context) // FindPolicy Find Router info for URL func (p *ControllerRegister) FindPolicy(cont *context.Context) []PolicyFunc { - var urlPath = cont.Input.URL() + urlPath := cont.Input.URL() if !BConfig.RouterCaseSensitive { urlPath = strings.ToLower(urlPath) } diff --git a/server/web/router.go b/server/web/router.go index f47cd6ff..e8e8e5d2 100644 --- a/server/web/router.go +++ b/server/web/router.go @@ -82,8 +82,7 @@ type FilterHandler interface { } // default log filter static file will not show -type logFilter struct { -} +type logFilter struct{} func (l *logFilter) Filter(ctx *beecontext.Context) bool { requestPath := path.Clean(ctx.Request.URL.Path) @@ -780,7 +779,6 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter // } // } func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, opts ...FilterOpt) { - opts = append(opts, WithCaseSensitive(p.cfg.RouterCaseSensitive)) p.filterChains = append(p.filterChains, filterChainConfig{ pattern: pattern, @@ -957,7 +955,6 @@ func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath str // Implement http.Handler interface. func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - ctx := p.GetContext() ctx.Reset(rw, r) @@ -1295,7 +1292,7 @@ func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, ex // FindRouter Find Router info for URL func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) { - var urlPath = context.Input.URL() + urlPath := context.Input.URL() if !p.cfg.RouterCaseSensitive { urlPath = strings.ToLower(urlPath) } diff --git a/server/web/router_test.go b/server/web/router_test.go index d81276d8..6840829c 100644 --- a/server/web/router_test.go +++ b/server/web/router_test.go @@ -34,8 +34,7 @@ func (ptc *PrefixTestController) PrefixList() { ptc.Ctx.Output.Body([]byte("i am list in prefix test")) } -type TestControllerWithInterface struct { -} +type TestControllerWithInterface struct{} func (m TestControllerWithInterface) Ping() { fmt.Println("pong") @@ -248,7 +247,6 @@ func TestAutoExtFunc(t *testing.T) { } func TestEscape(t *testing.T) { - r, _ := http.NewRequest("GET", "/search/%E4%BD%A0%E5%A5%BD", nil) w := httptest.NewRecorder() @@ -265,7 +263,6 @@ func TestEscape(t *testing.T) { } func TestRouteOk(t *testing.T) { - r, _ := http.NewRequest("GET", "/person/anderson/thomas?learn=kungfu", nil) w := httptest.NewRecorder() @@ -279,7 +276,6 @@ func TestRouteOk(t *testing.T) { } func TestManyRoute(t *testing.T) { - r, _ := http.NewRequest("GET", "/beego32-12.html", nil) w := httptest.NewRecorder() @@ -296,7 +292,6 @@ func TestManyRoute(t *testing.T) { // Test for issue #1669 func TestEmptyResponse(t *testing.T) { - r, _ := http.NewRequest("GET", "/beego-empty.html", nil) w := httptest.NewRecorder() @@ -839,7 +834,6 @@ func TestRouterSessionSet(t *testing.T) { if w.Header().Get("Set-Cookie") == "" { t.Errorf("TestRotuerSessionSet failed") } - } func TestRouterRouterGet(t *testing.T) { @@ -1019,7 +1013,7 @@ func TestRouterAddRouterMethodPanicInvalidMethod(t *testing.T) { message := "not support http method: " + strings.ToUpper(method) defer func() { err := recover() - if err != nil { //产生了panic异常 + if err != nil { // 产生了panic异常 errStr, ok := err.(string) if ok && errStr == message { return @@ -1037,7 +1031,7 @@ func TestRouterAddRouterMethodPanicNotAMethod(t *testing.T) { message := "not a method" defer func() { err := recover() - if err != nil { //产生了panic异常 + if err != nil { // 产生了panic异常 errStr, ok := err.(string) if ok && errStr == message { return @@ -1055,7 +1049,7 @@ func TestRouterAddRouterMethodPanicNotPublicMethod(t *testing.T) { message := "ping is not a public method" defer func() { err := recover() - if err != nil { //产生了panic异常 + if err != nil { // 产生了panic异常 errStr, ok := err.(string) if ok && errStr == message { return @@ -1073,7 +1067,7 @@ func TestRouterAddRouterMethodPanicNotImplementInterface(t *testing.T) { message := "web.TestControllerWithInterface is not implemented ControllerInterface" defer func() { err := recover() - if err != nil { //产生了panic异常 + if err != nil { // 产生了panic异常 errStr, ok := err.(string) if ok && errStr == message { return @@ -1091,7 +1085,7 @@ func TestRouterAddRouterPointerMethodPanicNotImplementInterface(t *testing.T) { message := "web.TestControllerWithInterface is not implemented ControllerInterface" defer func() { err := recover() - if err != nil { //产生了panic异常 + if err != nil { // 产生了panic异常 errStr, ok := err.(string) if ok && errStr == message { return diff --git a/server/web/server.go b/server/web/server.go index 2b7c9d26..5851e0b8 100644 --- a/server/web/server.go +++ b/server/web/server.go @@ -37,12 +37,10 @@ import ( "github.com/beego/beego/v2/server/web/grace" ) -var ( - // BeeApp is an application instance - // If you are using single server, you could use this - // But if you need multiple servers, do not use this - BeeApp *HttpServer -) +// BeeApp is an application instance +// If you are using single server, you could use this +// But if you need multiple servers, do not use this +var BeeApp *HttpServer func init() { // create beego application @@ -80,7 +78,6 @@ type MiddleWare func(http.Handler) http.Handler // Run beego application. func (app *HttpServer) Run(addr string, mws ...MiddleWare) { - initBeforeHTTPRun() // init... @@ -234,7 +231,6 @@ func (app *HttpServer) Run(addr string, mws ...MiddleWare) { endRunning <- true } }() - } if app.Cfg.Listen.EnableHTTP { go func() { @@ -864,21 +860,21 @@ func printTree(resultList *[][]string, t *Tree) { for _, l := range t.leaves { if v, ok := l.runObject.(*ControllerInfo); ok { if v.routerType == routerTypeBeego { - var result = []string{ + result := []string{ template.HTMLEscapeString(v.pattern), template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)), template.HTMLEscapeString(v.controllerType.String()), } *resultList = append(*resultList, result) } else if v.routerType == routerTypeRESTFul { - var result = []string{ + result := []string{ template.HTMLEscapeString(v.pattern), template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)), "", } *resultList = append(*resultList, result) } else if v.routerType == routerTypeHandler { - var result = []string{ + result := []string{ template.HTMLEscapeString(v.pattern), "", "", @@ -904,7 +900,7 @@ func (app *HttpServer) reportFilter() M { if bf := app.Handlers.filters[k]; len(bf) > 0 { resultList := new([][]string) for _, f := range bf { - var result = []string{ + result := []string{ // void xss template.HTMLEscapeString(f.pattern), template.HTMLEscapeString(utils.GetFuncName(f.filterFunc)), diff --git a/server/web/server_test.go b/server/web/server_test.go index 0734be77..ed214e75 100644 --- a/server/web/server_test.go +++ b/server/web/server_test.go @@ -23,12 +23,10 @@ import ( ) func TestNewHttpServerWithCfg(t *testing.T) { - BConfig.AppName = "Before" svr := NewHttpServerWithCfg(BConfig) svr.Cfg.AppName = "hello" assert.Equal(t, "hello", BConfig.AppName) - } func TestServerRouterGet(t *testing.T) { diff --git a/server/web/session/ledis/ledis_session.go b/server/web/session/ledis/ledis_session.go index 8e34388b..80524e20 100644 --- a/server/web/session/ledis/ledis_session.go +++ b/server/web/session/ledis/ledis_session.go @@ -186,6 +186,7 @@ func (lp *Provider) SessionGC(context.Context) { func (lp *Provider) SessionAll(context.Context) int { return 0 } + func init() { session.Register("ledis", ledispder) } diff --git a/server/web/session/memcache/sess_memcache.go b/server/web/session/memcache/sess_memcache.go index 64268532..11aee787 100644 --- a/server/web/session/memcache/sess_memcache.go +++ b/server/web/session/memcache/sess_memcache.go @@ -43,8 +43,10 @@ import ( "github.com/beego/beego/v2/server/web/session" ) -var mempder = &MemProvider{} -var client *memcache.Client +var ( + mempder = &MemProvider{} + client *memcache.Client +) // SessionStore memcache session store type SessionStore struct { diff --git a/server/web/session/postgres/sess_postgresql.go b/server/web/session/postgres/sess_postgresql.go index 810b27b9..9914cc0c 100644 --- a/server/web/session/postgres/sess_postgresql.go +++ b/server/web/session/postgres/sess_postgresql.go @@ -123,7 +123,6 @@ func (st *SessionStore) SessionRelease(ctx context.Context, w http.ResponseWrite } st.c.Exec("UPDATE session set session_data=$1, session_expiry=$2 where session_key=$3", b, time.Now().Format(time.RFC3339), st.sid) - } // Provider postgresql session provider diff --git a/server/web/session/redis/sess_redis_test.go b/server/web/session/redis/sess_redis_test.go index 2b15eef1..ef9834ad 100644 --- a/server/web/session/redis/sess_redis_test.go +++ b/server/web/session/redis/sess_redis_test.go @@ -101,7 +101,6 @@ func TestRedis(t *testing.T) { } func TestProvider_SessionInit(t *testing.T) { - savePath := ` { "save_path": "my save path", "idle_timeout": "3s"} ` diff --git a/server/web/session/redis_cluster/redis_cluster_test.go b/server/web/session/redis_cluster/redis_cluster_test.go index 0192cd87..e518af54 100644 --- a/server/web/session/redis_cluster/redis_cluster_test.go +++ b/server/web/session/redis_cluster/redis_cluster_test.go @@ -23,7 +23,6 @@ import ( ) func TestProvider_SessionInit(t *testing.T) { - savePath := ` { "save_path": "my save path", "idle_timeout": "3s"} ` diff --git a/server/web/session/redis_sentinel/sess_redis_sentinel_test.go b/server/web/session/redis_sentinel/sess_redis_sentinel_test.go index 489e8998..276fb5d8 100644 --- a/server/web/session/redis_sentinel/sess_redis_sentinel_test.go +++ b/server/web/session/redis_sentinel/sess_redis_sentinel_test.go @@ -90,11 +90,9 @@ func TestRedisSentinel(t *testing.T) { } sess.SessionRelease(nil, w) - } func TestProvider_SessionInit(t *testing.T) { - savePath := ` { "save_path": "my save path", "idle_timeout": "3s"} ` diff --git a/server/web/session/sess_cookie.go b/server/web/session/sess_cookie.go index 649f6510..622fb2fe 100644 --- a/server/web/session/sess_cookie.go +++ b/server/web/session/sess_cookie.go @@ -79,12 +79,14 @@ func (st *CookieSessionStore) SessionRelease(ctx context.Context, w http.Respons encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values) st.lock.Unlock() if err == nil { - cookie := &http.Cookie{Name: cookiepder.config.CookieName, + cookie := &http.Cookie{ + Name: cookiepder.config.CookieName, Value: url.QueryEscape(encodedCookie), Path: "/", HttpOnly: true, Secure: cookiepder.config.Secure, - MaxAge: cookiepder.config.Maxage} + MaxAge: cookiepder.config.Maxage, + } http.SetCookie(w, cookie) } } diff --git a/server/web/session/sess_file.go b/server/web/session/sess_file.go index a96bacb8..14cec1d9 100644 --- a/server/web/session/sess_file.go +++ b/server/web/session/sess_file.go @@ -91,7 +91,7 @@ func (fs *FileSessionStore) SessionRelease(ctx context.Context, w http.ResponseW _, err = os.Stat(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid)) var f *os.File if err == nil { - f, err = os.OpenFile(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0777) + f, err = os.OpenFile(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0o777) if err != nil { SLogger.Println(err) return @@ -140,23 +140,32 @@ func (fp *FileProvider) SessionRead(ctx context.Context, sid string) (Store, err filepder.lock.Lock() defer filepder.lock.Unlock() - err := os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0755) + sessionPath := filepath.Join(fp.savePath, string(sid[0]), string(sid[1])) + sidPath := filepath.Join(sessionPath, sid) + err := os.MkdirAll(sessionPath, 0o755) if err != nil { SLogger.Println(err.Error()) } - _, err = os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid)) var f *os.File - if err == nil { - f, err = os.OpenFile(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), os.O_RDWR, 0777) - } else if os.IsNotExist(err) { - f, err = os.Create(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid)) - } else { + _, err = os.Stat(sidPath) + switch { + case err == nil: + f, err = os.OpenFile(sidPath, os.O_RDWR, 0o777) + if err != nil { + return nil, err + } + case os.IsNotExist(err): + f, err = os.Create(sidPath) + if err != nil { + return nil, err + } + default: return nil, err } defer f.Close() - os.Chtimes(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), time.Now(), time.Now()) + os.Chtimes(sidPath, time.Now(), time.Now()) var kv map[interface{}]interface{} b, err := ioutil.ReadAll(f) if err != nil { @@ -236,7 +245,7 @@ func (fp *FileProvider) SessionRegenerate(ctx context.Context, oldsid, sid strin return nil, fmt.Errorf("newsid %s exist", newSidFile) } - err = os.MkdirAll(newPath, 0755) + err = os.MkdirAll(newPath, 0o755) if err != nil { SLogger.Println(err.Error()) } @@ -263,7 +272,7 @@ func (fp *FileProvider) SessionRegenerate(ctx context.Context, oldsid, sid strin } } - ioutil.WriteFile(newSidFile, b, 0777) + ioutil.WriteFile(newSidFile, b, 0o777) os.Remove(oldSidFile) os.Chtimes(newSidFile, time.Now(), time.Now()) ss := &FileSessionStore{sid: sid, values: kv} diff --git a/server/web/session/sess_file_test.go b/server/web/session/sess_file_test.go index e4fba3a3..84860813 100644 --- a/server/web/session/sess_file_test.go +++ b/server/web/session/sess_file_test.go @@ -23,14 +23,14 @@ import ( "time" ) -const sid = "Session_id" -const sidNew = "Session_id_new" -const sessionPath = "./_session_runtime" - -var ( - mutex sync.Mutex +const ( + sid = "Session_id" + sidNew = "Session_id_new" + sessionPath = "./_session_runtime" ) +var mutex sync.Mutex + func TestFileProviderSessionInit(t *testing.T) { mutex.Lock() defer mutex.Unlock() diff --git a/server/web/session/session.go b/server/web/session/session.go index 154db92a..881de8ea 100644 --- a/server/web/session/session.go +++ b/server/web/session/session.go @@ -252,7 +252,8 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) { manager.provider.SessionDestroy(nil, sid) if manager.config.EnableSetCookie { expiration := time.Now() - cookie = &http.Cookie{Name: manager.config.CookieName, + cookie = &http.Cookie{ + Name: manager.config.CookieName, Path: "/", HttpOnly: !manager.config.DisableHTTPOnly, Expires: expiration, @@ -294,7 +295,8 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque if err != nil { return nil, err } - cookie = &http.Cookie{Name: manager.config.CookieName, + cookie = &http.Cookie{ + Name: manager.config.CookieName, Value: url.QueryEscape(sid), Path: "/", HttpOnly: !manager.config.DisableHTTPOnly, diff --git a/server/web/session/session_config.go b/server/web/session/session_config.go index aedfc559..13c6d660 100644 --- a/server/web/session/session_config.go +++ b/server/web/session/session_config.go @@ -58,84 +58,84 @@ func CfgSessionIdPrefix(prefix string) ManagerConfigOpt { } } -//CfgSetCookie whether set `Set-Cookie` header in HTTP response +// CfgSetCookie whether set `Set-Cookie` header in HTTP response func CfgSetCookie(enable bool) ManagerConfigOpt { return func(config *ManagerConfig) { config.EnableSetCookie = enable } } -//CfgGcLifeTime set session gc lift time +// CfgGcLifeTime set session gc lift time func CfgGcLifeTime(lifeTime int64) ManagerConfigOpt { return func(config *ManagerConfig) { config.Gclifetime = lifeTime } } -//CfgMaxLifeTime set session lift time +// CfgMaxLifeTime set session lift time func CfgMaxLifeTime(lifeTime int64) ManagerConfigOpt { return func(config *ManagerConfig) { config.Maxlifetime = lifeTime } } -//CfgGcLifeTime set session lift time +// CfgGcLifeTime set session lift time func CfgCookieLifeTime(lifeTime int) ManagerConfigOpt { return func(config *ManagerConfig) { config.CookieLifeTime = lifeTime } } -//CfgProviderConfig configure session provider +// CfgProviderConfig configure session provider func CfgProviderConfig(providerConfig string) ManagerConfigOpt { return func(config *ManagerConfig) { config.ProviderConfig = providerConfig } } -//CfgDomain set cookie domain +// CfgDomain set cookie domain func CfgDomain(domain string) ManagerConfigOpt { return func(config *ManagerConfig) { config.Domain = domain } } -//CfgSessionIdInHTTPHeader enable session id in http header +// CfgSessionIdInHTTPHeader enable session id in http header func CfgSessionIdInHTTPHeader(enable bool) ManagerConfigOpt { return func(config *ManagerConfig) { config.EnableSidInHTTPHeader = enable } } -//CfgSetSessionNameInHTTPHeader set key of session id in http header +// CfgSetSessionNameInHTTPHeader set key of session id in http header func CfgSetSessionNameInHTTPHeader(name string) ManagerConfigOpt { return func(config *ManagerConfig) { config.SessionNameInHTTPHeader = name } } -//EnableSidInURLQuery enable session id in query string +// EnableSidInURLQuery enable session id in query string func CfgEnableSidInURLQuery(enable bool) ManagerConfigOpt { return func(config *ManagerConfig) { config.EnableSidInURLQuery = enable } } -//DisableHTTPOnly set HTTPOnly for http.Cookie +// DisableHTTPOnly set HTTPOnly for http.Cookie func CfgHTTPOnly(HTTPOnly bool) ManagerConfigOpt { return func(config *ManagerConfig) { config.DisableHTTPOnly = !HTTPOnly } } -//CfgSecure set Secure for http.Cookie +// CfgSecure set Secure for http.Cookie func CfgSecure(Enable bool) ManagerConfigOpt { return func(config *ManagerConfig) { config.Secure = Enable } } -//CfgSameSite set http.SameSite +// CfgSameSite set http.SameSite func CfgSameSite(sameSite http.SameSite) ManagerConfigOpt { return func(config *ManagerConfig) { config.CookieSameSite = sameSite diff --git a/server/web/staticfile.go b/server/web/staticfile.go index 9560c7ab..7a120f68 100644 --- a/server/web/staticfile.go +++ b/server/web/staticfile.go @@ -75,7 +75,7 @@ func serverStaticRouter(ctx *context.Context) { return } - var enableCompress = BConfig.EnableGzip && isStaticCompress(filePath) + enableCompress := BConfig.EnableGzip && isStaticCompress(filePath) var acceptEncoding string if enableCompress { acceptEncoding = context.ParseEncoding(ctx.Request) diff --git a/server/web/staticfile_test.go b/server/web/staticfile_test.go index 0725a2f8..621b4c17 100644 --- a/server/web/staticfile_test.go +++ b/server/web/staticfile_test.go @@ -12,8 +12,10 @@ import ( "testing" ) -var currentWorkDir, _ = os.Getwd() -var licenseFile = filepath.Join(currentWorkDir, "LICENSE") +var ( + currentWorkDir, _ = os.Getwd() + licenseFile = filepath.Join(currentWorkDir, "LICENSE") +) func testOpenFile(encoding string, content []byte, t *testing.T) { fi, _ := os.Stat(licenseFile) @@ -27,6 +29,7 @@ func testOpenFile(encoding string, content []byte, t *testing.T) { assetOpenFileAndContent(sch, reader, content, t) } + func TestOpenStaticFile_1(t *testing.T) { file, _ := os.Open(licenseFile) content, _ := ioutil.ReadAll(file) @@ -43,6 +46,7 @@ func TestOpenStaticFileGzip_1(t *testing.T) { testOpenFile("gzip", content, t) } + func TestOpenStaticFileDeflate_1(t *testing.T) { file, _ := os.Open(licenseFile) var zipBuf bytes.Buffer diff --git a/server/web/statistics.go b/server/web/statistics.go index 3677271b..74708cbd 100644 --- a/server/web/statistics.go +++ b/server/web/statistics.go @@ -65,7 +65,6 @@ func (m *URLMap) AddStatistics(requestMethod, requestURL, requestController stri } m.urlmap[requestURL][requestMethod] = nb } - } else { if m.LengthLimit > 0 && m.LengthLimit <= len(m.urlmap) { return @@ -89,7 +88,7 @@ func (m *URLMap) GetMap() map[string]interface{} { m.lock.RLock() defer m.lock.RUnlock() - var fields = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"} + fields := []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"} var resultLists [][]string content := make(map[string]interface{}) diff --git a/server/web/template.go b/server/web/template.go index 78ea958a..c683c565 100644 --- a/server/web/template.go +++ b/server/web/template.go @@ -349,7 +349,6 @@ func _getTemplate(t0 *template.Template, root string, fs http.FileSystem, subMod } } } - } return } diff --git a/server/web/template_test.go b/server/web/template_test.go index 9ccacfcd..2c2585ce 100644 --- a/server/web/template_test.go +++ b/server/web/template_test.go @@ -56,11 +56,11 @@ func TestTemplate(t *testing.T) { "index.tpl", "blocks/block.tpl", } - if err := os.MkdirAll(dir, 0777); err != nil { + if err := os.MkdirAll(dir, 0o777); err != nil { t.Fatal(err) } for k, name := range files { - dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) + dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0o777) assert.Nil(t, dirErr) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) @@ -100,6 +100,7 @@ var menu = ` ` + var user = ` @@ -124,11 +125,11 @@ func TestRelativeTemplate(t *testing.T) { "easyui/public/menu.tpl", "easyui/rbac/user.tpl", } - if err := os.MkdirAll(dir, 0777); err != nil { + if err := os.MkdirAll(dir, 0o777); err != nil { t.Fatal(err) } for k, name := range files { - os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) + os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0o777) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) } else { @@ -232,12 +233,12 @@ func TestTemplateLayout(t *testing.T) { "add.tpl", "layout_blog.tpl", } - if err := os.MkdirAll(dir, 0777); err != nil { + if err := os.MkdirAll(dir, 0o777); err != nil { t.Fatal(err) } for k, name := range files { - dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) + dirErr := os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0o777) assert.Nil(t, dirErr) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) diff --git a/server/web/templatefunc.go b/server/web/templatefunc.go index c620a4b5..6cd42faf 100644 --- a/server/web/templatefunc.go +++ b/server/web/templatefunc.go @@ -54,7 +54,6 @@ func Substr(s string, start, length int) string { // HTML2str returns escaping text convert from html. func HTML2str(html string) string { - re := regexp.MustCompile(`\<[\S\s]+?\>`) html = re.ReplaceAllStringFunc(html, strings.ToLower) @@ -255,7 +254,6 @@ func URLFor(endpoint string, values ...interface{}) string { // AssetsJs returns script tag with src string. func AssetsJs(text string) template.HTML { - text = "" return template.HTML(text) @@ -263,7 +261,6 @@ func AssetsJs(text string) template.HTML { // AssetsCSS returns stylesheet link tag with src string. func AssetsCSS(text string) template.HTML { - text = "" return template.HTML(text) @@ -423,8 +420,10 @@ func ParseForm(form url.Values, obj interface{}) error { return parseFormToStruct(form, objT, objV) } -var sliceOfInts = reflect.TypeOf([]int(nil)) -var sliceOfStrings = reflect.TypeOf([]string(nil)) +var ( + sliceOfInts = reflect.TypeOf([]int(nil)) + sliceOfStrings = reflect.TypeOf([]string(nil)) +) var unKind = map[reflect.Kind]bool{ reflect.Uintptr: true, @@ -504,7 +503,7 @@ func isValidForInput(fType string) bool { } // parseFormTag takes the stuct-tag of a StructField and parses the `form` value. -// returned are the form label, name-property, type and wether the field should be ignored. +// returned are the form label, name-property, type and whether the field should be ignored. func parseFormTag(fieldT reflect.StructField) (label, name, fType string, id string, class string, ignored bool, required bool) { tags := strings.Split(fieldT.Tag.Get("form"), ",") label = fieldT.Name + ": " diff --git a/server/web/templatefunc_test.go b/server/web/templatefunc_test.go index c94c3731..403a8547 100644 --- a/server/web/templatefunc_test.go +++ b/server/web/templatefunc_test.go @@ -299,7 +299,6 @@ func TestParseFormTag(t *testing.T) { if !(name == "name" && !required) { t.Errorf("Form Tag containing only name and not required was not correctly parsed.") } - } func TestMapGet(t *testing.T) { diff --git a/server/web/tree.go b/server/web/tree.go index 3716d4f4..24a58a01 100644 --- a/server/web/tree.go +++ b/server/web/tree.go @@ -23,9 +23,7 @@ import ( "github.com/beego/beego/v2/server/web/context" ) -var ( - allowSuffixExt = []string{".json", ".xml", ".html"} -) +var allowSuffixExt = []string{".json", ".xml", ".html"} // Tree has three elements: FixRouter/wildcard/leaves // fixRouter stores Fixed Router @@ -284,7 +282,7 @@ func (t *Tree) addseg(segments []string, route interface{}, wildcards []string, // Match router to runObject & params func (t *Tree) Match(pattern string, ctx *context.Context) (runObject interface{}) { - if len(pattern) == 0 || pattern[0] != '/' { + if pattern == "" || pattern[0] != '/' { return nil } w := make([]string, 0, 20) @@ -294,12 +292,13 @@ func (t *Tree) Match(pattern string, ctx *context.Context) (runObject interface{ func (t *Tree) match(treePattern string, pattern string, wildcardValues []string, ctx *context.Context) (runObject interface{}) { if len(pattern) > 0 { i, l := 0, len(pattern) - for ; i < l && pattern[i] == '/'; i++ { + for i < l && pattern[i] == '/' { + i++ } pattern = pattern[i:] } // Handle leaf nodes: - if len(pattern) == 0 { + if pattern == "" { for _, l := range t.leaves { if ok := l.match(treePattern, wildcardValues, ctx); ok { return l.runObject @@ -316,7 +315,8 @@ func (t *Tree) match(treePattern string, pattern string, wildcardValues []string } var seg string i, l := 0, len(pattern) - for ; i < l && pattern[i] != '/'; i++ { + for i < l && pattern[i] != '/' { + i++ } if i == 0 { seg = pattern @@ -327,7 +327,7 @@ func (t *Tree) match(treePattern string, pattern string, wildcardValues []string } for _, subTree := range t.fixrouters { if subTree.prefix == seg { - if len(pattern) != 0 && pattern[0] == '/' { + if pattern != "" && pattern[0] == '/' { treePattern = pattern[1:] } else { treePattern = pattern diff --git a/server/web/tree_test.go b/server/web/tree_test.go index 0885ffe8..00d8bc27 100644 --- a/server/web/tree_test.go +++ b/server/web/tree_test.go @@ -119,7 +119,6 @@ func init() { routers = append(routers, notMatchTestInfo(abcSuffix, "/abc/suffix.html/a")) routers = append(routers, matchTestInfo(abcSuffix, "/abc/suffix/a", nil)) routers = append(routers, notMatchTestInfo(abcSuffix, "/abc.j/suffix/a")) - } func TestTreeRouters(t *testing.T) { @@ -303,6 +302,7 @@ func TestAddTree5(t *testing.T) { t.Fatal("url /v1/shop/ need match router /v1/shop/ ") } } + func TestSplitPath(t *testing.T) { a := splitPath("") if len(a) != 0 { @@ -331,7 +331,6 @@ func TestSplitPath(t *testing.T) { } func TestSplitSegment(t *testing.T) { - items := map[string]struct { isReg bool params []string diff --git a/server/web/unregroute_test.go b/server/web/unregroute_test.go index 226cffb8..703497d3 100644 --- a/server/web/unregroute_test.go +++ b/server/web/unregroute_test.go @@ -27,13 +27,14 @@ import ( // that embed parent routers. // -const contentRootOriginal = "ok-original-root" -const contentLevel1Original = "ok-original-level1" -const contentLevel2Original = "ok-original-level2" - -const contentRootReplacement = "ok-replacement-root" -const contentLevel1Replacement = "ok-replacement-level1" -const contentLevel2Replacement = "ok-replacement-level2" +const ( + contentRootOriginal = "ok-original-root" + contentLevel1Original = "ok-original-level1" + contentLevel2Original = "ok-original-level2" + contentRootReplacement = "ok-replacement-root" + contentLevel1Replacement = "ok-replacement-level1" + contentLevel2Replacement = "ok-replacement-level2" +) // TestPreUnregController will supply content for the original routes, // before unregistration @@ -44,9 +45,11 @@ type TestPreUnregController struct { func (tc *TestPreUnregController) GetFixedRoot() { tc.Ctx.Output.Body([]byte(contentRootOriginal)) } + func (tc *TestPreUnregController) GetFixedLevel1() { tc.Ctx.Output.Body([]byte(contentLevel1Original)) } + func (tc *TestPreUnregController) GetFixedLevel2() { tc.Ctx.Output.Body([]byte(contentLevel2Original)) } @@ -60,9 +63,11 @@ type TestPostUnregController struct { func (tc *TestPostUnregController) GetFixedRoot() { tc.Ctx.Output.Body([]byte(contentRootReplacement)) } + func (tc *TestPostUnregController) GetFixedLevel1() { tc.Ctx.Output.Body([]byte(contentLevel1Replacement)) } + func (tc *TestPostUnregController) GetFixedLevel2() { tc.Ctx.Output.Body([]byte(contentLevel2Replacement)) } @@ -71,8 +76,7 @@ func (tc *TestPostUnregController) GetFixedLevel2() { // In this case, for a path like "/level1/level2" or "/level1", those actions // should remain intact, and continue to serve the original content. func TestUnregisterFixedRouteRoot(t *testing.T) { - - var method = "GET" + method := "GET" handler := NewControllerRegister() handler.Add("/", &TestPreUnregController{}, WithRouterMethods(&TestPreUnregController{}, "get:GetFixedRoot")) @@ -106,15 +110,13 @@ func TestUnregisterFixedRouteRoot(t *testing.T) { // Test level 2 (expect no change from the original) testHelperFnContentCheck(t, handler, "Test level 2 (expect no change from the original)", method, "/level1/level2", contentLevel2Original) - } // TestUnregisterFixedRouteLevel1 replaces just the "/level1" fixed route path. // In this case, for a path like "/level1/level2" or "/", those actions // should remain intact, and continue to serve the original content. func TestUnregisterFixedRouteLevel1(t *testing.T) { - - var method = "GET" + method := "GET" handler := NewControllerRegister() handler.Add("/", &TestPreUnregController{}, WithRouterMethods(&TestPreUnregController{}, "get:GetFixedRoot")) @@ -156,15 +158,13 @@ func TestUnregisterFixedRouteLevel1(t *testing.T) { // Test level 2 (expect no change from the original) testHelperFnContentCheck(t, handler, "Test level 2 (expect no change from the original)", method, "/level1/level2", contentLevel2Original) - } // TestUnregisterFixedRouteLevel2 unregisters just the "/level1/level2" fixed // route path. In this case, for a path like "/level1" or "/", those actions // should remain intact, and continue to serve the original content. func TestUnregisterFixedRouteLevel2(t *testing.T) { - - var method = "GET" + method := "GET" handler := NewControllerRegister() handler.Add("/", &TestPreUnregController{}, WithRouterMethods(&TestPreUnregController{}, "get:GetFixedRoot")) @@ -206,7 +206,6 @@ func TestUnregisterFixedRouteLevel2(t *testing.T) { // Test level 2 (expect change) testHelperFnContentCheck(t, handler, "Test level 2 (expect change)", method, "/level1/level2", contentLevel2Replacement) - } func testHelperFnContentCheck(t *testing.T, handler *ControllerRegister, diff --git a/task/govenor_command.go b/task/govenor_command.go index 20238435..5435fdf1 100644 --- a/task/govenor_command.go +++ b/task/govenor_command.go @@ -24,8 +24,7 @@ import ( "github.com/beego/beego/v2/core/admin" ) -type listTaskCommand struct { -} +type listTaskCommand struct{} func (l *listTaskCommand) Execute(params ...interface{}) *admin.Result { resultList := make([][]string, 0, len(globalTaskManager.adminTaskList)) @@ -45,8 +44,7 @@ func (l *listTaskCommand) Execute(params ...interface{}) *admin.Result { } } -type runTaskCommand struct { -} +type runTaskCommand struct{} func (r *runTaskCommand) Execute(params ...interface{}) *admin.Result { if len(params) == 0 { @@ -83,7 +81,6 @@ func (r *runTaskCommand) Execute(params ...interface{}) *admin.Result { Error: errors.New(fmt.Sprintf("task with name %s not found", tn)), } } - } func registerCommands() { diff --git a/task/task.go b/task/task.go index 00e67c4b..09a08144 100644 --- a/task/task.go +++ b/task/task.go @@ -37,6 +37,7 @@ type taskManager struct { stop chan bool changed chan bool started bool + wait sync.WaitGroup } func newTaskManager() *taskManager { @@ -136,7 +137,6 @@ type Task struct { // NewTask add new task with name, time and func func NewTask(tname string, spec string, f TaskFunc, opts ...Option) *Task { - task := &Task{ Taskname: tname, DoFunc: f, @@ -350,7 +350,6 @@ func (t *Task) parseSpec(spec string) *Schedule { // Next set schedule to next time func (s *Schedule) Next(t time.Time) time.Time { - // Start at the earliest possible time (the upcoming second). t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond) @@ -471,6 +470,11 @@ func ClearTask() { globalTaskManager.ClearTask() } +// GracefulShutdown wait all task done +func GracefulShutdown() <-chan struct{} { + return globalTaskManager.GracefulShutdown() +} + // StartTask start all tasks func (m *taskManager) StartTask() { m.taskLock.Lock() @@ -508,7 +512,7 @@ func (m *taskManager) run() { select { case now = <-time.After(effective.Sub(now)): // wait for effective time - runNextTasks(sortList, effective) + m.runNextTasks(sortList, effective) continue case <-m.changed: // tasks have been changed, set all tasks run again now now = time.Now().Local() @@ -540,9 +544,9 @@ func (m *taskManager) markManagerStop() { } // runNextTasks it runs next task which next run time is equal to effective -func runNextTasks(sortList *MapSorter, effective time.Time) { +func (m *taskManager) runNextTasks(sortList *MapSorter, effective time.Time) { // Run every entry whose next time was this effective time. - var i = 0 + i := 0 for _, e := range sortList.Vals { i++ if e.GetNext(context.Background()) != effective { @@ -551,8 +555,10 @@ func runNextTasks(sortList *MapSorter, effective time.Time) { // check if timeout is on, if yes passing the timeout context ctx := context.Background() + m.wait.Add(1) if duration := e.GetTimeout(ctx); duration != 0 { go func(e Tasker) { + defer m.wait.Done() ctx, cancelFunc := context.WithTimeout(ctx, duration) defer cancelFunc() err := e.Run(ctx) @@ -562,6 +568,7 @@ func runNextTasks(sortList *MapSorter, effective time.Time) { }(e) } else { go func(e Tasker) { + defer m.wait.Done() err := e.Run(ctx) if err != nil { log.Printf("tasker.run err: %s\n", err.Error()) @@ -581,6 +588,17 @@ func (m *taskManager) StopTask() { }() } +// GracefulShutdown wait all task done +func (m *taskManager) GracefulShutdown() <-chan struct{} { + done := make(chan struct{}) + go func() { + m.stop <- true + m.wait.Wait() + close(done) + }() + return done +} + // AddTask add task with name func (m *taskManager) AddTask(taskname string, t Tasker) { isChanged := false @@ -597,7 +615,6 @@ func (m *taskManager) AddTask(taskname string, t Tasker) { m.changed <- true }() } - } // DeleteTask delete task with name @@ -670,6 +687,7 @@ func (ms *MapSorter) Less(i, j int) bool { } return ms.Vals[i].GetNext(context.Background()).Before(ms.Vals[j].GetNext(context.Background())) } + func (ms *MapSorter) Swap(i, j int) { ms.Vals[i], ms.Vals[j] = ms.Vals[j], ms.Vals[i] ms.Keys[i], ms.Keys[j] = ms.Keys[j], ms.Keys[i] @@ -688,7 +706,6 @@ func getField(field string, r bounds) uint64 { // getRange returns the bits indicated by the given expression: // number | number "-" number [ "/" number ] func getRange(expr string, r bounds) uint64 { - var ( start, end, step uint rangeAndStep = strings.Split(expr, "/") diff --git a/task/task_test.go b/task/task_test.go index 1078aa01..8d274e8f 100644 --- a/task/task_test.go +++ b/task/task_test.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "sync" + "sync/atomic" "testing" "time" @@ -177,6 +178,26 @@ func TestCrudTask(t *testing.T) { assert.Equal(t, 0, len(m.adminTaskList)) } +func TestGracefulShutdown(t *testing.T) { + m := newTaskManager() + defer m.ClearTask() + waitDone := atomic.Value{} + waitDone.Store(false) + tk := NewTask("everySecond", "* * * * * *", func(ctx context.Context) error { + fmt.Println("hello world") + time.Sleep(2 * time.Second) + waitDone.Store(true) + return nil + }) + m.AddTask("taska", tk) + m.StartTask() + time.Sleep(1 * time.Second) + shutdown := m.GracefulShutdown() + assert.False(t, waitDone.Load().(bool)) + <-shutdown + assert.True(t, waitDone.Load().(bool)) +} + func wait(wg *sync.WaitGroup) chan bool { ch := make(chan bool) go func() { diff --git a/test/bindata.go b/test/bindata.go index 120d327c..1b996b53 100644 --- a/test/bindata.go +++ b/test/bindata.go @@ -56,18 +56,23 @@ type bindataFileInfo struct { func (fi bindataFileInfo) Name() string { return fi.name } + func (fi bindataFileInfo) Size() int64 { return fi.size } + func (fi bindataFileInfo) Mode() os.FileMode { return fi.mode } + func (fi bindataFileInfo) ModTime() time.Time { return fi.modTime } + func (fi bindataFileInfo) IsDir() bool { return false } + func (fi bindataFileInfo) Sys() interface{} { return nil } @@ -249,7 +254,7 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0o755)) if err != nil { return err }