From 379e48ed7a61e1c23958382e2c8df23a43f58c6a Mon Sep 17 00:00:00 2001 From: Asklv <47499836+IRONICBo@users.noreply.github.com> Date: Fri, 30 Jun 2023 10:09:59 +0800 Subject: [PATCH] fix: Fix golang ci piplines and docs. (#39) Co-authored-by: Xinwei Xiong <86140903+cubxxw@users.noreply.github.com> --- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/kubekf.yml | 26 +++++----- .golangci.yml | 51 ++++++++++--------- Makefile | 4 +- README.md | 2 +- README_zh-CN.md | 2 +- server/cmd/genhooks/pkg/gen.go | 5 ++ server/go.mod | 5 +- server/go.sum | 12 +++-- server/internal/api/mail.go | 2 + server/internal/common/code.go | 1 + server/internal/common/msg.go | 10 ++-- server/internal/common/response/response.go | 10 ++++ server/internal/config/config.go | 9 ++++ server/internal/config/viper.go | 17 ++++++- server/internal/conn/client/mail.go | 2 + server/internal/conn/client/minio.go | 13 +++-- server/internal/conn/db/mysql.go | 29 ++++++----- server/internal/conn/db/redis.go | 3 ++ server/internal/middleware/cros.go | 1 + .../internal/middleware/hooks/global_hook.go | 4 ++ server/internal/middleware/hooks/init.go | 2 +- server/internal/middleware/hooks/mail_hook.go | 4 ++ .../middleware/hooks/url_trie/hook.go | 5 +- .../middleware/hooks/url_trie/trie.go | 37 +++++--------- server/internal/middleware/jwt.go | 3 ++ server/internal/models/base.go | 1 + server/internal/models/user.go | 1 + server/internal/param/mail.go | 1 + server/internal/router/router.go | 3 +- server/internal/service/init.go | 3 ++ server/internal/service/mail.go | 2 + server/pkg/log/fileline_hook.go | 1 + server/pkg/log/logrus.go | 23 ++++++--- server/pkg/server/server.go | 2 + 35 files changed, 195 insertions(+), 103 deletions(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 057dcff..346c98e 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -45,7 +45,7 @@ jobs: # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 # Optional: show only new issues if it's a pull request. The default value is `false`. - only-new-issues: true + # only-new-issues: true # Optional:The mode to install golangci-lint. It can be 'binary' or 'goinstall'. install-mode: "goinstall" \ No newline at end of file diff --git a/.github/workflows/kubekf.yml b/.github/workflows/kubekf.yml index f890d94..a4a2322 100644 --- a/.github/workflows/kubekf.yml +++ b/.github/workflows/kubekf.yml @@ -58,9 +58,9 @@ jobs: run: | make cover - # - name: Build source code for host platform - # run: | - # make build + - name: Build source code for host platform + run: | + # make build # skip build for now - name: Collect Test Coverage File uses: actions/upload-artifact@v1.0.0 @@ -71,13 +71,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ env.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + # skip for now + # - name: Login to DockerHub + # uses: docker/login-action@v1 + # with: + # username: ${{ env.DOCKERHUB_USERNAME }} + # password: ${{ secrets.DOCKERHUB_TOKEN }} - # - name: Build docker images for host arch and push images to registry - # run: | - # set -e - # make docker-push + # skip for now + # - name: Build docker images for host arch and push images to registry + # run: | + # set -e + # make docker-push \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index d532082..1cf6a2a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -160,15 +160,15 @@ linters-settings: - '*.Embedded' - '*.External' - forbidigo: - # Forbid the following identifiers (identifiers are written using regexp): - forbid: - - ^print.*$ - - 'fmt\.Print.*' - - fmt.Println.* # too much log noise - - ginkgo\\.F.* # these are used just for local development - # Exclude godoc examples from forbidigo checks. Default is true. - exclude_godoc_examples: false + # forbidigo: + # # Forbid the following identifiers (identifiers are written using regexp): + # forbid: + # - ^print.*$ + # - 'fmt\.Print.*' + # - fmt.Println.* # too much log noise + # - ginkgo\\.F.* # these are used just for local development + # # Exclude godoc examples from forbidigo checks. Default is true. + # exclude_godoc_examples: false funlen: lines: 150 statements: 50 @@ -296,7 +296,7 @@ linters-settings: gofumpt: # Select the Go version to target. The default is `1.18`. - lang-version: "1.18" + lang-version: "1.20" # Choose whether or not to use the extra rules that are disabled # by default @@ -409,7 +409,7 @@ linters-settings: gosimple: # Select the Go version to target. The default is '1.13'. - go: "1.18" + go: "1.20" # https://staticcheck.io/docs/options#checks checks: [ "all" ] @@ -433,14 +433,14 @@ linters-settings: disable: - shadow disable-all: false - depguard: - list-type: blacklist - include-go-root: false - packages: - - github.com/Sirupsen/logrus - packages-with-error-message: - # specify an error message to output when a blacklisted package is used - - github.com/Sirupsen/logrus: "logging is allowed only by logutils.Log" + # depguard: + # list-type: blacklist + # include-go-root: false + # packages: + # - github.com/Sirupsen/logrus + # packages-with-error-message: + # # specify an error message to output when a blacklisted package is used + # - github.com/Sirupsen/logrus: "logging is allowed only by logutils.Log" ifshort: # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax. # Has higher priority than max-decl-chars. @@ -722,7 +722,7 @@ linters: - bodyclose - cyclop - deadcode - - depguard + # - depguard - dogsled - dupl - durationcheck @@ -730,10 +730,10 @@ linters: - errorlint - exhaustive - exportloopref - - forbidigo + # - forbidigo - funlen - #- gci - - gochecknoinits + # - gci + # - gochecknoinits - gocognit - goconst - gocyclo @@ -813,8 +813,9 @@ issues: # Excluding configuration per-path, per-linter, per-text and per-source exclude-rules: - linters: - - errorlint - path: (pkg/validator/.*)\.go + - golint + path: (internal/api/.*)\.go # exclude golint for internal/api/... files + - linters: - revive path: (log/.*)\.go diff --git a/Makefile b/Makefile index dfd82fb..32400c3 100644 --- a/Makefile +++ b/Makefile @@ -227,7 +227,7 @@ generate: .PHONY: lint lint: tools.verify.golangci-lint @echo "===========> Run golangci to lint source codes" - @cd $(SERVER_DIR) && $(TOOLS_DIR)/golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/$(SERVER_DIR)/... + @cd $(SERVER_DIR) && $(TOOLS_DIR)/golangci-lint run -c $(ROOT_DIR)/.golangci.yml ## test: Run unit test .PHONY: test @@ -237,7 +237,7 @@ test: ## cover: Run unit test with coverage. .PHONY: cover cover: test - @cd $(SERVER_DIR) && go test -cover + @cd $(SERVER_DIR) && go test -coverprofile=$(TMP_DIR)/coverage.out ## docker-build: Build docker image with the manager. .PHONY: docker-build diff --git a/README.md b/README.md index 3189e98..b941eba 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ ## 🧩 Awesome features -1. [OpenKF](https://https://github.com/OpenIMSDK/OpenKF) is an opensource customer service system based on [OpenIM](https://https://github.com/OpenIMSDK). +1. [OpenKF](https://github.com/OpenIMSDK/OpenKF) is an opensource customer service system based on [OpenIM](https://github.com/OpenIMSDK). 2. Support LLM(Local Knowledgebase) customer service. 3. Support multi-channel customer service, and easy to integrate with third-party systems. 4. Easy to deploy and secondary development. diff --git a/README_zh-CN.md b/README_zh-CN.md index 2ece7e0..3b211fd 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -30,7 +30,7 @@ ## 🧩 特性 -1. [OpenKF](https://https://github.com/OpenIMSDK/OpenKF) 是基于 [OpenIM](https://https://github.com/OpenIMSDK) 的开源客服系统。 +1. [OpenKF](https://github.com/OpenIMSDK/OpenKF) 是基于 [OpenIM](https://github.com/OpenIMSDK) 的开源客服系统。 2. 支持 LLM(本地知识库)客服。 3. 支持多渠道客服,并易于与第三方系统集成。 4. 易于部署和二次开发。 diff --git a/server/cmd/genhooks/pkg/gen.go b/server/cmd/genhooks/pkg/gen.go index d1202be..0212c6f 100644 --- a/server/cmd/genhooks/pkg/gen.go +++ b/server/cmd/genhooks/pkg/gen.go @@ -23,6 +23,7 @@ import ( "strings" ) +// HookGenerator is a generator for hooks type HookGenerator struct { buf *bytes.Buffer config *config @@ -34,6 +35,7 @@ type config struct { UrlPattern string } +// NewHookGenerator returns a new HookGenerator func NewHookGenerator(hookName, urlPattern, savePath string) *HookGenerator { return &HookGenerator{ buf: bytes.NewBuffer(nil), @@ -45,6 +47,7 @@ func NewHookGenerator(hookName, urlPattern, savePath string) *HookGenerator { } } +// Generate init the hook func (g *HookGenerator) Generate() *HookGenerator { if err := hookTemplate.Execute(g.buf, g.config); err != nil { panic(err) @@ -53,6 +56,7 @@ func (g *HookGenerator) Generate() *HookGenerator { return g } +// Format format the generated code func (g *HookGenerator) Format() *HookGenerator { formatOut, err := format.Source(g.buf.Bytes()) if err != nil { @@ -63,6 +67,7 @@ func (g *HookGenerator) Format() *HookGenerator { return g } +// Flush write the generated code to file func (g *HookGenerator) Flush() { filename := fmt.Sprintf("gen_%s_hook.go", strings.ToLower(g.config.HookName)) if err := ioutil.WriteFile( diff --git a/server/go.mod b/server/go.mod index a145186..ebcd2b5 100644 --- a/server/go.mod +++ b/server/go.mod @@ -42,7 +42,7 @@ require ( github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gookit/color v1.5.2 // indirect + github.com/gookit/color v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.3.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect @@ -64,9 +64,11 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/muesli/reflow v0.3.0 // indirect + github.com/onsi/gomega v1.27.6 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.5.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect @@ -79,6 +81,7 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.10.0 // indirect + golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect golang.org/x/net v0.11.0 // indirect golang.org/x/sys v0.9.0 // indirect golang.org/x/term v0.9.0 // indirect diff --git a/server/go.sum b/server/go.sum index 457a6d5..ad257ec 100644 --- a/server/go.sum +++ b/server/go.sum @@ -179,8 +179,9 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= +github.com/gookit/color v1.5.3 h1:twfIhZs4QLCtimkP7MOxlF3A0U/5cDPseRT9M/+2SCE= +github.com/gookit/color v1.5.3/go.mod h1:NUzwzeehUfl7GIb36pqId+UGmRfQcU/WiiyTTeNjHtE= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -257,7 +258,8 @@ github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKt github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -272,7 +274,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -352,8 +355,9 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea h1:vLCWI/yYrdEHyN2JzIzPO3aaQJHQdp89IZBA/+azVC4= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/server/internal/api/mail.go b/server/internal/api/mail.go index d5f886d..7297619 100644 --- a/server/internal/api/mail.go +++ b/server/internal/api/mail.go @@ -36,6 +36,7 @@ func SendCode(c *gin.Context) { err := c.ShouldBindJSON(¶ms) if err != nil { response.FailWithCode(common.INVALID_PARAMS, c) + return } @@ -44,6 +45,7 @@ func SendCode(c *gin.Context) { if err != nil { log.Debug("SendCode error: ", err) response.FailWithCode(common.ERROR, c) + return } diff --git a/server/internal/common/code.go b/server/internal/common/code.go index 7b3b8ca..056ab8b 100644 --- a/server/internal/common/code.go +++ b/server/internal/common/code.go @@ -14,6 +14,7 @@ package common +// Code. const ( SUCCESS = 200 ERROR = 500 diff --git a/server/internal/common/msg.go b/server/internal/common/msg.go index 0e1513b..d1f0d19 100644 --- a/server/internal/common/msg.go +++ b/server/internal/common/msg.go @@ -14,17 +14,19 @@ package common -var Msg = map[int]string{ +// msg is a mapping of message. +var msg = map[int]string{ SUCCESS: "success", ERROR: "error", INVALID_PARAMS: "request params error", } +// GetMsg get the message by code. func GetMsg(code int) string { - msg, ok := Msg[code] + m, ok := msg[code] if ok { - return msg + return m } - return Msg[ERROR] + return msg[ERROR] } diff --git a/server/internal/common/response/response.go b/server/internal/common/response/response.go index bcee84f..177429e 100644 --- a/server/internal/common/response/response.go +++ b/server/internal/common/response/response.go @@ -21,12 +21,14 @@ import ( "github.com/gin-gonic/gin" ) +// Response is a common struct for response type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data interface{} `json:"data"` } +// NewResponse returns a new Response func NewResponse(code int, msg string, data interface{}, c *gin.Context) { c.JSON(http.StatusOK, &Response{ Code: code, @@ -35,34 +37,42 @@ func NewResponse(code int, msg string, data interface{}, c *gin.Context) { }) } +// Success returns a success response func Success(c *gin.Context) { NewResponse(common.SUCCESS, common.GetMsg(common.SUCCESS), nil, c) } +// SuccessWithData returns a success response with data func SuccessWithData(data interface{}, c *gin.Context) { NewResponse(common.SUCCESS, common.GetMsg(common.SUCCESS), data, c) } +// SuccessWithCode returns a success response with code func SuccessWithCode(code int, c *gin.Context) { NewResponse(code, common.GetMsg(code), nil, c) } +// SuccessWithAll returns a success response with code and data func SuccessWithAll(code int, data interface{}, c *gin.Context) { NewResponse(code, common.GetMsg(code), data, c) } +// Fail returns a fail response func Fail(c *gin.Context) { NewResponse(common.ERROR, common.GetMsg(common.ERROR), nil, c) } +// FailWithData returns a fail response with data func FailWithData(data interface{}, c *gin.Context) { NewResponse(common.ERROR, common.GetMsg(common.ERROR), data, c) } +// FailWithCode returns a fail response with code func FailWithCode(code int, c *gin.Context) { NewResponse(code, common.GetMsg(code), nil, c) } +// FailWithAll returns a fail response with code and data func FailWithAll(code int, data interface{}, c *gin.Context) { NewResponse(code, common.GetMsg(code), data, c) } diff --git a/server/internal/config/config.go b/server/internal/config/config.go index f0b28c5..f4c647d 100644 --- a/server/internal/config/config.go +++ b/server/internal/config/config.go @@ -14,8 +14,10 @@ package config +// Config global config instance var Config *config +// ConfigInit init config func ConfigInit(configPath string) { // init viper initViper(configPath) @@ -81,23 +83,27 @@ type config struct { Email Email } +// App config type App struct { Version string `mapstructure:"version"` Debug bool `mapstructure:"debug"` LogFile string `mapstructure:"log_file"` } +// JWT config type JWT struct { Secret string `mapstructure:"secret"` Issuer string `mapstructure:"issuer"` ExpireDays int `mapstructure:"expire_days"` } +// Server config type Server struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` } +// Mysql config type Mysql struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` @@ -109,6 +115,7 @@ type Mysql struct { MaxIdleConns int `mapstructure:"max_idle_conns"` } +// Redis config type Redis struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` @@ -116,6 +123,7 @@ type Redis struct { Database int `mapstructure:"database"` } +// Minio config type Minio struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` @@ -126,6 +134,7 @@ type Minio struct { Location string `mapstructure:"location"` } +// Email config type Email struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` diff --git a/server/internal/config/viper.go b/server/internal/config/viper.go index b493889..679840c 100644 --- a/server/internal/config/viper.go +++ b/server/internal/config/viper.go @@ -32,36 +32,49 @@ func initViper(configPath string) { fmt.Println("Load ok") } -// get config +// GetInterface get interface config func GetInterface(key string) interface{} { return viper.Get(key) } + +// GetString get string config func GetString(key string) string { return viper.GetString(key) } + +// GetInt get int config func GetInt(key string) int { return viper.GetInt(key) } + +// GetBool get bool config func GetBool(key string) bool { return viper.GetBool(key) } -// get config or use default +// GetStringOrDefault get string config or use default func GetStringOrDefault(key string, defaultValue string) string { if viper.IsSet(key) { return viper.GetString(key) } + return defaultValue } + +// GetIntOrDefault get int config or use default func GetIntOrDefault(key string, defaultValue int) int { if viper.IsSet(key) { return viper.GetInt(key) } + return defaultValue } + +// GetBoolOrDefault get bool config or use default func GetBoolOrDefault(key string, defaultValue bool) bool { if viper.IsSet(key) { return viper.GetBool(key) } + return defaultValue } diff --git a/server/internal/conn/client/mail.go b/server/internal/conn/client/mail.go index 3981b04..f235fe0 100644 --- a/server/internal/conn/client/mail.go +++ b/server/internal/conn/client/mail.go @@ -25,6 +25,7 @@ import ( // todo: use email connection pool to reduce the cost of creating a connection // link: https://github.com/jordan-wright/email#a-pool-of-reusable-connections +// SendEmail send email func SendEmail(to string, subject string, body string) error { email := email.NewEmail() @@ -45,6 +46,7 @@ func SendEmail(to string, subject string, body string) error { return nil } +// SendHtmlEmail send html email func SendHtmlEmail(to string, subject string, html string) error { email := email.NewEmail() diff --git a/server/internal/conn/client/minio.go b/server/internal/conn/client/minio.go index b44dd6b..fdebc17 100644 --- a/server/internal/conn/client/minio.go +++ b/server/internal/conn/client/minio.go @@ -28,6 +28,7 @@ import ( var _minioClient *minio.Client var _bucket string +// InitMinio init minio client func InitMinio() { endpoint := fmt.Sprintf("%s:%d", config.Config.Minio.Ip, config.Config.Minio.Port) accessKeyID := config.Config.Minio.AccessKeyId @@ -36,7 +37,7 @@ func InitMinio() { _bucket = config.Config.Minio.Bucket // Initialize _minioClient - _minioClient, err := minio.New( + minioClient, err := minio.New( endpoint, &minio.Options{ Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), @@ -48,12 +49,12 @@ func InitMinio() { } // create bucket if not exists - exists, err := _minioClient.BucketExists(context.Background(), _bucket) + exists, err := minioClient.BucketExists(context.Background(), _bucket) if err != nil { log.Panicf("Minio", err.Error(), " Open Bucket failed ", endpoint) } if !exists { - if err = _minioClient.MakeBucket( + if err = minioClient.MakeBucket( context.Background(), _bucket, minio.MakeBucketOptions{Region: location, ObjectLocking: true}, @@ -61,14 +62,20 @@ func InitMinio() { log.Panicf("Minio", err.Error(), " Open failed ", endpoint) } } + + _minioClient = minioClient } +// PutObject put object to minio func PutObject(objectName string, r io.Reader, objectSize int64) error { _, err := _minioClient.PutObject(context.Background(), _bucket, objectName, r, objectSize, minio.PutObjectOptions{ContentType: "application/octet-stream"}) + return err } +// GetObject get object from minio func GetObject(objectName string) (io.Reader, error) { object, err := _minioClient.GetObject(context.Background(), _bucket, objectName, minio.GetObjectOptions{}) + return object, err } diff --git a/server/internal/conn/db/mysql.go b/server/internal/conn/db/mysql.go index 0e504c7..293ee9d 100644 --- a/server/internal/conn/db/mysql.go +++ b/server/internal/conn/db/mysql.go @@ -27,12 +27,14 @@ import ( var d *gorm.DB -type Writer struct{} +type writer struct{} -func (w Writer) Printf(format string, args ...interface{}) { +// Write implement log writer interface +func (w writer) Printf(format string, args ...interface{}) { fmt.Printf(format, args...) } +// InitMysqlDB init mysql connection. func InitMysqlDB() { // try to use default database [mysql] dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", @@ -71,7 +73,7 @@ func InitMysqlDB() { ) logger := logger.New( - Writer{}, + writer{}, logger.Config{ IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger Colorful: true, // Disable color @@ -103,21 +105,24 @@ func InitMysqlDB() { log.Info("Mysql", "connect ok", dsn) } -// get mysql connection. +// GetMysqlDB get mysql connection. func GetMysqlDB() *gorm.DB { return d } +// CloseMysqlDB close mysql connection. func CloseMysqlDB() { - if d != nil { - sqlDB, err := d.DB() + if d == nil { + return + } + + sqlDB, err := d.DB() + if err != nil { + log.Error("Mysql", err.Error(), " db.DB() failed ") + } else { + err = sqlDB.Close() if err != nil { - log.Error("Mysql", err.Error(), " db.DB() failed ") - } else { - err = sqlDB.Close() - if err != nil { - log.Error("Mysql", err.Error(), " sqlDB.Close() failed ") - } + log.Error("Mysql", err.Error(), " sqlDB.Close() failed ") } } } diff --git a/server/internal/conn/db/redis.go b/server/internal/conn/db/redis.go index a9a9623..24c845a 100644 --- a/server/internal/conn/db/redis.go +++ b/server/internal/conn/db/redis.go @@ -25,6 +25,7 @@ import ( var r *redis.Client +// InitRedisDB init redis client func InitRedisDB() { r = redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", config.Config.Redis.Ip, config.Config.Redis.Port), @@ -39,10 +40,12 @@ func InitRedisDB() { } } +// GetRedis get redis client instance func GetRedis() *redis.Client { return r } +// CloseRedis close redis client instance func CloseRedis() { if r != nil { err := r.Close() diff --git a/server/internal/middleware/cros.go b/server/internal/middleware/cros.go index 30a66eb..7be9008 100644 --- a/server/internal/middleware/cros.go +++ b/server/internal/middleware/cros.go @@ -20,6 +20,7 @@ import ( "github.com/gin-gonic/gin" ) +// EnableCROS enable cros func EnableCROS() gin.HandlerFunc { return func(c *gin.Context) { // c.Writer.Header().Set("Access-Control-Allow-Origin", "*") diff --git a/server/internal/middleware/hooks/global_hook.go b/server/internal/middleware/hooks/global_hook.go index b4b048b..13f18c9 100644 --- a/server/internal/middleware/hooks/global_hook.go +++ b/server/internal/middleware/hooks/global_hook.go @@ -27,19 +27,23 @@ func init() { fmt.Println("RegisterHook", "Register Hook[GlobalHook] success...") } +// GlobalHook implement urltrie.Hook type GlobalHook struct { urltrie.Hook } +// Pattern return pattern func (h GlobalHook) Pattern() string { return "/*" } +// BeforeRun do something before controller run func (h GlobalHook) BeforeRun(c *gin.Context) { log.Debugf("GlobalHook", "path: %v", c.Request.URL.Path) c.Next() } +// AfterRun do something after controller run func (h GlobalHook) AfterRun(c *gin.Context) { c.Next() } diff --git a/server/internal/middleware/hooks/init.go b/server/internal/middleware/hooks/init.go index 08b15ca..47caa85 100644 --- a/server/internal/middleware/hooks/init.go +++ b/server/internal/middleware/hooks/init.go @@ -14,6 +14,6 @@ package hooks -// Manual import hooks packages and do init +// InitHooks manual import hooks packages and do init func InitHooks() { } diff --git a/server/internal/middleware/hooks/mail_hook.go b/server/internal/middleware/hooks/mail_hook.go index b58bb3f..d1eaf0e 100644 --- a/server/internal/middleware/hooks/mail_hook.go +++ b/server/internal/middleware/hooks/mail_hook.go @@ -27,19 +27,23 @@ func init() { fmt.Println("RegisterHook", "Register Hook[MailHook] success...") } +// MailHook implement urltrie.Hook type MailHook struct { urltrie.Hook } +// Pattern return pattern func (h MailHook) Pattern() string { return "/api/v1/register/email/code" } +// BeforeRun do something before controller run func (h MailHook) BeforeRun(c *gin.Context) { log.Debugf("GlobalHook", "path: %v", c.Request.URL.Path) c.Next() } +// AfterRun do something after controller run func (h MailHook) AfterRun(c *gin.Context) { c.Next() } diff --git a/server/internal/middleware/hooks/url_trie/hook.go b/server/internal/middleware/hooks/url_trie/hook.go index 4c43595..1acd765 100644 --- a/server/internal/middleware/hooks/url_trie/hook.go +++ b/server/internal/middleware/hooks/url_trie/hook.go @@ -28,12 +28,12 @@ func init() { hookTrie = NewTrie() } -// Register url & hook to trie +// RegisterHook register url & hook to trie func RegisterHook(hook Hook) { hookTrie.Insert(hook.Pattern(), hook) } -// Enable hook for interceptor +// RunHook enable hook for interceptor func RunHook() gin.HandlerFunc { return func(c *gin.Context) { raw := c.Request.URL.Path @@ -48,6 +48,7 @@ func RunHook() gin.HandlerFunc { hooks, ok := hookTrie.Match(path) if !ok { c.Next() + return } diff --git a/server/internal/middleware/hooks/url_trie/trie.go b/server/internal/middleware/hooks/url_trie/trie.go index 1ffe9d5..cbae866 100644 --- a/server/internal/middleware/hooks/url_trie/trie.go +++ b/server/internal/middleware/hooks/url_trie/trie.go @@ -34,7 +34,7 @@ type Hook interface { AfterRun(c *gin.Context) } -const WILDCARD = "*" +const _wildcard = "*" type node struct { children map[string]*node @@ -46,10 +46,12 @@ type node struct { isEnd bool } +// Trie is a tree for url type Trie struct { root *node } +// NewTrie returns a new Trie func NewTrie() *Trie { return &Trie{ root: &node{ @@ -58,7 +60,7 @@ func NewTrie() *Trie { } } -// Insert url with hooks +// Insert insert url with hooks func (t *Trie) Insert(url string, hooks ...Hook) { current := t.root @@ -76,7 +78,7 @@ func (t *Trie) Insert(url string, hooks ...Hook) { data: part, } // match wildcard - if part == WILDCARD { + if part == _wildcard { child.isWildcard = true } @@ -92,7 +94,7 @@ func (t *Trie) Insert(url string, hooks ...Hook) { current.hooks = append(current.hooks, hooks...) } -// Match url with hooks +// Match match url with hooks func (t *Trie) Match(url string) ([]Hook, bool) { current := t.root @@ -110,36 +112,25 @@ func (t *Trie) Match(url string) ([]Hook, bool) { } if len(stack) == 0 { - if len(matchedValues) > 0 { - return matchedValues, true - } else { - return matchedValues, false - } + return matchedValues, len(matchedValues) > 0 } // get current level length levelLen := len(stack) for i := 0; i < levelLen; i++ { // pop - current = stack[0] - stack = stack[1:] + current, stack = stack[0], stack[1:] if current.isEnd { if current.isWildcard || current.data == part { // Match the last node, append the values matchedValues = append(matchedValues, current.hooks...) } - continue - } - // find wildcard node - if current.isWildcard { - for _, child := range current.children { - stack = append(stack, child) - } + continue } - // find expect node - if current.data == part { + // find wildcard node or expect node + if current.isWildcard || current.data == part { for _, child := range current.children { stack = append(stack, child) } @@ -147,9 +138,5 @@ func (t *Trie) Match(url string) ([]Hook, bool) { } } - if len(matchedValues) > 0 { - return matchedValues, true - } else { - return matchedValues, false - } + return matchedValues, len(matchedValues) > 0 } diff --git a/server/internal/middleware/jwt.go b/server/internal/middleware/jwt.go index 8c8d7c1..bf8d44f 100644 --- a/server/internal/middleware/jwt.go +++ b/server/internal/middleware/jwt.go @@ -22,17 +22,20 @@ import ( "github.com/gin-gonic/gin" ) +// EnableAuth enable auth middleware func EnableAuth() gin.HandlerFunc { return func(c *gin.Context) { token := c.GetHeader("Authorization") if token == "" || strings.Fields(token)[0] != "Bearer" { c.AbortWithStatus(http.StatusUnauthorized) + return } _, err := utils.ParseJwtToken(token) if err != nil { c.AbortWithStatus(http.StatusUnauthorized) + return } diff --git a/server/internal/models/base.go b/server/internal/models/base.go index 9b7ac7f..62b6e8a 100644 --- a/server/internal/models/base.go +++ b/server/internal/models/base.go @@ -16,6 +16,7 @@ package models import "time" +// Model base model type Model struct { ID uint `gorm:"primary_key" json:"id"` CreatedAt time.Time `json:"created_at"` diff --git a/server/internal/models/user.go b/server/internal/models/user.go index f7351f2..a51f12f 100644 --- a/server/internal/models/user.go +++ b/server/internal/models/user.go @@ -14,6 +14,7 @@ package models +// User user model type User struct { Model Username string `json:"username" gorm:"type:varchar(20);not null;unique"` diff --git a/server/internal/param/mail.go b/server/internal/param/mail.go index bb2a95a..f8ce5c9 100644 --- a/server/internal/param/mail.go +++ b/server/internal/param/mail.go @@ -14,6 +14,7 @@ package param +// SendToParams register params for email. type SendToParams struct { Email string `json:"email" binding:"required"` } diff --git a/server/internal/router/router.go b/server/internal/router/router.go index ea88b3e..fe54b4f 100644 --- a/server/internal/router/router.go +++ b/server/internal/router/router.go @@ -15,7 +15,7 @@ package router import ( - _ "github.com/OpenIMSDK/OpenKF/server/docs" + _ "github.com/OpenIMSDK/OpenKF/server/docs" //nolint:golint swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" @@ -26,6 +26,7 @@ import ( "github.com/gin-gonic/gin" ) +// InitRouter init router func InitRouter() *gin.Engine { if config.GetString("app.debug") == "true" { gin.SetMode(gin.DebugMode) diff --git a/server/internal/service/init.go b/server/internal/service/init.go index f65c6ee..eaa42c9 100644 --- a/server/internal/service/init.go +++ b/server/internal/service/init.go @@ -23,6 +23,7 @@ import ( "gorm.io/gorm" ) +// Service service type Service struct { // Context Ctx context.Context @@ -32,6 +33,7 @@ type Service struct { Cache *redis.Client } +// NewService return new service with context func NewService() *Service { return &Service{ Ctx: context.Background(), @@ -40,6 +42,7 @@ func NewService() *Service { } } +// NewServiceWithGin return new service with gin context func NewServiceWithGin(c *gin.Context) *Service { return &Service{ Ctx: c.Request.Context(), diff --git a/server/internal/service/mail.go b/server/internal/service/mail.go index 15dfafc..866dd37 100644 --- a/server/internal/service/mail.go +++ b/server/internal/service/mail.go @@ -22,6 +22,7 @@ import ( "github.com/OpenIMSDK/OpenKF/server/pkg/log" ) +// SendCode send code to email func (svc *Service) SendCode(email string) (err error) { // check the code is exist cmd := svc.Cache.Get(svc.Ctx, "code:"+email) @@ -41,6 +42,7 @@ func (svc *Service) SendCode(email string) (err error) { return err } +// Test test func (svc *Service) Test() { log.Info("test...") } diff --git a/server/pkg/log/fileline_hook.go b/server/pkg/log/fileline_hook.go index b352686..2d71940 100644 --- a/server/pkg/log/fileline_hook.go +++ b/server/pkg/log/fileline_hook.go @@ -40,5 +40,6 @@ func (hook *filelineHook) Fire(entry *logrus.Entry) error { s = i[len(i)-3] + i[len(i)-2] + i[len(i)-1] + ":" + utils.IntToString(line) } entry.Data["FilePath"] = s + return nil } diff --git a/server/pkg/log/logrus.go b/server/pkg/log/logrus.go index 144c96a..0114e7c 100644 --- a/server/pkg/log/logrus.go +++ b/server/pkg/log/logrus.go @@ -29,6 +29,7 @@ import ( var _logger *logrus.Logger +// InitLogger init logger func InitLogger() { _logger = loggerInit() } @@ -69,12 +70,13 @@ func loggerInit() *logrus.Logger { return logger } +// NewLfsHook add fileline hook func NewLfsHook(rotationTime time.Duration, maxRemainNum uint) logrus.Hook { lfsHook := lfshook.NewHook(lfshook.WriterMap{ - logrus.DebugLevel: initRotateLogs(rotationTime, maxRemainNum, "all"), - logrus.InfoLevel: initRotateLogs(rotationTime, maxRemainNum, "all"), - logrus.WarnLevel: initRotateLogs(rotationTime, maxRemainNum, "all"), - logrus.ErrorLevel: initRotateLogs(rotationTime, maxRemainNum, "all"), + logrus.DebugLevel: initRotateLogs(rotationTime, maxRemainNum), + logrus.InfoLevel: initRotateLogs(rotationTime, maxRemainNum), + logrus.WarnLevel: initRotateLogs(rotationTime, maxRemainNum), + logrus.ErrorLevel: initRotateLogs(rotationTime, maxRemainNum), }, &nested.Formatter{ TimestampFormat: "2006-01-02 15:04:05.000", HideKeys: false, @@ -84,9 +86,9 @@ func NewLfsHook(rotationTime time.Duration, maxRemainNum uint) logrus.Hook { return lfsHook } -func initRotateLogs(rotationTime time.Duration, maxRemainNum uint, level string) *rotatelogs.RotateLogs { +func initRotateLogs(rotationTime time.Duration, maxRemainNum uint) *rotatelogs.RotateLogs { writer, err := rotatelogs.New( - config.Config.App.LogFile+level+".%Y%m%d%H%M", + config.Config.App.LogFile+".%Y%m%d%H%M", rotatelogs.WithRotationTime(rotationTime), rotatelogs.WithRotationCount(maxRemainNum), ) @@ -97,52 +99,61 @@ func initRotateLogs(rotationTime time.Duration, maxRemainNum uint, level string) } } +// GetLogger get logger instance func GetLogger() *logrus.Logger { return _logger } +// Info log info func Info(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Infoln(args...) } +// Error log error func Error(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Errorln(args...) } +// Debug log debug func Debug(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Debugln(args...) } +// Panic log panic func Panic(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Panicln(args...) } +// Infof log info with format func Infof(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Infof(format, args...) } +// Errorf log error with format func Errorf(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Errorf(format, args...) } +// Debugf log debug with format func Debugf(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Debugf(format, args...) } +// Panicf log panic with format func Panicf(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, diff --git a/server/pkg/server/server.go b/server/pkg/server/server.go index 6952198..6ecf21e 100644 --- a/server/pkg/server/server.go +++ b/server/pkg/server/server.go @@ -21,10 +21,12 @@ import ( "github.com/gin-gonic/gin" ) +// Server server interface type Server interface { ListenAndServe() error } +// InitServer init server func InitServer(address string, r *gin.Engine) Server { server := endless.NewServer(address, r)