diff --git a/.github/workflows/push.tests.yml b/.github/workflows/push.tests.yml index abb1c99..b7df48e 100644 --- a/.github/workflows/push.tests.yml +++ b/.github/workflows/push.tests.yml @@ -25,7 +25,6 @@ jobs: version: latest tests: - needs: golangci-lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.golangci.yml b/.golangci.yml index d3c9fcb..69da674 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,13 +1,10 @@ -# This file contains all available configuration options -# with their default values. - # options for analysis running run: # default concurrency is a available CPU number concurrency: 4 # timeout for analysis, e.g. 30s, 5m, default is 1m - timeout: 1m + timeout: 5m # exit code when at least one issue was found, default is 1 issues-exit-code: 1 @@ -22,8 +19,11 @@ run: # can use regexp here: generated.*, regexp is applied on full path; # default value is empty list, but default dirs are skipped independently # from this option's value (see skip-dirs-use-default). + # "/" will be replaced by current OS file path separator to properly work + # on Windows. skip-dirs: - - vendor + - generated + - ".*mock(s)?.*" # default is true. Enables skipping of directories: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ @@ -33,10 +33,11 @@ run: # won't be reported. Default value is empty list, but there is # no need to include all autogenerated files, we confidently recognize # autogenerated files. If it's not please let us know. + # "/" will be replaced by current OS file path separator to properly work + # on Windows. skip-files: - - ".*easyjson.*" - - ".*mocks.*" - - ".*autogenerated.*" + - '.*mock.*\.go' + - '.*\.gen\.go' # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": # If invoked with -mod=readonly, the go command is disallowed from the implicit @@ -48,10 +49,15 @@ run: # the dependency descriptions in go.mod. modules-download-mode: readonly + # Allow multiple parallel golangci-lint instances running. + # If false (default) - golangci-lint acquires file lock on start. + allow-parallel-runners: false + # output configuration options output: - # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" + # colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions + # default is "colored-line-number" format: colored-line-number # print lines of code with issue, default is true @@ -60,30 +66,80 @@ output: # print linter name in the end of issue text, default is true print-linter-name: true + # make issues output unique by line, default is true + uniq-by-line: true + + # add a prefix to the output file references; default is no prefix + path-prefix: "" + + # sorts results by: filepath, line and column + sort-results: true + # all available settings of specific linters linters-settings: + cyclop: + # the maximal code complexity to report + max-complexity: 20 + # the maximal average package complexity. If it's higher than 0.0 (float) the check is enabled (default 0.0) + package-average: 0.0 + # should ignore tests (default false) + skip-tests: false + errcheck: - # report about not checking of errors in type assetions: `a := b.(MyStruct)`; + # report about not checking of errors in type assertions: `a := b.(MyStruct)`; # default is false: such cases aren't reported by default. - check-type-assertions: true + check-type-assertions: false # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; # default is false: such cases aren't reported by default. check-blank: false - # [deprecated] comma-separated list of pairs of the form pkg:regex - # the regex is used to ignore names within pkg. (default "fmt:.*"). - # see https://github.com/kisielk/errcheck#the-deprecated-method for details - ignore: fmt:.*,io/ioutil:^Read.* - - # path to a file containing a list of functions to exclude from checking + # list of functions to exclude from checking, where each entry is a single function to exclude. # see https://github.com/kisielk/errcheck#excluding-functions for details - exclude: + exclude-functions: + - io/ioutil.ReadFile + - io.Copy(*bytes.Buffer) + - io.Copy(os.Stdout) + + errorlint: + # Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats + errorf: true + # Check for plain type assertions and type switches + asserts: true + # Check for plain error comparisons + comparison: true + + forbidigo: + # Forbid the following identifiers (identifiers are written using regexp): + forbid: + - ^print.*$ + - 'fmt\.Print.*' + - ^spew\.Dump$ + # Exclude godoc examples from forbidigo checks. Default is true. + exclude_godoc_examples: true - funlen: - lines: 60 - statements: 40 + gocognit: + # minimal code complexity to report, 30 by default (but we recommend 10-20) + min-complexity: 20 + + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + + gosec: + # To specify a set of rules to explicitly exclude. + # Available rules: https://github.com/securego/gosec#available-rules + excludes: + # Look for bad TLS connection settings + # Disable it, since we don't use encrypted connection for inter-service communication. + - G402 + # Poor file permissions used when writing to a new file + # We only write files in codegen utils. So, there is no sense to set permissions 600 fot a new file. + - G306 + # Insecure random number source (rand) + # We don't actually need a crypto-safe random numbers. + - G404 govet: # report about shadowed variables @@ -99,75 +155,97 @@ linters-settings: - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf # enable or disable analyzers by name - enable: - - atomicalign - enable-all: false -# disable: -# - shadow + # run `go tool vet help` to see all analyzers + enable: [] + enable-all: true + disable: + - fieldalignment disable-all: false - golint: - # minimal confidence for issues, default is 0.8 - min-confidence: 0.8 - gofmt: - # simplify code: gofmt with `-s` option, true by default - simplify: true - goimports: - # put imports beginning with prefix after 3rd-party packages; - # it's a comma-separated list of prefixes - local-prefixes: github.com/titusjaka/go-sample - gocyclo: - # minimal code complexity to report, 30 by default (but we recommend 10-20) - min-complexity: 30 - gocognit: - # minimal code complexity to report, 30 by default (but we recommend 10-20) - min-complexity: 30 - maligned: - # print struct with more effective memory layout or not, false by default - suggest-new: true + + makezero: + # Allow only slices initialized with a length of zero. Default is false. + always: false + + predeclared: + # comma-separated list of predeclared identifiers to not report on + ignore: "" + # include method names and field names (i.e., qualified names) in checks + q: false + + staticcheck: + # Select the Go version to target. The default is '1.13'. + go: "1.22" + # https://staticcheck.io/docs/options#checks + checks: [ "all" ] + + unparam: + # Inspect exported functions, default is false. Set to true if no external program/library imports your code. + # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find external interfaces. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + + unused: + # Select the Go version to target. The default is '1.13'. + go: "1.22" + dupl: # tokens count to trigger issue, 150 by default threshold: 100 + + exhaustive: + # check switch statements in generated files also + check-generated: false + # presence of "default" case in switch statements satisfies exhaustiveness, + # even if all enum members are not listed + default-signifies-exhaustive: true + # enum members matching the supplied regex do not have to be listed in + # switch statements to satisfy exhaustiveness + ignore-enum-members: "" + # consider enums only in package scopes, not in inner scopes + package-scope-only: false + + funlen: + lines: 60 + statements: 40 + goconst: # minimal length of string constant, 3 by default min-len: 3 - # minimal occurrences count to trigger, 3 by default + # minimum occurrences of constant string count to trigger issue, 3 by default min-occurrences: 3 - depguard: - list-type: blacklist - include-go-root: false - packages: - - github.com/sirupsen/logrus - packages-with-error-messages: - # specify an error message to output when a blacklisted package is used - github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" - misspell: - # Correct spellings using locale preferences for US or UK. - # Default is to use a neutral variety of English. - # Setting locale to US will correct the British spelling of 'colour' to 'color'. - locale: US - # ignore-words: - # - someword - lll: - # max line length, lines longer will be reported. Default is 120. - # '\t' is counted as 1 character by default, and can be changed with the tab-width option - line-length: 120 - # tab width in spaces. Default to 1. - tab-width: 1 - unused: - # treat code as a program (not a library) and report unused exported identifiers; default is false. - # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find funcs usages. All text editor integrations - # with golangci-lint call it on a directory with the changed file. - check-exported: false - unparam: - # Inspect exported functions, default is false. Set to true if no external program/library imports your code. - # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find external interfaces. All text editor integrations - # with golangci-lint call it on a directory with the changed file. - check-exported: true + # ignore test files, false by default + ignore-tests: true + # look for existing constants matching the values, true by default + match-constant: true + # search also for duplicated numbers, false by default + numbers: false + # minimum value, only works with goconst.numbers, 3 by default + min: 3 + # maximum value, only works with goconst.numbers, 3 by default + max: 3 + # ignore when constant is not used as function argument, true by default + ignore-calls: true + + goimports: + # put imports beginning with prefix after 3rd-party packages; + # it's a comma-separated list of prefixes + local-prefixes: github.com/titusjaka + + gosimple: + # Select the Go version to target. The default is '1.13'. + go: "1.22" + # https://staticcheck.io/docs/options#checks + checks: [ "all" ] + nakedret: # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 max-func-lines: 5 + + nestif: + # minimal complexity of if statements to report, 5 by default + min-complexity: 6 + prealloc: # XXX: we don't recommend using this linter before doing performance profiling. # For most programs usage of prealloc will be a premature optimization. @@ -177,134 +255,112 @@ linters-settings: simple: true range-loops: true # Report preallocation suggestions on range loops, true by default for-loops: false # Report preallocation suggestions on for loops, false by default - gocritic: - # Which checks should be enabled; can't be combined with 'disabled-checks'; - # See https://go-critic.github.io/overview#checks-overview - # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` - # By default list of stable checks is used. - enabled-checks: - - # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty - disabled-checks: - - regexpMust - - # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. - # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". - enabled-tags: - - performance - - settings: # settings passed to gocritic - hugeParam: - sizeThreshold: 150 - captLocal: # must be valid enabled check name - paramsOnly: true - rangeValCopy: - sizeThreshold: 32 - godox: - # report any comments starting with keywords, this is useful for TODO or FIXME comments that - # might be left in the code accidentally and should be resolved before merging - keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting - - NOTE - - OPTIMIZE # marks code that should be optimized before merging - - HACK # marks hack-arounds that should be removed before merging - dogsled: - # checks assignments with too many blank identifiers; default is 2 - max-blank-identifiers: 2 - - whitespace: - multi-if: false # Enforces newlines (or comments) after every multi-line if statement - multi-func: false # Enforces newlines (or comments) after every multi-line function signature - wsl: - # If true append is only allowed to be cuddled if appending value is - # matching variables, fields or types on line above. Default is true. - strict-append: true - # Allow calls and assignments to be cuddled as long as the lines have any - # matching variables, fields or types. Default is true. - allow-assign-and-call: true - # Allow multiline assignments to be cuddled. Default is true. - allow-multiline-assign: true - # Allow case blocks to end with a whitespace. - allow-case-traling-whitespace: true - # Allow declarations (var) to be cuddled. - allow-cuddle-declarations: false linters: enable-all: false disable-all: true enable: - bodyclose - - deadcode - - depguard - - dogsled + - cyclop + - durationcheck - errcheck - - gochecknoglobals - - gochecknoinits + # TODO (titusjaka): enable when I update packages + # - errorlint + - exportloopref + - forbidigo + # TODO (titusjaka): enable when I get rid of gokit +# - forcetypeassert - gocognit - - goconst - - gocritic - - gocyclo - - godox - gofmt - - goimports - - golint - gosec - - gosimple - govet - - ineffassign - - interfacer - - misspell - - nakedret - - prealloc + - makezero + - predeclared - staticcheck - - structcheck - typecheck - - unconvert - unparam - unused - - varcheck - - whitespace +# TODO (titusjaka): enable when I get rid of gokit +# - contextcheck +# - dupl + - errname + - exhaustive + - funlen + - gochecknoglobals + - gochecknoinits + - goconst + - goimports + - gosimple + - nakedret + - nestif + - noctx + - prealloc + - unconvert fast: false + issues: # List of regexps of issue texts to exclude, empty list by default. # But independently from this option we use default exclude patterns, # it can be disabled by `exclude-use-default: false`. To list all # excluded by default patterns execute `golangci-lint run --help` - exclude: - - should have comment or be unexported - - exported .+ should have comment - - package comment should be of the form - - exported func .+ returns unexported type - - comment on exported const .+ should be of the form - - comment on exported method .+ should be of the form + exclude: [] # Excluding configuration per-path, per-linter, per-text and per-source exclude-rules: # Exclude some linters from running on tests files. - path: _test\.go linters: + - bodyclose + - forcetypeassert - dupl - gomnd - gochecknoglobals - goconst - - bodyclose + - funlen + - noctx - # Exclude some staticcheck messages - # - linters: - # - staticcheck - # text: "SA9003:" + # disable errorlint for exact ErrStopped error, used in main.go to determine when app is manually stopped + - path: 'commands/.*\.go' + linters: + - errorlint + source: 'ErrStopped' - # Exclude lll issues for long lines with go:generate - - linters: - - lll - source: "^//go:generate " + - path: 'commands/.*\.go' + linters: + - funlen + - gochecknoglobals - # Independently from option `exclude` we use default exclude patterns, + - path: 'main\.go' + linters: + - funlen + - gochecknoglobals + + - path: _test\.go + linters: + - gosec + # G107: Potential HTTP request made with variable url + # We need to suppress it in tests for helper functions purpose. + text: G107 + +# TODO (titusjaka): remove this exclusion in future + - path: _test\.go + linters: + - govet + + # Independently of option `exclude` we use default exclude patterns, # it can be disabled by this option. To list all # excluded by default patterns execute `golangci-lint run --help`. # Default value for this option is true. exclude-use-default: false + # The default value is false. If set to true exclude and exclude-rules + # regular expressions become case sensitive. + exclude-case-sensitive: false + + # The list of ids of default excludes to include or disable. By default it's empty. + include: [] + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. max-issues-per-linter: 0 @@ -317,10 +373,28 @@ issues: # large codebase. It's not practical to fix all existing issues at the moment # of integration: much better don't allow issues in new code. # Default is false. - # new: false + new: false # Show only new issues created after git revision `REV` - # new-from-rev: abac118d4a36439a39418289fd5a4cb217952588 + new-from-rev: "" # Show only new issues created in git patch with set file path. - # new-from-patch: path/to/patch/file + new-from-patch: "" + + # Fix found issues (if it's supported by the linter) + fix: false + +severity: + # Default value is empty string. + # Set the default severity for issues. If severity rules are defined and the issues + # do not match or no severity is provided to the rule this will be the default + # severity applied. Severities should match the supported severity names of the + # selected out format. + # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity + # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity + # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + default-severity: error + + # The default value is false. + # If set to true severity-rules regular expressions become case sensitive. + case-sensitive: false diff --git a/commands/server.go b/commands/server.go index 87339d1..39af447 100644 --- a/commands/server.go +++ b/commands/server.go @@ -25,7 +25,7 @@ import ( "github.com/titusjaka/go-sample/migrate" ) -var errStopped = errors.New("stopped") +var ErrStopped = errors.New("stopped") // NewServerCmd creates a new server CLI sub-command func NewServerCmd() *cli.Command { @@ -101,13 +101,13 @@ func runServer(c *cli.Context) (err error) { select { case <-stop: - return errStopped + return ErrStopped case <-ctx.Done(): return nil } }) - if err = gr.Wait(); err != nil && err != errStopped { + if err = gr.Wait(); err != nil && err != ErrStopped { return fmt.Errorf("error during wait: %w", err) }