update linter
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
|
||||
linters-settings:
|
||||
version: "2"
|
||||
linters:
|
||||
default: all
|
||||
disable:
|
||||
- noinlineerr
|
||||
- depguard
|
||||
- ireturn
|
||||
# deprecated
|
||||
- wsl
|
||||
settings:
|
||||
dupl:
|
||||
threshold: 100
|
||||
funlen:
|
||||
@@ -12,16 +18,10 @@ linters-settings:
|
||||
min-occurrences: 2
|
||||
gocyclo:
|
||||
min-complexity: 15
|
||||
golint:
|
||||
min-confidence: 0
|
||||
govet:
|
||||
check-shadowing: true
|
||||
lll:
|
||||
line-length: 140
|
||||
maligned:
|
||||
suggest-new: true
|
||||
misspell:
|
||||
locale: US
|
||||
locale: US
|
||||
varnamelen:
|
||||
min-name-length: 2
|
||||
ignore-decls:
|
||||
@@ -31,43 +31,39 @@ linters-settings:
|
||||
- i int
|
||||
- b bytes.Buffer
|
||||
- h Handle
|
||||
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- exhaustivestruct
|
||||
- maligned
|
||||
- interfacer
|
||||
- scopelint
|
||||
- exhaustruct
|
||||
- depguard
|
||||
- nolintlint
|
||||
#deprecated
|
||||
- structcheck
|
||||
- varcheck
|
||||
- golint
|
||||
- deadcode
|
||||
- ifshort
|
||||
- nosnakecase
|
||||
|
||||
- ireturn # implement provider interface
|
||||
|
||||
issues:
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- wrapcheck
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
- tenv
|
||||
- funlen
|
||||
- path: test/*
|
||||
linters:
|
||||
- gomnd
|
||||
- exhaustivestruct
|
||||
- wrapcheck
|
||||
- exhaustruct
|
||||
- varnamelen
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- linters:
|
||||
- exhaustivestruct
|
||||
- exhaustruct
|
||||
- funlen
|
||||
- mnd
|
||||
- tenv
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
path: _test\.go
|
||||
- linters:
|
||||
- exhaustivestruct
|
||||
- exhaustruct
|
||||
- mnd
|
||||
- varnamelen
|
||||
- wrapcheck
|
||||
path: test/*
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
default: all
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
|
||||
43
client.go
43
client.go
@@ -8,7 +8,7 @@ import (
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
func Must(providers ...interface{}) *Client {
|
||||
func Must(providers ...any) *Client {
|
||||
client, err := New(providers...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -17,7 +17,7 @@ func Must(providers ...interface{}) *Client {
|
||||
return client
|
||||
}
|
||||
|
||||
func New(providers ...interface{}) (*Client, error) {
|
||||
func New(providers ...any) (*Client, error) {
|
||||
client := &Client{
|
||||
providers: make([]Provider, len(providers)),
|
||||
}
|
||||
@@ -31,6 +31,9 @@ func New(providers ...interface{}) (*Client, error) {
|
||||
factory: func(ctx context.Context) (Provider, error) {
|
||||
return current(ctx, client)
|
||||
},
|
||||
mu: sync.Mutex{},
|
||||
done: 0,
|
||||
provider: nil,
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("provier[%d]: %w %T", idx, ErrUnknowType, prov)
|
||||
@@ -47,23 +50,6 @@ type provider struct {
|
||||
factory func(ctx context.Context) (Provider, error)
|
||||
}
|
||||
|
||||
func (p *provider) init(ctx context.Context) error {
|
||||
if atomic.LoadUint32(&p.done) == 0 {
|
||||
if !p.mu.TryLock() {
|
||||
return fmt.Errorf("%w", ErrInitFactory)
|
||||
}
|
||||
defer atomic.StoreUint32(&p.done, 1)
|
||||
defer p.mu.Unlock()
|
||||
|
||||
var err error
|
||||
if p.provider, err = p.factory(ctx); err != nil {
|
||||
return fmt.Errorf("init provider factory:%w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *provider) Watch(ctx context.Context, callback WatchCallback, path ...string) error {
|
||||
if err := p.init(ctx); err != nil {
|
||||
return fmt.Errorf("init read:%w", err)
|
||||
@@ -94,6 +80,23 @@ func (p *provider) Value(ctx context.Context, path ...string) (Value, error) {
|
||||
return variable, nil
|
||||
}
|
||||
|
||||
func (p *provider) init(ctx context.Context) error {
|
||||
if atomic.LoadUint32(&p.done) == 0 {
|
||||
if !p.mu.TryLock() {
|
||||
return fmt.Errorf("%w", ErrInitFactory)
|
||||
}
|
||||
defer atomic.StoreUint32(&p.done, 1)
|
||||
defer p.mu.Unlock()
|
||||
|
||||
var err error
|
||||
if p.provider, err = p.factory(ctx); err != nil {
|
||||
return fmt.Errorf("init provider factory:%w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
providers []Provider
|
||||
}
|
||||
@@ -111,7 +114,7 @@ func (c *Client) Value(ctx context.Context, path ...string) (Value, error) {
|
||||
|
||||
for _, provider := range c.providers {
|
||||
value, err = provider.Value(ctx, path...)
|
||||
if err == nil || !(errors.Is(err, ErrValueNotFound) || errors.Is(err, ErrInitFactory)) {
|
||||
if err == nil || (!errors.Is(err, ErrValueNotFound) && !errors.Is(err, ErrInitFactory)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func ExampleClient_Watch() {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
err = watcher.Watch(ctx, func(ctx context.Context, oldVar, newVar config.Value) error {
|
||||
err = watcher.Watch(ctx, func(_ context.Context, oldVar, newVar config.Value) error {
|
||||
fmt.Println("update example_enable old: ", oldVar.Bool(), " new:", newVar.Bool())
|
||||
wg.Done()
|
||||
|
||||
@@ -93,7 +93,7 @@ func ExampleClient_Watch() {
|
||||
|
||||
_ = os.Setenv("FDEVS_CONFIG_EXAMPLE_ENABLE", "false")
|
||||
|
||||
err = watcher.Watch(ctx, func(ctx context.Context, oldVar, newVar config.Value) error {
|
||||
err = watcher.Watch(ctx, func(_ context.Context, oldVar, newVar config.Value) error {
|
||||
fmt.Println("update example_db_dsn old: ", oldVar.String(), " new:", newVar.String())
|
||||
wg.Done()
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ func (v View) Parse(valName string, value string, keys []string) string {
|
||||
return data
|
||||
}
|
||||
|
||||
//nolint:gochecknoglobals,unparam
|
||||
//nolint:gochecknoglobals
|
||||
var parses = map[string]func(data ParseData) (string, error){
|
||||
typesIntreface[0].Name(): func(data ParseData) (string, error) {
|
||||
var b bytes.Buffer
|
||||
|
||||
@@ -43,8 +43,44 @@ type Provider struct {
|
||||
name string
|
||||
}
|
||||
|
||||
// nolint: cyclop
|
||||
// return name, value, error.
|
||||
func (p *Provider) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *Provider) Value(_ context.Context, path ...string) (config.Value, error) {
|
||||
err := p.parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := p.key(path...)
|
||||
if val, ok := p.args[name]; ok {
|
||||
switch {
|
||||
case len(val) == 1:
|
||||
return value.JString(val[0]), nil
|
||||
default:
|
||||
data, jerr := json.Marshal(val)
|
||||
if jerr != nil {
|
||||
return nil, fmt.Errorf("failed load data:%w", jerr)
|
||||
}
|
||||
|
||||
return value.Decode(func(v any) error {
|
||||
err := json.Unmarshal(data, v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshal:%w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%s:%w", p.Name(), config.ErrValueNotFound)
|
||||
}
|
||||
|
||||
// parseOne return name, value, error.
|
||||
//
|
||||
//nolint:cyclop
|
||||
func (p *Provider) parseOne(arg string) (string, string, error) {
|
||||
if arg[0] != '-' {
|
||||
return "", "", nil
|
||||
@@ -101,36 +137,3 @@ func (p *Provider) parse() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *Provider) Value(_ context.Context, path ...string) (config.Value, error) {
|
||||
if err := p.parse(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := p.key(path...)
|
||||
if val, ok := p.args[name]; ok {
|
||||
switch {
|
||||
case len(val) == 1:
|
||||
return value.JString(val[0]), nil
|
||||
default:
|
||||
data, jerr := json.Marshal(val)
|
||||
if jerr != nil {
|
||||
return nil, fmt.Errorf("failed load data:%w", jerr)
|
||||
}
|
||||
|
||||
return value.Decode(func(v interface{}) error {
|
||||
if err := json.Unmarshal(data, v); err != nil {
|
||||
return fmt.Errorf("unmarshal:%w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%s:%w", p.Name(), config.ErrValueNotFound)
|
||||
}
|
||||
|
||||
@@ -65,5 +65,5 @@ func (d *Duration) UnmarshalJSON(in []byte) error {
|
||||
}
|
||||
|
||||
func (d *Duration) MarshalJSON() ([]byte, error) {
|
||||
return []byte(fmt.Sprintf("%q", d)), nil
|
||||
return fmt.Appendf(nil, "%q", d), nil
|
||||
}
|
||||
|
||||
1
provider/env/provider.go
vendored
1
provider/env/provider.go
vendored
@@ -26,6 +26,7 @@ func New(namespace, appName string, opts ...Option) *Provider {
|
||||
return strings.ToUpper(strings.Join(path, "_"))
|
||||
},
|
||||
prefix: strings.ToUpper(namespace + "_" + appName + "_"),
|
||||
name: "",
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
|
||||
7
provider/env/provider_test.go
vendored
7
provider/env/provider_test.go
vendored
@@ -1,7 +1,6 @@
|
||||
package env_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/config/provider/env"
|
||||
@@ -9,10 +8,8 @@ import (
|
||||
)
|
||||
|
||||
func TestProvider(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
os.Setenv("FDEVS_CONFIG_DSN", test.DSN)
|
||||
os.Setenv("FDEVS_CONFIG_PORT", "8080")
|
||||
t.Setenv("FDEVS_CONFIG_DSN", test.DSN)
|
||||
t.Setenv("FDEVS_CONFIG_PORT", "8080")
|
||||
|
||||
provider := env.New("fdevs", "config")
|
||||
|
||||
|
||||
@@ -39,18 +39,20 @@ type Option func(*Provider)
|
||||
|
||||
type Provider struct {
|
||||
config.Provider
|
||||
|
||||
duration time.Duration
|
||||
logger func(context.Context, string, ...any)
|
||||
}
|
||||
|
||||
func (p *Provider) Watch(ctx context.Context, callback config.WatchCallback, key ...string) error {
|
||||
old, err := p.Provider.Value(ctx, key...)
|
||||
old, err := p.Value(ctx, key...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed watch variable: %w", err)
|
||||
}
|
||||
|
||||
go func(oldVar config.Value) {
|
||||
ticker := time.NewTicker(p.duration)
|
||||
|
||||
defer func() {
|
||||
ticker.Stop()
|
||||
}()
|
||||
@@ -58,7 +60,7 @@ func (p *Provider) Watch(ctx context.Context, callback config.WatchCallback, key
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
newVar, err := p.Provider.Value(ctx, key...)
|
||||
newVar, err := p.Value(ctx, key...)
|
||||
if err != nil {
|
||||
p.logger(ctx, "get value%v:%v", key, err.Error())
|
||||
} else if !newVar.IsEquals(oldVar) {
|
||||
@@ -66,8 +68,10 @@ func (p *Provider) Watch(ctx context.Context, callback config.WatchCallback, key
|
||||
if errors.Is(err, config.ErrStopWatch) {
|
||||
return
|
||||
}
|
||||
|
||||
p.logger(ctx, "callback %v:%v", key, err)
|
||||
}
|
||||
|
||||
oldVar = newVar
|
||||
}
|
||||
case <-ctx.Done():
|
||||
|
||||
@@ -34,6 +34,7 @@ func TestWatcher(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
||||
|
||||
defer func() {
|
||||
cancel()
|
||||
}()
|
||||
@@ -48,9 +49,10 @@ func TestWatcher(t *testing.T) {
|
||||
|
||||
err := w.Watch(
|
||||
ctx,
|
||||
func(ctx context.Context, oldVar, newVar config.Value) error {
|
||||
func(_ context.Context, _, _ config.Value) error {
|
||||
atomic.AddInt32(&cnt, 1)
|
||||
wg.Done()
|
||||
|
||||
if atomic.LoadInt32(&cnt) == 2 {
|
||||
return config.ErrStopWatch
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Equal(t *testing.T, expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
func Equal(t *testing.T, expected any, actual any, msgAndArgs ...any) bool {
|
||||
t.Helper()
|
||||
|
||||
if reflect.DeepEqual(expected, actual) {
|
||||
@@ -17,7 +17,7 @@ func Equal(t *testing.T, expected interface{}, actual interface{}, msgAndArgs ..
|
||||
return false
|
||||
}
|
||||
|
||||
func Equalf(t *testing.T, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
func Equalf(t *testing.T, expected any, actual any, msg string, args ...any) bool {
|
||||
t.Helper()
|
||||
|
||||
if reflect.DeepEqual(expected, actual) {
|
||||
|
||||
@@ -2,7 +2,7 @@ package assert
|
||||
|
||||
import "testing"
|
||||
|
||||
func Nil(t *testing.T, data any, msgAndArgs ...interface{}) bool {
|
||||
func Nil(t *testing.T, data any, msgAndArgs ...any) bool {
|
||||
t.Helper()
|
||||
|
||||
if data != nil {
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewReadConfig(key ...string) Read {
|
||||
return NewReadUnmarshal(ex, &Config{}, key...)
|
||||
}
|
||||
|
||||
func NewReadUnmarshal(expected, target interface{}, key ...string) Read {
|
||||
func NewReadUnmarshal(expected, target any, key ...string) Read {
|
||||
return Read{
|
||||
Key: key,
|
||||
Assert: func(t *testing.T, v config.Value) {
|
||||
@@ -66,17 +66,21 @@ func Time(value string) time.Time {
|
||||
return t
|
||||
}
|
||||
|
||||
// nolint: cyclop
|
||||
func NewRead(expected interface{}, key ...string) Read {
|
||||
// NewRead test data.
|
||||
//
|
||||
//nolint:cyclop
|
||||
func NewRead(expected any, key ...string) Read {
|
||||
return Read{
|
||||
Key: key,
|
||||
Assert: func(t *testing.T, v config.Value) {
|
||||
t.Helper()
|
||||
|
||||
var (
|
||||
val interface{}
|
||||
val any
|
||||
err error
|
||||
short interface{}
|
||||
short any
|
||||
)
|
||||
|
||||
switch expected.(type) {
|
||||
case bool:
|
||||
val, err = v.ParseBool()
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"gitoa.ru/go-4devs/config/test/assert"
|
||||
)
|
||||
|
||||
func Equal(t *testing.T, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
func Equal(t *testing.T, expected any, actual any, msgAndArgs ...any) {
|
||||
t.Helper()
|
||||
|
||||
if assert.Equal(t, expected, actual, msgAndArgs...) {
|
||||
@@ -16,7 +16,7 @@ func Equal(t *testing.T, expected interface{}, actual interface{}, msgAndArgs ..
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
func Equalf(t *testing.T, expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
func Equalf(t *testing.T, expected any, actual any, msg string, args ...any) {
|
||||
t.Helper()
|
||||
|
||||
if assert.Equalf(t, expected, actual, msg, args...) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func NoError(t *testing.T, err error, msgAndArgs ...interface{}) {
|
||||
func NoError(t *testing.T, err error, msgAndArgs ...any) {
|
||||
t.Helper()
|
||||
|
||||
if err != nil {
|
||||
@@ -13,7 +13,7 @@ func NoError(t *testing.T, err error, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func NoErrorf(t *testing.T, err error, msg string, args ...interface{}) {
|
||||
func NoErrorf(t *testing.T, err error, msg string, args ...any) {
|
||||
t.Helper()
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -2,7 +2,7 @@ package require
|
||||
|
||||
import "testing"
|
||||
|
||||
func Fail(t *testing.T, msg string, args ...interface{}) {
|
||||
func Fail(t *testing.T, msg string, args ...any) {
|
||||
t.Helper()
|
||||
t.Errorf(msg, args...)
|
||||
t.FailNow()
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Truef(t *testing.T, value bool, msg string, args ...interface{}) {
|
||||
func Truef(t *testing.T, value bool, msg string, args ...any) {
|
||||
t.Helper()
|
||||
|
||||
if !value {
|
||||
|
||||
2
value.go
2
value.go
@@ -12,7 +12,7 @@ type Value interface {
|
||||
}
|
||||
|
||||
type UnmarshalValue interface {
|
||||
Unmarshal(val interface{}) error
|
||||
Unmarshal(val any) error
|
||||
}
|
||||
|
||||
type ReadValue interface {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// nolint: nonamedreturns
|
||||
// Package value decode value.
|
||||
//
|
||||
//nolint:nonamedreturns
|
||||
package value
|
||||
|
||||
import (
|
||||
@@ -9,9 +11,9 @@ import (
|
||||
|
||||
var _ config.Value = (*Decode)(nil)
|
||||
|
||||
type Decode func(v interface{}) error
|
||||
type Decode func(v any) error
|
||||
|
||||
func (s Decode) Unmarshal(v interface{}) error {
|
||||
func (s Decode) Unmarshal(v any) error {
|
||||
return s(v)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ type Empty struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e Empty) Unmarshal(_ interface{}) error {
|
||||
func (e Empty) Unmarshal(_ any) error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ func ParseBool(s string) (bool, error) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func JUnmarshal(b []byte, v interface{}) error {
|
||||
func JUnmarshal(b []byte, v any) error {
|
||||
if err := json.Unmarshal(b, v); err != nil {
|
||||
return fmt.Errorf("%w: %w", config.ErrInvalidValue, err)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ var _ config.Value = (*JBytes)(nil)
|
||||
|
||||
type JBytes []byte
|
||||
|
||||
func (s JBytes) Unmarshal(v interface{}) error {
|
||||
func (s JBytes) Unmarshal(v any) error {
|
||||
return JUnmarshal(s.Bytes(), v)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ var _ config.Value = (*JString)(nil)
|
||||
|
||||
type JString string
|
||||
|
||||
func (s JString) Unmarshal(v interface{}) error {
|
||||
func (s JString) Unmarshal(v any) error {
|
||||
return JUnmarshal(s.Bytes(), v)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
var _ config.Value = (*Value)(nil)
|
||||
|
||||
type Value struct {
|
||||
Val interface{}
|
||||
Val any
|
||||
}
|
||||
|
||||
func (s Value) Int() int {
|
||||
@@ -62,7 +62,7 @@ func (s Value) Duration() time.Duration {
|
||||
return v
|
||||
}
|
||||
|
||||
func (s Value) Raw() interface{} {
|
||||
func (s Value) Raw() any {
|
||||
return s.Val
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ func (s Value) Time() time.Time {
|
||||
return v
|
||||
}
|
||||
|
||||
func (s Value) Unmarshal(target interface{}) error {
|
||||
func (s Value) Unmarshal(target any) error {
|
||||
if v, ok := s.Raw().([]byte); ok {
|
||||
err := json.Unmarshal(v, target)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user