feat: update & fix lints

This commit is contained in:
Kevin Franklin Kim 2024-04-16 09:38:28 +02:00
parent 686ef11205
commit 8882274093
No known key found for this signature in database
18 changed files with 248 additions and 112 deletions

View File

@ -1,90 +1,229 @@
run: run:
timeout: 5m timeout: 5m
skip-dirs:
- tmp issues:
exclude-dirs:
- 'bin'
- 'tmp'
- 'vendor'
exclude-rules:
- path: _test\.go
linters:
- forcetypeassert
- gocheckcompilerdirectives
linters-settings: linters-settings:
# https://golangci-lint.run/usage/linters/#revive # https://golangci-lint.run/usage/linters/#misspell
revive: misspell:
rules: mode: restricted
- name: indent-error-flow # https://golangci-lint.run/usage/linters/#asasalint
disabled: true asasalint:
- name: exported ignore-test: true
disabled: true # https://golangci-lint.run/usage/linters/#exhaustive
exhaustive:
default-signifies-exhaustive: true
# https://golangci-lint.run/usage/linters/#gocritic # https://golangci-lint.run/usage/linters/#gocritic
gocritic: gocritic:
enabled-tags:
- diagnostic
- performance
- style
disabled-tags:
- experimental
- opinionated
disabled-checks: disabled-checks:
- assignOp
- ifElseChain - ifElseChain
settings: # https://golangci-lint.run/usage/linters/#testifylint
hugeParam: testifylint:
sizeThreshold: 512 disable:
- float-compare
# https://golangci-lint.run/usage/linters/#gosec # https://golangci-lint.run/usage/linters/#gosec
gosec: gosec:
config: confidence: medium
G306: "0700" # https://golangci-lint.run/usage/linters/#revive
excludes: revive:
- G101 # Potential hardcoded credentials enable-all-rules: true
- G102 # Bind to all interfaces ignore-generated-header: true
- G112 # Potential slowloris attack rules:
- G401 # Detect the usage of DES, RC4, MD5 or SHA1 - name: line-length-limit
- G402 # Look for bad TLS connection settings disabled: true
- G404 # Insecure random number source (rand) #- name: if-return
- G501 # Import blocklist: crypto/md5 # disabled: true
- G505 # Import blocklist: crypto/sha1 #- name: bare-return
# disabled: true
- name: cognitive-complexity
disabled: true
- name: unused-parameter
disabled: true
- name: add-constant
disabled: true
- name: indent-error-flow
disabled: true
- name: cyclomatic
disabled: true
- name: function-length
disabled: true
- name: early-return
disabled: true
#- name: nested-structs
# disabled: true
#- name: var-naming
# disabled: true
- name: use-any
disabled: true
- name: max-public-structs
disabled: true
#- name: function-result-limit
# disabled: true
- name: flag-parameter
disabled: true
- name: unused-receiver
disabled: true
#- name: argument-limit
# disabled: true
#- name: empty-lines
# disabled: true
- name: confusing-naming
disabled: true
#- name: import-alias-naming
# disabled: true
- name: empty-block
disabled: true
#- name: import-shadowing
# disabled: true
- name: unhandled-error
arguments:
- "fmt.Printf"
- "fmt.Println"
#- name: max-control-nesting
# disabled: true
- name: exported
disabled: true
#- name: unchecked-type-assertion
# disabled: true
#- name: unnecessary-stmt
# disabled: true
#- name: get-return
# disabled: true
#- name: context-keys-type
# disabled: true
#- name: comment-spacings
# disabled: true
#- name: struct-tag
# disabled: true
#- name: confusing-results
# disabled: true
- name: superfluous-else
disabled: true
- name: unexported-return
disabled: true
#- name: error-return
# disabled: true
#- name: redefines-builtin-id
# disabled: true
linters: linters:
disable-all: true
enable: enable:
# Enabled by default linters: # Enabled by default linters:
- errcheck - errcheck # errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases [fast: false, auto-fix: false]
- gosimple - gosimple # (megacheck) Linter for Go source code that specializes in simplifying code [fast: false, auto-fix: false]
- govet - govet # (vet, vetshadow) Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes. [fast: false, auto-fix: false]
- ineffassign - ineffassign # Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
- staticcheck - staticcheck # (megacheck) It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint. [fast: false, auto-fix: false]
- unused # (megacheck) Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
# Disabled by default linters: # Disabled by your configuration linters:
- asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers [fast: true, auto-fix: false] - asasalint # check for pass []any as any in variadic func(...any) [fast: false, auto-fix: false]
- asciicheck # checks that all code identifiers does not have non-ASCII symbols in the name [fast: true, auto-fix: false]
- bidichk # Checks for dangerous unicode character sequences [fast: true, auto-fix: false] - bidichk # Checks for dangerous unicode character sequences [fast: true, auto-fix: false]
- bodyclose # checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
#- containedctx # containedctx is a linter that detects struct contained context.Context field [fast: false, auto-fix: false]
- contextcheck # check whether the function uses a non-inherited context [fast: false, auto-fix: false]
#- copyloopvar # (go >= 1.22) copyloopvar is a linter detects places where loop variables are copied [fast: true, auto-fix: false]
#- cyclop # checks function and package cyclomatic complexity [fast: false, auto-fix: false]
- decorder # check declaration order and count of types, constants, variables and functions [fast: true, auto-fix: false]
#- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
#- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
#- dupl # Tool for code clone detection [fast: true, auto-fix: false] #- dupl # Tool for code clone detection [fast: true, auto-fix: false]
#- dupword # checks for duplicate words in the source code [fast: true, auto-fix: false]
- durationcheck # check for two durations multiplied together [fast: false, auto-fix: false]
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted. [fast: false, auto-fix: false]
- errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. [fast: false, auto-fix: false]
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. [fast: false, auto-fix: false]
- execinquery # execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds [fast: false, auto-fix: false]
- exhaustive # check exhaustiveness of enum switch statements [fast: false, auto-fix: false]
#- exhaustruct # Checks if all structure fields are initialized [fast: false, auto-fix: false]
- exportloopref # checks for pointers to enclosing loop variables [fast: false, auto-fix: false]
#- forbidigo # Forbids identifiers [fast: false, auto-fix: false]
- forcetypeassert # finds forced type assertions [fast: true, auto-fix: false] - forcetypeassert # finds forced type assertions [fast: true, auto-fix: false]
#- funlen # Tool for detection of long functions [fast: true, auto-fix: false]
#- gci # Gci controls Go package import order and makes it always deterministic. [fast: true, auto-fix: true]
#- ginkgolinter # enforces standards of using ginkgo and gomega [fast: false, auto-fix: false]
- gocheckcompilerdirectives # Checks that go compiler directive comments (//go:) are valid. [fast: true, auto-fix: false]
#- gochecknoglobals # Check that no global variables exist. [fast: false, auto-fix: false]
#- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false] #- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false] - gochecksumtype # Run exhaustiveness checks on Go "sum types" [fast: false, auto-fix: false]
- gocritic # Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: false] #- gocognit # Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]
- goimports # In addition to fixing imports, goimports also formats your code in the same style as gofmt. [fast: true, auto-fix: true] #- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
#- gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. [fast: true, auto-fix: false] - gocritic # Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: true]
#- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
#- godot # Check if comments end in a period [fast: true, auto-fix: true]
#- godox # Tool for detection of FIXME, TODO and other comment keywords [fast: true, auto-fix: false]
#- goerr113 # Go linter to check the errors handling expressions [fast: false, auto-fix: false]
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]
#- gofumpt # Gofumpt checks whether code was gofumpt-ed. [fast: true, auto-fix: true]
- goheader # Checks is file header matches to pattern [fast: true, auto-fix: true]
- goimports # Check import statements are formatted according to the 'goimport' command. Reformat imports in autofix mode. [fast: true, auto-fix: true]
#- gomnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
- gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. [fast: true, auto-fix: false]
- gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. [fast: true, auto-fix: false] - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. [fast: true, auto-fix: false]
- goprintffuncname # Checks that printf-like functions are named with `f` at the end [fast: true, auto-fix: false] - goprintffuncname # Checks that printf-like functions are named with `f` at the end. [fast: true, auto-fix: false]
- gosec # (gas): Inspects source code for security problems [fast: false, auto-fix: false] - gosec # (gas) Inspects source code for security problems [fast: false, auto-fix: false]
- grouper # An analyzer to analyze expression groups. [fast: true, auto-fix: false] #- gosmopolitan # Report certain i18n/l10n anti-patterns in your Go codebase [fast: false, auto-fix: false]
- grouper # Analyze expression groups. [fast: true, auto-fix: false]
- importas # Enforces consistent import aliases [fast: false, auto-fix: false] - importas # Enforces consistent import aliases [fast: false, auto-fix: false]
#- inamedparam # reports interfaces with unnamed method parameters [fast: true, auto-fix: false]
#- interfacebloat # A linter that checks the number of methods inside an interface. [fast: true, auto-fix: false]
#- intrange # (go >= 1.22) intrange is a linter to find places where for loops could make use of an integer range. [fast: true, auto-fix: false]
#- ireturn # Accept Interfaces, Return Concrete Types [fast: false, auto-fix: false]
#- lll # Reports long lines [fast: true, auto-fix: false]
#- loggercheck # (logrlint) Checks key value pairs for common logger libraries (kitlog,klog,logr,zap). [fast: false, auto-fix: false]
#- maintidx # maintidx measures the maintainability index of each function. [fast: true, auto-fix: false] #- maintidx # maintidx measures the maintainability index of each function. [fast: true, auto-fix: false]
- makezero # Finds slice declarations with non-zero initial length [fast: false, auto-fix: false] - makezero # Finds slice declarations with non-zero initial length [fast: false, auto-fix: false]
- misspell # Finds commonly misspelled English words in comments [fast: true, auto-fix: true] - misspell # Finds commonly misspelled English words [fast: true, auto-fix: true]
- nakedret # Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false] - mirror # reports wrong mirror patterns of bytes/strings usage [fast: false, auto-fix: true]
- musttag # enforce field tags in (un)marshaled structs [fast: false, auto-fix: false]
#- nakedret # Checks that functions with naked returns are not longer than a maximum size (can be zero). [fast: true, auto-fix: false]
#- nestif # Reports deeply nested if statements [fast: true, auto-fix: false] #- nestif # Reports deeply nested if statements [fast: true, auto-fix: false]
- nilerr # Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false] - nilerr # Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false]
- nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. [fast: false, auto-fix: false] - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. [fast: false, auto-fix: false]
- noctx # noctx finds sending http request without context.Context [fast: false, auto-fix: false] #- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity [fast: true, auto-fix: false]
- nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: false] - noctx # Finds sending http request without context.Context [fast: false, auto-fix: false]
- nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: true]
- nonamedreturns # Reports all named returns [fast: false, auto-fix: false] - nonamedreturns # Reports all named returns [fast: false, auto-fix: false]
- nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL. [fast: true, auto-fix: false] - nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL. [fast: true, auto-fix: false]
#- paralleltest # Detects missing usage of t.Parallel() method in your Go test [fast: false, auto-fix: false]
#- perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative. [fast: false, auto-fix: false]
- prealloc # Finds slice declarations that could potentially be pre-allocated [fast: true, auto-fix: false] - prealloc # Finds slice declarations that could potentially be pre-allocated [fast: true, auto-fix: false]
- predeclared # find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false] - predeclared # find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false]
- promlinter # Check Prometheus metrics naming via promlint [fast: true, auto-fix: false] - promlinter # Check Prometheus metrics naming via promlint [fast: true, auto-fix: false]
#- protogetter # Reports direct reads from proto message fields when getters should be used [fast: false, auto-fix: true]
- reassign # Checks that package variables are not reassigned [fast: false, auto-fix: false]
- revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. [fast: false, auto-fix: false] - revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. [fast: false, auto-fix: false]
#- rowserrcheck # checks whether Rows.Err of rows is checked successfully [fast: false, auto-fix: false]
#- sloglint # ensure consistent code style when using log/slog [fast: false, auto-fix: false]
#- spancheck # Checks for mistakes with OpenTelemetry/Census spans. [fast: false, auto-fix: false]
#- sqlclosecheck # Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed. [fast: false, auto-fix: false]
- stylecheck # Stylecheck is a replacement for golint [fast: false, auto-fix: false]
#- tagalign # check that struct tags are well aligned [fast: true, auto-fix: true]
- tagliatelle # Checks the struct tags. [fast: true, auto-fix: false] - tagliatelle # Checks the struct tags. [fast: true, auto-fix: false]
- tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 [fast: false, auto-fix: false]
- testableexamples # linter checks if examples are testable (have an expected output) [fast: true, auto-fix: false]
- testifylint # Checks usage of github.com/stretchr/testify. [fast: false, auto-fix: false]
- testpackage # linter that makes you use a separate _test package [fast: true, auto-fix: false] - testpackage # linter that makes you use a separate _test package [fast: true, auto-fix: false]
- thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers [fast: false, auto-fix: false] - thelper # thelper detects tests helpers which is not start with t.Helper() method. [fast: false, auto-fix: false]
#- tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes. [fast: false, auto-fix: false]
- unconvert # Remove unnecessary type conversions [fast: false, auto-fix: false] - unconvert # Remove unnecessary type conversions [fast: false, auto-fix: false]
- unparam # Reports unused function parameters [fast: false, auto-fix: false] #- unparam # Reports unused function parameters [fast: false, auto-fix: false]
- usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library. [fast: true, auto-fix: false] - usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library. [fast: true, auto-fix: false]
- wastedassign # wastedassign finds wasted assignment statements. [fast: false, auto-fix: false] #- varnamelen # checks that the length of a variable's name matches its scope [fast: false, auto-fix: false]
- whitespace # Tool for detection of leading and trailing whitespace [fast: true, auto-fix: true] - wastedassign # Finds wasted assignment statements [fast: false, auto-fix: false]
disable: - whitespace # Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc. [fast: true, auto-fix: true]
- unused #- wrapcheck # Checks that errors returned from external packages are wrapped [fast: false, auto-fix: false]
#- wsl # add or remove empty lines [fast: true, auto-fix: false]
#- zerologlint # Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg` [fast: false, auto-fix: false]

