linter fixes

This commit is contained in:
Pavel 2024-06-14 18:10:48 +03:00
parent 983dbe7229
commit 90e9de051a
49 changed files with 251 additions and 199 deletions

View File

@ -32,8 +32,7 @@ func main() {
if _, err := parser.Parse(); err != nil { if _, err := parser.Parse(); err != nil {
if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp { // nolint:errorlint if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp { // nolint:errorlint
os.Exit(0) os.Exit(0)
} else {
os.Exit(1)
} }
os.Exit(1)
} }
} }

View File

@ -1,7 +1,7 @@
package config package config
import ( import (
"io/ioutil" "os"
"path/filepath" "path/filepath"
"time" "time"
@ -132,7 +132,7 @@ func (c *Config) GetConfigData(path string) []byte {
panic(err) panic(err)
} }
source, err := ioutil.ReadFile(path) source, err := os.ReadFile(path)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -1,7 +1,6 @@
package config package config
import ( import (
"io/ioutil"
"os" "os"
"path" "path"
"testing" "testing"
@ -54,7 +53,7 @@ config_aws:
bucket: bucket bucket: bucket
folder_name: folder folder_name: folder
content_type: image/jpeg`) content_type: image/jpeg`)
err := ioutil.WriteFile(testConfigFile, c.data, os.ModePerm) err := os.WriteFile(testConfigFile, c.data, os.ModePerm)
require.Nil(c.T(), err) require.Nil(c.T(), err)
c.config = NewConfig(testConfigFile) c.config = NewConfig(testConfigFile)

View File

@ -51,7 +51,7 @@ func (x *NewMigrationCommand) FileExists(filename string) bool {
} }
// Execute migration generator command. // Execute migration generator command.
func (x *NewMigrationCommand) Execute(args []string) error { func (x *NewMigrationCommand) Execute(_ []string) error {
tpl, err := template.New("migration").Parse(migrationTemplate) tpl, err := template.New("migration").Parse(migrationTemplate)
if err != nil { if err != nil {
return fmt.Errorf("fatal: cannot parse base migration template: %w", err) return fmt.Errorf("fatal: cannot parse base migration template: %w", err)

View File

@ -2,7 +2,6 @@ package db
import ( import (
"fmt" "fmt"
"io/ioutil"
"log" "log"
"math/rand" "math/rand"
"os" "os"
@ -36,7 +35,7 @@ func (s *MigrationGeneratorSuite) Test_FileExists() {
func (s *MigrationGeneratorSuite) Test_Execute() { func (s *MigrationGeneratorSuite) Test_Execute() {
found := false found := false
assert.NoError(s.T(), s.command.Execute([]string{})) assert.NoError(s.T(), s.command.Execute([]string{}))
files, err := ioutil.ReadDir(s.command.Directory) files, err := os.ReadDir(s.command.Directory)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -14,11 +14,14 @@ type User struct {
// TableName will return table name for User // TableName will return table name for User
// It will not work if User is not embedded, but mapped as another type // It will not work if User is not embedded, but mapped as another type
// type MyUser User // will not work //
// type MyUser User // will not work
//
// but // but
// type MyUser struct { // will work //
// User // type MyUser struct { // will work
// } // User
// }
func (User) TableName() string { func (User) TableName() string {
return "mg_user" return "mg_user"
} }

View File

@ -2,6 +2,7 @@
Package core provides different functions like error-reporting, logging, localization, etc. Package core provides different functions like error-reporting, logging, localization, etc.
to make it easier to create transports. to make it easier to create transports.
Usage: Usage:
package main package main
import ( import (
@ -36,14 +37,19 @@ Usage:
} }
} }
Resource embedding # Resource embedding
packr can be used to provide resource embedding, see: packr can be used to provide resource embedding, see:
https://github.com/gobuffalo/packr/tree/master/v2 https://github.com/gobuffalo/packr/tree/master/v2
In order to use packr you must follow instruction, and provide boxes with templates, translations and assets to library. In order to use packr you must follow instruction, and provide boxes with templates, translations and assets to library.
You can find instruction here: You can find instruction here:
https://github.com/gobuffalo/packr/tree/master/v2#library-installation https://github.com/gobuffalo/packr/tree/master/v2#library-installation
Example of usage: Example of usage:
package main package main
import ( import (
@ -104,10 +110,12 @@ Example of usage:
} }
} }
Migration generator # Migration generator
This library contains helper tool for transports. You can install it via go: This library contains helper tool for transports. You can install it via go:
$ go get -u github.com/retailcrm/mg-transport-core/cmd/transport-core-tool $ go get -u github.com/retailcrm/mg-transport-core/cmd/transport-core-tool
Currently, it only can generate new migrations for your transport. Currently, it only can generate new migrations for your transport.
Copyright (c) 2019 RetailDriver LLC. Usage of this source code is governed by a MIT license. Copyright (c) 2019 RetailDriver LLC. Usage of this source code is governed by a MIT license.

View File

@ -2,7 +2,7 @@ package core
import ( import (
"encoding/json" "encoding/json"
"io/ioutil" "io"
"net/http" "net/http"
) )
@ -40,7 +40,7 @@ func getDomainsByStore(store string) []Domain {
return nil return nil
} }
respBody, readErr := ioutil.ReadAll(resp.Body) respBody, readErr := io.ReadAll(resp.Body)
if readErr != nil { if readErr != nil {
return nil return nil

View File

@ -7,6 +7,7 @@ import (
"io/fs" "io/fs"
"net/http" "net/http"
"sync" "sync"
"time"
"github.com/blacked/go-zabbix" "github.com/blacked/go-zabbix"
"github.com/getsentry/sentry-go" "github.com/getsentry/sentry-go"
@ -26,12 +27,14 @@ import (
"github.com/retailcrm/mg-transport-core/v2/core/logger" "github.com/retailcrm/mg-transport-core/v2/core/logger"
) )
const DefaultHTTPClientTimeout time.Duration = 30
var boolTrue = true var boolTrue = true
// DefaultHTTPClientConfig is a default config for HTTP client. It will be used by Engine for building HTTP client // DefaultHTTPClientConfig is a default config for HTTP client. It will be used by Engine for building HTTP client
// if HTTP client config is not present in the configuration. // if HTTP client config is not present in the configuration.
var DefaultHTTPClientConfig = &config.HTTPClientConfig{ var DefaultHTTPClientConfig = &config.HTTPClientConfig{
Timeout: 30, Timeout: DefaultHTTPClientTimeout,
SSLVerification: &boolTrue, SSLVerification: &boolTrue,
} }
@ -279,10 +282,9 @@ func (e *Engine) BuildHTTPClient(certs *x509.CertPool, replaceDefault ...bool) *
if err != nil { if err != nil {
panic(err) panic(err)
} else {
e.httpClient = client
} }
e.httpClient = client
return e return e
} }

View File

@ -6,7 +6,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"html/template" "html/template"
"io/ioutil" "io"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -365,7 +365,7 @@ func (e *EngineTest) Test_GetCSRFToken() {
URL: &url.URL{ URL: &url.URL{
RawQuery: "", RawQuery: "",
}, },
Body: ioutil.NopCloser(bytes.NewReader([]byte{})), Body: io.NopCloser(bytes.NewReader([]byte{})),
Header: http.Header{"X-CSRF-Token": []string{"token"}}, Header: http.Header{"X-CSRF-Token": []string{"token"}},
}} }}
c.Set("csrf_token", "token") c.Set("csrf_token", "token")

View File

@ -10,7 +10,7 @@ import (
const DefaultResetPeriod = time.Minute * 15 const DefaultResetPeriod = time.Minute * 15
// AtomicCounter is a default Counter implementation. // AtomicCounter is a default Counter implementation.
// It uses atomics under the hood (hence the name) and can be configured with custom reset timeout and // It uses atomics under the hood (hence the name) and can be configured with custom reset timeout and.
type AtomicCounter struct { type AtomicCounter struct {
name atomic.String name atomic.String
msg atomic.String msg atomic.String

View File

@ -1,7 +1,7 @@
package healthcheck package healthcheck
var ( var (
// compile-time checks to ensure that implementations are compatible with the interface // compile-time checks to ensure that implementations are compatible with the interface.
_ = Storage(&SyncMapStorage{}) _ = Storage(&SyncMapStorage{})
_ = Counter(&AtomicCounter{}) _ = Counter(&AtomicCounter{})
_ = Processor(CounterProcessor{}) _ = Processor(CounterProcessor{})

View File

@ -44,7 +44,7 @@ type callbackLogger struct {
fn callbackLoggerFunc fn callbackLoggerFunc
} }
func (n *callbackLogger) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { func (n *callbackLogger) Check(_ zapcore.Level, _ string) *zapcore.CheckedEntry {
return &zapcore.CheckedEntry{} return &zapcore.CheckedEntry{}
} }
@ -75,7 +75,7 @@ func (n *callbackLogger) cloneWithFields(fields []zap.Field) *callbackLogger {
cl.fields = fields cl.fields = fields
return cl return cl
} }
cl.fields = append(existing, fields...) cl.fields = append(existing, fields...) // nolint:gocritic
return cl return cl
} }
@ -91,19 +91,19 @@ func (n *callbackLogger) WithLazy(args ...zap.Field) logger.Logger {
return n.cloneWithFields(args) return n.cloneWithFields(args)
} }
func (n *callbackLogger) WithGroup(name string) logger.Logger { func (n *callbackLogger) WithGroup(_ string) logger.Logger {
return n return n
} }
func (n *callbackLogger) ForHandler(handler any) logger.Logger { func (n *callbackLogger) ForHandler(_ any) logger.Logger {
return n return n
} }
func (n *callbackLogger) ForConnection(conn any) logger.Logger { func (n *callbackLogger) ForConnection(_ any) logger.Logger {
return n return n
} }
func (n *callbackLogger) ForAccount(acc any) logger.Logger { func (n *callbackLogger) ForAccount(_ any) logger.Logger {
return n return n
} }
@ -288,11 +288,11 @@ func (t *JobTest) oncePanicJob() {
} }
func (t *JobTest) regularJob() { func (t *JobTest) regularJob() {
rand.Seed(time.Now().UnixNano()) r := rand.New(rand.NewSource(time.Now().UnixNano())) // nolint:gosec
t.job = &Job{ t.job = &Job{
Command: func(log logger.Logger) error { Command: func(log logger.Logger) error {
t.executedChan <- true t.executedChan <- true
t.randomNumber <- rand.Int() // nolint:gosec t.randomNumber <- r.Int() // nolint:gosec
return nil return nil
}, },
ErrorHandler: t.testErrorHandler(), ErrorHandler: t.testErrorHandler(),
@ -303,7 +303,6 @@ func (t *JobTest) regularJob() {
} }
func (t *JobTest) regularSyncJob() { func (t *JobTest) regularSyncJob() {
rand.Seed(time.Now().UnixNano())
t.job = &Job{ t.job = &Job{
Command: func(log logger.Logger) error { Command: func(log logger.Logger) error {
t.syncBool = true t.syncBool = true

View File

@ -3,7 +3,7 @@ package core
import ( import (
"html/template" "html/template"
"io/fs" "io/fs"
"io/ioutil" "os"
"path" "path"
"sync" "sync"
@ -90,7 +90,8 @@ type CloneableLocalizer interface {
// NewLocalizer returns localizer instance with specified parameters. // NewLocalizer returns localizer instance with specified parameters.
// Usage: // Usage:
// NewLocalizer(language.English, DefaultLocalizerMatcher(), "translations") //
// NewLocalizer(language.English, DefaultLocalizerMatcher(), "translations")
func NewLocalizer(locale language.Tag, matcher language.Matcher, translationsPath string) LocalizerInterface { func NewLocalizer(locale language.Tag, matcher language.Matcher, translationsPath string) LocalizerInterface {
localizer := &Localizer{ localizer := &Localizer{
i18nStorage: &sync.Map{}, i18nStorage: &sync.Map{},
@ -106,7 +107,9 @@ func NewLocalizer(locale language.Tag, matcher language.Matcher, translationsPat
// NewLocalizerFS returns localizer instance with specified parameters. // NewLocalizerFS returns localizer instance with specified parameters.
// Usage: // Usage:
// NewLocalizerFS(language.English, DefaultLocalizerMatcher(), translationsFS) //
// NewLocalizerFS(language.English, DefaultLocalizerMatcher(), translationsFS)
//
// TODO This code should be covered with tests. // TODO This code should be covered with tests.
func NewLocalizerFS( func NewLocalizerFS(
locale language.Tag, matcher language.Matcher, translationsFS fs.FS, locale language.Tag, matcher language.Matcher, translationsFS fs.FS,
@ -161,9 +164,10 @@ func (l *Localizer) Clone() CloneableLocalizer {
// Because of that all Localizer instances from this middleware will share *same* mutex. This mutex is used to wrap // Because of that all Localizer instances from this middleware will share *same* mutex. This mutex is used to wrap
// i18n.Bundle methods (those aren't goroutine-safe to use). // i18n.Bundle methods (those aren't goroutine-safe to use).
// Usage: // Usage:
// engine := gin.New() //
// localizer := NewLocalizer("en", DefaultLocalizerMatcher(), "translations") // engine := gin.New()
// engine.Use(localizer.LocalizationMiddleware()) // localizer := NewLocalizer("en", DefaultLocalizerMatcher(), "translations")
// engine.Use(localizer.LocalizationMiddleware())
func (l *Localizer) LocalizationMiddleware() gin.HandlerFunc { func (l *Localizer) LocalizationMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
clone := l.Clone().(LocaleControls) clone := l.Clone().(LocaleControls)
@ -174,15 +178,21 @@ func (l *Localizer) LocalizationMiddleware() gin.HandlerFunc {
// LocalizationFuncMap returns template.FuncMap (html template is used) with one method - trans // LocalizationFuncMap returns template.FuncMap (html template is used) with one method - trans
// Usage in code: // Usage in code:
// engine := gin.New() //
// engine.FuncMap = localizer.LocalizationFuncMap() // engine := gin.New()
// engine.FuncMap = localizer.LocalizationFuncMap()
//
// or (with multitemplate) // or (with multitemplate)
// renderer := multitemplate.NewRenderer() //
// funcMap := localizer.LocalizationFuncMap() // renderer := multitemplate.NewRenderer()
// renderer.AddFromFilesFuncs("index", funcMap, "template/index.html") // funcMap := localizer.LocalizationFuncMap()
// renderer.AddFromFilesFuncs("index", funcMap, "template/index.html")
//
// funcMap must be passed for every .AddFromFilesFuncs call // funcMap must be passed for every .AddFromFilesFuncs call
// Usage in templates: // Usage in templates:
// <p class="info">{{"need_login_msg" | trans}} //
// <p class="info">{{"need_login_msg" | trans}}
//
// You can borrow FuncMap from this method and add your functions to it. // You can borrow FuncMap from this method and add your functions to it.
func (l *Localizer) LocalizationFuncMap() template.FuncMap { func (l *Localizer) LocalizationFuncMap() template.FuncMap {
return template.FuncMap{ return template.FuncMap{
@ -196,7 +206,7 @@ func (l *Localizer) LocalizationFuncMap() template.FuncMap {
parts = append(parts, "") parts = append(parts, "")
} }
partsMap := make(map[string]interface{}, len(parts)/2) partsMap := make(map[string]interface{}, len(parts)/2) // nolint:gomnd
for i := 0; i < len(parts)-1; i += 2 { for i := 0; i < len(parts)-1; i += 2 {
partsMap[parts[i]] = parts[i+1] partsMap[parts[i]] = parts[i+1]
@ -239,7 +249,7 @@ func (l *Localizer) loadTranslationsToBundle(i18nBundle *i18n.Bundle) {
// LoadTranslations will load all translation files from translations directory. // LoadTranslations will load all translation files from translations directory.
func (l *Localizer) loadFromDirectory(i18nBundle *i18n.Bundle) error { func (l *Localizer) loadFromDirectory(i18nBundle *i18n.Bundle) error {
files, err := ioutil.ReadDir(l.TranslationsPath) files, err := os.ReadDir(l.TranslationsPath)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,7 +1,6 @@
package core package core
import ( import (
"io/ioutil"
"math/rand" "math/rand"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@ -40,7 +39,7 @@ func createTestLangFiles(t *testing.T) {
} }
if _, err := os.Stat(fileName); err != nil && os.IsNotExist(err) { if _, err := os.Stat(fileName); err != nil && os.IsNotExist(err) {
err = ioutil.WriteFile(fileName, data, os.ModePerm) err = os.WriteFile(fileName, data, os.ModePerm)
require.Nil(t, err) require.Nil(t, err)
} }
} }
@ -103,7 +102,7 @@ func (l *LocalizerTest) Test_LocalizationMiddleware_Context() {
func (l *LocalizerTest) Test_LocalizationMiddleware_Httptest() { func (l *LocalizerTest) Test_LocalizationMiddleware_Httptest() {
var wg sync.WaitGroup var wg sync.WaitGroup
rand.Seed(time.Now().UnixNano()) r := rand.New(rand.NewSource(time.Now().UnixNano())) // nolint:gosec
l.localizer.Preload(DefaultLanguages) l.localizer.Preload(DefaultLanguages)
langMsgMap := map[language.Tag]string{ langMsgMap := map[language.Tag]string{
language.English: "Test message", language.English: "Test message",
@ -122,7 +121,7 @@ func (l *LocalizerTest) Test_LocalizationMiddleware_Httptest() {
wg.Add(1) wg.Add(1)
go func(m map[language.Tag]string, wg *sync.WaitGroup) { go func(m map[language.Tag]string, wg *sync.WaitGroup) {
var tag language.Tag var tag language.Tag
switch rand.Intn(3-1) + 1 { // nolint:gosec switch r.Intn(3-1) + 1 { // nolint:gosec
case 1: case 1:
tag = language.English tag = language.English
case 2: case 2:

View File

@ -2,6 +2,7 @@ package logger
import ( import (
"fmt" "fmt"
"go.uber.org/zap" "go.uber.org/zap"
retailcrm "github.com/retailcrm/api-client-go/v2" retailcrm "github.com/retailcrm/api-client-go/v2"

View File

@ -1,12 +1,13 @@
package logger package logger
import ( import (
"net/http"
"testing"
"github.com/h2non/gock" "github.com/h2non/gock"
retailcrm "github.com/retailcrm/api-client-go/v2" retailcrm "github.com/retailcrm/api-client-go/v2"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"net/http"
"testing"
) )
func TestAPIClientAdapter(t *testing.T) { func TestAPIClientAdapter(t *testing.T) {

View File

@ -2,10 +2,11 @@ package logger
import ( import (
"fmt" "fmt"
json "github.com/goccy/go-json"
"io" "io"
"net/http" "net/http"
json "github.com/goccy/go-json"
"go.uber.org/zap" "go.uber.org/zap"
) )

View File

@ -4,11 +4,12 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"io" "io"
"net/http" "net/http"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
) )
func TestErr(t *testing.T) { func TestErr(t *testing.T) {

View File

@ -4,11 +4,12 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"encoding/json" "encoding/json"
"github.com/guregu/null/v5"
"io" "io"
"os" "os"
"sync" "sync"
"github.com/guregu/null/v5"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
) )

View File

@ -27,7 +27,8 @@ type Logger interface {
Warn(msg string, fields ...zap.Field) Warn(msg string, fields ...zap.Field)
// Error logs an error-level message with the given fields. // Error logs an error-level message with the given fields.
Error(msg string, fields ...zap.Field) Error(msg string, fields ...zap.Field)
// DPanic logs a debug-panic-level message with the given fields and panics if the logger's panic level is set to a non-zero value. // DPanic logs a debug-panic-level message with the given fields and panics
// if the logger's panic level is set to a non-zero value.
DPanic(msg string, fields ...zap.Field) DPanic(msg string, fields ...zap.Field)
// Panic logs a panic-level message with the given fields and panics immediately. // Panic logs a panic-level message with the given fields and panics immediately.
Panic(msg string, fields ...zap.Field) Panic(msg string, fields ...zap.Field)

View File

@ -1,11 +1,12 @@
package logger package logger
import ( import (
"testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"go.uber.org/zap" "go.uber.org/zap"
"testing"
) )
type TestDefaultSuite struct { type TestDefaultSuite struct {

View File

@ -1,12 +1,13 @@
package logger package logger
import ( import (
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestGinMiddleware(t *testing.T) { func TestGinMiddleware(t *testing.T) {

View File

@ -18,19 +18,21 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
// nolint
package logger package logger
import ( import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"io" "io"
"math" "math"
"time" "time"
"unicode/utf8" "unicode/utf8"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/buffer" "go.uber.org/zap/buffer"
) )

View File

@ -2,8 +2,10 @@ package logger
import ( import (
"fmt" "fmt"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
"go.uber.org/zap" "go.uber.org/zap"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
) )
const ( const (
@ -36,10 +38,10 @@ func (m *mgTransportClientAdapter) Debugf(msg string, args ...interface{}) {
if len(args) > 1 { if len(args) > 1 {
uri = fmt.Sprint(args[1]) uri = fmt.Sprint(args[1])
} }
if len(args) > 2 { if len(args) > 2 { // nolint:gomnd
token = fmt.Sprint(args[2]) token = fmt.Sprint(args[2])
} }
if len(args) > 3 { if len(args) > 3 { // nolint:gomnd
body = args[3] body = args[3]
} }
m.log.Debug("MG TRANSPORT API Request", m.log.Debug("MG TRANSPORT API Request",

View File

@ -1,12 +1,14 @@
package logger package logger
import ( import (
"github.com/h2non/gock"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/http" "net/http"
"testing" "testing"
"github.com/h2non/gock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
) )
func TestMGTransportClientAdapter(t *testing.T) { func TestMGTransportClientAdapter(t *testing.T) {

View File

@ -13,11 +13,11 @@ func NewNil() Logger {
return &Nil{} return &Nil{}
} }
func (l *Nil) With(fields ...zap.Field) Logger { func (l *Nil) With(_ ...zap.Field) Logger {
return l return l
} }
func (l *Nil) WithLazy(fields ...zap.Field) Logger { func (l *Nil) WithLazy(_ ...zap.Field) Logger {
return l return l
} }
@ -25,35 +25,35 @@ func (l *Nil) Level() zapcore.Level {
return zapcore.DebugLevel return zapcore.DebugLevel
} }
func (l *Nil) Check(lvl zapcore.Level, msg string) *zapcore.CheckedEntry { func (l *Nil) Check(_ zapcore.Level, _ string) *zapcore.CheckedEntry {
return &zapcore.CheckedEntry{} return &zapcore.CheckedEntry{}
} }
func (l *Nil) Log(lvl zapcore.Level, msg string, fields ...zap.Field) {} func (l *Nil) Log(_ zapcore.Level, _ string, _ ...zap.Field) {}
func (l *Nil) Debug(msg string, fields ...zap.Field) {} func (l *Nil) Debug(_ string, _ ...zap.Field) {}
func (l *Nil) Info(msg string, fields ...zap.Field) {} func (l *Nil) Info(_ string, _ ...zap.Field) {}
func (l *Nil) Warn(msg string, fields ...zap.Field) {} func (l *Nil) Warn(_ string, _ ...zap.Field) {}
func (l *Nil) Error(msg string, fields ...zap.Field) {} func (l *Nil) Error(_ string, _ ...zap.Field) {}
func (l *Nil) DPanic(msg string, fields ...zap.Field) {} func (l *Nil) DPanic(_ string, _ ...zap.Field) {}
func (l *Nil) Panic(msg string, fields ...zap.Field) {} func (l *Nil) Panic(_ string, _ ...zap.Field) {}
func (l *Nil) Fatal(msg string, fields ...zap.Field) {} func (l *Nil) Fatal(_ string, _ ...zap.Field) {}
func (l *Nil) ForHandler(handler any) Logger { func (l *Nil) ForHandler(_ any) Logger {
return l return l
} }
func (l *Nil) ForConnection(conn any) Logger { func (l *Nil) ForConnection(_ any) Logger {
return l return l
} }
func (l *Nil) ForAccount(acc any) Logger { func (l *Nil) ForAccount(_ any) Logger {
return l return l
} }

View File

@ -1,8 +1,9 @@
package logger package logger
import ( import (
"github.com/stretchr/testify/assert"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
func TestPool(t *testing.T) { func TestPool(t *testing.T) {

View File

@ -1,10 +1,11 @@
package logger package logger
import ( import (
"testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/zap" "go.uber.org/zap"
"testing"
) )
func TestWriterAdapter(t *testing.T) { func TestWriterAdapter(t *testing.T) {

View File

@ -2,9 +2,10 @@ package logger
import ( import (
"errors" "errors"
"testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing"
) )
func TestZabbixCollectorAdapter(t *testing.T) { func TestZabbixCollectorAdapter(t *testing.T) {

View File

@ -6,7 +6,6 @@ import (
"crypto/sha1" "crypto/sha1"
"encoding/base64" "encoding/base64"
"io" "io"
"io/ioutil"
"math/rand" "math/rand"
"time" "time"
@ -57,10 +56,10 @@ var DefaultCSRFTokenGetter = func(c *gin.Context) string {
} else if t := r.Header.Get("X-XSRF-Token"); len(t) > 0 { } else if t := r.Header.Get("X-XSRF-Token"); len(t) > 0 {
return t return t
} else if c.Request.Body != nil { } else if c.Request.Body != nil {
data, _ := ioutil.ReadAll(c.Request.Body) data, _ := io.ReadAll(c.Request.Body)
c.Request.Body = ioutil.NopCloser(bytes.NewReader(data)) c.Request.Body = io.NopCloser(bytes.NewReader(data))
t := r.FormValue("csrf_token") t := r.FormValue("csrf_token")
c.Request.Body = ioutil.NopCloser(bytes.NewReader(data)) c.Request.Body = io.NopCloser(bytes.NewReader(data))
if len(t) > 0 { if len(t) > 0 {
return t return t
@ -91,17 +90,20 @@ type CSRF struct {
// csrfTokenGetter will be used to obtain token. // csrfTokenGetter will be used to obtain token.
// //
// Usage (with random salt): // Usage (with random salt):
// core.NewCSRF("", "super secret", "csrf_session", store, func (c *gin.Context, reason core.CSRFErrorReason) { //
// c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid CSRF token"}) // core.NewCSRF("", "super secret", "csrf_session", store, func (c *gin.Context, reason core.CSRFErrorReason) {
// }, core.DefaultCSRFTokenGetter) // c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid CSRF token"})
// }, core.DefaultCSRFTokenGetter)
// //
// Note for csrfTokenGetter: if you want to read token from request body (for example, from form field) // Note for csrfTokenGetter: if you want to read token from request body (for example, from form field)
// - don't forget to restore Body data! // - don't forget to restore Body data!
// //
// Body in http.Request is io.ReadCloser instance. Reading CSRF token from form like that: // Body in http.Request is io.ReadCloser instance. Reading CSRF token from form like that:
// if t := r.FormValue("csrf_token"); len(t) > 0 { //
// return t // if t := r.FormValue("csrf_token"); len(t) > 0 {
// } // return t
// }
//
// will close body - and all next middlewares won't be able to read body at all! // will close body - and all next middlewares won't be able to read body at all!
// //
// Use DefaultCSRFTokenGetter as example to implement your own token getter. // Use DefaultCSRFTokenGetter as example to implement your own token getter.
@ -185,11 +187,11 @@ func (x *CSRF) generateSalt() string {
// pseudoRandomString generates pseudo-random string with specified length. // pseudoRandomString generates pseudo-random string with specified length.
func (x *CSRF) pseudoRandomString(length int) string { func (x *CSRF) pseudoRandomString(length int) string {
rand.Seed(time.Now().UnixNano()) r := rand.New(rand.NewSource(time.Now().UnixNano())) // nolint:gosec
data := make([]byte, length) data := make([]byte, length)
for i := 0; i < length; i++ { // it is supposed to use pseudo-random data. for i := 0; i < length; i++ { // it is supposed to use pseudo-random data.
data[i] = byte(65 + rand.Intn(90-65)) // nolint:gosec,gomnd data[i] = byte(65 + r.Intn(90-65)) // nolint:gosec,gomnd
} }
return string(data) return string(data)
@ -209,15 +211,16 @@ func (x *CSRF) CSRFFromContext(c *gin.Context) string {
// GenerateCSRFMiddleware returns gin.HandlerFunc which will generate CSRF token // GenerateCSRFMiddleware returns gin.HandlerFunc which will generate CSRF token
// Usage: // Usage:
// engine := gin.New() //
// csrf := NewCSRF("salt", "secret", "not_found", "incorrect", localizer) // engine := gin.New()
// engine.Use(csrf.GenerateCSRFMiddleware()) // csrf := NewCSRF("salt", "secret", "not_found", "incorrect", localizer)
// engine.Use(csrf.GenerateCSRFMiddleware())
func (x *CSRF) GenerateCSRFMiddleware() gin.HandlerFunc { func (x *CSRF) GenerateCSRFMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
session, _ := x.store.Get(c.Request, x.sessionName) session, _ := x.store.Get(c.Request, x.sessionName)
if i, ok := session.Values["csrf_token"]; ok { if i, ok := session.Values["csrf_token"]; ok { // nolint:nestif
if i, ok := i.(string); !ok || i == "" { if i, ok := i.(string); !ok || i == "" { // nolint:nestif
if x.fillToken(session, c) != nil { if x.fillToken(session, c) != nil {
x.abortFunc(c, CSRFErrorCannotStoreTokenInSession) x.abortFunc(c, CSRFErrorCannotStoreTokenInSession)
c.Abort() c.Abort()
@ -243,8 +246,9 @@ func (x *CSRF) fillToken(s *sessions.Session, c *gin.Context) error {
// VerifyCSRFMiddleware verifies CSRF token // VerifyCSRFMiddleware verifies CSRF token
// Usage: // Usage:
// engine := gin.New() //
// engine.Use(csrf.VerifyCSRFMiddleware()) // engine := gin.New()
// engine.Use(csrf.VerifyCSRFMiddleware())
func (x *CSRF) VerifyCSRFMiddleware(ignoredMethods []string) gin.HandlerFunc { func (x *CSRF) VerifyCSRFMiddleware(ignoredMethods []string) gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
if x.strInSlice(ignoredMethods, c.Request.Method) { if x.strInSlice(ignoredMethods, c.Request.Method) {
@ -254,9 +258,9 @@ func (x *CSRF) VerifyCSRFMiddleware(ignoredMethods []string) gin.HandlerFunc {
var token string var token string
session, _ := x.store.Get(c.Request, x.sessionName) session, _ := x.store.Get(c.Request, x.sessionName)
if i, ok := session.Values["csrf_token"]; ok { if i, ok := session.Values["csrf_token"]; ok { // nolint:nestif
var v string var v string
if v, ok = i.(string); !ok || v == "" { if v, ok = i.(string); !ok || v == "" { // nolint:nestif
if !ok { if !ok {
x.abortFunc(c, CSRFErrorIncorrectTokenType) x.abortFunc(c, CSRFErrorIncorrectTokenType)
} else if v == "" { } else if v == "" {

View File

@ -3,7 +3,6 @@ package middleware
import ( import (
"bytes" "bytes"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
@ -32,7 +31,7 @@ func TestCSRF_DefaultCSRFTokenGetter_Empty(t *testing.T) {
URL: &url.URL{ URL: &url.URL{
RawQuery: "", RawQuery: "",
}, },
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), Body: io.NopCloser(bytes.NewReader([]byte(""))),
}} }}
assert.Empty(t, DefaultCSRFTokenGetter(c)) assert.Empty(t, DefaultCSRFTokenGetter(c))
@ -85,14 +84,14 @@ func TestCSRF_DefaultCSRFTokenGetter_Form(t *testing.T) {
RawQuery: "", RawQuery: "",
}, },
Header: headers, Header: headers,
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), Body: io.NopCloser(bytes.NewReader([]byte(""))),
}} }}
c.Request.PostForm = url.Values{"csrf_token": {"token"}} c.Request.PostForm = url.Values{"csrf_token": {"token"}}
assert.NotEmpty(t, DefaultCSRFTokenGetter(c)) assert.NotEmpty(t, DefaultCSRFTokenGetter(c))
assert.Equal(t, "token", DefaultCSRFTokenGetter(c)) assert.Equal(t, "token", DefaultCSRFTokenGetter(c))
_, err := ioutil.ReadAll(c.Request.Body) _, err := io.ReadAll(c.Request.Body)
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -23,6 +23,8 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
const recoveryMiddlewareSkipFrames = 3
// ErrorHandlerFunc will handle errors. // ErrorHandlerFunc will handle errors.
type ErrorHandlerFunc func(recovery interface{}, c *gin.Context) type ErrorHandlerFunc func(recovery interface{}, c *gin.Context)
@ -249,7 +251,7 @@ func (s *Sentry) recoveryMiddleware() gin.HandlerFunc { // nolint
} }
if l != nil { if l != nil {
// TODO: Check if we can output stacktraces with prefix data like before if we really need it. // TODO: Check if we can output stacktraces with prefix data like before if we really need it.
stack := stacktrace.FormattedStack(3, "trace: ") stack := stacktrace.FormattedStack(recoveryMiddlewareSkipFrames, "trace: ")
formattedErr := logger.Err(err) formattedErr := logger.Err(err)
httpRequest, _ := httputil.DumpRequest(c.Request, false) httpRequest, _ := httputil.DumpRequest(c.Request, false)
headers := strings.Split(string(httpRequest), "\r\n") headers := strings.Split(string(httpRequest), "\r\n")

View File

@ -31,12 +31,12 @@ type sentryMockTransport struct {
sending sync.RWMutex sending sync.RWMutex
} }
func (s *sentryMockTransport) Flush(timeout time.Duration) bool { func (s *sentryMockTransport) Flush(_ time.Duration) bool {
// noop // noop
return true return true
} }
func (s *sentryMockTransport) Configure(options sentry.ClientOptions) { func (s *sentryMockTransport) Configure(_ sentry.ClientOptions) {
// noop // noop
} }

View File

@ -18,7 +18,7 @@ func TestError(t *testing.T) {
func (t *ErrorTest) TestAppendToError() { func (t *ErrorTest) TestAppendToError() {
err := errors.New("test error") err := errors.New("test error")
_, ok := err.(StackTraced) _, ok := err.(StackTraced) // nolint:errorlint
t.Assert().False(ok) t.Assert().False(ok)
@ -28,16 +28,16 @@ func (t *ErrorTest) TestAppendToError() {
t.Assert().Nil(AppendToError(nil)) t.Assert().Nil(AppendToError(nil))
t.Assert().Implements((*StackTraced)(nil), withTrace) t.Assert().Implements((*StackTraced)(nil), withTrace)
t.Assert().Implements((*StackTraced)(nil), twiceTrace) t.Assert().Implements((*StackTraced)(nil), twiceTrace)
t.Assert().Equal(withTrace.(StackTraced).StackTrace(), twiceTrace.(StackTraced).StackTrace()) t.Assert().Equal(withTrace.(StackTraced).StackTrace(), twiceTrace.(StackTraced).StackTrace()) // nolint:errorlint
} }
func (t *ErrorTest) TestCauseUnwrap() { func (t *ErrorTest) TestCauseUnwrap() {
err := errors.New("test error") err := errors.New("test error")
wrapped := AppendToError(err) wrapped := AppendToError(err)
t.Assert().Equal(err, wrapped.(*withStack).Cause()) t.Assert().Equal(err, wrapped.(*withStack).Cause()) // nolint:errorlint
t.Assert().Equal(err, errors.Unwrap(wrapped)) t.Assert().Equal(err, errors.Unwrap(wrapped))
t.Assert().Equal(wrapped.(*withStack).Cause(), errors.Unwrap(wrapped)) t.Assert().Equal(wrapped.(*withStack).Cause(), errors.Unwrap(wrapped)) // nolint:errorlint
} }
func (t *ErrorTest) TestFormat() { func (t *ErrorTest) TestFormat() {

View File

@ -5,7 +5,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"io/ioutil" "os"
"path" "path"
"runtime" "runtime"
"strconv" "strconv"
@ -63,34 +63,34 @@ func (f Frame) name() string {
// Format formats the frame according to the fmt.Formatter interface. // Format formats the frame according to the fmt.Formatter interface.
// //
// %s source file // %s source file
// %d source line // %d source line
// %n function name // %n function name
// %v equivalent to %s:%d // %v equivalent to %s:%d
// //
// Format accepts flags that alter the printing of some verbs, as follows: // Format accepts flags that alter the printing of some verbs, as follows:
// //
// %+s function name and path of source file relative to the compile time // %+s function name and path of source file relative to the compile time
// GOPATH separated by \n\t (<funcname>\n\t<path>) // GOPATH separated by \n\t (<funcname>\n\t<path>)
// %+v equivalent to %+s:%d // %+v equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) { func (f Frame) Format(s fmt.State, verb rune) {
switch verb { switch verb {
case 's': case 's':
switch { switch {
case s.Flag('+'): case s.Flag('+'):
io.WriteString(s, f.name()) _, _ = io.WriteString(s, f.name())
io.WriteString(s, "\n\t") _, _ = io.WriteString(s, "\n\t")
io.WriteString(s, f.file()) _, _ = io.WriteString(s, f.file())
default: default:
io.WriteString(s, path.Base(f.file())) _, _ = io.WriteString(s, path.Base(f.file()))
} }
case 'd': case 'd':
io.WriteString(s, strconv.Itoa(f.line())) _, _ = io.WriteString(s, strconv.Itoa(f.line()))
case 'n': case 'n':
io.WriteString(s, funcname(f.name())) _, _ = io.WriteString(s, funcname(f.name()))
case 'v': case 'v':
f.Format(s, 's') f.Format(s, 's')
io.WriteString(s, ":") _, _ = io.WriteString(s, ":")
f.Format(s, 'd') f.Format(s, 'd')
} }
} }
@ -110,23 +110,23 @@ type StackTrace []Frame
// Format formats the stack of Frames according to the fmt.Formatter interface. // Format formats the stack of Frames according to the fmt.Formatter interface.
// //
// %s lists source files for each Frame in the stack // %s lists source files for each Frame in the stack
// %v lists the source file and line number for each Frame in the stack // %v lists the source file and line number for each Frame in the stack
// //
// Format accepts flags that alter the printing of some verbs, as follows: // Format accepts flags that alter the printing of some verbs, as follows:
// //
// %+v Prints filename, function, and line number for each Frame in the stack. // %+v Prints filename, function, and line number for each Frame in the stack.
func (st StackTrace) Format(s fmt.State, verb rune) { func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb { switch verb {
case 'v': case 'v':
switch { switch {
case s.Flag('+'): case s.Flag('+'):
for _, f := range st { for _, f := range st {
io.WriteString(s, "\n") _, _ = io.WriteString(s, "\n")
f.Format(s, verb) f.Format(s, verb)
} }
case s.Flag('#'): case s.Flag('#'):
fmt.Fprintf(s, "%#v", []Frame(st)) _, _ = fmt.Fprintf(s, "%#v", []Frame(st))
default: default:
st.formatSlice(s, verb) st.formatSlice(s, verb)
} }
@ -138,14 +138,14 @@ func (st StackTrace) Format(s fmt.State, verb rune) {
// formatSlice will format this StackTrace into the given buffer as a slice of // formatSlice will format this StackTrace into the given buffer as a slice of
// Frame, only valid when called with '%s' or '%v'. // Frame, only valid when called with '%s' or '%v'.
func (st StackTrace) formatSlice(s fmt.State, verb rune) { func (st StackTrace) formatSlice(s fmt.State, verb rune) {
io.WriteString(s, "[") _, _ = io.WriteString(s, "[")
for i, f := range st { for i, f := range st {
if i > 0 { if i > 0 {
io.WriteString(s, " ") _, _ = io.WriteString(s, " ")
} }
f.Format(s, verb) f.Format(s, verb)
} }
io.WriteString(s, "]") _, _ = io.WriteString(s, "]")
} }
// stack represents a stack of program counters. // stack represents a stack of program counters.
@ -159,7 +159,7 @@ func (s *stack) Format(st fmt.State, verb rune) {
if verb == 'v' && st.Flag('+') { if verb == 'v' && st.Flag('+') {
for _, pc := range *s { for _, pc := range *s {
f := Frame(pc) f := Frame(pc)
fmt.Fprintf(st, "\n%+v", f) _, _ = fmt.Fprintf(st, "\n%+v", f)
} }
} }
} }
@ -185,16 +185,16 @@ func FormattedStack(skip int, prefix string) []byte {
break break
} }
// Print this much at least. If we can't find the source, it won't show. // Print this much at least. If we can't find the source, it won't show.
fmt.Fprintf(buf, "%s%s:%d (0x%x)\n", prefix, file, line, pc) _, _ = fmt.Fprintf(buf, "%s%s:%d (0x%x)\n", prefix, file, line, pc)
if file != lastFile { if file != lastFile {
data, err := ioutil.ReadFile(file) data, err := os.ReadFile(file)
if err != nil { if err != nil {
continue continue
} }
lines = bytes.Split(data, []byte{'\n'}) lines = bytes.Split(data, []byte{'\n'})
lastFile = file lastFile = file
} }
fmt.Fprintf(buf, "%s\t%s: %s\n", prefix, function(pc), source(lines, line)) _, _ = fmt.Fprintf(buf, "%s\t%s: %s\n", prefix, function(pc), source(lines, line))
} }
return buf.Bytes() return buf.Bytes()
} }

View File

@ -3,7 +3,6 @@ package core
import ( import (
"fmt" "fmt"
"html/template" "html/template"
"io/ioutil"
"os" "os"
"path" "path"
"testing" "testing"
@ -37,8 +36,8 @@ func (t *TemplateTest) initTestData() {
require.Nil(t.T(), err) require.Nil(t.T(), err)
data1 := []byte(`data {{template "body" .}}`) data1 := []byte(`data {{template "body" .}}`)
data2 := []byte(`{{define "body"}}test {{"test" | trans}}{{end}}`) data2 := []byte(`{{define "body"}}test {{"test" | trans}}{{end}}`)
err1 := ioutil.WriteFile(fmt.Sprintf(testTemplatesFile, 1), data1, os.ModePerm) err1 := os.WriteFile(fmt.Sprintf(testTemplatesFile, 1), data1, os.ModePerm)
err2 := ioutil.WriteFile(fmt.Sprintf(testTemplatesFile, 2), data2, os.ModePerm) err2 := os.WriteFile(fmt.Sprintf(testTemplatesFile, 2), data2, os.ModePerm)
require.Nil(t.T(), err1) require.Nil(t.T(), err1)
require.Nil(t.T(), err2) require.Nil(t.T(), err2)
} }

View File

@ -18,36 +18,41 @@ import (
// because AsError() returns nil if there are no errors in the list. // because AsError() returns nil if there are no errors in the list.
// //
// Example: // Example:
// err := errorutil.NewCollector(). //
// Do(errors.New("error 1")). // err := errorutil.NewCollector().
// Do(errors.New("error 2"), errors.New("error 3")) // Do(errors.New("error 1")).
// // Will print error message. // Do(errors.New("error 2"), errors.New("error 3"))
// fmt.Println(err) // // Will print error message.
// fmt.Println(err)
// //
// This code will produce something like this: // This code will produce something like this:
// #1 err at /home/user/main.go:62: error 1 //
// #2 err at /home/user/main.go:63: error 2 // #1 err at /home/user/main.go:62: error 1
// #3 err at /home/user/main.go:64: error 3 // #2 err at /home/user/main.go:63: error 2
// #3 err at /home/user/main.go:64: error 3
// //
// You can also iterate over the error to use their data instead of using predefined message: // You can also iterate over the error to use their data instead of using predefined message:
// err := errorutil.NewCollector().
// Do(errors.New("error 1")).
// Do(errors.New("error 2"), errors.New("error 3"))
// //
// for err := range c.Iterate() { // err := errorutil.NewCollector().
// fmt.Printf("Error at %s:%d: %v\n", err.File, err.Line, err) // Do(errors.New("error 1")).
// } // Do(errors.New("error 2"), errors.New("error 3"))
//
// for err := range c.Iterate() {
// fmt.Printf("Error at %s:%d: %v\n", err.File, err.Line, err)
// }
// //
// This code will produce output that looks like this: // This code will produce output that looks like this:
// Error at /home/user/main.go:164: error 0 //
// Error at /home/user/main.go:164: error 1 // Error at /home/user/main.go:164: error 0
// Error at /home/user/main.go:164: error 2 // Error at /home/user/main.go:164: error 1
// Error at /home/user/main.go:164: error 2
// //
// Example with GORM migration (Collector is returned as an error here). // Example with GORM migration (Collector is returned as an error here).
// return errorutil.NewCollector().Do( //
// db.CreateTable(models.Account{}, models.Connection{}).Error, // return errorutil.NewCollector().Do(
// db.Table("account").AddUniqueIndex("account_key", "channel").Error, // db.CreateTable(models.Account{}, models.Connection{}).Error,
// ).AsError() // db.Table("account").AddUniqueIndex("account_key", "channel").Error,
// ).AsError()
type Collector struct { type Collector struct {
errors *errList errors *errList
} }

View File

@ -14,7 +14,8 @@ type ListResponse struct {
// GetErrorResponse returns ErrorResponse with specified status code // GetErrorResponse returns ErrorResponse with specified status code
// Usage (with gin): // Usage (with gin):
// context.JSON(GetErrorResponse(http.StatusPaymentRequired, "Not enough money")) //
// context.JSON(GetErrorResponse(http.StatusPaymentRequired, "Not enough money"))
func GetErrorResponse(statusCode int, err string) (int, interface{}) { func GetErrorResponse(statusCode int, err string) (int, interface{}) {
return statusCode, Response{ return statusCode, Response{
Error: err, Error: err,
@ -23,28 +24,32 @@ func GetErrorResponse(statusCode int, err string) (int, interface{}) {
// BadRequest returns ErrorResponse with code 400 // BadRequest returns ErrorResponse with code 400
// Usage (with gin): // Usage (with gin):
// context.JSON(BadRequest("invalid data")) //
// context.JSON(BadRequest("invalid data"))
func BadRequest(err string) (int, interface{}) { func BadRequest(err string) (int, interface{}) {
return GetErrorResponse(http.StatusBadRequest, err) return GetErrorResponse(http.StatusBadRequest, err)
} }
// Unauthorized returns ErrorResponse with code 401 // Unauthorized returns ErrorResponse with code 401
// Usage (with gin): // Usage (with gin):
// context.JSON(Unauthorized("invalid credentials")) //
// context.JSON(Unauthorized("invalid credentials"))
func Unauthorized(err string) (int, interface{}) { func Unauthorized(err string) (int, interface{}) {
return GetErrorResponse(http.StatusUnauthorized, err) return GetErrorResponse(http.StatusUnauthorized, err)
} }
// Forbidden returns ErrorResponse with code 403 // Forbidden returns ErrorResponse with code 403
// Usage (with gin): // Usage (with gin):
// context.JSON(Forbidden("forbidden")) //
// context.JSON(Forbidden("forbidden"))
func Forbidden(err string) (int, interface{}) { func Forbidden(err string) (int, interface{}) {
return GetErrorResponse(http.StatusForbidden, err) return GetErrorResponse(http.StatusForbidden, err)
} }
// InternalServerError returns ErrorResponse with code 500 // InternalServerError returns ErrorResponse with code 500
// Usage (with gin): // Usage (with gin):
// context.JSON(BadRequest("invalid data")) //
// context.JSON(BadRequest("invalid data"))
func InternalServerError(err string) (int, interface{}) { func InternalServerError(err string) (int, interface{}) {
return GetErrorResponse(http.StatusInternalServerError, err) return GetErrorResponse(http.StatusInternalServerError, err)
} }

View File

@ -5,12 +5,13 @@ import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"fmt" "fmt"
"go.uber.org/zap"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"time" "time"
"go.uber.org/zap"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/retailcrm/mg-transport-core/v2/core/config" "github.com/retailcrm/mg-transport-core/v2/core/config"
"github.com/retailcrm/mg-transport-core/v2/core/logger" "github.com/retailcrm/mg-transport-core/v2/core/logger"
@ -229,7 +230,7 @@ func (b *HTTPClientBuilder) buildMocks() error {
return errors.New("dialer must be built first") return errors.New("dialer must be built first")
} }
if b.mockHost != "" && b.mockPort != "" && len(b.mockedDomains) > 0 { if b.mockHost != "" && b.mockPort != "" && len(b.mockedDomains) > 0 { // nolint:nestif
b.log("Mock address has been set", zap.String("address", net.JoinHostPort(b.mockHost, b.mockPort))) b.log("Mock address has been set", zap.String("address", net.JoinHostPort(b.mockHost, b.mockPort)))
b.log("Mocked domains: ") b.log("Mocked domains: ")

View File

@ -7,7 +7,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"net" "net"
"net/http" "net/http"
@ -209,6 +208,7 @@ x5porosgI2RgOTTwmiYOcYQTS2650jYydHhK16Gu2b3UKernO16mAWXNDWfvS2bk
nAI2GL2ACEdOCyRvgq16AycJJYU7nYQ+t9aveefx0uhbYYIVeYub9NxmCfD3MojI nAI2GL2ACEdOCyRvgq16AycJJYU7nYQ+t9aveefx0uhbYYIVeYub9NxmCfD3MojI
saG/63vo0ng851n90DVoMRWx9n1CjEvss/vvz+jXIl9njaCtizN3WUf1NwUB saG/63vo0ng851n90DVoMRWx9n1CjEvss/vvz+jXIl9njaCtizN3WUf1NwUB
-----END CERTIFICATE-----` -----END CERTIFICATE-----`
// nolint:gosec
keyFileData := `-----BEGIN RSA PRIVATE KEY----- keyFileData := `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEArcVIOmlAXGS4xGBIM8xPgfMALMiunU/X22w3zv+Z/T4R48UC MIIEogIBAAKCAQEArcVIOmlAXGS4xGBIM8xPgfMALMiunU/X22w3zv+Z/T4R48UC
5402K7PcQAJe0Qmo/J1INEc319/Iw9UxsJBawtbtaYzn++DlTF7MNsWu4JmZZyXn 5402K7PcQAJe0Qmo/J1INEc319/Iw9UxsJBawtbtaYzn++DlTF7MNsWu4JmZZyXn
@ -237,9 +237,9 @@ weywTxDl/OD5ybNkZIRKsIXciFYG1VCGO2HNGN9qJcV+nJ63kyrIBauwUkuEhiN5
uf/TQPpjrGW5nxOf94qn6FzV2WSype9BcM5MD7z7rk202Fs7Zqc= uf/TQPpjrGW5nxOf94qn6FzV2WSype9BcM5MD7z7rk202Fs7Zqc=
-----END RSA PRIVATE KEY-----` -----END RSA PRIVATE KEY-----`
certFile, err := ioutil.TempFile("/tmp", "cert_") certFile, err := os.CreateTemp("/tmp", "cert_")
require.NoError(t.T(), err, "cannot create temp cert file") require.NoError(t.T(), err, "cannot create temp cert file")
keyFile, err := ioutil.TempFile("/tmp", "key_") keyFile, err := os.CreateTemp("/tmp", "key_")
require.NoError(t.T(), err, "cannot create temp key file") require.NoError(t.T(), err, "cannot create temp key file")
_, err = certFile.WriteString(certFileData) _, err = certFile.WriteString(certFileData)
@ -252,7 +252,7 @@ uf/TQPpjrGW5nxOf94qn6FzV2WSype9BcM5MD7z7rk202Fs7Zqc=
errorutil.Collect(keyFile.Sync(), keyFile.Close()), "cannot sync and close temp key file") errorutil.Collect(keyFile.Sync(), keyFile.Close()), "cannot sync and close temp key file")
mux := &http.ServeMux{} mux := &http.ServeMux{}
srv := &http.Server{Addr: mockServerAddr, Handler: mux} srv := &http.Server{Addr: mockServerAddr, Handler: mux, ReadHeaderTimeout: defaultDialerTimeout}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusCreated) w.WriteHeader(http.StatusCreated)
_, _ = io.WriteString(w, "ok") _, _ = io.WriteString(w, "ok")
@ -307,7 +307,7 @@ uf/TQPpjrGW5nxOf94qn6FzV2WSype9BcM5MD7z7rk202Fs7Zqc=
defer resp.Body.Close() defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body) data, err := io.ReadAll(resp.Body)
require.NoError(t.T(), err, "error while reading body") require.NoError(t.T(), err, "error while reading body")
assert.Equal(t.T(), http.StatusCreated, resp.StatusCode, "invalid status code") assert.Equal(t.T(), http.StatusCreated, resp.StatusCode, "invalid status code")

View File

@ -46,7 +46,7 @@ func printRequestData(t UnmatchedRequestsTestingT, r *http.Request) {
} }
} }
if r.Body == nil { if r.Body == nil { // nolint:nestif
t.Log("No body is present.") t.Log("No body is present.")
} else { } else {
data, err := io.ReadAll(r.Body) data, err := io.ReadAll(r.Body)

View File

@ -11,11 +11,11 @@ import (
// remove all the entities created after the hook was set up. // remove all the entities created after the hook was set up.
// You can use it like this: // You can use it like this:
// //
// func TestSomething(t *testing.T){ // func TestSomething(t *testing.T){
// db, _ := gorm.Open(...) // db, _ := gorm.Open(...)
// cleaner := DeleteCreatedEntities(db) // cleaner := DeleteCreatedEntities(db)
// defer cleaner() // defer cleaner()
// }. // }.
func DeleteCreatedEntities(db *gorm.DB) func() { // nolint func DeleteCreatedEntities(db *gorm.DB) func() { // nolint
type entity struct { type entity struct {
key interface{} key interface{}

View File

@ -3,8 +3,9 @@ package testutil
import ( import (
"bufio" "bufio"
"encoding/json" "encoding/json"
"github.com/guregu/null/v5"
"io" "io"
"github.com/guregu/null/v5"
) )
type LogRecord struct { type LogRecord struct {

View File

@ -2,11 +2,12 @@ package testutil
import ( import (
"bytes" "bytes"
"github.com/stretchr/testify/suite"
"io" "io"
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/suite"
) )
type JSONRecordScannerTest struct { type JSONRecordScannerTest struct {

View File

@ -3,7 +3,6 @@ package testutil
import ( import (
"errors" "errors"
"io/fs" "io/fs"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@ -63,8 +62,8 @@ func (t *TranslationsExtractor) loadYAMLFile(fileName string) (map[string]interf
err error err error
) )
if info, err = os.Stat(fileName); err == nil { if info, err = os.Stat(fileName); err == nil { // nolint:nestif
if !info.IsDir() { if !info.IsDir() { // nolint:nestif
var ( var (
path string path string
source []byte source []byte
@ -75,7 +74,7 @@ func (t *TranslationsExtractor) loadYAMLFile(fileName string) (map[string]interf
return dataMap, err return dataMap, err
} }
if source, err = ioutil.ReadFile(path); err != nil { if source, err = os.ReadFile(path); err != nil {
return dataMap, err return dataMap, err
} }

View File

@ -1,7 +1,6 @@
package testutil package testutil
import ( import (
"io/ioutil"
"os" "os"
"reflect" "reflect"
"sort" "sort"
@ -40,7 +39,7 @@ func (t *TranslationsExtractorTest) SetupSuite() {
data, _ := yaml.Marshal(translation) data, _ := yaml.Marshal(translation)
// It's not regular temporary file. Little hack in order to test translations extractor. // It's not regular temporary file. Little hack in order to test translations extractor.
// nolint:gosec // nolint:gosec
errWrite := ioutil.WriteFile("/tmp/translate.en.yml", data, os.ModePerm) errWrite := os.WriteFile("/tmp/translate.en.yml", data, os.ModePerm)
require.NoError(t.T(), errWrite) require.NoError(t.T(), errWrite)
t.extractor = NewTranslationsExtractor("translate.{}.yml") t.extractor = NewTranslationsExtractor("translate.{}.yml")

View File

@ -20,9 +20,10 @@ import (
"github.com/aws/aws-sdk-go/service/s3/s3manager" "github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
retailcrm "github.com/retailcrm/api-client-go/v2" retailcrm "github.com/retailcrm/api-client-go/v2"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
"github.com/retailcrm/mg-transport-core/v2/core/config" "github.com/retailcrm/mg-transport-core/v2/core/config"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
"github.com/retailcrm/mg-transport-core/v2/core/logger" "github.com/retailcrm/mg-transport-core/v2/core/logger"
"github.com/retailcrm/mg-transport-core/v2/core/util/errorutil" "github.com/retailcrm/mg-transport-core/v2/core/util/errorutil"

View File

@ -11,11 +11,12 @@ import (
"github.com/h2non/gock" "github.com/h2non/gock"
retailcrm "github.com/retailcrm/api-client-go/v2" retailcrm "github.com/retailcrm/api-client-go/v2"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
"github.com/retailcrm/mg-transport-core/v2/core/config" "github.com/retailcrm/mg-transport-core/v2/core/config"
"github.com/retailcrm/mg-transport-core/v2/core/logger" "github.com/retailcrm/mg-transport-core/v2/core/logger"