Static analysis (#23)

* lint stage for a workflow
* golangci-lint config
* lint only new code or last commit
* run lint only for pull requests
This commit is contained in:
Pavel 2021-02-09 14:57:14 +03:00 committed by GitHub
parent 2eb1b78871
commit d15ed7ffec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 457 additions and 243 deletions

View File

@ -12,6 +12,18 @@ env:
GO111MODULE: on
jobs:
golangci:
name: lint
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Lint code with golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.36
only-new-issues: true
tests:
name: Tests
runs-on: ubuntu-latest

197
.golangci.yml Normal file
View File

@ -0,0 +1,197 @@
run:
skip-dirs-use-default: true
allow-parallel-runners: true
output:
format: colored-line-number
sort-results: true
linters:
disable-all: true
enable:
- deadcode
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- structcheck
- unused
- unparam
- varcheck
- bodyclose
- dogsled
- dupl
- errorlint
- exhaustive
- exportloopref
- funlen
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- goimports
- golint
- gomnd
- gosec
- ifshort
- interfacer
- lll
- makezero
- maligned
- misspell
- nestif
- prealloc
- predeclared
- scopelint
- sqlclosecheck
- unconvert
- whitespace
linters-settings:
govet:
check-shadowing: false
disable-all: true
enable:
- assign
- atomic
- bools
- buildtag
- copylocks
- httpresponse
- loopclosure
- lostcancel
- printf
- shift
- stdmethods
- structtag
- tests
- unmarshal
- unreachable
- unsafeptr
- unused
settings:
printf:
funcs:
- (*log.Logger).Fatal
- (*log.Logger).Fatalf
- (*log.Logger).Fatalln
- (*log.Logger).Panic
- (*log.Logger).Panicf
- (*log.Logger).Panicln
- (*log.Logger).Print
- (*log.Logger).Printf
- (*log.Logger).Println
- (*testing.common).Error
- (*testing.common).Errorf
- (*testing.common).Fatal
- (*testing.common).Fatalf
- (*testing.common).Log
- (*testing.common).Logf
- (*testing.common).Skip
- (*testing.common).Skipf
- (testing.TB).Error
- (testing.TB).Errorf
- (testing.TB).Fatal
- (testing.TB).Fatalf
- (testing.TB).Log
- (testing.TB).Logf
- (testing.TB).Skip
- (testing.TB).Skipf
- fmt.Errorf
- fmt.Fprint
- fmt.Fprintf
- fmt.Fprintln
- fmt.Print
- fmt.Printf
- fmt.Println
- fmt.Sprint
- fmt.Sprintf
- fmt.Sprintln
- log.Fatal
- log.Fatalf
- log.Fatalln
- log.Panic
- log.Panicf
- log.Panicln
- log.Print
- log.Printf
- log.Println
- runtime/trace.Logf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Fatalf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Panicf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Panicf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Criticalf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Errorf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Warningf
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Noticef
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Infof
- (github.com/retailcrm/mg-transport-core/core.LoggerInterface).Debugf
unused:
check-exported: false
unparam:
check-exported: false
dogsled:
max-blank-identifiers: 3
dupl:
threshold: 200
errorlint:
errorf: true
exhaustive:
check-generated: false
default-signifies-exhaustive: false
funlen:
lines: 60
statements: 40
gocognit:
min-complexity: 25
gocyclo:
min-complexity: 25
goimports:
local-prefixes: github.com/retailcrm/mg-transport-core
lll:
line-length: 120
maligned:
suggest-new: true
misspell:
locale: US
nestif:
min-complexity: 4
whitespace:
multi-if: false
multi-func: false
issues:
exclude-rules:
- path: _test\.go
linters:
- gomnd
- lll
- bodyclose
- errcheck
- sqlclosecheck
- misspell
- ineffassign
- whitespace
- makezero
- maligned
- ifshort
- errcheck
- funlen
- goconst
- gocognit
- gocyclo
- godot
exclude-use-default: true
exclude-case-sensitive: false
max-issues-per-linter: 0
max-same-issues: 0
fix: true
severity:
default-severity: error
case-sensitive: false
service:
golangci-lint-version: 1.36.x

View File

@ -4,10 +4,11 @@ import (
"os"
"github.com/jessevdk/go-flags"
"github.com/retailcrm/mg-transport-core/core"
)
// Options for tool command
// Options for tool command.
type Options struct{}
var (

View File

@ -21,7 +21,7 @@ var (
slashRegex = regexp.MustCompile(`/+$`)
)
// ConfigInterface settings data structure
// ConfigInterface settings data structure.
type ConfigInterface interface {
GetVersion() string
GetSentryDSN() string
@ -35,14 +35,14 @@ type ConfigInterface interface {
IsDebug() bool
}
// InfoInterface transport settings data structure
// InfoInterface transport settings data structure.
type InfoInterface interface {
GetName() string
GetCode() string
GetLogoPath() string
}
// Config struct
// Config struct.
type Config struct {
Version string `yaml:"version"`
LogLevel logging.Level `yaml:"log_level"`
@ -56,14 +56,14 @@ type Config struct {
HTTPClientConfig *HTTPClientConfig `yaml:"http_client"`
}
// Info struct
// Info struct.
type Info struct {
Name string `yaml:"name"`
Code string `yaml:"code"`
LogoPath string `yaml:"logo_path"`
}
// ConfigAWS struct
// ConfigAWS struct.
type ConfigAWS struct {
AccessKeyID string `yaml:"access_key_id"`
SecretAccessKey string `yaml:"secret_access_key"`
@ -73,7 +73,7 @@ type ConfigAWS struct {
ContentType string `yaml:"content_type"`
}
// DatabaseConfig struct
// DatabaseConfig struct.
type DatabaseConfig struct {
Connection interface{} `yaml:"connection"`
Logging bool `yaml:"logging"`
@ -83,7 +83,7 @@ type DatabaseConfig struct {
ConnectionLifetime int `yaml:"connection_lifetime"`
}
// HTTPClientConfig struct
// HTTPClientConfig struct.
type HTTPClientConfig struct {
Timeout time.Duration `yaml:"timeout"`
SSLVerification *bool `yaml:"ssl_verification"`
@ -91,7 +91,7 @@ type HTTPClientConfig struct {
MockedDomains []string `yaml:"mocked_domains"`
}
// HTTPServerConfig struct
// HTTPServerConfig struct.
type HTTPServerConfig struct {
Host string `yaml:"host"`
Listen string `yaml:"listen"`
@ -104,12 +104,12 @@ func NewConfig(path string) *Config {
return (&Config{}).LoadConfig(path)
}
// LoadConfig read & load configuration file
// LoadConfig read & load configuration file.
func (c *Config) LoadConfig(path string) *Config {
return c.LoadConfigFromData(c.GetConfigData(path))
}
// LoadConfigFromData loads config from byte sequence
// LoadConfigFromData loads config from byte sequence.
func (c *Config) LoadConfigFromData(data []byte) *Config {
if err := yaml.Unmarshal(data, c); err != nil {
panic(err)
@ -118,7 +118,7 @@ func (c *Config) LoadConfigFromData(data []byte) *Config {
return c
}
// GetConfigData returns config file data in form of byte sequence
// GetConfigData returns config file data in form of byte sequence.
func (c *Config) GetConfigData(path string) []byte {
var err error
@ -135,72 +135,72 @@ func (c *Config) GetConfigData(path string) []byte {
return source
}
// GetSentryDSN sentry connection dsn
// GetSentryDSN sentry connection dsn.
func (c Config) GetSentryDSN() string {
return c.SentryDSN
}
// GetVersion transport version
// GetVersion transport version.
func (c Config) GetVersion() string {
return c.Version
}
// GetLogLevel log level
// GetLogLevel log level.
func (c Config) GetLogLevel() logging.Level {
return c.LogLevel
}
// GetTransportInfo transport basic data
// GetTransportInfo transport basic data.
func (c Config) GetTransportInfo() InfoInterface {
return c.TransportInfo
}
// IsDebug debug flag
// IsDebug debug flag.
func (c Config) IsDebug() bool {
return c.Debug
}
// GetAWSConfig AWS configuration
// GetAWSConfig AWS configuration.
func (c Config) GetAWSConfig() ConfigAWS {
return c.ConfigAWS
}
// GetDBConfig database configuration
// GetDBConfig database configuration.
func (c Config) GetDBConfig() DatabaseConfig {
return c.Database
}
// GetHTTPConfig server configuration
// GetHTTPConfig server configuration.
func (c Config) GetHTTPConfig() HTTPServerConfig {
return c.HTTPServer
}
// GetUpdateInterval user data update interval
// GetUpdateInterval user data update interval.
func (c Config) GetUpdateInterval() int {
return c.UpdateInterval
}
// GetHTTPClientConfig returns http client config
// GetHTTPClientConfig returns http client config.
func (c Config) GetHTTPClientConfig() *HTTPClientConfig {
return c.HTTPClientConfig
}
// GetName transport name
// GetName transport name.
func (t Info) GetName() string {
return t.Name
}
// GetCode transport code
// GetCode transport code.
func (t Info) GetCode() string {
return t.Code
}
// GetLogoPath transport logo
// GetLogoPath transport logo.
func (t Info) GetLogoPath() string {
return t.LogoPath
}
// IsSSLVerificationEnabled returns SSL verification flag (default is true)
// IsSSLVerificationEnabled returns SSL verification flag (default is true).
func (h *HTTPClientConfig) IsSSLVerificationEnabled() bool {
if h.SSLVerification == nil {
return true

View File

@ -15,33 +15,33 @@ import (
"github.com/gorilla/sessions"
)
// CSRFErrorReason is a error reason type
// CSRFErrorReason is a error reason type.
type CSRFErrorReason uint8
// CSRFTokenGetter func type
// CSRFTokenGetter func type.
type CSRFTokenGetter func(*gin.Context) string
// CSRFAbortFunc is a callback which
// CSRFAbortFunc is a callback which.
type CSRFAbortFunc func(*gin.Context, CSRFErrorReason)
const (
// CSRFErrorNoTokenInSession will be returned if token is not present in session
// CSRFErrorNoTokenInSession will be returned if token is not present in session.
CSRFErrorNoTokenInSession CSRFErrorReason = iota
// CSRFErrorCannotStoreTokenInSession will be returned if middleware cannot store token in session
// CSRFErrorCannotStoreTokenInSession will be returned if middleware cannot store token in session.
CSRFErrorCannotStoreTokenInSession
// CSRFErrorIncorrectTokenType will be returned if data type of token in session is not string
// CSRFErrorIncorrectTokenType will be returned if data type of token in session is not string.
CSRFErrorIncorrectTokenType
// CSRFErrorEmptyToken will be returned if token in session is empty
// CSRFErrorEmptyToken will be returned if token in session is empty.
CSRFErrorEmptyToken
// CSRFErrorTokenMismatch will be returned in case of invalid token
// CSRFErrorTokenMismatch will be returned in case of invalid token.
CSRFErrorTokenMismatch
)
// DefaultCSRFTokenGetter default getter
// DefaultCSRFTokenGetter default getter.
var DefaultCSRFTokenGetter = func(c *gin.Context) string {
r := c.Request
@ -65,7 +65,7 @@ var DefaultCSRFTokenGetter = func(c *gin.Context) string {
return ""
}
// DefaultIgnoredMethods ignored methods for CSRF verifier middleware
// DefaultIgnoredMethods ignored methods for CSRF verifier middleware.
var DefaultIgnoredMethods = []string{"GET", "HEAD", "OPTIONS"}
// CSRF struct. Provides CSRF token verification.
@ -124,7 +124,7 @@ func NewCSRF(salt, secret, sessionName string, store sessions.Store, abortFunc C
return csrf
}
// strInSlice checks whether string exists in slice
// strInSlice checks whether string exists in slice.
func (x *CSRF) strInSlice(slice []string, v string) bool {
exists := false
@ -138,7 +138,7 @@ func (x *CSRF) strInSlice(slice []string, v string) bool {
return exists
}
// generateCSRFToken generates new CSRF token
// generateCSRFToken generates new CSRF token.
func (x *CSRF) generateCSRFToken() string {
// nolint:gosec
h := sha1.New()
@ -166,7 +166,7 @@ func (x *CSRF) generateSalt() string {
return string(salt)
}
// pseudoRandomString generates pseudo-random string with specified length
// pseudoRandomString generates pseudo-random string with specified length.
func (x *CSRF) pseudoRandomString(length int) string {
rand.Seed(time.Now().UnixNano())
data := make([]byte, length)
@ -217,7 +217,7 @@ func (x *CSRF) GenerateCSRFMiddleware() gin.HandlerFunc {
}
}
// fillToken stores token in session and context
// fillToken stores token in session and context.
func (x *CSRF) fillToken(s *sessions.Session, c *gin.Context) error {
s.Values["csrf_token"] = x.generateCSRFToken()
c.Set("csrf_token", s.Values["csrf_token"])
@ -265,7 +265,7 @@ func (x *CSRF) VerifyCSRFMiddleware(ignoredMethods []string) gin.HandlerFunc {
}
}
// GetCSRFErrorMessage returns generic error message for CSRFErrorReason in English (useful for logs)
// GetCSRFErrorMessage returns generic error message for CSRFErrorReason in English (useful for logs).
func GetCSRFErrorMessage(r CSRFErrorReason) string {
switch r {
case CSRFErrorNoTokenInSession:

View File

@ -23,7 +23,7 @@ var DefaultHTTPClientConfig = &HTTPClientConfig{
SSLVerification: &boolTrue,
}
// Engine struct
// Engine struct.
type Engine struct {
Localizer
ORM
@ -42,7 +42,8 @@ type Engine struct {
prepared bool
}
// New Engine instance (must be configured manually, gin can be accessed via engine.Router() directly or engine.ConfigureRouter(...) with callback)
// New Engine instance (must be configured manually, gin can be accessed via engine.Router() directly or
// engine.ConfigureRouter(...) with callback).
func New() *Engine {
return &Engine{
Config: nil,
@ -77,7 +78,7 @@ func (e *Engine) initGin() {
e.ginEngine = r
}
// Prepare engine for start
// Prepare engine for start.
func (e *Engine) Prepare() *Engine {
if e.prepared {
panic("engine already initialized")
@ -119,7 +120,7 @@ func (e *Engine) Prepare() *Engine {
return e
}
// TemplateFuncMap combines func map for templates
// TemplateFuncMap combines func map for templates.
func (e *Engine) TemplateFuncMap(functions template.FuncMap) template.FuncMap {
funcMap := e.LocalizationFuncMap()
@ -134,14 +135,14 @@ func (e *Engine) TemplateFuncMap(functions template.FuncMap) template.FuncMap {
return funcMap
}
// CreateRenderer with translation function
// CreateRenderer with translation function.
func (e *Engine) CreateRenderer(callback func(*Renderer), funcs template.FuncMap) Renderer {
renderer := NewRenderer(e.TemplateFuncMap(funcs))
callback(&renderer)
return renderer
}
// CreateRendererFS with translation function and packr box with templates data
// CreateRendererFS with translation function and packr box with templates data.
func (e *Engine) CreateRendererFS(box *packr.Box, callback func(*Renderer), funcs template.FuncMap) Renderer {
renderer := NewRenderer(e.TemplateFuncMap(funcs))
renderer.TemplatesBox = box
@ -149,7 +150,7 @@ func (e *Engine) CreateRendererFS(box *packr.Box, callback func(*Renderer), func
return renderer
}
// Router will return current gin.Engine or panic if it's not present
// Router will return current gin.Engine or panic if it's not present.
func (e *Engine) Router() *gin.Engine {
if !e.prepared {
panic("prepare engine first")
@ -161,7 +162,7 @@ func (e *Engine) Router() *gin.Engine {
return e.ginEngine
}
// JobManager will return singleton JobManager from Engine
// JobManager will return singleton JobManager from Engine.
func (e *Engine) JobManager() *JobManager {
if e.jobManager == nil {
e.jobManager = NewJobManager().SetLogger(e.Logger()).SetLogging(e.Config.IsDebug())
@ -170,12 +171,12 @@ func (e *Engine) JobManager() *JobManager {
return e.jobManager
}
// Logger returns current logger
// Logger returns current logger.
func (e *Engine) Logger() LoggerInterface {
return e.logger
}
// SetLogger sets provided logger instance to engine
// SetLogger sets provided logger instance to engine.
func (e *Engine) SetLogger(l LoggerInterface) *Engine {
if l == nil {
return e
@ -187,7 +188,7 @@ func (e *Engine) SetLogger(l LoggerInterface) *Engine {
return e
}
// BuildHTTPClient builds HTTP client with provided configuration
// BuildHTTPClient builds HTTP client with provided configuration.
func (e *Engine) BuildHTTPClient(certs *x509.CertPool, replaceDefault ...bool) *Engine {
client, err := NewHTTPClientBuilder().
WithLogger(e.Logger()).
@ -205,7 +206,7 @@ func (e *Engine) BuildHTTPClient(certs *x509.CertPool, replaceDefault ...bool) *
return e
}
// GetHTTPClientConfig returns configuration for HTTP client
// GetHTTPClientConfig returns configuration for HTTP client.
func (e *Engine) GetHTTPClientConfig() *HTTPClientConfig {
if e.Config.GetHTTPClientConfig() != nil {
return e.Config.GetHTTPClientConfig()
@ -214,7 +215,7 @@ func (e *Engine) GetHTTPClientConfig() *HTTPClientConfig {
return DefaultHTTPClientConfig
}
// SetHTTPClient sets HTTP client to engine
// SetHTTPClient sets HTTP client to engine.
func (e *Engine) SetHTTPClient(client *http.Client) *Engine {
if client != nil {
e.httpClient = client
@ -223,7 +224,7 @@ func (e *Engine) SetHTTPClient(client *http.Client) *Engine {
return e
}
// HTTPClient returns inner http client or default http client
// HTTPClient returns inner http client or default http client.
func (e *Engine) HTTPClient() *http.Client {
if e.httpClient == nil {
return http.DefaultClient
@ -292,7 +293,7 @@ func (e *Engine) GenerateCSRFMiddleware() gin.HandlerFunc {
return e.csrf.GenerateCSRFMiddleware()
}
// GetCSRFToken returns CSRF token from provided context
// GetCSRFToken returns CSRF token from provided context.
func (e *Engine) GetCSRFToken(c *gin.Context) string {
if e.csrf == nil {
panic("csrf is not initialized")
@ -301,13 +302,13 @@ func (e *Engine) GetCSRFToken(c *gin.Context) string {
return e.csrf.CSRFFromContext(c)
}
// ConfigureRouter will call provided callback with current gin.Engine, or panic if engine is not present
// ConfigureRouter will call provided callback with current gin.Engine, or panic if engine is not present.
func (e *Engine) ConfigureRouter(callback func(*gin.Engine)) *Engine {
callback(e.Router())
return e
}
// Run gin.Engine loop, or panic if engine is not present
// Run gin.Engine loop, or panic if engine is not present.
func (e *Engine) Run() error {
return e.Router().Run(e.Config.GetHTTPConfig().Listen)
}

View File

@ -2,12 +2,12 @@ package core
import "net/http"
// ErrorResponse struct
// ErrorResponse struct.
type ErrorResponse struct {
Error string `json:"error"`
}
// ErrorsResponse struct
// ErrorsResponse struct.
type ErrorsResponse struct {
Error []string `json:"error"`
}

View File

@ -12,10 +12,10 @@ import (
"github.com/pkg/errors"
)
// DefaultClient stores original http.DefaultClient
// DefaultClient stores original http.DefaultClient.
var DefaultClient = http.DefaultClient
// DefaultTransport stores original http.DefaultTransport
// DefaultTransport stores original http.DefaultTransport.
var DefaultTransport = http.DefaultTransport
// HTTPClientBuilder builds http client with mocks (if necessary) and timeout.
@ -57,7 +57,7 @@ type HTTPClientBuilder struct {
mockedDomains []string
}
// NewHTTPClientBuilder returns HTTPClientBuilder with default values
// NewHTTPClientBuilder returns HTTPClientBuilder with default values.
func NewHTTPClientBuilder() *HTTPClientBuilder {
return &HTTPClientBuilder{
built: false,
@ -70,7 +70,7 @@ func NewHTTPClientBuilder() *HTTPClientBuilder {
}
}
// WithLogger sets provided logger into HTTPClientBuilder
// WithLogger sets provided logger into HTTPClientBuilder.
func (b *HTTPClientBuilder) WithLogger(logger LoggerInterface) *HTTPClientBuilder {
if logger != nil {
b.logger = logger
@ -79,7 +79,7 @@ func (b *HTTPClientBuilder) WithLogger(logger LoggerInterface) *HTTPClientBuilde
return b
}
// SetTimeout sets timeout for http client
// SetTimeout sets timeout for http client.
func (b *HTTPClientBuilder) SetTimeout(seconds time.Duration) *HTTPClientBuilder {
seconds = seconds * time.Second
b.timeout = seconds
@ -87,25 +87,25 @@ func (b *HTTPClientBuilder) SetTimeout(seconds time.Duration) *HTTPClientBuilder
return b
}
// SetMockAddress sets mock address
// SetMockAddress sets mock address.
func (b *HTTPClientBuilder) SetMockAddress(address string) *HTTPClientBuilder {
b.mockAddress = address
return b
}
// AddMockedDomain adds new mocked domain
// AddMockedDomain adds new mocked domain.
func (b *HTTPClientBuilder) AddMockedDomain(domain string) *HTTPClientBuilder {
b.mockedDomains = append(b.mockedDomains, domain)
return b
}
// SetMockedDomains sets mocked domains from slice
// SetMockedDomains sets mocked domains from slice.
func (b *HTTPClientBuilder) SetMockedDomains(domains []string) *HTTPClientBuilder {
b.mockedDomains = domains
return b
}
// SetSSLVerification enables or disables SSL certificates verification in client
// SetSSLVerification enables or disables SSL certificates verification in client.
func (b *HTTPClientBuilder) SetSSLVerification(enabled bool) *HTTPClientBuilder {
if b.httpTransport.TLSClientConfig == nil {
b.httpTransport.TLSClientConfig = &tls.Config{}
@ -116,7 +116,7 @@ func (b *HTTPClientBuilder) SetSSLVerification(enabled bool) *HTTPClientBuilder
return b
}
// SetSSLVerification enables or disables SSL certificates verification in client
// SetSSLVerification enables or disables SSL certificates verification in client.
func (b *HTTPClientBuilder) SetCertPool(pool *x509.CertPool) *HTTPClientBuilder {
if b.httpTransport.TLSClientConfig == nil {
b.httpTransport.TLSClientConfig = &tls.Config{}
@ -127,13 +127,13 @@ func (b *HTTPClientBuilder) SetCertPool(pool *x509.CertPool) *HTTPClientBuilder
return b
}
// SetLogging enables or disables logging in mocks
// SetLogging enables or disables logging in mocks.
func (b *HTTPClientBuilder) SetLogging(flag bool) *HTTPClientBuilder {
b.logging = flag
return b
}
// FromConfig fulfills mock configuration from HTTPClientConfig
// FromConfig fulfills mock configuration from HTTPClientConfig.
func (b *HTTPClientBuilder) FromConfig(config *HTTPClientConfig) *HTTPClientBuilder {
if config == nil {
return b
@ -153,12 +153,12 @@ func (b *HTTPClientBuilder) FromConfig(config *HTTPClientConfig) *HTTPClientBuil
return b
}
// FromEngine fulfills mock configuration from ConfigInterface inside Engine
// FromEngine fulfills mock configuration from ConfigInterface inside Engine.
func (b *HTTPClientBuilder) FromEngine(engine *Engine) *HTTPClientBuilder {
return b.FromConfig(engine.GetHTTPClientConfig())
}
// buildDialer initializes dialer with provided timeout
// buildDialer initializes dialer with provided timeout.
func (b *HTTPClientBuilder) buildDialer() *HTTPClientBuilder {
b.dialer = &net.Dialer{
Timeout: b.timeout,
@ -168,7 +168,7 @@ func (b *HTTPClientBuilder) buildDialer() *HTTPClientBuilder {
return b
}
// parseAddress parses address and returns error in case of error (port is necessary)
// parseAddress parses address and returns error in case of error (port is necessary).
func (b *HTTPClientBuilder) parseAddress() error {
if b.mockAddress == "" {
return nil
@ -184,7 +184,7 @@ func (b *HTTPClientBuilder) parseAddress() error {
return nil
}
// buildMocks builds mocks for http client
// buildMocks builds mocks for http client.
func (b *HTTPClientBuilder) buildMocks() error {
if b.dialer == nil {
return errors.New("dialer must be built first")
@ -229,7 +229,7 @@ func (b *HTTPClientBuilder) buildMocks() error {
return nil
}
// logf prints logs via Engine or via fmt.Printf
// logf prints logs via Engine or via fmt.Printf.
func (b *HTTPClientBuilder) logf(format string, args ...interface{}) {
if b.logging {
if b.logger != nil {
@ -240,7 +240,7 @@ func (b *HTTPClientBuilder) logf(format string, args ...interface{}) {
}
}
// ReplaceDefault replaces default client and transport with generated ones
// ReplaceDefault replaces default client and transport with generated ones.
func (b *HTTPClientBuilder) ReplaceDefault() *HTTPClientBuilder {
if b.built {
http.DefaultClient = b.httpClient
@ -250,7 +250,7 @@ func (b *HTTPClientBuilder) ReplaceDefault() *HTTPClientBuilder {
return b
}
// RestoreDefault restores default client and transport after replacement
// RestoreDefault restores default client and transport after replacement.
func (b *HTTPClientBuilder) RestoreDefault() *HTTPClientBuilder {
http.DefaultClient = DefaultClient
http.DefaultTransport = DefaultTransport
@ -258,7 +258,7 @@ func (b *HTTPClientBuilder) RestoreDefault() *HTTPClientBuilder {
return b
}
// Build builds client, pass true to replace http.DefaultClient with generated one
// Build builds client, pass true to replace http.DefaultClient with generated one.
func (b *HTTPClientBuilder) Build(replaceDefault ...bool) (*http.Client, error) {
if err := b.buildDialer().parseAddress(); err != nil {
return nil, err

View File

@ -9,10 +9,10 @@ import (
"github.com/op/go-logging"
)
// JobFunc is empty func which should be executed in a parallel goroutine
// JobFunc is empty func which should be executed in a parallel goroutine.
type JobFunc func(JobLogFunc) error
// JobLogFunc is a function which logs data from job
// JobLogFunc is a function which logs data from job.
type JobLogFunc func(string, logging.Level, ...interface{})
// JobErrorHandler is a function to handle jobs errors. First argument is a job name.
@ -56,7 +56,7 @@ type JobManager struct {
logger LoggerInterface
}
// getWrappedFunc wraps job into function
// getWrappedFunc wraps job into function.
func (j *Job) getWrappedFunc(name string, log JobLogFunc) func() {
return func() {
defer func() {
@ -71,7 +71,7 @@ func (j *Job) getWrappedFunc(name string, log JobLogFunc) func() {
}
}
// getWrappedTimerFunc returns job timer func to run in the separate goroutine
// getWrappedTimerFunc returns job timer func to run in the separate goroutine.
func (j *Job) getWrappedTimerFunc(name string, log JobLogFunc) func(chan bool) {
return func(stopChannel chan bool) {
for range time.NewTicker(j.Interval).C {
@ -85,7 +85,7 @@ func (j *Job) getWrappedTimerFunc(name string, log JobLogFunc) func(chan bool) {
}
}
// run job
// run job.
func (j *Job) run(name string, log JobLogFunc) *Job {
j.writeLock.RLock()
@ -104,7 +104,7 @@ func (j *Job) run(name string, log JobLogFunc) *Job {
return j
}
// stop running job
// stop running job.
func (j *Job) stop() *Job {
j.writeLock.RLock()
@ -123,24 +123,24 @@ func (j *Job) stop() *Job {
return j
}
// runOnce run job once
// runOnce run job once.
func (j *Job) runOnce(name string, log JobLogFunc) *Job {
go j.getWrappedFunc(name, log)()
return j
}
// runOnceSync run job once in current goroutine
// runOnceSync run job once in current goroutine.
func (j *Job) runOnceSync(name string, log JobLogFunc) *Job {
j.getWrappedFunc(name, log)()
return j
}
// NewJobManager is a JobManager constructor
// NewJobManager is a JobManager constructor.
func NewJobManager() *JobManager {
return &JobManager{jobs: &sync.Map{}}
}
// DefaultJobErrorHandler returns default error handler for a job
// DefaultJobErrorHandler returns default error handler for a job.
func DefaultJobErrorHandler() JobErrorHandler {
return func(name string, err error, log JobLogFunc) {
if err != nil && name != "" {
@ -149,7 +149,7 @@ func DefaultJobErrorHandler() JobErrorHandler {
}
}
// DefaultJobPanicHandler returns default panic handler for a job
// DefaultJobPanicHandler returns default panic handler for a job.
func DefaultJobPanicHandler() JobPanicHandler {
return func(name string, recoverValue interface{}, log JobLogFunc) {
if recoverValue != nil && name != "" {
@ -158,7 +158,7 @@ func DefaultJobPanicHandler() JobPanicHandler {
}
}
// SetLogger sets logger into JobManager
// SetLogger sets logger into JobManager.
func (j *JobManager) SetLogger(logger LoggerInterface) *JobManager {
if logger != nil {
j.logger = logger
@ -167,13 +167,13 @@ func (j *JobManager) SetLogger(logger LoggerInterface) *JobManager {
return j
}
// SetLogging enables or disables JobManager logging
// SetLogging enables or disables JobManager logging.
func (j *JobManager) SetLogging(enableLogging bool) *JobManager {
j.enableLogging = enableLogging
return j
}
// RegisterJob registers new job
// RegisterJob registers new job.
func (j *JobManager) RegisterJob(name string, job *Job) error {
if job == nil {
return errors.New("job shouldn't be nil")
@ -198,7 +198,7 @@ func (j *JobManager) UnregisterJob(name string) error {
return fmt.Errorf("cannot find job `%s`", name)
}
// FetchJob fetches already exist job
// FetchJob fetches already exist job.
func (j *JobManager) FetchJob(name string) (value *Job, ok bool) {
if i, ok := j.jobs.Load(name); ok {
if job, ok := i.(*Job); ok {
@ -209,7 +209,7 @@ func (j *JobManager) FetchJob(name string) (value *Job, ok bool) {
return &Job{}, false
}
// UpdateJob updates job
// UpdateJob updates job.
func (j *JobManager) UpdateJob(name string, job *Job) error {
if job, ok := j.FetchJob(name); ok {
_ = j.UnregisterJob(name)
@ -259,7 +259,7 @@ func (j *JobManager) RunJobOnceSync(name string) error {
return fmt.Errorf("cannot find job `%s`", name)
}
// Start all jobs in the manager
// Start all jobs in the manager.
func (j *JobManager) Start() {
j.jobs.Range(func(key, value interface{}) bool {
name := key.(string)
@ -269,7 +269,7 @@ func (j *JobManager) Start() {
})
}
// log logs via logger or as plaintext
// log logs via logger or as plaintext.
func (j *JobManager) log(format string, severity logging.Level, args ...interface{}) {
if !j.enableLogging {
return

View File

@ -14,20 +14,20 @@ import (
"gopkg.in/yaml.v2"
)
// DefaultLanguages for transports
// DefaultLanguages for transports.
var DefaultLanguages = []language.Tag{
language.English,
language.Russian,
language.Spanish,
}
// DefaultLanguage is a base language which will be chosen if current language is unspecified
// DefaultLanguage is a base language which will be chosen if current language is unspecified.
var DefaultLanguage = language.English
// LocalizerContextKey is a key which is used to store localizer in gin.Context key-value storage
// LocalizerContextKey is a key which is used to store localizer in gin.Context key-value storage.
const LocalizerContextKey = "localizer"
// Localizer struct
// Localizer struct.
type Localizer struct {
i18nStorage *sync.Map
TranslationsBox *packr.Box
@ -70,17 +70,17 @@ func NewLocalizerFS(locale language.Tag, matcher language.Matcher, translationsB
return localizer
}
// DefaultLocalizerBundle returns new localizer bundle with English as default language
// DefaultLocalizerBundle returns new localizer bundle with English as default language.
func DefaultLocalizerBundle() *i18n.Bundle {
return i18n.NewBundle(DefaultLanguage)
}
// LocalizerBundle returns new localizer bundle provided language as default
// LocalizerBundle returns new localizer bundle provided language as default.
func LocalizerBundle(tag language.Tag) *i18n.Bundle {
return i18n.NewBundle(tag)
}
// DefaultLocalizerMatcher returns matcher with English, Russian and Spanish tags
// DefaultLocalizerMatcher returns matcher with English, Russian and Spanish tags.
func DefaultLocalizerMatcher() language.Matcher {
return language.NewMatcher(DefaultLanguages)
}
@ -137,12 +137,12 @@ func (l *Localizer) LocalizationFuncMap() template.FuncMap {
}
}
// getLocaleBundle returns current locale bundle and creates it if needed
// getLocaleBundle returns current locale bundle and creates it if needed.
func (l *Localizer) getLocaleBundle() *i18n.Bundle {
return l.createLocaleBundleByTag(l.LanguageTag)
}
// createLocaleBundleByTag creates locale bundle by language tag
// createLocaleBundleByTag creates locale bundle by language tag.
func (l *Localizer) createLocaleBundleByTag(tag language.Tag) *i18n.Bundle {
bundle := i18n.NewBundle(tag)
bundle.RegisterUnmarshalFunc("yml", yaml.Unmarshal)
@ -151,14 +151,14 @@ func (l *Localizer) createLocaleBundleByTag(tag language.Tag) *i18n.Bundle {
return bundle
}
// LoadTranslations will load all translation files from translations directory or from embedded box
// LoadTranslations will load all translation files from translations directory or from embedded box.
func (l *Localizer) LoadTranslations() {
defer l.loadMutex.Unlock()
l.loadMutex.Lock()
l.getCurrentLocalizer()
}
// loadTranslationsToBundle loads translations to provided bundle
// loadTranslationsToBundle loads translations to provided bundle.
func (l *Localizer) loadTranslationsToBundle(i18nBundle *i18n.Bundle) {
switch {
case l.TranslationsPath != "":
@ -174,7 +174,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 {
files, err := ioutil.ReadDir(l.TranslationsPath)
if err != nil {
@ -190,7 +190,7 @@ func (l *Localizer) loadFromDirectory(i18nBundle *i18n.Bundle) error {
return nil
}
// LoadTranslations will load all translation files from embedded box
// LoadTranslations will load all translation files from embedded box.
func (l *Localizer) loadFromFS(i18nBundle *i18n.Bundle) error {
err := l.TranslationsBox.Walk(func(s string, file packd.File) error {
if fileInfo, err := file.FileInfo(); err == nil {
@ -217,7 +217,7 @@ func (l *Localizer) loadFromFS(i18nBundle *i18n.Bundle) error {
return nil
}
// getLocalizer returns *i18n.Localizer with provided language tag. It will be created if not exist
// getLocalizer returns *i18n.Localizer with provided language tag. It will be created if not exist.
func (l *Localizer) getLocalizer(tag language.Tag) *i18n.Localizer {
var localizer *i18n.Localizer
@ -247,24 +247,24 @@ func (l *Localizer) isUnd(tag language.Tag) bool {
return tag == language.Und || tag.IsRoot()
}
// getCurrentLocalizer returns *i18n.Localizer with current language tag
// getCurrentLocalizer returns *i18n.Localizer with current language tag.
func (l *Localizer) getCurrentLocalizer() *i18n.Localizer {
return l.getLocalizer(l.LanguageTag)
}
// SetLocale will change language for current localizer
// SetLocale will change language for current localizer.
func (l *Localizer) SetLocale(al string) {
l.SetLanguage(l.matchByString(al))
}
// Preload provided languages (so they will not be loaded every time in middleware)
// Preload provided languages (so they will not be loaded every time in middleware).
func (l *Localizer) Preload(tags []language.Tag) {
for _, tag := range tags {
l.getLocalizer(tag)
}
}
// SetLanguage will change language using language tag
// SetLanguage will change language using language tag.
func (l *Localizer) SetLanguage(tag language.Tag) {
if l.isUnd(tag) {
tag = DefaultLanguage
@ -276,7 +276,7 @@ func (l *Localizer) SetLanguage(tag language.Tag) {
// FetchLanguage will load language from tag
//
// Deprecated: Use `(*core.Localizer).LoadTranslations()` instead
// Deprecated: Use `(*core.Localizer).LoadTranslations()` instead.
func (l *Localizer) FetchLanguage() {
l.LoadTranslations()
}
@ -295,7 +295,7 @@ func (l *Localizer) GetLocalizedTemplateMessage(messageID string, templateData m
})
}
// Localize will return localized message by it's ID, or error if message wasn't found
// Localize will return localized message by it's ID, or error if message wasn't found.
func (l *Localizer) Localize(messageID string) (string, error) {
return l.getCurrentLocalizer().Localize(&i18n.LocalizeConfig{MessageID: messageID})
}
@ -309,12 +309,12 @@ func (l *Localizer) LocalizeTemplateMessage(messageID string, templateData map[s
})
}
// BadRequestLocalized is same as BadRequest(string), but passed string will be localized
// BadRequestLocalized is same as BadRequest(string), but passed string will be localized.
func (l *Localizer) BadRequestLocalized(err string) (int, interface{}) {
return BadRequest(l.GetLocalizedMessage(err))
}
// GetContextLocalizer returns localizer from context if it exist there
// GetContextLocalizer returns localizer from context if it exist there.
func GetContextLocalizer(c *gin.Context) (*Localizer, bool) {
if c == nil {
return nil, false

View File

@ -186,7 +186,7 @@ func (l *LocalizerTest) Test_BadRequestLocalized() {
assert.Equal(l.T(), "Test message", resp.(ErrorResponse).Error)
}
// getContextWithLang generates context with Accept-Language header
// getContextWithLang generates context with Accept-Language header.
func (l *LocalizerTest) getContextWithLang(tag language.Tag) *gin.Context {
urlInstance, _ := url.Parse("https://example.com")
headers := http.Header{}

View File

@ -7,7 +7,7 @@ import (
"github.com/op/go-logging"
)
// LoggerInterface contains methods which should be present in logger implementation
// LoggerInterface contains methods which should be present in logger implementation.
type LoggerInterface interface {
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
@ -28,7 +28,7 @@ type LoggerInterface interface {
}
// Logger component. Uses github.com/op/go-logging under the hood.
// This logger can prevent any write operations (disabled by default, use .Exclusive() method to enable)
// This logger can prevent any write operations (disabled by default, use .Exclusive() method to enable).
type Logger struct {
logger *logging.Logger
mutex *sync.RWMutex
@ -55,14 +55,14 @@ func newInheritedLogger(transportCode string, logLevel logging.Level, logFormat
return logger
}
// DefaultLogFormatter will return default formatter for logs
// DefaultLogFormatter will return default formatter for logs.
func DefaultLogFormatter() logging.Formatter {
return logging.MustStringFormatter(
`%{time:2006-01-02 15:04:05.000} %{level:.4s} => %{message}`,
)
}
// Exclusive makes logger goroutine-safe
// Exclusive makes logger goroutine-safe.
func (l *Logger) Exclusive() *Logger {
if l.mutex == nil {
l.mutex = &sync.RWMutex{}
@ -71,14 +71,14 @@ func (l *Logger) Exclusive() *Logger {
return l
}
// lock locks logger
// lock locks logger.
func (l *Logger) lock() {
if l.mutex != nil {
l.mutex.Lock()
}
}
// unlock unlocks logger
// unlock unlocks logger.
func (l *Logger) unlock() {
if l.mutex != nil {
l.mutex.Unlock()

View File

@ -2,7 +2,7 @@ package core
import (
// "os"
// "os/exec"
// "os/exec".
"testing"
"github.com/op/go-logging"

View File

@ -9,10 +9,10 @@ import (
"gopkg.in/gormigrate.v1"
)
// migrations default GORMigrate tool
// migrations default GORMigrate tool.
var migrations *Migrate
// Migrate tool, decorates gormigrate.Migration in order to provide better interface & versioning
// Migrate tool, decorates gormigrate.Migration in order to provide better interface & versioning.
type Migrate struct {
db *gorm.DB
first *gormigrate.Migration
@ -22,17 +22,17 @@ type Migrate struct {
prepared bool
}
// MigrationInfo with migration info
// MigrationInfo with migration info.
type MigrationInfo struct {
ID string `gorm:"column:id; type:varchar(255)"`
}
// TableName for MigrationInfo
// TableName for MigrationInfo.
func (MigrationInfo) TableName() string {
return "migrations"
}
// Migrations returns default migrate
// Migrations returns default migrate.
func Migrations() *Migrate {
if migrations == nil {
migrations = &Migrate{
@ -45,7 +45,7 @@ func Migrations() *Migrate {
return migrations
}
// Add GORMigrate to migrate
// Add GORMigrate to migrate.
func (m *Migrate) Add(migration *gormigrate.Migration) {
if migration == nil {
return
@ -54,13 +54,13 @@ func (m *Migrate) Add(migration *gormigrate.Migration) {
m.migrations[migration.ID] = migration
}
// SetDB to migrate
// SetDB to migrate.
func (m *Migrate) SetDB(db *gorm.DB) *Migrate {
m.db = db
return m
}
// Migrate all, including schema initialization
// Migrate all, including schema initialization.
func (m *Migrate) Migrate() error {
if err := m.prepareMigrations(); err != nil {
return err
@ -73,7 +73,7 @@ func (m *Migrate) Migrate() error {
return nil
}
// Rollback all migrations
// Rollback all migrations.
func (m *Migrate) Rollback() error {
if err := m.prepareMigrations(); err != nil {
return err
@ -94,7 +94,7 @@ func (m *Migrate) Rollback() error {
return nil
}
// MigrateTo specified version
// MigrateTo specified version.
func (m *Migrate) MigrateTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
@ -111,7 +111,7 @@ func (m *Migrate) MigrateTo(version string) error {
}
}
// MigrateNextTo migrate to next version from specified version
// MigrateNextTo migrate to next version from specified version.
func (m *Migrate) MigrateNextTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
@ -132,7 +132,7 @@ func (m *Migrate) MigrateNextTo(version string) error {
}
}
// MigratePreviousTo migrate to previous version from specified version
// MigratePreviousTo migrate to previous version from specified version.
func (m *Migrate) MigratePreviousTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
@ -155,7 +155,7 @@ func (m *Migrate) MigratePreviousTo(version string) error {
}
}
// RollbackTo specified version
// RollbackTo specified version.
func (m *Migrate) RollbackTo(version string) error {
if err := m.prepareMigrations(); err != nil {
return err
@ -164,7 +164,7 @@ func (m *Migrate) RollbackTo(version string) error {
return m.GORMigrate.RollbackTo(version)
}
// Current migration version
// Current migration version.
func (m *Migrate) Current() string {
var migrationInfo MigrationInfo
@ -191,7 +191,7 @@ func (m *Migrate) Current() string {
return migrationInfo.ID
}
// NextFrom returns next version from passed version
// NextFrom returns next version from passed version.
func (m *Migrate) NextFrom(version string) (string, error) {
for key, ver := range m.versions {
if ver == version {
@ -206,7 +206,7 @@ func (m *Migrate) NextFrom(version string) (string, error) {
return "", errors.New("cannot find specified migration")
}
// PreviousFrom returns previous version from passed version
// PreviousFrom returns previous version from passed version.
func (m *Migrate) PreviousFrom(version string) (string, error) {
for key, ver := range m.versions {
if ver == version {
@ -221,12 +221,12 @@ func (m *Migrate) PreviousFrom(version string) (string, error) {
return "", errors.New("cannot find specified migration")
}
// Close db connection
// Close db connection.
func (m *Migrate) Close() error {
return m.db.Close()
}
// prepareMigrations prepare migrate
// prepareMigrations prepare migrate.
func (m *Migrate) prepareMigrations() error {
var (
keys []string

View File

@ -30,12 +30,12 @@ func init() {
}
`
// NewMigrationCommand struct
// NewMigrationCommand struct.
type NewMigrationCommand struct {
Directory string `short:"d" long:"directory" default:"./migrations" description:"Directory where migration will be created"`
}
// FileExists returns true if provided file exist and it's not directory
// FileExists returns true if provided file exist and it's not directory.
func (x *NewMigrationCommand) FileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
@ -44,7 +44,7 @@ func (x *NewMigrationCommand) FileExists(filename string) bool {
return !info.IsDir()
}
// Execute migration generator command
// Execute migration generator command.
func (x *NewMigrationCommand) Execute(args []string) error {
version := strconv.FormatInt(time.Now().Unix(), 10)
directory := path.Clean(x.Directory)

View File

@ -2,7 +2,7 @@ package core
import "time"
// Connection model
// Connection model.
type Connection struct {
ID int `gorm:"primary_key"`
ClientID string `gorm:"column:client_id; type:varchar(70); not null; unique" json:"clientId,omitempty"`
@ -16,7 +16,7 @@ type Connection struct {
Accounts []Account `gorm:"foreignkey:ConnectionID"`
}
// Account model
// Account model.
type Account struct {
ID int `gorm:"primary_key"`
ConnectionID int `gorm:"column:connection_id" json:"connectionId,omitempty"`
@ -28,7 +28,7 @@ type Account struct {
UpdatedAt time.Time
}
// User model
// User model.
type User struct {
ID int `gorm:"primary_key"`
ExternalID string `gorm:"column:external_id; type:varchar(255); not null; unique"`
@ -49,5 +49,5 @@ func (User) TableName() string {
return "mg_user"
}
// Accounts list
// Accounts list.
type Accounts []Account

View File

@ -4,16 +4,16 @@ import (
"time"
"github.com/jinzhu/gorm"
// PostgreSQL is an default
// PostgreSQL is an default.
_ "github.com/jinzhu/gorm/dialects/postgres"
)
// ORM struct
// ORM struct.
type ORM struct {
DB *gorm.DB
}
// NewORM will init new database connection
// NewORM will init new database connection.
func NewORM(config DatabaseConfig) *ORM {
orm := &ORM{}
orm.createDB(config)
@ -36,7 +36,7 @@ func (orm *ORM) createDB(config DatabaseConfig) {
orm.DB = db
}
// CloseDB close database connection
// CloseDB close database connection.
func (orm *ORM) CloseDB() {
_ = orm.DB.Close()
}

View File

@ -8,22 +8,23 @@ import (
"strconv"
"github.com/pkg/errors"
"github.com/retailcrm/mg-transport-core/core/stacktrace"
"github.com/getsentry/raven-go"
"github.com/gin-gonic/gin"
)
// ErrorHandlerFunc will handle errors
// ErrorHandlerFunc will handle errors.
type ErrorHandlerFunc func(recovery interface{}, c *gin.Context)
// SentryTaggedTypes list
// SentryTaggedTypes list.
type SentryTaggedTypes []SentryTagged
// SentryTags list for SentryTaggedStruct. Format: name => property name
// SentryTags list for SentryTaggedStruct. Format: name => property name.
type SentryTags map[string]string
// SentryTagged interface for both tagged scalar and struct
// SentryTagged interface for both tagged scalar and struct.
type SentryTagged interface {
BuildTags(interface{}) (map[string]string, error)
GetContextKey() string
@ -31,7 +32,7 @@ type SentryTagged interface {
GetName() string
}
// Sentry struct. Holds SentryTaggedStruct list
// Sentry struct. Holds SentryTaggedStruct list.
type Sentry struct {
TaggedTypes SentryTaggedTypes
Stacktrace bool
@ -41,20 +42,20 @@ type Sentry struct {
Client stacktrace.RavenClientInterface
}
// SentryTaggedStruct holds information about type, it's key in gin.Context (for middleware), and it's properties
// SentryTaggedStruct holds information about type, it's key in gin.Context (for middleware), and it's properties.
type SentryTaggedStruct struct {
Type reflect.Type
GinContextKey string
Tags SentryTags
}
// SentryTaggedScalar variable from context
// SentryTaggedScalar variable from context.
type SentryTaggedScalar struct {
SentryTaggedStruct
Name string
}
// NewSentry constructor
// NewSentry constructor.
func NewSentry(sentryDSN string, defaultError string, taggedTypes SentryTaggedTypes, logger LoggerInterface, localizer *Localizer) *Sentry {
sentry := &Sentry{
DefaultError: defaultError,
@ -67,7 +68,7 @@ func NewSentry(sentryDSN string, defaultError string, taggedTypes SentryTaggedTy
return sentry
}
// NewTaggedStruct constructor
// NewTaggedStruct constructor.
func NewTaggedStruct(sample interface{}, ginCtxKey string, tags map[string]string) *SentryTaggedStruct {
n := make(map[string]string)
for k, v := range tags {
@ -81,7 +82,7 @@ func NewTaggedStruct(sample interface{}, ginCtxKey string, tags map[string]strin
}
}
// NewTaggedScalar constructor
// NewTaggedScalar constructor.
func NewTaggedScalar(sample interface{}, ginCtxKey string, name string) *SentryTaggedScalar {
return &SentryTaggedScalar{
SentryTaggedStruct: SentryTaggedStruct{
@ -93,13 +94,13 @@ func NewTaggedScalar(sample interface{}, ginCtxKey string, name string) *SentryT
}
}
// createRavenClient will init raven.Client
// createRavenClient will init raven.Client.
func (s *Sentry) createRavenClient(sentryDSN string) {
client, _ := raven.New(sentryDSN)
s.Client = client
}
// combineGinErrorHandlers calls several error handlers simultaneously
// combineGinErrorHandlers calls several error handlers simultaneously.
func (s *Sentry) combineGinErrorHandlers(handlers ...ErrorHandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
@ -117,7 +118,7 @@ func (s *Sentry) combineGinErrorHandlers(handlers ...ErrorHandlerFunc) gin.Handl
}
}
// ErrorMiddleware returns error handlers, attachable to gin.Engine
// ErrorMiddleware returns error handlers, attachable to gin.Engine.
func (s *Sentry) ErrorMiddleware() gin.HandlerFunc {
defaultHandlers := []ErrorHandlerFunc{
s.ErrorResponseHandler(),
@ -132,7 +133,7 @@ func (s *Sentry) ErrorMiddleware() gin.HandlerFunc {
return s.combineGinErrorHandlers(defaultHandlers...)
}
// PanicLogger logs panic
// PanicLogger logs panic.
func (s *Sentry) PanicLogger() ErrorHandlerFunc {
return func(recovery interface{}, c *gin.Context) {
if recovery != nil {
@ -146,7 +147,7 @@ func (s *Sentry) PanicLogger() ErrorHandlerFunc {
}
}
// ErrorLogger logs basic errors
// ErrorLogger logs basic errors.
func (s *Sentry) ErrorLogger() ErrorHandlerFunc {
return func(recovery interface{}, c *gin.Context) {
for _, err := range c.Errors {
@ -159,7 +160,7 @@ func (s *Sentry) ErrorLogger() ErrorHandlerFunc {
}
}
// ErrorResponseHandler will be executed in case of any unexpected error
// ErrorResponseHandler will be executed in case of any unexpected error.
func (s *Sentry) ErrorResponseHandler() ErrorHandlerFunc {
return func(recovery interface{}, c *gin.Context) {
publicErrors := c.Errors.ByType(gin.ErrorTypePublic)
@ -194,7 +195,7 @@ func (s *Sentry) ErrorResponseHandler() ErrorHandlerFunc {
}
}
// ErrorCaptureHandler will generate error data and send it to sentry
// ErrorCaptureHandler will generate error data and send it to sentry.
func (s *Sentry) ErrorCaptureHandler() ErrorHandlerFunc {
return func(recovery interface{}, c *gin.Context) {
tags := map[string]string{
@ -248,23 +249,23 @@ func (s *Sentry) ErrorCaptureHandler() ErrorHandlerFunc {
}
}
// AddTag will add tag with property name which holds tag in object
// AddTag will add tag with property name which holds tag in object.
func (t *SentryTaggedStruct) AddTag(name string, property string) *SentryTaggedStruct {
t.Tags[property] = name
return t
}
// GetTags is Tags getter
// GetTags is Tags getter.
func (t *SentryTaggedStruct) GetTags() SentryTags {
return t.Tags
}
// GetContextKey is GinContextKey getter
// GetContextKey is GinContextKey getter.
func (t *SentryTaggedStruct) GetContextKey() string {
return t.GinContextKey
}
// GetName is useless for SentryTaggedStruct
// GetName is useless for SentryTaggedStruct.
func (t *SentryTaggedStruct) GetName() string {
return ""
}
@ -303,7 +304,7 @@ func (t *SentryTaggedStruct) GetProperty(v interface{}, property string) (name s
return
}
// BuildTags will extract tags for Sentry from specified object
// BuildTags will extract tags for Sentry from specified object.
func (t *SentryTaggedStruct) BuildTags(v interface{}) (tags map[string]string, err error) {
items := make(map[string]string)
for prop, name := range t.Tags {
@ -319,7 +320,7 @@ func (t *SentryTaggedStruct) BuildTags(v interface{}) (tags map[string]string, e
return
}
// valueToString convert reflect.Value to string representation
// valueToString convert reflect.Value to string representation.
func (t *SentryTaggedStruct) valueToString(field reflect.Value) string {
k := field.Kind()
switch {
@ -340,17 +341,17 @@ func (t *SentryTaggedStruct) valueToString(field reflect.Value) string {
}
}
// GetTags is useless for SentryTaggedScalar
// GetTags is useless for SentryTaggedScalar.
func (t *SentryTaggedScalar) GetTags() SentryTags {
return SentryTags{}
}
// GetContextKey is getter for GinContextKey
// GetContextKey is getter for GinContextKey.
func (t *SentryTaggedScalar) GetContextKey() string {
return t.GinContextKey
}
// GetName is getter for Name (tag name for scalar)
// GetName is getter for Name (tag name for scalar).
func (t *SentryTaggedScalar) GetName() string {
return t.Name
}
@ -377,7 +378,7 @@ func (t *SentryTaggedScalar) Get(v interface{}) (value string, err error) {
return
}
// BuildTags returns map with single item in this format: <tag name> => <scalar value>
// BuildTags returns map with single item in this format: <tag name> => <scalar value>.
func (t *SentryTaggedScalar) BuildTags(v interface{}) (items map[string]string, err error) {
items = make(map[string]string)
if value, e := t.Get(v); e == nil {

View File

@ -125,7 +125,7 @@ func (n *simpleError) Error() string {
return n.msg
}
// wrappableError is a simple implementation of wrappable error
// wrappableError is a simple implementation of wrappable error.
type wrappableError struct {
msg string
err error

View File

@ -5,10 +5,10 @@ import (
"github.com/pkg/errors"
)
// ErrUnfeasibleBuilder will be returned if builder for stacktrace was chosen incorrectly
// ErrUnfeasibleBuilder will be returned if builder for stacktrace was chosen incorrectly.
var ErrUnfeasibleBuilder = errors.New("unfeasible builder for this error type")
// StackBuilderInterface is an interface for every stacktrace builder
// StackBuilderInterface is an interface for every stacktrace builder.
type StackBuilderInterface interface {
SetClient(RavenClientInterface) StackBuilderInterface
SetError(error) StackBuilderInterface
@ -16,7 +16,7 @@ type StackBuilderInterface interface {
GetResult() (*raven.Stacktrace, error)
}
// AbstractStackBuilder contains methods, which would be implemented in every builder anyway
// AbstractStackBuilder contains methods, which would be implemented in every builder anyway.
type AbstractStackBuilder struct {
err error
buildErr error
@ -30,7 +30,7 @@ func (a *AbstractStackBuilder) SetClient(client RavenClientInterface) StackBuild
return a
}
// SetError sets error in builder, which will be processed
// SetError sets error in builder, which will be processed.
func (a *AbstractStackBuilder) SetError(err error) StackBuilderInterface {
a.err = err
return a
@ -46,7 +46,7 @@ func (a *AbstractStackBuilder) GetResult() (*raven.Stacktrace, error) {
return a.stack, a.buildErr
}
// FallbackToGeneric fallbacks to GenericStackBuilder method
// FallbackToGeneric fallbacks to GenericStackBuilder method.
func (a *AbstractStackBuilder) FallbackToGeneric() {
a.stack, a.err = GenericStack(a.client), nil
}

View File

@ -4,27 +4,27 @@ import (
pkgErrors "github.com/pkg/errors"
)
// PkgErrorCauseable is an interface for checking Cause() method existence in the error
// PkgErrorCauseable is an interface for checking Cause() method existence in the error.
type PkgErrorCauseable interface {
Cause() error
}
// PkgErrorTraceable is an interface for checking StackTrace() method existence in the error
// PkgErrorTraceable is an interface for checking StackTrace() method existence in the error.
type PkgErrorTraceable interface {
StackTrace() pkgErrors.StackTrace
}
// PkgErrorsStackTransformer transforms stack data from github.com/pkg/errors error to stacktrace.Stacktrace
// PkgErrorsStackTransformer transforms stack data from github.com/pkg/errors error to stacktrace.Stacktrace.
type PkgErrorsStackTransformer struct {
stack pkgErrors.StackTrace
}
// NewPkgErrorsStackTransformer is a PkgErrorsStackTransformer constructor
// NewPkgErrorsStackTransformer is a PkgErrorsStackTransformer constructor.
func NewPkgErrorsStackTransformer(stack pkgErrors.StackTrace) *PkgErrorsStackTransformer {
return &PkgErrorsStackTransformer{stack: stack}
}
// Stack returns stacktrace (which is []uintptr internally, each uintptc is a pc)
// Stack returns stacktrace (which is []uintptr internally, each uintptc is a pc).
func (p *PkgErrorsStackTransformer) Stack() Stacktrace {
if p.stack == nil {
return Stacktrace{}
@ -37,12 +37,12 @@ func (p *PkgErrorsStackTransformer) Stack() Stacktrace {
return result
}
// PkgErrorsBuilder builds stacktrace with data from github.com/pkg/errors error
// PkgErrorsBuilder builds stacktrace with data from github.com/pkg/errors error.
type PkgErrorsBuilder struct {
AbstractStackBuilder
}
// Build stacktrace
// Build stacktrace.
func (b *PkgErrorsBuilder) Build() StackBuilderInterface {
if !isPkgErrors(b.err) {
b.buildErr = ErrUnfeasibleBuilder
@ -69,7 +69,7 @@ func (b *PkgErrorsBuilder) Build() StackBuilderInterface {
return b
}
// getErrorCause will try to extract original error from wrapper - it is used only if stacktrace is not present
// getErrorCause will try to extract original error from wrapper - it is used only if stacktrace is not present.
func (b *PkgErrorsBuilder) getErrorCause(err error) error {
causeable, ok := err.(PkgErrorCauseable)
if !ok {
@ -78,7 +78,8 @@ func (b *PkgErrorsBuilder) getErrorCause(err error) error {
return causeable.Cause()
}
// getErrorStackTrace will try to extract stacktrace from error using StackTrace method (default errors doesn't have it)
// getErrorStackTrace will try to extract stacktrace from error using StackTrace method
// (default errors doesn't have it).
func (b *PkgErrorsBuilder) getErrorStack(err error) pkgErrors.StackTrace {
traceable, ok := err.(PkgErrorTraceable)
if !ok {

View File

@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/suite"
)
// errorWithCause has Cause() method, but doesn't have StackTrace() method
// errorWithCause has Cause() method, but doesn't have StackTrace() method.
type errorWithCause struct {
msg string
cause error

View File

@ -10,31 +10,32 @@ import (
// Frame is a program counter inside a stack frame.
type Frame uintptr
// Stacktrace is stack of Frames
// Stacktrace is stack of Frames.
type Stacktrace []Frame
// RavenStackTransformer is an interface for any component, which will transform some unknown stacktrace data to stacktrace.Stacktrace
// RavenStackTransformer is an interface for any component, which will transform some
// unknown stacktrace data to stacktrace.Stacktrace.
type RavenStackTransformer interface {
Stack() Stacktrace
}
// RavenStacktraceBuilder builds *raven.Stacktrace for any generic stack data
// RavenStacktraceBuilder builds *raven.Stacktrace for any generic stack data.
type RavenStacktraceBuilder struct {
transformer RavenStackTransformer
}
// NewRavenStacktraceBuilder is a RavenStacktraceBuilder constructor
// NewRavenStacktraceBuilder is a RavenStacktraceBuilder constructor.
func NewRavenStacktraceBuilder(p RavenStackTransformer) *RavenStacktraceBuilder {
return (&RavenStacktraceBuilder{}).SetTransformer(p)
}
// SetTransformer sets stack transformer into stacktrace builder
// SetTransformer sets stack transformer into stacktrace builder.
func (b *RavenStacktraceBuilder) SetTransformer(p RavenStackTransformer) *RavenStacktraceBuilder {
b.transformer = p
return b
}
// Build converts generic stacktrace to to github.com/getsentry/raven-go.Stacktrace
// Build converts generic stacktrace to to github.com/getsentry/raven-go.Stacktrace.
func (b *RavenStacktraceBuilder) Build(context int, appPackagePrefixes []string) *raven.Stacktrace {
// This code is borrowed from github.com/getsentry/raven-go.NewStacktrace().
var frames []*raven.StacktraceFrame
@ -53,7 +54,7 @@ func (b *RavenStacktraceBuilder) Build(context int, appPackagePrefixes []string)
return &raven.Stacktrace{Frames: frames}
}
// convertFrame converts single generic stacktrace frame to github.com/pkg/errors.Frame
// convertFrame converts single generic stacktrace frame to github.com/pkg/errors.Frame.
func (b *RavenStacktraceBuilder) convertFrame(f Frame, context int, appPackagePrefixes []string) *raven.StacktraceFrame {
// This code is borrowed from github.com/pkg/errors.Frame.
pc := uintptr(f) - 1

View File

@ -14,7 +14,7 @@ func GetStackBuilderByErrorType(err error) StackBuilderInterface {
return &GenericStackBuilder{AbstractStackBuilder{err: err}}
}
// isPkgErrors returns true if passed error might be github.com/pkg/errors error
// isPkgErrors returns true if passed error might be github.com/pkg/errors error.
func isPkgErrors(err error) bool {
_, okTraceable := err.(PkgErrorTraceable)
_, okCauseable := err.(PkgErrorCauseable)

View File

@ -4,17 +4,17 @@ import (
"github.com/getsentry/raven-go"
)
// Unwrappable is the interface for errors with Unwrap() method
// Unwrappable is the interface for errors with Unwrap() method.
type Unwrappable interface {
Unwrap() error
}
// UnwrapBuilder builds stacktrace from the chain of wrapped errors
// UnwrapBuilder builds stacktrace from the chain of wrapped errors.
type UnwrapBuilder struct {
AbstractStackBuilder
}
// Build stacktrace
// Build stacktrace.
func (b *UnwrapBuilder) Build() StackBuilderInterface {
if _, ok := b.err.(Unwrappable); !ok {
b.buildErr = ErrUnfeasibleBuilder

View File

@ -23,7 +23,7 @@ func (n *simpleError) Error() string {
return n.msg
}
// wrappableError is a simple implementation of wrappable error
// wrappableError is a simple implementation of wrappable error.
type wrappableError struct {
msg string
err error

View File

@ -7,7 +7,7 @@ import (
"github.com/gobuffalo/packr/v2"
)
// Renderer wraps multitemplate.Renderer in order to make it easier to use
// Renderer wraps multitemplate.Renderer in order to make it easier to use.
type Renderer struct {
multitemplate.Renderer
TemplatesBox *packr.Box
@ -15,22 +15,22 @@ type Renderer struct {
alreadyAdded map[string]*template.Template
}
// NewRenderer is a Renderer constructor
// NewRenderer is a Renderer constructor.
func NewRenderer(funcMap template.FuncMap) Renderer {
return newRendererWithMultitemplate(funcMap, multitemplate.NewRenderer())
}
// NewStaticRenderer is a Renderer constructor with multitemplate.Render
// NewStaticRenderer is a Renderer constructor with multitemplate.Render.
func NewStaticRenderer(funcMap template.FuncMap) Renderer {
return newRendererWithMultitemplate(funcMap, multitemplate.New())
}
// NewDynamicRenderer is a Renderer constructor with multitemplate.DynamicRender
// NewDynamicRenderer is a Renderer constructor with multitemplate.DynamicRender.
func NewDynamicRenderer(funcMap template.FuncMap) Renderer {
return newRendererWithMultitemplate(funcMap, multitemplate.NewDynamic())
}
// newRendererWithMultitemplate initializes Renderer with provided multitemplate.Renderer instance
// newRendererWithMultitemplate initializes Renderer with provided multitemplate.Renderer instance.
func newRendererWithMultitemplate(funcMap template.FuncMap, renderer multitemplate.Renderer) Renderer {
return Renderer{
Renderer: renderer,
@ -39,7 +39,7 @@ func newRendererWithMultitemplate(funcMap template.FuncMap, renderer multitempla
}
}
// Push is an AddFromFilesFuncs wrapper
// Push is an AddFromFilesFuncs wrapper.
func (r *Renderer) Push(name string, files ...string) *template.Template {
if tpl := r.getTemplate(name); tpl != nil {
return tpl
@ -52,7 +52,7 @@ func (r *Renderer) Push(name string, files ...string) *template.Template {
return r.storeTemplate(name, r.addFromBox(name, r.FuncMap, files...))
}
// addFromBox adds embedded template
// addFromBox adds embedded template.
func (r *Renderer) addFromBox(name string, funcMap template.FuncMap, files ...string) *template.Template {
var filesData []string
@ -76,7 +76,7 @@ func (r *Renderer) storeTemplate(name string, tpl *template.Template) *template.
return tpl
}
// getTemplate returns template from render or from storage
// getTemplate returns template from render or from storage.
func (r *Renderer) getTemplate(name string) *template.Template {
if renderer, ok := r.Renderer.(multitemplate.Render); ok {
if i, ok := renderer[name]; ok {

View File

@ -23,12 +23,13 @@ type TranslationsExtractor struct {
TranslationsPath string
}
// NewTranslationsExtractor constructor. Use "translate.{}.yml" as template if your translations are named like "translate.en.yml"
// NewTranslationsExtractor constructor. Use "translate.{}.yml" as template
// if your translations are named like "translate.en.yml".
func NewTranslationsExtractor(fileNameTemplate string) *TranslationsExtractor {
return &TranslationsExtractor{fileNameTemplate: fileNameTemplate}
}
// unmarshalToMap returns map with unmarshaled data or error
// unmarshalToMap returns map with unmarshaled data or error.
func (t *TranslationsExtractor) unmarshalToMap(in []byte) (map[string]interface{}, error) {
var dataMap map[string]interface{}
@ -39,7 +40,7 @@ func (t *TranslationsExtractor) unmarshalToMap(in []byte) (map[string]interface{
return dataMap, nil
}
// loadYAMLBox loads YAML from box
// loadYAMLBox loads YAML from box.
func (t *TranslationsExtractor) loadYAMLBox(fileName string) (map[string]interface{}, error) {
var (
dataMap map[string]interface{}
@ -54,7 +55,7 @@ func (t *TranslationsExtractor) loadYAMLBox(fileName string) (map[string]interfa
return t.unmarshalToMap(data)
}
// loadYAMLFile loads YAML from file
// loadYAMLFile loads YAML from file.
func (t *TranslationsExtractor) loadYAMLFile(fileName string) (map[string]interface{}, error) {
var (
dataMap map[string]interface{}
@ -98,7 +99,7 @@ func (t *TranslationsExtractor) loadYAML(fileName string) (map[string]interface{
}
}
// GetMapKeys returns sorted map keys from map[string]interface{} - useful to check keys in several translation files
// GetMapKeys returns sorted map keys from map[string]interface{} - useful to check keys in several translation files.
func (t *TranslationsExtractor) GetMapKeys(data map[string]interface{}) []string {
keys := make([]string, len(data))
@ -113,12 +114,12 @@ func (t *TranslationsExtractor) GetMapKeys(data map[string]interface{}) []string
return keys
}
// LoadLocale returns translation file data with provided locale
// LoadLocale returns translation file data with provided locale.
func (t *TranslationsExtractor) LoadLocale(locale string) (map[string]interface{}, error) {
return t.loadYAML(strings.Replace(t.fileNameTemplate, "{}", locale, 1))
}
// LoadLocaleKeys returns only sorted keys from translation file
// LoadLocaleKeys returns only sorted keys from translation file.
func (t *TranslationsExtractor) LoadLocaleKeys(locale string) ([]string, error) {
var (
data map[string]interface{}

View File

@ -73,7 +73,7 @@ var defaultCurrencies = map[string]string{
"gbp": "£",
}
// Utils service object
// Utils service object.
type Utils struct {
IsDebug bool
TokenCounter uint32
@ -82,7 +82,7 @@ type Utils struct {
slashRegex *regexp.Regexp
}
// NewUtils will create new Utils instance
// NewUtils will create new Utils instance.
func NewUtils(awsConfig ConfigAWS, logger LoggerInterface, debug bool) *Utils {
return &Utils{
IsDebug: debug,
@ -93,7 +93,7 @@ func NewUtils(awsConfig ConfigAWS, logger LoggerInterface, debug bool) *Utils {
}
}
// resetUtils
// resetUtils.
func (u *Utils) resetUtils(awsConfig ConfigAWS, debug bool, tokenCounter uint32) {
u.TokenCounter = tokenCounter
u.ConfigAWS = awsConfig
@ -108,7 +108,7 @@ func (u *Utils) GenerateToken() string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(fmt.Sprintf("%d%d", time.Now().UnixNano(), c))))
}
// GetAPIClient will initialize RetailCRM api client from url and key
// GetAPIClient will initialize RetailCRM api client from url and key.
func (u *Utils) GetAPIClient(url, key string) (*v5.Client, int, error) {
client := v5.New(url, key)
client.Debug = u.IsDebug
@ -117,7 +117,6 @@ func (u *Utils) GetAPIClient(url, key string) (*v5.Client, int, error) {
if e != nil && e.Error() != "" {
u.Logger.Error(url, status, e.Error(), cr)
return nil, http.StatusInternalServerError, errors.New(e.Error())
}
if !cr.Success {
@ -166,7 +165,7 @@ func (u *Utils) checkCredentials(credential []string) []string {
return rc
}
// UploadUserAvatar will upload avatar for user
// UploadUserAvatar will upload avatar for user.
func (u *Utils) UploadUserAvatar(url string) (picURLs3 string, err error) {
s3Config := &aws.Config{
Credentials: credentials.NewStaticCredentials(
@ -206,12 +205,12 @@ func (u *Utils) UploadUserAvatar(url string) (picURLs3 string, err error) {
return
}
// RemoveTrailingSlash will remove slash at the end of any string
// RemoveTrailingSlash will remove slash at the end of any string.
func (u *Utils) RemoveTrailingSlash(crmURL string) string {
return u.slashRegex.ReplaceAllString(crmURL, ``)
}
// GetMGItemData will upload file to MG by URL and return information about attachable item
// GetMGItemData will upload file to MG by URL and return information about attachable item.
func GetMGItemData(client *v1.MgClient, url string, caption string) (v1.Item, int, error) {
item := v1.Item{}
@ -230,7 +229,7 @@ func GetMGItemData(client *v1.MgClient, url string, caption string) (v1.Item, in
return item, st, err
}
// GetEntitySHA1 will serialize any value to JSON and return SHA1 hash of this JSON
// GetEntitySHA1 will serialize any value to JSON and return SHA1 hash of this JSON.
func GetEntitySHA1(v interface{}) (hash string, err error) {
res, _ := json.Marshal(v)
@ -242,7 +241,7 @@ func GetEntitySHA1(v interface{}) (hash string, err error) {
return
}
// ReplaceMarkdownSymbols will remove markdown symbols from text
// ReplaceMarkdownSymbols will remove markdown symbols from text.
func ReplaceMarkdownSymbols(s string) string {
for _, v := range markdownSymbols {
s = strings.Replace(s, v, "\\"+v, -1)
@ -251,13 +250,13 @@ func ReplaceMarkdownSymbols(s string) string {
return s
}
// DefaultCurrencies will return default currencies list for all bots
// DefaultCurrencies will return default currencies list for all bots.
func DefaultCurrencies() map[string]string {
return defaultCurrencies
}
// GetCurrencySymbol returns currency symbol by it's ISO 4127 code.
// It returns provided currency code in uppercase if currency symbol cannot be found
// It returns provided currency code in uppercase if currency symbol cannot be found.
func GetCurrencySymbol(code string) string {
if i, ok := DefaultCurrencies()[strings.ToLower(code)]; ok {
return i

View File

@ -243,7 +243,7 @@ func TestUtils_GetEntitySHA1(t *testing.T) {
}
func TestUtils_GetCurrencySymbol(t *testing.T) {
for code, _ := range DefaultCurrencies() {
for code := range DefaultCurrencies() {
if strings.ToUpper(code) == defaultCurrencies[code] {
continue
}

View File

@ -5,7 +5,7 @@ import (
"github.com/go-playground/validator/v10"
)
// init here will register `validatecrmurl` function for gin validator
// init here will register `validatecrmurl` function for gin validator.
func init() {
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
if err := v.RegisterValidation("validatecrmurl", validateCrmURL); err != nil {
@ -14,7 +14,7 @@ func init() {
}
}
// validateCrmURL will validate CRM URL
// validateCrmURL will validate CRM URL.
func validateCrmURL(fl validator.FieldLevel) bool {
return regCommandName.Match([]byte(fl.Field().String()))
}