View File

@ -3,7 +3,7 @@ package config
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/viper" "github.com/spf13/viper"
_ "github.com/spf13/viper/remote" _ "github.com/spf13/viper/remote" // required import
) )
var remotes []struct { var remotes []struct {

View File

@ -20,7 +20,7 @@ func WatchBool(ctx context.Context, fn func() bool, callback func(bool)) {
func WatchTime(ctx context.Context, fn func() time.Time, callback func(time.Time)) { func WatchTime(ctx context.Context, fn func() time.Time, callback func(time.Time)) {
current := fn() current := fn()
watch(ctx, func() { watch(ctx, func() {
if value := fn(); value != current { if value := fn(); !value.Equal(current) {
current = value current = value
callback(current) callback(current)
} }
@ -102,7 +102,7 @@ func WatchBoolChan(ctx context.Context, fn func() bool, ch chan bool) {
func WatchTimeChan(ctx context.Context, fn func() time.Time, ch chan time.Time) { func WatchTimeChan(ctx context.Context, fn func() time.Time, ch chan time.Time) {
current := fn() current := fn()
watch(ctx, func() { watch(ctx, func() {
if value := fn(); value != current { if value := fn(); !value.Equal(current) {
current = value current = value
ch <- current ch <- current
} }

View File

@ -7,6 +7,7 @@ import (
keelerrors "github.com/foomo/keel/errors" keelerrors "github.com/foomo/keel/errors"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func ExampleNewWrappedError() { func ExampleNewWrappedError() {
@ -63,13 +64,13 @@ func Test_wrappedError_Error(t *testing.T) {
parentErr := errors.New("parent") parentErr := errors.New("parent")
childErr := errors.New("child") childErr := errors.New("child")
wrappedErr := keelerrors.NewWrappedError(parentErr, childErr) wrappedErr := keelerrors.NewWrappedError(parentErr, childErr)
assert.Equal(t, wrappedErr.Error(), "parent: child") assert.Equal(t, "parent: child", wrappedErr.Error())
} }
func Test_wrappedError_Is(t *testing.T) { func Test_wrappedError_Is(t *testing.T) {
parentErr := errors.New("parent") parentErr := errors.New("parent")
childErr := errors.New("child") childErr := errors.New("child")
wrappedErr := keelerrors.NewWrappedError(parentErr, childErr) wrappedErr := keelerrors.NewWrappedError(parentErr, childErr)
assert.ErrorIs(t, wrappedErr, parentErr) require.ErrorIs(t, wrappedErr, parentErr)
assert.ErrorIs(t, wrappedErr, childErr) require.ErrorIs(t, wrappedErr, childErr)
} }

2
go.mod
View File

@ -152,5 +152,3 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )
replace go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 => github.com/foomo/opentelemetry-go-contrib/instrumentation/net/http/otelhttp v0.32.1-0.20220517120905-10e2553b9bac

View File

@ -38,9 +38,9 @@ func NewKeyFromFilenames(publicKeyPemFilename, privateKeyPemFilename string) (Ke
// load private key // load private key
if privateKeyPemFilename != "" { if privateKeyPemFilename != "" {
if bytes, err := os.ReadFile(privateKeyPemFilename); err != nil { if value, err := os.ReadFile(privateKeyPemFilename); err != nil {
return Key{}, errors.Wrap(err, "failed to read private key: "+privateKeyPemFilename) return Key{}, errors.Wrap(err, "failed to read private key: "+privateKeyPemFilename)
} else if key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(strings.ReplaceAll(string(bytes), `\n`, "\n"))); err != nil { } else if key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(strings.ReplaceAll(string(value), `\n`, "\n"))); err != nil {
return Key{}, errors.Wrap(err, "failed to parse private key: "+privateKeyPemFilename) return Key{}, errors.Wrap(err, "failed to parse private key: "+privateKeyPemFilename)
} else { } else {
private = key private = key
@ -54,7 +54,7 @@ func NewKeyFromFilenames(publicKeyPemFilename, privateKeyPemFilename string) (Ke
return Key{}, errors.Wrap(err, "failed to parse public key: "+publicKeyPemFilename) return Key{}, errors.Wrap(err, "failed to parse public key: "+publicKeyPemFilename)
} else { } else {
hasher := sha256.New() hasher := sha256.New()
hasher.Write(bytes.TrimSpace(v)) _, _ = hasher.Write(bytes.TrimSpace(v))
id = hex.EncodeToString(hasher.Sum(nil)) id = hex.EncodeToString(hasher.Sum(nil))
public = key public = key
} }

View File

@ -40,7 +40,7 @@ func WithServiceName(l *zap.Logger, name string) *zap.Logger {
return With(l, FServiceName(name)) return With(l, FServiceName(name))
} }
func WithTraceID(l *zap.Logger, ctx context.Context) *zap.Logger { func WithTraceID(l *zap.Logger, ctx context.Context) *zap.Logger { //nolint:revive
if spanCtx := trace.SpanContextFromContext(ctx); spanCtx.IsValid() && spanCtx.IsSampled() { if spanCtx := trace.SpanContextFromContext(ctx); spanCtx.IsValid() && spanCtx.IsSampled() {
l = With(l, FTraceID(spanCtx.TraceID().String()), FSpanID(spanCtx.SpanID().String())) l = With(l, FTraceID(spanCtx.TraceID().String()), FSpanID(spanCtx.SpanID().String()))
} }

View File

@ -19,7 +19,7 @@ func NewError(e Error) *Error {
func (e *Error) Is(err error) bool { func (e *Error) Is(err error) bool {
if e == nil || err == nil { if e == nil || err == nil {
return false return false
} else if v, ok := err.(*Error); ok && v != nil { //nolint:errorlint } else if v, ok := err.(*Error); ok && v != nil {
return e.Error() == v.Error() return e.Error() == v.Error()
} }
return false return false

View File

@ -125,18 +125,18 @@ func JWTWithSetContext(v bool) JWTOption {
} }
// JWT middleware // JWT middleware
func JWT(jwt *jwt.JWT, contextKey interface{}, opts ...JWTOption) Middleware { func JWT(v *jwt.JWT, contextKey interface{}, opts ...JWTOption) Middleware {
options := GetDefaultJWTOptions() options := GetDefaultJWTOptions()
for _, opt := range opts { for _, opt := range opts {
if opt != nil { if opt != nil {
opt(&options) opt(&options)
} }
} }
return JWTWithOptions(jwt, contextKey, options) return JWTWithOptions(v, contextKey, options)
} }
// JWTWithOptions middleware // JWTWithOptions middleware
func JWTWithOptions(jwt *jwt.JWT, contextKey interface{}, opts JWTOptions) Middleware { func JWTWithOptions(v *jwt.JWT, contextKey interface{}, opts JWTOptions) Middleware {
return func(l *zap.Logger, name string, next http.Handler) http.Handler { return func(l *zap.Logger, name string, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims := opts.ClaimsProvider() claims := opts.ClaimsProvider()
@ -174,7 +174,7 @@ func JWTWithOptions(jwt *jwt.JWT, contextKey interface{}, opts JWTOptions) Middl
} }
// handle existing token // handle existing token
jwtToken, err := jwt.ParseWithClaims(token, claims) jwtToken, err := v.ParseWithClaims(token, claims)
if err != nil { if err != nil {
if resume := opts.ErrorHandler(l, w, r, err); resume { if resume := opts.ErrorHandler(l, w, r, err); resume {
next.ServeHTTP(w, r) next.ServeHTTP(w, r)

View File

@ -191,7 +191,7 @@ func CircuitBreaker(set *CircuitBreakerSettings, opts ...CircuitBreakerOption) R
} }
// continue with the middleware chain // continue with the middleware chain
resp, err = next(r) //nolint:bodyclose resp, err = next(r)
var respCopy *http.Response var respCopy *http.Response
if resp != nil { if resp != nil {

View File

@ -41,7 +41,7 @@ var cbSettings = &roundtripware.CircuitBreakerSettings{
return counts.ConsecutiveFailures > 3 return counts.ConsecutiveFailures > 3
}, },
OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) { OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
fmt.Printf("\n\nstate changed from %s to %s\n\n", from, to) _, _ = fmt.Printf("\n\nstate changed from %s to %s\n\n", from, to)
}, },
} }
@ -101,7 +101,7 @@ func TestCircuitBreaker(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker)
} }
@ -112,7 +112,7 @@ func TestCircuitBreaker(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if err == nil { if err == nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.ErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.ErrorIs(t, err, roundtripware.ErrCircuitBreaker)
@ -123,7 +123,7 @@ func TestCircuitBreaker(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err = client.Do(req) resp, err = client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NoError(t, err) require.NoError(t, err)
} }
@ -161,7 +161,7 @@ func TestCircuitBreakerCopyBodies(t *testing.T) {
require.NoError(t, errRead) require.NoError(t, errRead)
// also try to close one of the bodies (should also be handled by the RoundTripware) // also try to close one of the bodies (should also be handled by the RoundTripware)
req.Body.Close() _ = req.Body.Close()
return err return err
}, true, true, }, true, true,
@ -175,7 +175,7 @@ func TestCircuitBreakerCopyBodies(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NoError(t, err) require.NoError(t, err)
// make sure the correct data is returned // make sure the correct data is returned
@ -227,7 +227,7 @@ func TestCircuitBreakerReadFromNotCopiedBodies(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.Error(t, err) require.Error(t, err)
require.ErrorIs(t, err, roundtripware.ErrReadFromActualBody) require.ErrorIs(t, err, roundtripware.ErrReadFromActualBody)
@ -256,7 +256,7 @@ func TestCircuitBreakerReadFromNotCopiedBodies(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err = client.Do(req) resp, err = client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.Error(t, err) require.Error(t, err)
require.ErrorIs(t, err, roundtripware.ErrReadFromActualBody) require.ErrorIs(t, err, roundtripware.ErrReadFromActualBody)
@ -303,7 +303,7 @@ func TestCircuitBreakerInterval(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker)
} }
@ -318,7 +318,7 @@ func TestCircuitBreakerInterval(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker)
} }
@ -328,7 +328,7 @@ func TestCircuitBreakerInterval(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.ErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.ErrorIs(t, err, roundtripware.ErrCircuitBreaker)
} }
@ -370,7 +370,7 @@ func TestCircuitBreakerIgnore(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker)
require.NoError(t, err) require.NoError(t, err)
@ -399,16 +399,16 @@ func TestCircuitBreakerTimeout(t *testing.T) {
// -> circuit breaker should change to open state // -> circuit breaker should change to open state
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, svr.URL, nil) req, err := http.NewRequestWithContext(ctx, http.MethodGet, svr.URL, nil)
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.NotErrorIs(t, err, roundtripware.ErrCircuitBreaker)
require.ErrorIs(t, err, context.DeadlineExceeded) require.ErrorIs(t, err, context.DeadlineExceeded)
cancel()
} }
// send another request with a bigger timeout // send another request with a bigger timeout
@ -419,7 +419,7 @@ func TestCircuitBreakerTimeout(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
resp, err := client.Do(req) resp, err := client.Do(req)
if resp != nil { if resp != nil {
defer resp.Body.Close() _ = resp.Body.Close()
} }
require.ErrorIs(t, err, roundtripware.ErrCircuitBreaker) require.ErrorIs(t, err, roundtripware.ErrCircuitBreaker)
} }

View File

@ -394,7 +394,7 @@ func (c *Collection) FindIterate(ctx context.Context, filter interface{}, handle
return err return err
} }
defer CloseCursor(cursor) defer CloseCursor(context.WithoutCancel(ctx), cursor)
for cursor.Next(ctx) { for cursor.Next(ctx) {
if err := handler(cursor.Decode); err != nil { if err := handler(cursor.Decode); err != nil {
@ -424,7 +424,7 @@ func (c *Collection) AggregateIterate(ctx context.Context, pipeline mongo.Pipeli
return err return err
} }
defer CloseCursor(cursor) defer CloseCursor(context.WithoutCancel(ctx), cursor)
for cursor.Next(ctx) { for cursor.Next(ctx) {
if err := handler(cursor.Decode); err != nil { if err := handler(cursor.Decode); err != nil {

View File

@ -8,8 +8,8 @@ import (
) )
// CloseCursor with defer // CloseCursor with defer
func CloseCursor(cursor *mongo.Cursor) { func CloseCursor(ctx context.Context, cursor *mongo.Cursor) {
if err := cursor.Close(context.Background()); err != nil { if err := cursor.Close(ctx); err != nil {
log.WithError(nil, err).Error("failed to close cursor") log.WithError(nil, err).Error("failed to close cursor")
} }
} }

View File

@ -233,11 +233,11 @@ func (s *Server) ShutdownCancel() context.CancelFunc {
} }
// AddService add a single service // AddService add a single service
func (s *Server) AddService(service Service) { func (s *Server) AddService(v Service) {
if !slices.Contains(s.services, service) { if !slices.Contains(s.services, v) {
s.services = append(s.services, service) s.services = append(s.services, v)
s.AddAlwaysHealthzers(service) s.AddAlwaysHealthzers(v)
s.AddCloser(service) s.AddCloser(v)
} }
} }

View File

@ -11,7 +11,6 @@ import (
"time" "time"
"github.com/foomo/keel/service" "github.com/foomo/keel/service"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"go.uber.org/goleak" "go.uber.org/goleak"
"go.uber.org/zap" "go.uber.org/zap"
@ -102,7 +101,7 @@ func (s *KeelTestSuite) TestServiceHTTPZap() {
s.Run("default", func() { s.Run("default", func() {
if statusCode, body, err := s.httpGet("http://localhost:9100/log"); s.NoError(err) { if statusCode, body, err := s.httpGet("http://localhost:9100/log"); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
s.Equal(body, `{"level":"info","disableCaller":true,"disableStacktrace":true}`) s.Equal(`{"level":"info","disableCaller":true,"disableStacktrace":true}`, body)
} }
if statusCode, _, err := s.httpGet("http://localhost:55000/log/info"); s.NoError(err) { if statusCode, _, err := s.httpGet("http://localhost:55000/log/info"); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
@ -115,7 +114,7 @@ func (s *KeelTestSuite) TestServiceHTTPZap() {
s.Run("set debug level", func() { s.Run("set debug level", func() {
if statusCode, body, err := s.httpPut("http://localhost:9100/log", `{"level":"debug"}`); s.NoError(err) { if statusCode, body, err := s.httpPut("http://localhost:9100/log", `{"level":"debug"}`); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
s.Equal(body, `{"level":"debug","disableCaller":true,"disableStacktrace":true}`) s.Equal(`{"level":"debug","disableCaller":true,"disableStacktrace":true}`, body)
} }
if statusCode, _, err := s.httpGet("http://localhost:55000/log/info"); s.NoError(err) { if statusCode, _, err := s.httpGet("http://localhost:55000/log/info"); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
@ -128,7 +127,7 @@ func (s *KeelTestSuite) TestServiceHTTPZap() {
s.Run("enable caller", func() { s.Run("enable caller", func() {
if statusCode, body, err := s.httpPut("http://localhost:9100/log", `{"disableCaller":false}`); s.NoError(err) { if statusCode, body, err := s.httpPut("http://localhost:9100/log", `{"disableCaller":false}`); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
s.Equal(body, `{"level":"debug","disableCaller":false,"disableStacktrace":true}`) s.Equal(`{"level":"debug","disableCaller":false,"disableStacktrace":true}`, body)
} }
if statusCode, _, err := s.httpGet("http://localhost:55000/log/error"); s.NoError(err) { if statusCode, _, err := s.httpGet("http://localhost:55000/log/error"); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
@ -138,7 +137,7 @@ func (s *KeelTestSuite) TestServiceHTTPZap() {
s.Run("enable stacktrace", func() { s.Run("enable stacktrace", func() {
if statusCode, body, err := s.httpPut("http://localhost:9100/log", `{"disableStacktrace":false}`); s.NoError(err) { if statusCode, body, err := s.httpPut("http://localhost:9100/log", `{"disableStacktrace":false}`); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
s.Equal(body, `{"level":"debug","disableCaller":false,"disableStacktrace":false}`) s.Equal(`{"level":"debug","disableCaller":false,"disableStacktrace":false}`, body)
} }
if statusCode, _, err := s.httpGet("http://localhost:55000/log/error"); s.NoError(err) { if statusCode, _, err := s.httpGet("http://localhost:55000/log/error"); s.NoError(err) {
s.Equal(http.StatusOK, statusCode) s.Equal(http.StatusOK, statusCode)
@ -179,7 +178,7 @@ func (s *KeelTestSuite) TestGraceful() {
go func(waitChan chan string) { go func(waitChan chan string) {
waitChan <- "ok" waitChan <- "ok"
time.Sleep(time.Second) time.Sleep(time.Second)
if assert.NoError(s.T(), syscall.Kill(syscall.Getpid(), syscall.SIGINT)) { if s.NoError(syscall.Kill(syscall.Getpid(), syscall.SIGINT)) {
s.l.Info("killed myself") s.l.Info("killed myself")
} }
}(waitChan) }(waitChan)
@ -190,7 +189,7 @@ func (s *KeelTestSuite) TestGraceful() {
{ // check that server is down { // check that server is down
_, _, err := s.httpGet("http://localhost:55000/ok") _, _, err := s.httpGet("http://localhost:55000/ok")
s.Error(err) s.Require().Error(err)
} }
s.l.Info("done") s.l.Info("done")

View File

@ -18,7 +18,7 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
func _ExampleNewHTTPReadme() { func _ExampleNewHTTPReadme() { //nolint:unused
// define vars so it does not panic // define vars so it does not panic
_ = os.Setenv("EXAMPLE_REQUIRED_BOOL", "true") _ = os.Setenv("EXAMPLE_REQUIRED_BOOL", "true")
_ = os.Setenv("EXAMPLE_REQUIRED_STRING", "foo") _ = os.Setenv("EXAMPLE_REQUIRED_STRING", "foo")

View File

@ -40,10 +40,10 @@ func (w *ServiceEnabler) Name() string {
} }
func (w *ServiceEnabler) Start(ctx context.Context) error { func (w *ServiceEnabler) Start(ctx context.Context) error {
w.watch() w.watch(w.ctx) //nolint:contextcheck
w.ctx = ctx w.ctx = ctx
if w.enabled() { if w.enabled() {
if err := w.enable(w.ctx); err != nil { if err := w.enable(w.ctx); err != nil { //nolint:contextcheck
return err return err
} }
} else { } else {
@ -56,7 +56,7 @@ func (w *ServiceEnabler) Close(ctx context.Context) error {
l := log.WithServiceName(w.l, w.Name()) l := log.WithServiceName(w.l, w.Name())
w.setClosed(true) w.setClosed(true)
if w.enabled() { if w.enabled() {
if err := w.disable(w.ctx); err != nil { if err := w.disable(w.ctx); err != nil { //nolint:contextcheck
return err return err
} }
} else { } else {
@ -102,7 +102,7 @@ func (w *ServiceEnabler) disable(ctx context.Context) error {
return w.service.Close(ctx) return w.service.Close(ctx)
} }
func (w *ServiceEnabler) watch() { func (w *ServiceEnabler) watch(ctx context.Context) {
go func() { go func() {
for { for {
if w.closed() { if w.closed() {
@ -112,12 +112,12 @@ func (w *ServiceEnabler) watch() {
if value := w.enabledFn(); value != w.enabled() { if value := w.enabledFn(); value != w.enabled() {
if value { if value {
go func() { go func() {
if err := w.enable(w.ctx); err != nil { if err := w.enable(ctx); err != nil {
w.l.Fatal("failed to dynamically start service", log.FError(err)) w.l.Fatal("failed to dynamically start service", log.FError(err))
} }
}() }()
} else { } else {
if err := w.disable(context.TODO()); err != nil { if err := w.disable(context.TODO()); err != nil { //nolint:contextcheck
w.l.Fatal("failed to dynamically close service", log.FError(err)) w.l.Fatal("failed to dynamically close service", log.FError(err))
} }
} }

View File

@ -3,7 +3,6 @@ package telemetry
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"log"
"os" "os"
"github.com/foomo/keel/env" "github.com/foomo/keel/env"
@ -44,7 +43,7 @@ func NewStdOutMeterProvider(ctx context.Context, opts ...stdoutmetric.Option) (m
exporter, err := stdoutmetric.New(opts...) exporter, err := stdoutmetric.New(opts...)
if err != nil { if err != nil {
log.Fatalf("creating stdoutmetric exporter: %v", err) return nil, err
} }
resource := otelresource.NewSchemaless( resource := otelresource.NewSchemaless(