diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5dfd147..8600570 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,31 +1,21 @@ +# This file is a template, and might need editing before it works on your project. image: golang:latest stages: - test #- build + - deploy test: stage: test - before_script: - - export PATH=$PATH:$GOPATH/bin - - go install gotest.tools/gotestsum@latest script: - - gotestsum --junitfile tests.xml -- -coverprofile=coverage.txt -covermode atomic . - after_script: - - export PATH=$PATH:$GOPATH/bin - - go install github.com/boumenot/gocover-cobertura@latest - - gocover-cobertura < coverage.txt > coverage.xml - - go tool cover -func=coverage.txt | grep "total:" - coverage: '/total:\s+\(statements\)\s+(\d+.\d+\%)/' - artifacts: - reports: - junit: tests.xml - coverage_report: - coverage_format: cobertura - path: coverage.xml + - go test -race -lint: - stage: test - image: golangci/golangci-lint +pages: + stage: deploy script: - - golangci-lint run + - mkdir public + - echo "go/log page" >public/index.html + artifacts: + paths: + - public diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index 61a7448..0000000 --- a/.golangci.yml +++ /dev/null @@ -1,3092 +0,0 @@ -# yaml-language-server: $schema=https://golangci-lint.run/jsonschema/golangci.jsonschema.json -# This file contains all available configuration options -# with their default values (in comments). -# -# This file is not a configuration example, -# it contains the exhaustive configuration with explanations of the options. - -# Defines the configuration version. -# The only possible value is "2". -version: "2" - -linters: - # Default set of linters. - # The value can be: `standard`, `all`, `none`, or `fast`. - # Default: standard - default: all - - # Disable specific linter. - # https://golangci-lint.run/usage/linters/#disabled-by-default - disable: - - cyclop # Done by revive - - decorder # too restrictive - - depguard # gomodguard is better - - exhaustruct # Too noisy - - funlen # Done by revive - - gocognit # Done by revive - - goconst # Done by revive - - gocyclo # Done by revive - - goheader - - grouper # not that useful - - lll # Done by revive with better messages - - mnd # Done by revive - - tagalign # too noisy and useless - - # All available settings of specific linters. - settings: - asasalint: - # To specify a set of function names to exclude. - # The values are merged with the builtin exclusions. - # The builtin exclusions can be disabled by setting `use-builtin-exclusions` to `false`. - # Default: ["^(fmt|log|logger|t|)\.(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug|Log)(|f|ln)$"] - exclude: [] - # To enable/disable the asasalint builtin exclusions of function names. - # See the default value of `exclude` to get the builtin exclusions. - # Default: true - use-builtin-exclusions: true - - bidichk: - # The following configurations check for all mentioned invisible Unicode runes. - # All runes are enabled by default. - left-to-right-embedding: true - right-to-left-embedding: true - pop-directional-formatting: true - left-to-right-override: true - right-to-left-override: true - left-to-right-isolate: true - right-to-left-isolate: true - first-strong-isolate: true - pop-directional-isolate: true - - copyloopvar: - # Check all assigning the loop variable to another variable. - # Default: false - check-alias: true - - dogsled: - # Checks assignments with too many blank identifiers. - # Default: 2 - max-blank-identifiers: 2 - - dupl: - # Tokens count to trigger issue. - # Default: 150 - threshold: 100 - - dupword: - # Keywords for detecting duplicate words. - # If this list is not empty, only the words defined in this list will be detected. - # Default: [] - keywords: [] - # Keywords used to ignore detection. - # Default: [] - ignore: [] - - errcheck: - # Report about not checking of errors in type assertions: `a := b.(MyStruct)`. - # Such cases aren't reported by default. - # Default: false - check-type-assertions: true - - # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`. - # Such cases aren't reported by default. - # Default: false - check-blank: true - - # To disable the errcheck built-in exclude list. - # See `-excludeonly` option in https://github.com/kisielk/errcheck#excluding-functions for details. - # Default: false - disable-default-exclusions: false - - # 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-functions: - - io.Copy(*bytes.Buffer) - - io.Copy(os.Stdout) - - encoding/json.Marshal - - encoding/json.MarshalIndent - - errchkjson: - # With check-error-free-encoding set to true, errchkjson does warn about errors - # from json encoding functions that are safe to be ignored, - # because they are not possible to happen. - # - # if check-error-free-encoding is set to true and errcheck linter is enabled, - # it is recommended to add the following exceptions to prevent from false positives: - # - # linters: - # settings: - # errcheck: - # exclude-functions: - # - encoding/json.Marshal - # - encoding/json.MarshalIndent - # - # Default: false - check-error-free-encoding: true - - # Issue on struct encoding that doesn't have exported fields. - # Default: false - report-no-exported: true - - errorlint: - # Check whether fmt.Errorf uses the %w verb for formatting errors. - # See the https://github.com/polyfloyd/go-errorlint for caveats. - # Default: true - errorf: true - # Permit more than 1 %w verb, valid per Go 1.20 (Requires errorf:true) - # Default: true - errorf-multi: true - # Check for plain type assertions and type switches. - # Default: true - asserts: true - # Check for plain error comparisons. - # Default: true - comparison: true - # Allowed errors. - # Default: [] - allowed-errors: [] - # - err: "io.EOF" - # fun: "example.com/pkg.Read" - # Allowed error "wildcards". - # Default: [] - allowed-errors-wildcard: [] - # - err: "example.com/pkg.ErrMagic" - # fun: "example.com/pkg.Magic" - - exhaustive: - # Program elements to check for exhaustiveness. - # Default: [ switch ] - check: - - switch - - map - # Presence of "default" case in switch statements satisfies exhaustiveness, - # even if all enum members are not listed. - # Default: false - default-signifies-exhaustive: true - # Enum members matching the supplied regex do not have to be listed in - # switch statements to satisfy exhaustiveness. - # Default: "" - #ignore-enum-members: "Example.+" - # Enum types matching the supplied regex do not have to be listed in - # switch statements to satisfy exhaustiveness. - # Default: "" - #ignore-enum-types: "Example.+" - # Consider enums only in package scopes, not in inner scopes. - # Default: false - package-scope-only: false - # Only run exhaustive check on switches with "//exhaustive:enforce" comment. - # Default: false - explicit-exhaustive-switch: false - # Only run exhaustive check on map literals with "//exhaustive:enforce" comment. - # Default: false - explicit-exhaustive-map: false - # Switch statement requires default case even if exhaustive. - # Default: false - default-case-required: true - - exhaustruct: - # List of regular expressions to match struct packages and their names. - # Regular expressions must match complete canonical struct package/name/structname. - # If this list is empty, all structs are tested. - # Default: [] - include: [] - # List of regular expressions to exclude struct packages and their names from checks. - # Regular expressions must match complete canonical struct package/name/structname. - # Default: [] - exclude: [] - - fatcontext: - # Check for potential fat contexts in struct pointers. - # May generate false positives. - # Default: false - check-struct-pointers: true - - forbidigo: - # Forbid the following identifiers (list of regexp). - # Default: ["^(fmt\\.Print(|f|ln)|print|println)$"] - forbid: - - pattern: ^(fmt\\.Print(|f|ln)|print|println)$ - msg: Do not commit print statements. - # Exclude godoc examples from forbidigo checks. - # Default: true - exclude-godoc-examples: true - # Instead of matching the literal source code, - # use type information to replace expressions with strings that contain the package name - # and (for methods and fields) the type name. - # This makes it possible to handle import renaming and forbid struct fields and methods. - # Default: false - analyze-types: true - - funcorder: - # Checks that constructors are placed after the structure declaration. - # Default: true - constructor: true - # Checks if the exported methods of a structure are placed before the non-exported ones. - # Default: true - struct-method: true - - gochecksumtype: - # Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed. - # Default: true - default-signifies-exhaustive: true - # Include shared interfaces in the exhaustiveness check. - # Default: false - include-shared-interfaces: true - - - gocritic: - # Enable all checks. - # Default: false - enable-all: true - # Which checks should be disabled; can't be combined with 'enabled-checks'. - # Default: [] - disabled-checks: [] - - # Settings passed to gocritic. - # The settings key is the name of a supported gocritic checker. - # The list of supported checkers can be found at https://go-critic.com/overview. - settings: - # Must be valid enabled check name. - captLocal: - # Whether to restrict checker to params only. - # Default: true - paramsOnly: false - commentedOutCode: - # Min length of the comment that triggers a warning. - # Default: 15 - minLength: 10 - elseif: - # Whether to skip balanced if-else pairs. - # Default: true - skipBalanced: true - hugeParam: - # Size in bytes that makes the warning trigger. - # Default: 80 - sizeThreshold: 70 - ifElseChain: - # Min number of if-else blocks that makes the warning trigger. - # Default: 2 - minThreshold: 2 - nestingReduce: - # Min number of statements inside a branch to trigger a warning. - # Default: 5 - bodyWidth: 5 - rangeExprCopy: - # Size in bytes that makes the warning trigger. - # Default: 512 - sizeThreshold: 512 - # Whether to check test functions - # Default: true - skipTestFuncs: true - rangeValCopy: - # Size in bytes that makes the warning trigger. - # Default: 128 - sizeThreshold: 128 - # Whether to check test functions. - # Default: true - skipTestFuncs: true - ruleguard: - # Enable debug to identify which 'Where' condition was rejected. - # The value of the parameter is the name of a function in a ruleguard file. - # - # When a rule is evaluated: - # If: - # The Match() clause is accepted; and - # One of the conditions in the Where() clause is rejected, - # Then: - # ruleguard prints the specific Where() condition that was rejected. - # - # The option is passed to the ruleguard 'debug-group' argument. - # Default: "" - debug: '' - # Determines the behavior when an error occurs while parsing ruleguard files. - # If flag is not set, log error and skip rule files that contain an error. - # If flag is set, the value must be a comma-separated list of error conditions. - # - 'all': fail on all errors. - # - 'import': ruleguard rule imports a package that cannot be found. - # - 'dsl': gorule file does not comply with the ruleguard DSL. - # Default: "" - failOn: "" - # Comma-separated list of file paths containing ruleguard rules. - # By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed. - # The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`. - # The placeholder '${config-path}' is substituted with a path relative to the configuration file. - # Glob patterns such as 'rules-*.go' may be specified. - # Default: "" - rules: '' - # Comma-separated list of enabled groups or skip empty to enable everything. - # Tags can be defined with # character prefix. - # Default: "" - enable: "" - # Comma-separated list of disabled groups or skip empty to enable everything. - # Tags can be defined with # character prefix. - # Default: "" - disable: "" - tooManyResultsChecker: - # Maximum number of results. - # Default: 5 - maxResults: 2 - truncateCmp: - # Whether to skip int/uint/uintptr types. - # Default: true - skipArchDependent: false - underef: - # Whether to skip (*x).method() calls where x is a pointer receiver. - # Default: true - skipRecvDeref: true - unnamedResult: - # Whether to check exported functions. - # Default: false - checkExported: true - - godot: - # Comments to be checked: `declarations`, `toplevel`, or `all`. - # Default: declarations - scope: declarations - # List of regexps for excluding particular comment lines from check. - # Default: [] - exclude: - # Exclude todo and fixme comments. - - "^fixme:|^FIXME:" - - "^todo:|^TODO:" - # Check that each sentence ends with a period. - # Default: true - period: true - # Check that each sentence starts with a capital letter. - # Default: false - capital: true - - 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. - # Default: ["TODO", "BUG", "FIXME"] - keywords: - - BUG - - FIXME - - TODO - - NOTE - - OPTIMIZE # marks code that should be optimized before merging - - HACK # marks hack-around that should be removed before merging - - goheader: - # Supports two types 'const` and `regexp`. - # Values can be used recursively. - # Default: {} - values: - const: - # Define here const type values in format k:v. - # For example: - AUTHOR: Bruno Carlin - regexp: {} - # Define here regexp type values. - # for example: - # The template used for checking. - # Put here copyright header template for source code files. - # Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time. - # Default: "" - template: |- - SPDX-FileCopyrightText: {{ YEAR }} {{ AUTHOR }} - - SPDX-License-Identifier: MIT - - # As alternative of directive 'template', you may put the path to file with the template source. - # Useful if you need to load the template from a specific file. - # By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed. - # The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`. - # The placeholder '${config-path}' is substituted with a path relative to the configuration file. - # Default: "" - #template-path: /path/to/my/template.tmpl - - gomoddirectives: - # Allow local `replace` directives. - # Default: false - replace-local: false - # List of allowed `replace` directives. - # Default: [] - #replace-allow-list: - # - launchpad.net/gocheck - # Allow to not explain why the version has been retracted in the `retract` directives. - # Default: false - #retract-allow-no-explanation: false - # Forbid the use of the `exclude` directives. - # Default: false - #exclude-forbidden: false - # Forbid the use of the `toolchain` directive. - # Default: false - toolchain-forbidden: false - # Defines a pattern to validate `toolchain` directive. - # Default: '' (no match) - #toolchain-pattern: 'go1\.23\.\d+$' - # Forbid the use of the `tool` directives. - # Default: false - #tool-forbidden: true - # Forbid the use of the `godebug` directive. - # Default: false - #go-debug-forbidden: true - # Defines a pattern to validate `go` minimum version directive. - # Default: '' (no match) - #go-version-pattern: '\d\.\d+(\.0)?' - - gomodguard: - allowed: - # List of allowed modules. - # Default: [] - modules: - - github.com/alexedwards/argon2id - - github.com/google/uuid - - github.com/hack-pad/hackpadfs - - github.com/jessevdk/go-flags - - github.com/pressly/goose/v3 - - github.com/PuerkitoBio/goquery - - github.com/stretchr/testify - - gopkg.in/yaml.v3 - - modernc.org/sqlite - # List of allowed module domains. - # Default: [] - domains: - - golang.org - - code.bcarlin.xyz - - code.bcarlin.net - - code.waarp.fr - blocked: {} - # List of blocked modules. - # Default: [] - #modules: - # Blocked module. - # - github.com/uudashr/go-module: - # # Recommended modules that should be used instead. (Optional) - # recommendations: - # - golang.org/x/mod - # # Reason why the recommended module should be used. (Optional) - # reason: "`mod` is the official go.mod parser library." - # List of blocked module version constraints. - # Default: [] - #versions: - # # Blocked module with version constraint. - # - github.com/mitchellh/go-homedir: - # # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons. - # version: "< 1.1.0" - # # Reason why the version constraint exists. (Optional) - # reason: "testing if blocked version constraint works." - # Set to true to raise lint issues for packages that are loaded from a local path via replace directive. - # Default: false - #local_replace_directives: false - - gosec: - # To select a subset of rules to run. - # Available rules: https://github.com/securego/gosec#available-rules - # Default: [] - means include all rules - includes: [] - - # To specify a set of rules to explicitly exclude. - # Available rules: https://github.com/securego/gosec#available-rules - excludes: [] - - # Filter out the issues with a lower severity than the given value. - # Valid options are: low, medium, high. - # Default: low - severity: low - - # Filter out the issues with a lower confidence than the given value. - # Valid options are: low, medium, high. - # Default: low - confidence: low - - # Concurrency value. - # Default: the number of logical CPUs usable by the current process. - #concurrency: 12 - - # To specify the configuration of rules. - config: - # Globals are applicable to all rules. - global: - # If true, ignore #nosec in comments (and an alternative as well). - # Default: false - nosec: false - # Add an alternative comment prefix to #nosec (both will work at the same time). - # Default: "" - #"#nosec": "#my-custom-nosec" - # Define whether nosec issues are counted as finding or not. - # Default: false - show-ignored: false - # Audit mode enables addition checks that for normal code analysis might be too nosy. - # Default: false - audit: true - G101: - # Regexp pattern for variables and constants to find. - # Default: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred" - #pattern: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred" - # If true, complain about all cases (even with low entropy). - # Default: false - ignore_entropy: true - # Maximum allowed entropy of the string. - # Default: "80.0" - entropy_threshold: "80.0" - # Maximum allowed value of entropy/string length. - # Is taken into account if entropy >= entropy_threshold/2. - # Default: "3.0" - per_char_threshold: "3.0" - # Calculate entropy for first N chars of the string. - # Default: "16" - truncate: "32" - # Additional functions to ignore while checking unhandled errors. - # Following functions always ignored: - # bytes.Buffer: - # - Write - # - WriteByte - # - WriteRune - # - WriteString - # fmt: - # - Print - # - Printf - # - Println - # - Fprint - # - Fprintf - # - Fprintln - # strings.Builder: - # - Write - # - WriteByte - # - WriteRune - # - WriteString - # io.PipeWriter: - # - CloseWithError - # hash.Hash: - # - Write - # os: - # - Unsetenv - # Default: {} - G104: - json: - - Marshal - - MarshalIndent - G111: - # Regexp pattern to find potential directory traversal. - # Default: "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)" - #pattern: "custom\\.Dir\\(\\)" - # Maximum allowed permissions mode for os.Mkdir and os.MkdirAll - # Default: "0750" - G301: "0750" - # Maximum allowed permissions mode for os.OpenFile and os.Chmod - # Default: "0600" - G302: "0600" - # Maximum allowed permissions mode for os.WriteFile and ioutil.WriteFile - # Default: "0600" - G306: "0600" - - gosmopolitan: - # Allow and ignore `time.Local` usages. - # - # Default: false - allow-time-local: false - # List of fully qualified names in the `full/pkg/path.name` form, to act as "i18n escape hatches". - # String literals inside call-like expressions to, or struct literals of those names, - # are exempt from the writing system check. - # - # Default: [] - escape-hatches: [] - # List of Unicode scripts to watch for any usage in string literals. - # https://pkg.go.dev/unicode#pkg-variables - # - # Default: ["Han"] - #watch-for-scripts: - # - Devanagari - # - Han - # - Hangul - # - Hiragana - # - Katakana - - govet: - # Disable all analyzers. - # Default: false - disable-all: false - # Enable analyzers by name. - # (In addition to default: - # appends, asmdecl, assign, atomic, bools, buildtag, cgocall, composites, copylocks, defers, directive, errorsas, - # framepointer, httpresponse, ifaceassert, loopclosure, lostcancel, nilfunc, printf, shift, sigchanyzer, slog, - # stdmethods, stringintconv, structtag, testinggoroutine, tests, timeformat, unmarshal, unreachable, unsafeptr, - # unusedresult - # ). - # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers. - # Default: [] - enable: [] - # Enable all analyzers. - # Default: false - enable-all: true - # Disable analyzers by name. - # (In addition to default - # atomicalign, deepequalerrors, fieldalignment, findcall, nilness, reflectvaluecompare, shadow, sortslice, - # timeformat, unusedwrite - # ). - # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers. - # Default: [] - disable: - - fieldalignment - # Settings per analyzer. - settings: - # Analyzer name, run `go tool vet help` to see all analyzers. - printf: {} - # Comma-separated list of print function names to check (in addition to default, see `go tool vet help printf`). - # Default: [] - #funcs: - # - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - # - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - # - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - # - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf - shadow: - # Whether to be strict about shadowing; can be noisy. - # Default: false - strict: true - unusedresult: - # Comma-separated list of functions whose results must be used. - # (In addition to default: - # context.WithCancel, context.WithDeadline, context.WithTimeout, context.WithValue, errors.New, fmt.Errorf, - # fmt.Sprint, fmt.Sprintf, sort.Reverse - # ). - # Default: [] - funcs: [] - # - pkg.MyFunc - # Comma-separated list of names of methods of type func() string whose results must be used - # (in addition to default Error,String) - # Default: [] - #stringmethods: - # - MyMethod - - iface: - # List of analyzers. - # Default: ["identical"] - enable: - - identical # Identifies interfaces in the same package that have identical method sets. - - unused # Identifies interfaces that are not used anywhere in the same package where the interface is defined. - - opaque # Identifies functions that return interfaces, but the actual returned value is always a single concrete implementation. - settings: - unused: - # List of packages path to exclude from the check. - # Default: [] - exclude: - - github.com/example/log - - importas: - # Do not allow unaliased imports of aliased packages. - # Default: false - #no-unaliased: true - # Do not allow non-required aliases. - # Default: false - no-extra-aliases: true - # List of aliases - # Default: [] - alias: - # Using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package. - #- pkg: knative.dev/serving/pkg/apis/serving/v1 - # alias: servingv1 - # Using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package. - #- pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1 - # alias: autoscalingv1alpha1 - # You can specify the package path by regular expression, - # and alias by regular expression expansion syntax like below. - # see https://github.com/julz/importas#use-regular-expression for details - - pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+) - alias: $1$2 - - inamedparam: - # Skips check for interface methods with only a single parameter. - # Default: false - skip-single-param: false - - interfacebloat: - # The maximum number of methods allowed for an interface. - # Default: 10 - max: 5 - - ireturn: - # List of interfaces to allow. - # Lists of the keywords and regular expressions matched to interface or package names can be used. - # `allow` and `reject` settings cannot be used at the same time. - # - # Keywords: - # - `empty` for `interface{}` - # - `error` for errors - # - `stdlib` for standard library - # - `anon` for anonymous interfaces - # - `generic` for generic interfaces added in go 1.18 - # - # Default: [anon, error, empty, stdlib] - allow: - - anon - - error - - empty - - stdlib - - generic - # You can specify idiomatic endings for interface - #- (or|er)$ - - # List of interfaces to reject. - # Lists of the keywords and regular expressions matched to interface or package names can be used. - # `allow` and `reject` settings cannot be used at the same time. - # - # Keywords: - # - `empty` for `interface{}` - # - `error` for errors - # - `stdlib` for standard library - # - `anon` for anonymous interfaces - # - `generic` for generic interfaces added in go 1.18 - # - # Default: [] - #reject: - # - github.com\/user\/package\/v4\.Type - - loggercheck: - # Allow check for the github.com/go-kit/log library. - # Default: true - kitlog: false - # Allow check for the k8s.io/klog/v2 library. - # Default: true - klog: false - # Allow check for the github.com/go-logr/logr library. - # Default: true - logr: false - # Allow check for the log/slog library. - # Default: true - slog: true - # Allow check for the "sugar logger" from go.uber.org/zap library. - # Default: true - zap: false - # Require all logging keys to be inlined constant strings. - # Default: false - require-string-key: true - # Require printf-like format specifier (%s, %d for example) not present. - # Default: false - #no-printf-like: true - # List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers. - # For example: https://github.com/timonwong/loggercheck/blob/7395ab86595781e33f7afba27ad7b55e6956ebcd/testdata/custom-rules.txt - # Default: empty - #rules: - # - k8s.io/klog/v2.InfoS # package level exported functions - # - (github.com/go-logr/logr.Logger).Error # "Methods" - # - (*go.uber.org/zap.SugaredLogger).With # Also "Methods", but with a pointer receiver - - maintidx: - # Show functions with maintainability index lower than N. - # A high index indicates better maintainability (it's kind of the opposite of complexity). - # Default: 20 - under: 20 - - makezero: - # Allow only slices initialized with a length of zero. - # Default: false - always: false - - misspell: - # Correct spellings using locale preferences for US or UK. - # Setting locale to US will correct the British spelling of 'colour' to 'color'. - # Default is to use a neutral variety of English. - locale: US - # Typos to ignore. - # Should be in lower case. - # Default: [] - ignore-rules: [] - #- someword - # Extra word corrections. - # `typo` and `correction` should only contain letters. - # The words are case-insensitive. - # Default: [] - extra-words: - - typo: "iff" - correction: "if" - - typo: "cancelation" - correction: "cancellation" - # Mode of the analysis: - # - default: checks all the file content. - # - restricted: checks only comments. - # Default: "" - mode: restricted - - musttag: - # A set of custom functions to check in addition to the builtin ones. - # Default: json, xml, gopkg.in/yaml.v3, BurntSushi/toml, mitchellh/mapstructure, jmoiron/sqlx - functions: [] - # The full name of the function, including the package. - #- name: github.com/jmoiron/sqlx.Get - # # The struct tag whose presence should be ensured. - # tag: db - # # The position of the argument to check. - # arg-pos: 1 - - nakedret: - # Make an issue if func has more lines of code than this setting, and it has naked returns. - # Default: 30 - max-func-lines: 30 - - nestif: - # Minimal complexity of if statements to report. - # Default: 5 - min-complexity: 5 - - nilnil: - # To check functions with only two return values (`return nil, nil`). - # If disabled then returns like `return nil, nil, ..., nil` are supported. - # Default: true - only-two: false - # In addition, detect opposite situation (simultaneous return of non-nil error and valid value). - # E.g, `return clone, fh.indexer.Update(clone)` will be considered as invalid. - # Default: false - detect-opposite: true - # List of return types to check. - # Default: ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"] - #checked-types: - # - chan - # - func - # - iface - # - map - # - ptr - # - uintptr - # - unsafeptr - - nlreturn: - # Size of the block (including return statement that is still "OK"), - # so no return split required. - # Default: 1 - block-size: 2 - - nolintlint: - # Disable to ensure that all nolint directives actually have an effect. - # Default: false - allow-unused: false - # Exclude following linters from requiring an explanation. - # Default: [] - allow-no-explanation: [ ] - # Enable to require an explanation of nonzero length after each nolint directive. - # Default: false - require-explanation: true - # Enable to require nolint directives to mention the specific linter being suppressed. - # Default: false - require-specific: true - - nonamedreturns: - # Report named error if it is assigned inside defer. - # Default: false - report-error-in-defer: true - - paralleltest: - # Ignore missing calls to `t.Parallel()` and only report incorrect uses of it. - # Default: false - ignore-missing: false - # Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are - # still required to have `t.Parallel`, but subtests are allowed to skip it. - # Default: false - ignore-missing-subtests: false - - perfsprint: - # Enable/disable optimization of integer formatting. - # Default: true - integer-format: true - # Optimizes even if it requires an int or uint type cast. - # Default: true - int-conversion: false - # Enable/disable optimization of error formatting. - # Default: true - error-format: true - # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors. - # Default: false - err-error: true - # Optimizes `fmt.Errorf`. - # Default: true - errorf: false - # Enable/disable optimization of string formatting. - # Default: true - string-format: true - # Optimizes `fmt.Sprintf` with only one argument. - # Default: true - sprintf1: true - # Optimizes into strings concatenation. - # Default: true - strconcat: true - # Enable/disable optimization of bool formatting. - # Default: true - bool-format: true - # Enable/disable optimization of hex formatting. - # Default: true - hex-format: true - - prealloc: - # IMPORTANT: we don't recommend using this linter before doing performance profiling. - # For most programs usage of prealloc will be a premature optimization. - - # Report pre-allocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them. - # Default: true - simple: true - # Report pre-allocation suggestions on range loops. - # Default: true - range-loops: true - # Report pre-allocation suggestions on for loops. - # Default: false - for-loops: true - - predeclared: - # List of predeclared identifiers to not report on. - # Default: [] - ignore: [] - #- new - #- int - # Include method names and field names in checks. - # Default: false - qualified-name: true - - promlinter: - # Promlinter cannot infer all metrics name in static analysis. - # Enable strict mode will also include the errors caused by failing to parse the args. - # Default: false - strict: true - # Please refer to https://github.com/yeya24/promlinter#usage for detailed usage. - # Default: [] - disabled-linters: [] - # Help detects issues related to the help text for a metric. - #- Help - # MetricUnits detects issues with metric unit names. - #- MetricUnits - # Counter detects issues specific to counters, as well as patterns that should only be used with counters. - #- Counter - # HistogramSummaryReserved detects when other types of metrics use names or labels reserved for use by histograms and/or summaries. - #- HistogramSummaryReserved - # MetricTypeInName detects when metric types are included in the metric name. - #- MetricTypeInName - # ReservedChars detects colons in metric names. - #- ReservedChars - # CamelCase detects metric names and label names written in camelCase. - #- CamelCase - # UnitAbbreviations detects abbreviated units in the metric name. - #- UnitAbbreviations - - protogetter: - # Skip files generated by specified generators from the checking. - # Checks only the file's initial comment, which must follow the format: "// Code generated by ". - # Files generated by protoc-gen-go, protoc-gen-go-grpc, and protoc-gen-grpc-gateway are always excluded automatically. - # Default: [] - skip-generated-by: ["protoc-gen-go-my-own-generator"] - # Skip files matching the specified glob pattern from the checking. - # Default: [] - skip-files: - - "*.pb.go" - - "*/vendor/*" - - "/full/path/to/file.go" - # Skip any generated files from the checking. - # Default: false - skip-any-generated: true - # Skip first argument of append function. - # Default: false - replace-first-arg-in-append: true - - reassign: - # Patterns for global variable names that are checked for reassignment. - # See https://github.com/curioswitch/go-reassign#usage - # Default: ["EOF", "Err.*"] - patterns: - - ".*" - - recvcheck: - # Disables the built-in method exclusions: - # - `MarshalText` - # - `MarshalJSON` - # - `MarshalYAML` - # - `MarshalXML` - # - `MarshalBinary` - # - `GobEncode` - # Default: false - disable-builtin: false - # User-defined method exclusions. - # The format is `struct_name.method_name` (ex: `Foo.MethodName`). - # A wildcard `*` can use as a struct name (ex: `*.MethodName`). - # Default: [] - exclusions: - - "*.Value" - - revive: - # Maximum number of open files at the same time. - # See https://github.com/mgechev/revive#command-line-flags - # Defaults to unlimited. - #max-open-files: 2048 - - # Sets the default severity. - # See https://github.com/mgechev/revive#configuration - # Default: warning - #severity: error - - # Enable all available rules. - # Default: false - enable-all-rules: true - - # Enable validation of comment directives. - # See https://github.com/mgechev/revive#comment-directives - directives: - - name: specify-disable-reason - severity: error - - # Sets the default failure confidence. - # This means that linting errors with less than 0.8 confidence will be ignored. - # Default: 0.8 - #confidence: 0.1 - # Run `GL_DEBUG=revive golangci-lint run --enable-only=revive` to see default, all available rules, and enabled rules. - rules: - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#add-constant - - name: add-constant - severity: warning - disabled: false - exclude: [""] - arguments: - - max-lit-count: "3" - allow-strs: '"","\n"' - allow-ints: "0,1,2,0o600,0o700" - allow-floats: "0.0,0.,1.0,1.,2.0,2." - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#argument-limit - - name: argument-limit - severity: warning - disabled: false - exclude: [""] - arguments: [ 4 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#atomic - - name: atomic - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#banned-characters - - name: banned-characters - severity: warning - disabled: false - exclude: [""] - arguments: [ "Ω","Σ","σ", "7" ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bare-return - - name: bare-return - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#blank-imports - - name: blank-imports - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#bool-literal-in-expr - - name: bool-literal-in-expr - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#call-to-gc - - name: call-to-gc - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#cognitive-complexity - - name: cognitive-complexity - severity: warning - disabled: false - exclude: [""] - arguments: [ 7 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comment-spacings - - name: comment-spacings - severity: warning - disabled: false - exclude: [""] - arguments: - - nolint - #- otherpragma - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#comments-density - - name: comments-density - severity: warning - disabled: true - exclude: [""] - arguments: [ 15 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-naming - - name: confusing-naming - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#confusing-results - - name: confusing-results - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#constant-logical-expr - - name: constant-logical-expr - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#context-as-argument - - name: context-as-argument - severity: warning - disabled: false - exclude: [""] - arguments: - - allowTypesBefore: "*testing.T" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#context-keys-type - - name: context-keys-type - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#cyclomatic - - name: cyclomatic - severity: warning - disabled: false - exclude: [""] - arguments: [ 15 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#datarace - - name: datarace - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#deep-exit - - name: deep-exit - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#defer - - name: defer - severity: error - disabled: false - exclude: [""] - arguments: - - - "call-chain" - - "loop" - - "method-call" - - "recover" - - "immediate-recover" - - "return" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#dot-imports - - name: dot-imports - severity: warning - disabled: false - exclude: [""] - arguments: [ ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#duplicated-imports - - name: duplicated-imports - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#early-return - - name: early-return - severity: warning - disabled: false - exclude: [""] - arguments: - - "preserve-scope" - - "allow-jump" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#empty-block - - name: empty-block - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#empty-lines - - name: empty-lines - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-map-style - - name: enforce-map-style - severity: warning - disabled: false - exclude: [""] - arguments: - - "make" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-repeated-arg-type-style - - name: enforce-repeated-arg-type-style - severity: warning - disabled: false - exclude: [""] - arguments: - - "short" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#enforce-slice-style - - name: enforce-slice-style - severity: warning - disabled: false - exclude: [""] - arguments: - - "make" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-naming - - name: error-naming - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-return - - name: error-return - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#error-strings - - name: error-strings - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#errorf - - name: errorf - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#exported - - name: exported - severity: warning - disabled: false - exclude: [""] - arguments: - - "check-private-receivers" - #- "disable-stuttering-check" - - "say-repetitive-instead-of-stutters" - - "check-public-interface" - #- "disable-checks-on-constants" - #- "disable-checks-on-functions" - #- "disable-checks-on-methods" - #- "disable-checks-on-types" - #- "disable-checks-on-variables" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#file-header - - name: file-header - severity: warning - disabled: true - exclude: [""] - arguments: - - This is the text that must appear at the top of source files. - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#file-length-limit - - name: file-length-limit - severity: warning - disabled: true - exclude: [""] - arguments: - - max: 100 - skipComments: true - skipBlankLines: true - - name: filename-format - severity: warning - disabled: false - exclude: [""] - arguments: - - "^[_a-z][_a-z0-9]*\\.go$" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#flag-parameter - - name: flag-parameter - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-length - - name: function-length - severity: warning - disabled: false - exclude: [""] - arguments: [20, 0] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#function-result-limit - - name: function-result-limit - severity: warning - disabled: false - exclude: [""] - arguments: [ 2 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#get-return - - name: get-return - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#identical-branches - - name: identical-branches - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#if-return - - name: if-return - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#import-alias-naming - - name: import-alias-naming - severity: warning - disabled: false - exclude: [""] - arguments: - - "^[a-z][a-z0-9]{0,}$" - # Or this parameter: - #- allow-regex: "^[a-z][a-z0-9]{0,}$" - # deny-regex: '^v\d+$' - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#import-shadowing - - name: import-shadowing - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#imports-blocklist - - name: imports-blocklist - severity: warning - disabled: false - exclude: [""] - arguments: - - "crypto/md5" - - "crypto/sha1" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#increment-decrement - - name: increment-decrement - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#indent-error-flow - - name: indent-error-flow - severity: warning - disabled: false - exclude: [""] - arguments: - - "preserve-scope" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#line-length-limit - - name: line-length-limit - severity: warning - disabled: false - exclude: [""] - arguments: [ 80 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-control-nesting - - name: max-control-nesting - severity: warning - disabled: false - exclude: [""] - arguments: [ 5 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#max-public-structs - - name: max-public-structs - severity: warning - disabled: true - exclude: [""] - arguments: [ 3 ] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-parameter - - name: modifies-parameter - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#modifies-value-receiver - - name: modifies-value-receiver - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#nested-structs - - name: nested-structs - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#optimize-operands-order - - name: optimize-operands-order - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#package-comments - - name: package-comments - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range - - name: range - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range-val-address - - name: range-val-address - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#range-val-in-closure - - name: range-val-in-closure - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#receiver-naming - - name: receiver-naming - severity: warning - disabled: false - exclude: [""] - arguments: - - max-length: 2 - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redefines-builtin-id - - name: redefines-builtin-id - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-build-tag - - name: redundant-build-tag - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#redundant-import-alias - - name: redundant-import-alias - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redundant-test-main-exit - - name: redundant-test-main-exit - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#string-format - - name: string-format - severity: warning - disabled: false - exclude: [""] - arguments: - - - 'core.WriteError[1].Message' - - '/^([^A-Z]|$)/' - - must not start with a capital letter - - - 'fmt.Errorf[0]' - - '/(^|[^\.!?])$/' - - must not end in punctuation - - - panic - - '/^[^\n]*$/' - - must not contain line breaks - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#string-of-int - - name: string-of-int - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#struct-tag - - name: struct-tag - severity: warning - disabled: false - exclude: [""] - arguments: - - "json,inline" - - "bson,outline,gnu" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#superfluous-else - - name: superfluous-else - severity: warning - disabled: false - exclude: [""] - arguments: - - "preserve-scope" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-equal - - name: time-equal - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#time-naming - - name: time-naming - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unchecked-type-assertion - - name: unchecked-type-assertion - severity: warning - disabled: false - exclude: [""] - arguments: - - accept-ignored-assertion-result: true - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unconditional-recursion - - name: unconditional-recursion - severity: error - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unexported-naming - - name: unexported-naming - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unexported-return - - name: unexported-return - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unhandled-error - - name: unhandled-error - severity: warning - disabled: false - exclude: [""] - arguments: - - "fmt.Print(f|ln)" - - "myFunction" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unnecessary-stmt - - name: unnecessary-stmt - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unreachable-code - - name: unreachable-code - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unused-parameter - - name: unused-parameter - severity: warning - disabled: false - exclude: [""] - arguments: - - allow-regex: "^_" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#unused-receiver - - name: unused-receiver - severity: warning - disabled: false - exclude: [""] - arguments: - - allow-regex: "^_" - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-any - - name: use-any - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#use-errors-new - - name: use-errors-new - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#useless-break - - name: useless-break - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#var-declaration - - name: var-declaration - severity: warning - disabled: false - exclude: [""] - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#var-naming - - name: var-naming - severity: warning - disabled: false - exclude: [""] - arguments: - - [ "ID" ] # AllowList - - [ "VM" ] # DenyList - - - upper-case-const: true # Extra parameter (upper-case-const|skip-package-name-checks) - # https://github.com/mgechev/revive/blob/HEAD/RULES_DESCRIPTIONS.md#waitgroup-by-value - - name: waitgroup-by-value - severity: error - disabled: false - exclude: [""] - - rowserrcheck: - # database/sql is always checked. - # Default: [] - packages: - - github.com/jmoiron/sqlx - - sloglint: - # Enforce not mixing key-value pairs and attributes. - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-mixed-arguments - # Default: true - no-mixed-args: true - # Enforce using key-value pairs only (overrides no-mixed-args, incompatible with attr-only). - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#key-value-pairs-only - # Default: false - kv-only: false - # Enforce using attributes only (overrides no-mixed-args, incompatible with kv-only). - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#attributes-only - # Default: false - attr-only: false - # Enforce not using global loggers. - # Values: - # - "": disabled - # - "all": report all global loggers - # - "default": report only the default slog logger - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global - # Default: "" - no-global: "all" - # Enforce using methods that accept a context. - # Values: - # - "": disabled - # - "all": report all contextless calls - # - "scope": report only if a context exists in the scope of the outermost function - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only - # Default: "" - context: "all" - # Enforce using static values for log messages. - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#static-messages - # Default: false - static-msg: true - # Enforce message style. - # Values: lowercased, capitalized - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#message-style - # Default: "" - msg-style: capitalized - # Enforce using constants instead of raw keys. - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-raw-keys - # Default: false - no-raw-keys: true - # Enforce key naming convention. - # Values: snake, kebab, camel, pascal - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#key-naming-convention - # Default: "" - key-naming-case: camel - # Enforce not using specific keys. - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#forbidden-keys - # Default: [] - forbidden-keys: - - time - - level - - msg - - source - # Enforce putting arguments on separate lines. - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#arguments-on-separate-lines - # Default: false - args-on-sep-lines: false - - spancheck: - # Checks to enable. - # Options include: - # - `end`: check that `span.End()` is called - # - `record-error`: check that `span.RecordError(err)` is called when an error is returned - # - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned - # Default: ["end"] - checks: - - end - - record-error - - set-status - # A list of regexes for function signatures that silence `record-error` and `set-status` reports - # if found in the call path to a returned error. - # https://github.com/jjti/go-spancheck#ignore-check-signatures - # Default: [] - ignore-check-signatures: - - "telemetry.RecordError" - # A list of regexes for additional function signatures that create spans. - # This is useful if you have a utility method to create spans. - # Each entry should be of the form `:`, where `telemetry-type` can be `opentelemetry` or `opencensus`. - # https://github.com/jjti/go-spancheck#extra-start-span-signatures - # Default: [] - extra-start-span-signatures: - - "github.com/user/repo/telemetry/trace.Start:opentelemetry" - - staticcheck: - # https://staticcheck.dev/docs/configuration/options/#dot_import_whitelist - # Default: ["github.com/mmcloughlin/avo/build", "github.com/mmcloughlin/avo/operand", "github.com/mmcloughlin/avo/reg"] - dot-import-whitelist: - - fmt - # https://staticcheck.dev/docs/configuration/options/#initialisms - # Default: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"] - initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ] - # https://staticcheck.dev/docs/configuration/options/#http_status_code_whitelist - # Default: ["200", "400", "404", "500"] - http-status-code-whitelist: [] - # SAxxxx checks in https://staticcheck.dev/docs/configuration/options/#checks - # Example (to disable some checks): [ "all", "-SA1000", "-SA1001"] - # Default: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"] - checks: - # Invalid regular expression. - # https://staticcheck.dev/docs/checks/#SA1000 - - SA1000 - # Invalid template. - # https://staticcheck.dev/docs/checks/#SA1001 - - SA1001 - # Invalid format in 'time.Parse'. - # https://staticcheck.dev/docs/checks/#SA1002 - - SA1002 - # Unsupported argument to functions in 'encoding/binary'. - # https://staticcheck.dev/docs/checks/#SA1003 - - SA1003 - # Suspiciously small untyped constant in 'time.Sleep'. - # https://staticcheck.dev/docs/checks/#SA1004 - - SA1004 - # Invalid first argument to 'exec.Command'. - # https://staticcheck.dev/docs/checks/#SA1005 - - SA1005 - # 'Printf' with dynamic first argument and no further arguments. - # https://staticcheck.dev/docs/checks/#SA1006 - - SA1006 - # Invalid URL in 'net/url.Parse'. - # https://staticcheck.dev/docs/checks/#SA1007 - - SA1007 - # Non-canonical key in 'http.Header' map. - # https://staticcheck.dev/docs/checks/#SA1008 - - SA1008 - # '(*regexp.Regexp).FindAll' called with 'n == 0', which will always return zero results. - # https://staticcheck.dev/docs/checks/#SA1010 - - SA1010 - # Various methods in the "strings" package expect valid UTF-8, but invalid input is provided. - # https://staticcheck.dev/docs/checks/#SA1011 - - SA1011 - # A nil 'context.Context' is being passed to a function, consider using 'context.TODO' instead. - # https://staticcheck.dev/docs/checks/#SA1012 - - SA1012 - # 'io.Seeker.Seek' is being called with the whence constant as the first argument, but it should be the second. - # https://staticcheck.dev/docs/checks/#SA1013 - - SA1013 - # Non-pointer value passed to 'Unmarshal' or 'Decode'. - # https://staticcheck.dev/docs/checks/#SA1014 - - SA1014 - # Using 'time.Tick' in a way that will leak. Consider using 'time.NewTicker', and only use 'time.Tick' in tests, commands and endless functions. - # https://staticcheck.dev/docs/checks/#SA1015 - - SA1015 - # Trapping a signal that cannot be trapped. - # https://staticcheck.dev/docs/checks/#SA1016 - - SA1016 - # Channels used with 'os/signal.Notify' should be buffered. - # https://staticcheck.dev/docs/checks/#SA1017 - - SA1017 - # 'strings.Replace' called with 'n == 0', which does nothing. - # https://staticcheck.dev/docs/checks/#SA1018 - - SA1018 - # Using a deprecated function, variable, constant or field. - # https://staticcheck.dev/docs/checks/#SA1019 - - SA1019 - # Using an invalid host:port pair with a 'net.Listen'-related function. - # https://staticcheck.dev/docs/checks/#SA1020 - - SA1020 - # Using 'bytes.Equal' to compare two 'net.IP'. - # https://staticcheck.dev/docs/checks/#SA1021 - - SA1021 - # Modifying the buffer in an 'io.Writer' implementation. - # https://staticcheck.dev/docs/checks/#SA1023 - - SA1023 - # A string cutset contains duplicate characters. - # https://staticcheck.dev/docs/checks/#SA1024 - - SA1024 - # It is not possible to use '(*time.Timer).Reset''s return value correctly. - # https://staticcheck.dev/docs/checks/#SA1025 - - SA1025 - # Cannot marshal channels or functions. - # https://staticcheck.dev/docs/checks/#SA1026 - - SA1026 - # Atomic access to 64-bit variable must be 64-bit aligned. - # https://staticcheck.dev/docs/checks/#SA1027 - - SA1027 - # 'sort.Slice' can only be used on slices. - # https://staticcheck.dev/docs/checks/#SA1028 - - SA1028 - # Inappropriate key in call to 'context.WithValue'. - # https://staticcheck.dev/docs/checks/#SA1029 - - SA1029 - # Invalid argument in call to a 'strconv' function. - # https://staticcheck.dev/docs/checks/#SA1030 - - SA1030 - # Overlapping byte slices passed to an encoder. - # https://staticcheck.dev/docs/checks/#SA1031 - - SA1031 - # Wrong order of arguments to 'errors.Is'. - # https://staticcheck.dev/docs/checks/#SA1032 - - SA1032 - # 'sync.WaitGroup.Add' called inside the goroutine, leading to a race condition. - # https://staticcheck.dev/docs/checks/#SA2000 - - SA2000 - # Empty critical section, did you mean to defer the unlock?. - # https://staticcheck.dev/docs/checks/#SA2001 - - SA2001 - # Called 'testing.T.FailNow' or 'SkipNow' in a goroutine, which isn't allowed. - # https://staticcheck.dev/docs/checks/#SA2002 - - SA2002 - # Deferred 'Lock' right after locking, likely meant to defer 'Unlock' instead. - # https://staticcheck.dev/docs/checks/#SA2003 - - SA2003 - # 'TestMain' doesn't call 'os.Exit', hiding test failures. - # https://staticcheck.dev/docs/checks/#SA3000 - - SA3000 - # Assigning to 'b.N' in benchmarks distorts the results. - # https://staticcheck.dev/docs/checks/#SA3001 - - SA3001 - # Binary operator has identical expressions on both sides. - # https://staticcheck.dev/docs/checks/#SA4000 - - SA4000 - # '&*x' gets simplified to 'x', it does not copy 'x'. - # https://staticcheck.dev/docs/checks/#SA4001 - - SA4001 - # Comparing unsigned values against negative values is pointless. - # https://staticcheck.dev/docs/checks/#SA4003 - - SA4003 - # The loop exits unconditionally after one iteration. - # https://staticcheck.dev/docs/checks/#SA4004 - - SA4004 - # Field assignment that will never be observed. Did you mean to use a pointer receiver?. - # https://staticcheck.dev/docs/checks/#SA4005 - - SA4005 - # A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?. - # https://staticcheck.dev/docs/checks/#SA4006 - - SA4006 - # The variable in the loop condition never changes, are you incrementing the wrong variable?. - # https://staticcheck.dev/docs/checks/#SA4008 - - SA4008 - # A function argument is overwritten before its first use. - # https://staticcheck.dev/docs/checks/#SA4009 - - SA4009 - # The result of 'append' will never be observed anywhere. - # https://staticcheck.dev/docs/checks/#SA4010 - - SA4010 - # Break statement with no effect. Did you mean to break out of an outer loop?. - # https://staticcheck.dev/docs/checks/#SA4011 - - SA4011 - # Comparing a value against NaN even though no value is equal to NaN. - # https://staticcheck.dev/docs/checks/#SA4012 - - SA4012 - # Negating a boolean twice ('!!b') is the same as writing 'b'. This is either redundant, or a typo. - # https://staticcheck.dev/docs/checks/#SA4013 - - SA4013 - # An if/else if chain has repeated conditions and no side-effects; if the condition didn't match the first time, it won't match the second time, either. - # https://staticcheck.dev/docs/checks/#SA4014 - - SA4014 - # Calling functions like 'math.Ceil' on floats converted from integers doesn't do anything useful. - # https://staticcheck.dev/docs/checks/#SA4015 - - SA4015 - # Certain bitwise operations, such as 'x ^ 0', do not do anything useful. - # https://staticcheck.dev/docs/checks/#SA4016 - - SA4016 - # Discarding the return values of a function without side effects, making the call pointless. - # https://staticcheck.dev/docs/checks/#SA4017 - - SA4017 - # Self-assignment of variables. - # https://staticcheck.dev/docs/checks/#SA4018 - - SA4018 - # Multiple, identical build constraints in the same file. - # https://staticcheck.dev/docs/checks/#SA4019 - - SA4019 - # Unreachable case clause in a type switch. - # https://staticcheck.dev/docs/checks/#SA4020 - - SA4020 - # "x = append(y)" is equivalent to "x = y". - # https://staticcheck.dev/docs/checks/#SA4021 - - SA4021 - # Comparing the address of a variable against nil. - # https://staticcheck.dev/docs/checks/#SA4022 - - SA4022 - # Impossible comparison of interface value with untyped nil. - # https://staticcheck.dev/docs/checks/#SA4023 - - SA4023 - # Checking for impossible return value from a builtin function. - # https://staticcheck.dev/docs/checks/#SA4024 - - SA4024 - # Integer division of literals that results in zero. - # https://staticcheck.dev/docs/checks/#SA4025 - - SA4025 - # Go constants cannot express negative zero. - # https://staticcheck.dev/docs/checks/#SA4026 - - SA4026 - # '(*net/url.URL).Query' returns a copy, modifying it doesn't change the URL. - # https://staticcheck.dev/docs/checks/#SA4027 - - SA4027 - # 'x % 1' is always zero. - # https://staticcheck.dev/docs/checks/#SA4028 - - SA4028 - # Ineffective attempt at sorting slice. - # https://staticcheck.dev/docs/checks/#SA4029 - - SA4029 - # Ineffective attempt at generating random number. - # https://staticcheck.dev/docs/checks/#SA4030 - - SA4030 - # Checking never-nil value against nil. - # https://staticcheck.dev/docs/checks/#SA4031 - - SA4031 - # Comparing 'runtime.GOOS' or 'runtime.GOARCH' against impossible value. - # https://staticcheck.dev/docs/checks/#SA4032 - - SA4032 - # Assignment to nil map. - # https://staticcheck.dev/docs/checks/#SA5000 - - SA5000 - # Deferring 'Close' before checking for a possible error. - # https://staticcheck.dev/docs/checks/#SA5001 - - SA5001 - # The empty for loop ("for {}") spins and can block the scheduler. - # https://staticcheck.dev/docs/checks/#SA5002 - - SA5002 - # Defers in infinite loops will never execute. - # https://staticcheck.dev/docs/checks/#SA5003 - - SA5003 - # "for { select { ..." with an empty default branch spins. - # https://staticcheck.dev/docs/checks/#SA5004 - - SA5004 - # The finalizer references the finalized object, preventing garbage collection. - # https://staticcheck.dev/docs/checks/#SA5005 - - SA5005 - # Infinite recursive call. - # https://staticcheck.dev/docs/checks/#SA5007 - - SA5007 - # Invalid struct tag. - # https://staticcheck.dev/docs/checks/#SA5008 - - SA5008 - # Invalid Printf call. - # https://staticcheck.dev/docs/checks/#SA5009 - - SA5009 - # Impossible type assertion. - # https://staticcheck.dev/docs/checks/#SA5010 - - SA5010 - # Possible nil pointer dereference. - # https://staticcheck.dev/docs/checks/#SA5011 - - SA5011 - # Passing odd-sized slice to function expecting even size. - # https://staticcheck.dev/docs/checks/#SA5012 - - SA5012 - # Using 'regexp.Match' or related in a loop, should use 'regexp.Compile'. - # https://staticcheck.dev/docs/checks/#SA6000 - - SA6000 - # Missing an optimization opportunity when indexing maps by byte slices. - # https://staticcheck.dev/docs/checks/#SA6001 - - SA6001 - # Storing non-pointer values in 'sync.Pool' allocates memory. - # https://staticcheck.dev/docs/checks/#SA6002 - - SA6002 - # Converting a string to a slice of runes before ranging over it. - # https://staticcheck.dev/docs/checks/#SA6003 - - SA6003 - # Inefficient string comparison with 'strings.ToLower' or 'strings.ToUpper'. - # https://staticcheck.dev/docs/checks/#SA6005 - - SA6005 - # Using io.WriteString to write '[]byte'. - # https://staticcheck.dev/docs/checks/#SA6006 - - SA6006 - # Defers in range loops may not run when you expect them to. - # https://staticcheck.dev/docs/checks/#SA9001 - - SA9001 - # Using a non-octal 'os.FileMode' that looks like it was meant to be in octal. - # https://staticcheck.dev/docs/checks/#SA9002 - - SA9002 - # Empty body in an if or else branch. - # https://staticcheck.dev/docs/checks/#SA9003 - - SA9003 - # Only the first constant has an explicit type. - # https://staticcheck.dev/docs/checks/#SA9004 - - SA9004 - # Trying to marshal a struct with no public fields nor custom marshaling. - # https://staticcheck.dev/docs/checks/#SA9005 - - SA9005 - # Dubious bit shifting of a fixed size integer value. - # https://staticcheck.dev/docs/checks/#SA9006 - - SA9006 - # Deleting a directory that shouldn't be deleted. - # https://staticcheck.dev/docs/checks/#SA9007 - - SA9007 - # 'else' branch of a type assertion is probably not reading the right value. - # https://staticcheck.dev/docs/checks/#SA9008 - - SA9008 - # Ineffectual Go compiler directive. - # https://staticcheck.dev/docs/checks/#SA9009 - - SA9009 - # Incorrect or missing package comment. - # https://staticcheck.dev/docs/checks/#ST1000 - - ST1000 - # Dot imports are discouraged. - # https://staticcheck.dev/docs/checks/#ST1001 - - ST1001 - # Poorly chosen identifier. - # https://staticcheck.dev/docs/checks/#ST1003 - - ST1003 - # Incorrectly formatted error string. - # https://staticcheck.dev/docs/checks/#ST1005 - - ST1005 - # Poorly chosen receiver name. - # https://staticcheck.dev/docs/checks/#ST1006 - - ST1006 - # A function's error value should be its last return value. - # https://staticcheck.dev/docs/checks/#ST1008 - - ST1008 - # Poorly chosen name for variable of type 'time.Duration'. - # https://staticcheck.dev/docs/checks/#ST1011 - - ST1011 - # Poorly chosen name for error variable. - # https://staticcheck.dev/docs/checks/#ST1012 - - ST1012 - # Should use constants for HTTP error codes, not magic numbers. - # https://staticcheck.dev/docs/checks/#ST1013 - - ST1013 - # A switch's default case should be the first or last case. - # https://staticcheck.dev/docs/checks/#ST1015 - - ST1015 - # Use consistent method receiver names. - # https://staticcheck.dev/docs/checks/#ST1016 - - ST1016 - # Don't use Yoda conditions. - # https://staticcheck.dev/docs/checks/#ST1017 - - ST1017 - # Avoid zero-width and control characters in string literals. - # https://staticcheck.dev/docs/checks/#ST1018 - - ST1018 - # Importing the same package multiple times. - # https://staticcheck.dev/docs/checks/#ST1019 - - ST1019 - # The documentation of an exported function should start with the function's name. - # https://staticcheck.dev/docs/checks/#ST1020 - - ST1020 - # The documentation of an exported type should start with type's name. - # https://staticcheck.dev/docs/checks/#ST1021 - - ST1021 - # The documentation of an exported variable or constant should start with variable's name. - # https://staticcheck.dev/docs/checks/#ST1022 - - ST1022 - # Redundant type in variable declaration. - # https://staticcheck.dev/docs/checks/#ST1023 - - ST1023 - # Use plain channel send or receive instead of single-case select. - # https://staticcheck.dev/docs/checks/#S1000 - - S1000 - # Replace for loop with call to copy. - # https://staticcheck.dev/docs/checks/#S1001 - - S1001 - # Omit comparison with boolean constant. - # https://staticcheck.dev/docs/checks/#S1002 - - S1002 - # Replace call to 'strings.Index' with 'strings.Contains'. - # https://staticcheck.dev/docs/checks/#S1003 - - S1003 - # Replace call to 'bytes.Compare' with 'bytes.Equal'. - # https://staticcheck.dev/docs/checks/#S1004 - - S1004 - # Drop unnecessary use of the blank identifier. - # https://staticcheck.dev/docs/checks/#S1005 - - S1005 - # Use "for { ... }" for infinite loops. - # https://staticcheck.dev/docs/checks/#S1006 - - S1006 - # Simplify regular expression by using raw string literal. - # https://staticcheck.dev/docs/checks/#S1007 - - S1007 - # Simplify returning boolean expression. - # https://staticcheck.dev/docs/checks/#S1008 - - S1008 - # Omit redundant nil check on slices, maps, and channels. - # https://staticcheck.dev/docs/checks/#S1009 - - S1009 - # Omit default slice index. - # https://staticcheck.dev/docs/checks/#S1010 - - S1010 - # Use a single 'append' to concatenate two slices. - # https://staticcheck.dev/docs/checks/#S1011 - - S1011 - # Replace 'time.Now().Sub(x)' with 'time.Since(x)'. - # https://staticcheck.dev/docs/checks/#S1012 - - S1012 - # Use a type conversion instead of manually copying struct fields. - # https://staticcheck.dev/docs/checks/#S1016 - - S1016 - # Replace manual trimming with 'strings.TrimPrefix'. - # https://staticcheck.dev/docs/checks/#S1017 - - S1017 - # Use "copy" for sliding elements. - # https://staticcheck.dev/docs/checks/#S1018 - - S1018 - # Simplify "make" call by omitting redundant arguments. - # https://staticcheck.dev/docs/checks/#S1019 - - S1019 - # Omit redundant nil check in type assertion. - # https://staticcheck.dev/docs/checks/#S1020 - - S1020 - # Merge variable declaration and assignment. - # https://staticcheck.dev/docs/checks/#S1021 - - S1021 - # Omit redundant control flow. - # https://staticcheck.dev/docs/checks/#S1023 - - S1023 - # Replace 'x.Sub(time.Now())' with 'time.Until(x)'. - # https://staticcheck.dev/docs/checks/#S1024 - - S1024 - # Don't use 'fmt.Sprintf("%s", x)' unnecessarily. - # https://staticcheck.dev/docs/checks/#S1025 - - S1025 - # Simplify error construction with 'fmt.Errorf'. - # https://staticcheck.dev/docs/checks/#S1028 - - S1028 - # Range over the string directly. - # https://staticcheck.dev/docs/checks/#S1029 - - S1029 - # Use 'bytes.Buffer.String' or 'bytes.Buffer.Bytes'. - # https://staticcheck.dev/docs/checks/#S1030 - - S1030 - # Omit redundant nil check around loop. - # https://staticcheck.dev/docs/checks/#S1031 - - S1031 - # Use 'sort.Ints(x)', 'sort.Float64s(x)', and 'sort.Strings(x)'. - # https://staticcheck.dev/docs/checks/#S1032 - - S1032 - # Unnecessary guard around call to "delete". - # https://staticcheck.dev/docs/checks/#S1033 - - S1033 - # Use result of type assertion to simplify cases. - # https://staticcheck.dev/docs/checks/#S1034 - - S1034 - # Redundant call to 'net/http.CanonicalHeaderKey' in method call on 'net/http.Header'. - # https://staticcheck.dev/docs/checks/#S1035 - - S1035 - # Unnecessary guard around map access. - # https://staticcheck.dev/docs/checks/#S1036 - - S1036 - # Elaborate way of sleeping. - # https://staticcheck.dev/docs/checks/#S1037 - - S1037 - # Unnecessarily complex way of printing formatted string. - # https://staticcheck.dev/docs/checks/#S1038 - - S1038 - # Unnecessary use of 'fmt.Sprint'. - # https://staticcheck.dev/docs/checks/#S1039 - - S1039 - # Type assertion to current type. - # https://staticcheck.dev/docs/checks/#S1040 - - S1040 - # Apply De Morgan's law. - # https://staticcheck.dev/docs/checks/#QF1001 - - QF1001 - # Convert untagged switch to tagged switch. - # https://staticcheck.dev/docs/checks/#QF1002 - - QF1002 - # Convert if/else-if chain to tagged switch. - # https://staticcheck.dev/docs/checks/#QF1003 - - QF1003 - # Use 'strings.ReplaceAll' instead of 'strings.Replace' with 'n == -1'. - # https://staticcheck.dev/docs/checks/#QF1004 - - QF1004 - # Expand call to 'math.Pow'. - # https://staticcheck.dev/docs/checks/#QF1005 - - QF1005 - # Lift 'if'+'break' into loop condition. - # https://staticcheck.dev/docs/checks/#QF1006 - - QF1006 - # Merge conditional assignment into variable declaration. - # https://staticcheck.dev/docs/checks/#QF1007 - - QF1007 - # Omit embedded fields from selector expression. - # https://staticcheck.dev/docs/checks/#QF1008 - - QF1008 - # Use 'time.Time.Equal' instead of '==' operator. - # https://staticcheck.dev/docs/checks/#QF1009 - - QF1009 - # Convert slice of bytes to string when printing it. - # https://staticcheck.dev/docs/checks/#QF1010 - - QF1010 - # Omit redundant type from variable declaration. - # https://staticcheck.dev/docs/checks/#QF1011 - - QF1011 - # Use 'fmt.Fprintf(x, ...)' instead of 'x.Write(fmt.Sprintf(...))'. - # https://staticcheck.dev/docs/checks/#QF1012 - - QF1012 - - tagalign: - # Align and sort can be used together or separately. - # - # Whether enable align. If true, the struct tags will be aligned. - # E.g.: - # type FooBar struct { - # Bar string `json:"bar" validate:"required"` - # FooFoo int8 `json:"foo_foo" validate:"required"` - # } - # will be formatted to: - # type FooBar struct { - # Bar string `json:"bar" validate:"required"` - # FooFoo int8 `json:"foo_foo" validate:"required"` - # } - # Default: true. - align: false - # Whether enable tags sort. - # If true, the tags will be sorted by name in ascending order. - # E.g.: `xml:"bar" json:"bar" validate:"required"` -> `json:"bar" validate:"required" xml:"bar"`. - # Default: true - sort: false - # Specify the order of tags, the other tags will be sorted by name. - # This option will be ignored if `sort` is false. - # Default: [] - order: - - json - - yaml - - yml - - toml - - mapstructure - - binding - - validate - # Whether enable strict style. - # In this style, the tags will be sorted and aligned in the dictionary order, - # and the tags with the same name will be aligned together. - # Note: This option will be ignored if 'align' or 'sort' is false. - # Default: false - strict: true - - tagliatelle: - # Checks the struct tag name case. - case: - # Defines the association between tag name and case. - # Any struct tag name can be used. - # Supported string cases: - # - `camel` - # - `pascal` - # - `kebab` - # - `snake` - # - `upperSnake` - # - `goCamel` - # - `goPascal` - # - `goKebab` - # - `goSnake` - # - `upper` - # - `lower` - # - `header` - rules: - json: camel - yaml: goCamel - xml: goCamel - toml: snake - bson: camel - avro: snake - mapstructure: kebab - env: upperSnake - envconfig: upperSnake - - - testifylint: - # Enable all checkers (https://github.com/Antonboom/testifylint#checkers). - # Default: false - enable-all: true - # Disable checkers by name - # (in addition to default - # suite-thelper - # ). - disable: [] - #- blank-import - #- bool-compare - #- compares - #- contains - #- empty - #- encoded-compare - #- equal-values - #- error-is-as - #- error-nil - #- expected-actual - #- float-compare - #- formatter - #- go-require - #- len - #- negative-positive - #- nil-compare - #- regexp - #- require-error - #- suite-broken-parallel - #- suite-dont-use-pkg - #- suite-extra-assert-call - #- suite-method-signature - #- suite-subtest-run - #- suite-thelper - #- useless-assert - - # Disable all checkers (https://github.com/Antonboom/testifylint#checkers). - # Default: false - disable-all: false - # Enable checkers by name - # (in addition to default - # blank-import, bool-compare, compares, contains, empty, encoded-compare, equal-values, error-is-as, error-nil, - # expected-actual, go-require, float-compare, formatter, len, negative-positive, nil-compare, regexp, require-error, - # suite-broken-parallel, suite-dont-use-pkg, suite-extra-assert-call, suite-subtest-run, suite-method-signature, - # useless-assert - # ). - enable: [] - #- blank-import - #- bool-compare - #- compares - #- contains - #- empty - #- encoded-compare - #- equal-values - #- error-is-as - #- error-nil - #- expected-actual - #- float-compare - #- formatter - #- go-require - #- len - #- negative-positive - #- nil-compare - #- regexp - #- require-error - #- suite-broken-parallel - #- suite-dont-use-pkg - #- suite-extra-assert-call - #- suite-method-signature - #- suite-subtest-run - #- suite-thelper - #- useless-assert - - bool-compare: - # To ignore user defined types (over builtin bool). - # Default: false - ignore-custom-types: false - expected-actual: - # Regexp for expected variable name. - # Default: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$) - pattern: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$) - formatter: - # To enable go vet's printf checks. - # Default: true - check-format-string: true - # To require f-assertions (e.g. `assert.Equalf`) if format string is used, even if there are no variable-length - # variables, i.e. it requires `require.NoErrorf` for both these cases: - # - require.NoErrorf(t, err, "unexpected error") - # - require.NoErrorf(t, err, "unexpected error for sid: %v", sid) - # To understand this behavior, please read the - # https://github.com/Antonboom/testifylint?tab=readme-ov-file#historical-reference-of-formatter. - # Default: false - require-f-funcs: false - # To require that the first element of msgAndArgs (msg) has a string type. - # For example, in such case assertion like `assert.True(t, b, tt.case)` will be considered as invalid. - # Default: true - require-string-msg: true - go-require: - # To ignore HTTP handlers (like http.HandlerFunc). - # Default: false - ignore-http-handlers: false - require-error: - # Regexp for assertions to analyze. If defined, then only matched error assertions will be reported. - # Default: "" - fn-pattern: "" - suite-extra-assert-call: - # To require or remove extra Assert() call? - # Default: remove - mode: require - - testpackage: - # Regexp pattern to skip files. - # Default: "(export|internal)_test\\.go" - skip-regexp: (export|internal)_test\.go - # List of packages that don't end with _test that tests are allowed to be in. - # Default: "main" - allow-packages: - - main - - thelper: - test: - # Check *testing.T is first param (or after context.Context) of helper function. - # Default: true - first: true - # Check *testing.T param has name t. - # Default: true - name: true - # Check t.Helper() begins helper function. - # Default: true - begin: true - benchmark: - # Check *testing.B is first param (or after context.Context) of helper function. - # Default: true - first: true - # Check *testing.B param has name b. - # Default: true - name: true - # Check b.Helper() begins helper function. - # Default: true - begin: true - tb: - # Check *testing.TB is first param (or after context.Context) of helper function. - # Default: true - first: true - # Check *testing.TB param has name tb. - # Default: true - name: true - # Check tb.Helper() begins helper function. - # Default: true - begin: true - fuzz: - # Check *testing.F is first param (or after context.Context) of helper function. - # Default: true - first: true - # Check *testing.F param has name f. - # Default: true - name: true - # Check f.Helper() begins helper function. - # Default: true - begin: true - - usestdlibvars: - # Suggest the use of http.MethodXX. - # Default: true - http-method: true - # Suggest the use of http.StatusXX. - # Default: true - http-status-code: true - # Suggest the use of time.Weekday.String(). - # Default: true - time-weekday: true - # Suggest the use of time.Month.String(). - # Default: false - time-month: true - # Suggest the use of time.Layout. - # Default: false - time-layout: true - # Suggest the use of crypto.Hash.String(). - # Default: false - crypto-hash: true - # Suggest the use of rpc.DefaultXXPath. - # Default: false - default-rpc-path: true - # Suggest the use of sql.LevelXX.String(). - # Default: false - sql-isolation-level: true - # Suggest the use of tls.SignatureScheme.String(). - # Default: false - tls-signature-scheme: true - # Suggest the use of constant.Kind.String(). - # Default: false - constant-kind: true - - usetesting: - # Enable/disable `os.CreateTemp("", ...)` detections. - # Default: true - os-create-temp: true - - # Enable/disable `os.MkdirTemp()` detections. - # Default: true - os-mkdir-temp: true - - # Enable/disable `os.Setenv()` detections. - # Default: true - os-setenv: true - - # Enable/disable `os.TempDir()` detections. - # Default: false - os-temp-dir: true - - # Enable/disable `os.Chdir()` detections. - # Disabled if Go < 1.24. - # Default: true - os-chdir: true - - # Enable/disable `context.Background()` detections. - # Disabled if Go < 1.24. - # Default: true - context-background: true - - # Enable/disable `context.TODO()` detections. - # Disabled if Go < 1.24. - # Default: true - context-todo: true - - unconvert: - # Remove conversions that force intermediate rounding. - # Default: false - fast-math: true - # Be more conservative (experimental). - # Default: false - safe: false - - unparam: - # Inspect exported functions. - # - # 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. - # - # Default: false - check-exported: false - - unused: - # Mark all struct fields that have been written to as used. - # Default: true - field-writes-are-uses: true - # Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write. - # Default: false - post-statements-are-reads: true - # Mark all exported fields as used. - # default: true - exported-fields-are-used: true - # Mark all function parameters as used. - # default: true - parameters-are-used: true - # Mark all local variables as used. - # default: true - local-variables-are-used: false - # Mark all identifiers inside generated files as used. - # Default: true - generated-is-used: true - - varnamelen: - # The longest distance, in source lines, that is being considered a "small scope". - # Variables used in at most this many lines will be ignored. - # Default: 5 - max-distance: 15 - # The minimum length of a variable's name that is considered "long". - # Variable names that are at least this long will be ignored. - # Default: 3 - #min-name-length: 2 - # Check method receivers. - # Default: false - #check-receiver: true - # Check named return values. - # Default: false - check-return: true - # Check type parameters. - # Default: false - check-type-param: true - # Ignore "ok" variables that hold the bool return value of a type assertion. - # Default: false - ignore-type-assert-ok: true - # Ignore "ok" variables that hold the bool return value of a map index. - # Default: false - ignore-map-index-ok: true - # Ignore "ok" variables that hold the bool return value of a channel receive. - # Default: false - ignore-chan-recv-ok: true - # Optional list of variable names that should be ignored completely. - # Default: [] - ignore-names: - - err - # Optional list of variable declarations that should be ignored completely. - # Entries must be in one of the following forms (see below for examples): - # - for variables, parameters, named return values, method receivers, or type parameters: - # ( can also be a pointer/slice/map/chan/...) - # - for constants: const - # - # Default: [] - ignore-decls: - - t *testing.T - - w http.ResponseWriter - - r *http.Request - - r io.Reader - - c convey.C - - i int - - T any - - op string - - whitespace: - # Enforces newlines (or comments) after every multi-line if statement. - # Default: false - multi-if: false - # Enforces newlines (or comments) after every multi-line function signature. - # Default: false - multi-func: false - - wrapcheck: - # An array of strings specifying additional substrings of signatures to ignore. - # Unlike 'ignore-sigs', this option extends the default set (or the set specified in 'ignore-sigs') without replacing it entirely. - # This allows you to add specific signatures to the ignore list - # while retaining the defaults or any items in 'ignore-sigs'. - # Default: [] - extra-ignore-sigs: [] - #- .CustomError( - #- .SpecificWrap( - - # An array of strings that specify substrings of signatures to ignore. - # If this set, it will override the default set of ignored signatures. - # See https://github.com/tomarrell/wrapcheck#configuration for more information. - # Default: [".Errorf(", "errors.New(", "errors.Unwrap(", "errors.Join(", ".Wrap(", ".Wrapf(", ".WithMessage(", ".WithMessagef(", ".WithStack("] - #ignoreSigs: - # - .Errorf( - # - errors.New( - # - errors.Unwrap( - # - errors.Join( - # - .Wrap( - # - .Wrapf( - # - .WithMessage( - # - .WithMessagef( - # - .WithStack( - # An array of strings that specify regular expressions of signatures to ignore. - # Default: [] - ignore-sig-regexps: - #- \.New.*Error\( - # An array of strings that specify globs of packages to ignore. - # Default: [] - ignore-package-globs: [] - #- encoding/* - #- github.com/pkg/* - # An array of strings that specify regular expressions of interfaces to ignore. - # Default: [] - ignore-interface-regexps: [] - #- ^(?i)c(?-i)ach(ing|e) - # Determines whether wrapcheck should report errors returned from inside the package. - # Default: false - report-internal-errors: false - - wsl: - # Do strict checking when assigning from append (x = append(x, y)). - # If this is set to true - the append call must append either a variable - # assigned, called or used on the line above. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#strict-append - # Default: true - strict-append: true - - # Allows assignments to be cuddled with variables used in calls on - # line above and calls to be cuddled with assignments of variables - # used in call on line above. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-assign-and-call - # Default: true - allow-assign-and-call: true - - # Allows assignments to be cuddled with anything. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-assign-and-anything - # Default: false - allow-assign-and-anything: false - - # Allows cuddling to assignments even if they span over multiple lines. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-multiline-assign - # Default: true - allow-multiline-assign: true - - # If the number of lines in a case block is equal to or lager than this number, - # the case *must* end white a newline. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-case-trailing-whitespace - # Default: 0 - force-case-trailing-whitespace: 2 - - # Allow blocks to end with comments. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-trailing-comment - # Default: false - allow-trailing-comment: false - - # Allow multiple comments in the beginning of a block separated with newline. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-separated-leading-comment - # Default: false - allow-separated-leading-comment: true - - # Allow multiple var/declaration statements to be cuddled. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-cuddle-declarations - # Default: false - allow-cuddle-declarations: false - - # A list of call idents that everything can be cuddled with. - # Defaults: [ "Lock", "RLock" ] - allow-cuddle-with-calls: [ "Lock", "RLock", "defer" ] - - # AllowCuddleWithRHS is a list of right hand side variables that is allowed - # to be cuddled with anything. - # Defaults: [ "Unlock", "RUnlock" ] - allow-cuddle-with-rhs: [ "Unlock", "RUnlock" ] - - # Allow cuddling with any block as long as the variable is used somewhere in - # the block. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#allow-cuddle-used-in-block - # Default: false - allow-cuddle-used-in-block: true - - # Causes an error when an If statement that checks an error variable doesn't - # cuddle with the assignment of that variable. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-err-cuddling - # Default: false - force-err-cuddling: true - - # When force-err-cuddling is enabled this is a list of names - # used for error variables to check for in the conditional. - # Default: [ "err" ] - error-variable-names: [ "err", "err2", "err3" ] - - # Causes an error if a short declaration (:=) cuddles with anything other than - # another short declaration. - # This logic overrides force-err-cuddling among others. - # https://github.com/bombsimon/wsl/blob/HEAD/doc/configuration.md#force-short-decl-cuddling - # Default: false - force-short-decl-cuddling: false - - # The custom section can be used to define linter plugins to be loaded at runtime. - # See README documentation for more info. - custom: {} - # Each custom linter should have a unique name. - #example: - # The plugin type. - # It can be `goplugin` or `module`. - # Default: goplugin - #type: module - # The path to the plugin *.so. Can be absolute or local. - # Required for each custom linter. - #path: /path/to/example.so - # The description of the linter. - # Optional. - #description: This is an example usage of a plugin linter. - # Intended to point to the repo location of the linter. - # Optional. - #original-url: github.com/golangci/example-linter - # Plugins settings/configuration. - # Only work with plugin based on `linterdb.PluginConstructor`. - # Optional. - #settings: - # foo: bar - - # Defines a set of rules to ignore issues. - # It does not skip the analysis, and so does not ignore "typecheck" errors. - exclusions: - # Mode of the generated files analysis. - # - # - `strict`: sources are excluded by strictly following the Go generated file convention. - # Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$` - # This line must appear before the first non-comment, non-blank text in the file. - # https://go.dev/s/generatedcode - # - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc. - # - `disable`: disable the generated files exclusion. - # - # Default: strict - generated: lax - # Log a warning if an exclusion rule is unused. - # Default: false - warn-unused: false - # Predefined exclusion rules. - # Default: [] - presets: [] - #- comments - #- std-error-handling - #- common-false-positives - #- legacy - - # Excluding configuration per-path, per-linter, per-text and per-source - rules: - # Exclude some linters from running on tests files. - - path: _test\.go - linters: - - cyclop - - dupl - - errcheck - - forcetypeassert - - funlen - - goconst - - gocognit - - gocyclo - - goerr113 - - gosec - - varnamelen - - # Exclude some linters from running on tests files. - - path: _test\.go - linters: - - revive - text: "(comments-density|line-length-limit|unchecked-type-assertion)" - - # Run some linter only for test files by excluding its issues for everything else. - #- path-except: _test\.go - # linters: - # - forbidigo - - # Exclude known linters from partially hard-vendored code, - # which is impossible to exclude via `nolint` comments. - # `/` will be replaced by the current OS file path separator to properly work on Windows. - - path: internal/hmac/ - text: "weak cryptographic primitive" - linters: - - gosec - - # Exclude some `staticcheck` messages. - #- linters: - # - staticcheck - # text: "SA9003:" - - - linters: - - revive - text: "(line-length-limit)" - source: "(//revive:disable|//nolint:)" - - # Which file paths to exclude: they will be analyzed, but issues from them won't be reported. - # "/" will be replaced by the current OS file path separator to properly work on Windows. - # Default: [] - paths: - - ".*\\.my\\.go$" - - lib/bad.go - # Which file paths to not exclude. - # Default: [] - paths-except: - - ".*\\.my\\.go$" - - lib/bad.go - -formatters: - # Enable specific formatter. - # Default: [] (uses standard Go formatting) - enable: - - gci - #- gofmt - - gofumpt - #- goimports - - golines - - # Formatters settings. - settings: - gci: - # Section configuration to compare against. - # Section names are case-insensitive and may contain parameters in (). - # The default order of sections is `standard > default > custom > blank > dot > alias > localmodule`. - # If `custom-order` is `true`, it follows the order of `sections` option. - # Default: ["standard", "default"] - sections: - - standard # Standard section: captures all standard packages. - - prefix(golang.org/x) # Custom section: groups all imports with the specified Prefix. - - default # Default section: contains all imports that could not be matched to another section type. - - blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. - - dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. - - alias # Alias section: contains all alias imports. This section is not present unless explicitly enabled. - - localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled. - - # Checks that no inline comments are present. - # Default: false - no-inline-comments: false - - # Checks that no prefix comments (comment lines above an import) are present. - # Default: false - no-prefix-comments: true - - # Enable custom order of sections. - # If `true`, make the section order the same as the order of `sections`. - # Default: false - custom-order: true - - # Drops lexical ordering for custom sections. - # Default: false - no-lex-order: true - - gofmt: - # Simplify code: gofmt with `-s` option. - # Default: true - simplify: false - # Apply the rewrite rules to the source before reformatting. - # https://pkg.go.dev/cmd/gofmt - # Default: [] - rewrite-rules: - - pattern: 'interface{}' - replacement: 'any' - - pattern: 'a[b:len(a)]' - replacement: 'a[b:]' - - gofumpt: - # Module path which contains the source code being formatted. - # Default: "" - #module-path: github.com/org/project - - # Choose whether to use the extra rules. - # Default: false - extra-rules: true - - golines: - # Target maximum line length. - # Default: 100 - max-len: 200 - # Length of a tabulation. - # Default: 4 - tab-len: 4 - # Shorten single-line comments. - # Default: false - shorten-comments: true - # Default: true - reformat-tags: false - # Split chained methods on the dots as opposed to the arguments. - # Default: true - chain-split-dots: true - - exclusions: - # Log a warning if an exclusion path is unused. - # Default: false - warn-unused: false - # Mode of the generated files analysis. - # - # - `strict`: sources are excluded by strictly following the Go generated file convention. - # Source files that have lines matching only the following regular expression will be excluded: `^// Code generated .* DO NOT EDIT\.$` - # This line must appear before the first non-comment, non-blank text in the file. - # https://go.dev/s/generatedcode - # - `lax`: sources are excluded if they contain lines like `autogenerated file`, `code generated`, `do not edit`, etc. - # - `disable`: disable the generated files exclusion. - # - # Default: lax - generated: lax - # Which file paths to exclude. - # Default: [] - paths: - - ".*\\.my\\.go$" - - lib/bad.go - -issues: - # Maximum issues count per one linter. - # Set to 0 to disable. - # Default: 50 - max-issues-per-linter: 0 - - # Maximum count of issues with the same text. - # Set to 0 to disable. - # Default: 3 - max-same-issues: 0 - - # Make issues output unique by line. - # Default: true - uniq-by-line: false - - # Show only new issues: if there are unstaged changes or untracked files, - # only those changes are analyzed, else only changes in HEAD~ are analyzed. - # It's a super-useful option for integration of golangci-lint into existing 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: false. - new: false - - # Show only new issues created after the best common ancestor (merge-base against HEAD). - # Default: "" - #new-from-merge-base: main - - # Show only new issues created after git revision `REV`. - # Default: "" - #new-from-rev: HEAD - - # Show only new issues created in git patch with set file path. - # Default: "" - #new-from-patch: path/to/patch/file - - # Show issues in any part of update files (requires new-from-rev or new-from-patch). - # Default: false - whole-files: true - - # Fix found issues (if it's supported by the linter). - # Default: false - fix: false - - -# output configuration options -output: - # The formats used to render issues. - #formats: - # Prints issues in a text format with colors, line number, and linter name. - # This format is the default format. - #text: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # # Print linter name in the end of issue text. - # # Default: true - # print-linter-name: true - # # Print lines of code with issue. - # # Default: true - # print-issued-lines: true - # # Use colors. - # # Default: true - # colors: true - # Prints issues in a JSON representation. - #json: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # Prints issues in columns representation separated by tabulations. - #tab: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # # Print linter name in the end of issue text. - # # Default: true - # print-linter-name: true - # # Use colors. - # # Default: true - # colors: false - # Prints issues in an HTML page. - # It uses the Cloudflare CDN (cdnjs) and React. - #html: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # Prints issues in the Checkstyle format. - #checkstyle: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # Prints issues in the Code Climate format. - #code-climate: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # Prints issues in the JUnit XML format. - #junit-xml: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # # Support extra JUnit XML fields. - # # Default: false - # extended: true - # Prints issues in the TeamCity format. - #teamcity: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - # Prints issues in the SARIF format. - #sarif: - # # Output path can be either `stdout`, `stderr` or path to the file to write to. - # # Default: stdout - # path: stdout - - # Add a prefix to the output file references. - # This option is ignored when using `output.path-mode: abs` mode. - # Default: "" - path-prefix: "" - - # By default, the report are related to the path obtained by `run.relative-path-mode`. - # The mode `abs` allows to show absolute file paths instead of relative file paths. - # The option `output.path-prefix` is ignored when using `abs` mode. - # Default: "" - path-mode: "abs" - - # Order to use when sorting results. - # Possible values: `file`, `linter`, and `severity`. - # - # If the severity values are inside the following list, they are ordered in this order: - # 1. error - # 2. warning - # 3. high - # 4. medium - # 5. low - # Either they are sorted alphabetically. - # - # Default: ["linter", "file"] - sort-order: - - file # filepath, line, and column. - - severity - - linter - - # Show statistics per linter. - # Default: false - show-stats: false - - -# Options for analysis running. -run: - # Timeout for total work, e.g. 30s, 5m, 5m30s. - # If the value is lower or equal to 0, the timeout is disabled. - # Default: 0 (disabled) - timeout: 5m - - # The mode used to evaluate relative paths. - # It's used by exclusions, Go plugins, and some linters. - # The value can be: - # - `gomod`: the paths will be relative to the directory of the `go.mod` file. - # - `gitroot`: the paths will be relative to the git root (the parent directory of `.git`). - # - `cfg`: the paths will be relative to the configuration file. - # - `wd` (NOT recommended): the paths will be relative to the place where golangci-lint is run. - # Default: cfg - relative-path-mode: gomod - - # Exit code when at least one issue was found. - # Default: 1 - issues-exit-code: 1 - - # Include test files or not. - # Default: true - tests: true - - # List of build tags, all linters use it. - # Default: [] - build-tags: [] - #- mytag - - # 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 - # automatic updating of go.mod described above. Instead, it fails when any changes - # to go.mod are needed. This setting is most useful to check that go.mod does - # not need updates, such as in a continuous integration and testing system. - # If invoked with -mod=vendor, the go command assumes that the vendor - # directory holds the correct copies of dependencies and ignores - # the dependency descriptions in go.mod. - # - # Allowed values: readonly|vendor|mod - # Default: "" - #modules-download-mode: readonly - - # Allow multiple parallel golangci-lint instances running. - # If false, golangci-lint acquires file lock on start. - # Default: false - allow-parallel-runners: true - - # Allow multiple golangci-lint instances running, but serialize them around a lock. - # If false, golangci-lint exits with an error if it fails to acquire file lock on start. - # Default: false - allow-serial-runners: true - - # Define the Go version limit. - # Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.22. - #go: '1.19' - - # Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously. - # Default: 0 (automatically set to match Linux container CPU quota and - # fall back to the number of logical CPUs in the machine) - #concurrency: 4 - - -severity: - # 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#SeverityLevel - # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message - # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance - # - # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) - # - # Default: "" - default: "@linter" - - # When a list of severity rules are provided, severity information will be added to lint issues. - # Severity rules have the same filtering capability as exclude rules - # except you are allowed to specify one matcher per severity rule. - # - # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) - # - # Only affects out formats that support setting severity information. - # - # Default: [] - rules: - - linters: - - dupl - severity: info - - linters: - - gosec - - errcheck - severity: error diff --git a/CHANGELOG.md b/CHANGELOG.md index c971374..ff1cc36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,38 +1,11 @@ -# go/logging Changelog +# go/logging ## Unreleased -## v0.5.0 (2025-05-07) - -- The default formatter now prints timestamps with microseconds -- Fix the use of syslog on darwin - -## v0.4.1 (2022-06-03) - -- Ensure all backends implement the interface `BACKEND`. -- `FileBackend` and `SyslogBackend` always returned errors for `Write` - operations. - -## v0.4.0 (2022-05-31) - -- Add three new log levels: `Trace`, `Notice` and `Alert` with the following - order: `Trace`, `Debug`, `Info`, `Notice`, `Warning`, `Error`, `Critical`, - `Alert`, `Fatal`. - As Syslog has no equivalent of `Trace`, it is mapped to `Debug`. - -## v0.3.0 (2020-05-17) - -### Incompatible Changes - -- Log level names have changed. They were fully capitalized, only their first - letter is capitalized now: DEBUG -> Debug, INFO -> Info, etc. -- NoopBackend.Level() now returns DefaultLevel instead of Fatal -- New loggers are created with level `DefaultLevel` instead of `Debug` -- The `Backend` interface now has a `Close()` method, so that backends can free - the resources they use - -### Fixes - -- FileBackend now properly closes the file before reopening it (fixes a +- Uncompatible: log level names hace changed. They were fully + capitalized, only their first letter is capitalized now: DEBUG -> Debug, + INFO -> Info, etc. +- Uncompatible NoopBackend.Level() now returns DefaultLevel instead of Fatal +- Fix: creates new logger with level DefaultLevel instead of Debug +- Fix: FileBackend now properly closes the file befor reopening it (fixes a potential file descriptor leak) -- Logger methods did not always acquire locks, causing race conditions diff --git a/backend.go b/backend.go index 695b45d..fe6359a 100644 --- a/backend.go +++ b/backend.go @@ -4,14 +4,13 @@ import ( "fmt" "io" "os" - "path/filepath" ) // Backend is the interface that specifies the methods that a backend must -// implement. +// implement type Backend interface { Write(*Record) error - SetFormatter(Formatter) + SetFormatter(*Formatter) SetLevel(Level) Level() Level Reopen() error @@ -22,94 +21,88 @@ type Backend interface { // Backend to write in file-like objects // -var _ Backend = &FileBackend{} - // FileBackend is a backend that writes to a file. type FileBackend struct { - formatter Formatter l io.Writer - filepath string + formatter *Formatter level Level + filepath string } // NewStdoutBackend creates a new backend to write the logs on the standard -// output. -func NewStdoutBackend() *FileBackend { - return &FileBackend{ +// output +func NewStdoutBackend() (b *FileBackend) { + b = &FileBackend{ l: os.Stdout, - formatter: defaultFormatter, + formatter: &defaultFormatter, } + return } -// NewStderrBackend creates a new backend to write the logs on the error output. -func NewStderrBackend() *FileBackend { - return &FileBackend{ +// NewStderrBackend creates a new backend to write the logs on the error output +func NewStderrBackend() (b *FileBackend) { + b = &FileBackend{ l: os.Stderr, - formatter: defaultFormatter, + formatter: &defaultFormatter, } + return } -// NewFileBackend creates a new backend to write the logs in a given file. +// NewFileBackend creates a new backend to write the logs in a given file func NewFileBackend(filename string) (*FileBackend, error) { - fd, err := os.OpenFile(filepath.Clean(filename), - os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o600) + fd, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) //nolint: gosec if err != nil { - return nil, fmt.Errorf("cannot open log file %s: %w", filename, err) + return nil, fmt.Errorf("Cannot open log file %s: %w", filename, err) } b := &FileBackend{ l: fd, - formatter: defaultFormatter, + formatter: &defaultFormatter, filepath: filename, } return b, nil } -// NewIoBackend creates a new backend to write the logs in a given io.Writer. -func NewIoBackend(buf io.Writer) *FileBackend { +// NewIoBackend creates a new backend to write the logs in a given io.Writer +func NewIoBackend(buf io.Writer) (b *FileBackend) { return &FileBackend{ l: buf, - formatter: defaultFormatter, + formatter: &defaultFormatter, } } func (b FileBackend) Write(r *Record) error { - text := b.formatter(r) - + text := (*b.formatter)(r) _, err := io.WriteString(b.l, text) - if err != nil { - return fmt.Errorf("cannot write logs: %w", err) - } - - return nil + return err } -// SetLevel changes the log level of the backend. +// SetLevel changes the log level of the backend func (b *FileBackend) SetLevel(l Level) { b.level = l } -// Level returns the log level set for this backend. +// Level returns the log level set for this backend func (b *FileBackend) Level() Level { return b.level } -// SetFormatter defines the formatter for this backend. -func (b *FileBackend) SetFormatter(f Formatter) { +// SetFormatter defines the formatter for this backend +func (b *FileBackend) SetFormatter(f *Formatter) { b.formatter = f } // Reopen closes and reopens the file it writes to. It should be used after log -// rotation. +// rotation func (b *FileBackend) Reopen() error { if err := b.Close(); err != nil { return err } - fd, err := os.OpenFile(b.filepath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o600) + fd, err := os.OpenFile(b.filepath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) //nolint: gosec if err != nil { - return fmt.Errorf("cannot open log file %s: %w", b.filepath, err) + return fmt.Errorf("Cannot open log file %s: %w", b.filepath, err) } b.l = fd @@ -117,7 +110,7 @@ func (b *FileBackend) Reopen() error { return nil } -// Close closes the underlying file used by the backend. +// Close closes the underlying file used by the backend func (b *FileBackend) Close() error { if b.filepath == "" { return nil @@ -125,7 +118,7 @@ func (b *FileBackend) Close() error { if c, ok := b.l.(io.Closer); ok { if err := c.Close(); err != nil { - return fmt.Errorf("cannot close log file: %w", err) + return err } } @@ -136,38 +129,36 @@ func (b *FileBackend) Close() error { // Noop Backend // -var _ Backend = &NoopBackend{} - -// NoopBackend does nothing and discards all log entries without writing them anywhere. +// NoopBackend does nothing and discards all log entries without writing them anywhere type NoopBackend struct{} -// NewNoopBackend creates a noop backend. -func NewNoopBackend() (*NoopBackend, error) { +// NewNoopBackend creates a noop backend +func NewNoopBackend() (Backend, error) { return &NoopBackend{}, nil } -// Write is a noop. -func (*NoopBackend) Write(_ *Record) error { +// Write is a noop +func (nb *NoopBackend) Write(r *Record) error { return nil } -// SetFormatter is a noop. -func (*NoopBackend) SetFormatter(_ Formatter) {} +// SetFormatter is a noop +func (nb *NoopBackend) SetFormatter(f *Formatter) {} -// SetLevel is a noop. -func (*NoopBackend) SetLevel(_ Level) {} +// SetLevel is a noop +func (nb *NoopBackend) SetLevel(level Level) {} -// Level always returns DefeultLevel. -func (*NoopBackend) Level() Level { +// Level always returns DefeultLevel +func (nb *NoopBackend) Level() Level { return DefaultLevel } -// Reopen is a noop. -func (*NoopBackend) Reopen() error { +// Reopen is a noop +func (nb *NoopBackend) Reopen() error { return nil } -// Close is a noop. -func (*NoopBackend) Close() error { +// Close is a noop +func (nb *NoopBackend) Close() error { return nil } diff --git a/backend_syslog_unix.go b/backend_syslog_linux.go similarity index 58% rename from backend_syslog_unix.go rename to backend_syslog_linux.go index 970ac95..e0f62f1 100644 --- a/backend_syslog_unix.go +++ b/backend_syslog_linux.go @@ -1,114 +1,88 @@ -//go:build !windows && !nacl && !plan9 // +build !windows,!nacl,!plan9 package logging import ( - "errors" "fmt" "log/syslog" "strings" ) -var errUnknownFacility = errors.New("unknown facility") - // // Syslog Backend // -var _ Backend = &SyslogBackend{} - -// SyslogBackend writes the logs to a syslog system. +// SyslogBackend writes the logs to a syslog system type SyslogBackend struct { w *syslog.Writer - formatter Formatter + formatter *Formatter level Level } // NewSyslogBackend initializes a new connection to a syslog server with the // given facility. // tag can contain an identifier for the log stream. It defaults to os.Arg[0]. -func NewSyslogBackend(facilityName, tag string) (*SyslogBackend, error) { +func NewSyslogBackend(facilityName string, tag string) (Backend, error) { f, err := facility(facilityName) if err != nil { return nil, err } - w, err := syslog.New(f, tag) if err != nil { - return nil, fmt.Errorf("cannot initialize syslog: %w", err) + return nil, err } - sb := &SyslogBackend{ w: w, - formatter: basicFormatter, + formatter: &basicFormatter, } - return sb, nil } -// Write sends an entry to the syslog server. -func (sb *SyslogBackend) Write(r *Record) error { - var err error - - text := sb.formatter(r) - +// Write sends an entry to the syslog server +func (sb *SyslogBackend) Write(r *Record) (err error) { + text := (*sb.formatter)(r) switch r.Level { - case Trace, Debug: + case Debug: err = sb.w.Debug(text) case Info: err = sb.w.Info(text) - case Notice: - err = sb.w.Notice(text) case Warning: err = sb.w.Warning(text) case Error: err = sb.w.Err(text) case Critical: err = sb.w.Crit(text) - case Alert: - err = sb.w.Alert(text) case Fatal: err = sb.w.Emerg(text) } - - if err != nil { - return fmt.Errorf("cannot log to syslog: %w", err) - } - - return nil + return err } -// SetFormatter defines the formatter for this backend. -func (sb *SyslogBackend) SetFormatter(f Formatter) { +// SetFormatter defines the formatter for this backend +func (sb *SyslogBackend) SetFormatter(f *Formatter) { sb.formatter = f } -// SetLevel changes the log level of the backend. +// SetLevel changes the log level of the backend func (sb *SyslogBackend) SetLevel(level Level) { sb.level = level } -// Level returns the log level set for this backend. +// Level returns the log level set for this backend func (sb *SyslogBackend) Level() Level { return sb.level } -// Reopen is a no-op. -func (*SyslogBackend) Reopen() error { +// Reopen is a no-op +func (sb *SyslogBackend) Reopen() error { return nil } -// Close closes the connection to the syslog daemon. +// Close closes the connection to the syslog daemon func (sb *SyslogBackend) Close() error { - if err := sb.w.Close(); err != nil { - return fmt.Errorf("cannot close syslog: %w", err) - } - - return nil + return sb.w.Close() } -//nolint:gochecknoglobals // global var is used by design var facilities = map[string]syslog.Priority{ "kern": syslog.LOG_KERN, "user": syslog.LOG_USER, @@ -135,7 +109,7 @@ var facilities = map[string]syslog.Priority{ func facility(name string) (syslog.Priority, error) { p, ok := facilities[strings.ToLower(name)] if !ok { - return 0, fmt.Errorf("facility '%s' does not exist: %w", name, errUnknownFacility) + return 0, fmt.Errorf("Facility '%s' does not exist", name) } return p, nil diff --git a/backend_test.go b/backend_test.go deleted file mode 100644 index 3766ecd..0000000 --- a/backend_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package logging - -import ( - "bytes" - "errors" - "testing" - - "github.com/stretchr/testify/require" -) - -type WriteErrorBuffer struct{} - -func (*WriteErrorBuffer) Write(_ []byte) (int, error) { - return 0, errors.New("cannot write") -} - -func TestFileBackendWrite(t *testing.T) { - t.Parallel() - - t.Run("It should write the logs to the buffer", func(t *testing.T) { - t.Parallel() - - buf := new(bytes.Buffer) - b := NewIoBackend(buf) - - err := b.Write(&Record{ - Level: Info, - Message: "my log line", - }) - - require.NoError(t, err) - require.Contains(t, buf.String(), "my log line") - }) - - t.Run("It should return an error if it cannot write the log", func(t *testing.T) { - t.Parallel() - - buf := new(WriteErrorBuffer) - b := NewIoBackend(buf) - - err := b.Write(&Record{ - Level: Info, - Message: "my log line", - }) - - require.Error(t, err) - }) -} diff --git a/go.mod b/go.mod index 56e6673..72e56a7 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,3 @@ -module code.bcarlin.net/go/logging +module code.bcarlin.xyz/go/logging go 1.13 - -require github.com/stretchr/testify v1.7.1 diff --git a/go.sum b/go.sum deleted file mode 100644 index 2dca7c9..0000000 --- a/go.sum +++ /dev/null @@ -1,11 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/logger.go b/logger.go index 2123741..0f24b48 100644 --- a/logger.go +++ b/logger.go @@ -7,39 +7,37 @@ import ( "sync" ) -const exitCodeFatal = 100 - // Logger is a facility that writes logs to one or more backands (files, // stdout/stderr, syslog, etc.) which can be configured independently // // Loggers are concurrent-safe. type Logger struct { - mutex sync.Mutex + sync.Mutex + name string backends []Backend } // NewLogger initializes a new Logger with no backend and with the default log level. -func NewLogger(name string) *Logger { - l := &Logger{ +func NewLogger(name string) (l *Logger) { + l = &Logger{ name: name, } - - return l + return } // AddBackend add a new Backend to the logger. All set backends are kept. func (l *Logger) AddBackend(b Backend) { - l.mutex.Lock() - defer l.mutex.Unlock() + l.Lock() + defer l.Unlock() l.backends = append(l.backends, b) } // SetBackend sets the backend list to the logger. Any existing backend will be lost. func (l *Logger) SetBackend(b ...Backend) { - l.mutex.Lock() - defer l.mutex.Unlock() + l.Lock() + defer l.Unlock() l.backends = b } @@ -52,11 +50,11 @@ func (l *Logger) SetLevel(level Level) { } type buffer struct { - logger *Logger level Level + logger *Logger } -func (b *buffer) Write(p []byte) (int, error) { +func (b *buffer) Write(p []byte) (n int, err error) { b.logger.Log(b.level, string(p)) return len(p), nil } @@ -72,119 +70,82 @@ func (l *Logger) AsStdLog(level Level) *log.Logger { } // Log sends a record containing the message `m` to the registered backends -// whose level is at least `level`. +// whose level is at least `level` func (l *Logger) Log(level Level, m string) { - l.mutex.Lock() - defer l.mutex.Unlock() + l.Lock() + defer l.Unlock() r := NewRecord(l.name, level, m) for _, backend := range l.backends { if r.Level >= backend.Level() { - if err := backend.Write(r); err != nil { - //revive:disable-next-line:unhandled-error stop error handling recursion! - fmt.Fprintf(os.Stderr, "Cannot write logs: %v", err) - } + _ = backend.Write(r) } } } -// Trace logs a message with the Trace level. -func (l *Logger) Trace(text string) { - l.Log(Trace, text) -} - -// Tracef formats the message with given args and logs the result with the -// Trace level. -func (l *Logger) Tracef(text string, args ...interface{}) { - l.Trace(fmt.Sprintf(text, args...)) -} - -// Debug logs a message with the Debug level. +// Debug logs a message with the Debug level func (l *Logger) Debug(text string) { l.Log(Debug, text) } // Debugf formats the message with given args and logs the result with the -// Debug level. +// Debug level func (l *Logger) Debugf(text string, args ...interface{}) { l.Debug(fmt.Sprintf(text, args...)) } -// Info logs a message with the Info level. +// Info logs a message with the Info level func (l *Logger) Info(text string) { l.Log(Info, text) } // Infof formats the message with given args and logs the result with the -// Info level. +// Info level func (l *Logger) Infof(text string, args ...interface{}) { l.Info(fmt.Sprintf(text, args...)) } -// Notice logs a message with the Notice level. -func (l *Logger) Notice(text string) { - l.Log(Notice, text) -} - -// Noticef formats the message with given args and logs the result with the -// Notice level. -func (l *Logger) Noticef(text string, args ...interface{}) { - l.Notice(fmt.Sprintf(text, args...)) -} - -// Warning logs a message with the Warning level. +// Warning logs a message with the Warning level func (l *Logger) Warning(text string) { l.Log(Warning, text) } // Warningf formats the message with given args and logs the result with the -// Warning level. +// Warning level func (l *Logger) Warningf(text string, args ...interface{}) { l.Warning(fmt.Sprintf(text, args...)) } -// Error logs a message with the Error level. +// Error logs a message with the Error level func (l *Logger) Error(text string) { l.Log(Error, text) } // Errorf formats the message with given args and logs the result with the -// Error level. +// Error level func (l *Logger) Errorf(text string, args ...interface{}) { l.Error(fmt.Sprintf(text, args...)) } -// Critical logs a message with the Critical level. +// Critical logs a message with the Critical level func (l *Logger) Critical(text string) { l.Log(Critical, text) } -// Criticalf formats the message with given args and logs the result with the. -// Critical level. +// Criticalf formats the message with given args and logs the result with the +// Critical level func (l *Logger) Criticalf(text string, args ...interface{}) { l.Critical(fmt.Sprintf(text, args...)) } -// Alert logs a message with the Alert level. -func (l *Logger) Alert(text string) { - l.Log(Alert, text) -} - -// Alertf formats the message with given args and logs the result with the. -// Alert level. -func (l *Logger) Alertf(text string, args ...interface{}) { - l.Alert(fmt.Sprintf(text, args...)) -} - -// Fatal logs a message with the Fatal level. +// Fatal logs a message with the Fatal level func (l *Logger) Fatal(text string) { l.Log(Debug, text) - - os.Exit(exitCodeFatal) //nolint:revive // This is wanted if fatal is called + os.Exit(100) } // Fatalf formats the message with given args and logs the result with the -// Fatal level. +// Fatal level func (l *Logger) Fatalf(text string, args ...interface{}) { l.Fatal(fmt.Sprintf(text, args...)) } diff --git a/logging.go b/logging.go index 890ea9a..7e43ce6 100644 --- a/logging.go +++ b/logging.go @@ -12,53 +12,40 @@ package logging defines the following builtin backends: A backend can safely be used by multiple loggers. -It is the caller's responsibility to call Close on backends when they are not +It is the caller's responsability to call Close on backends when they are not used anymore to free their resources. */ package logging import ( - "errors" "fmt" "strings" "sync" ) -//nolint:gochecknoglobals // designed this way var ( loggers map[string]*Logger lock sync.Mutex - - errInvalidLogLevel = errors.New("invalid log level") ) -// Level is the type of log levels. +// Level is the type of log levels type Level byte -//revive:disable:exported +//nolint: golint const ( - Trace Level = iota - Debug + Debug Level = iota Info - Notice Warning Error Critical - Alert Fatal DefaultLevel = Info ) -//revive:enable:exported +var levelNames = [6]string{"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"} -//nolint:gochecknoglobals // designed this way -var levelNames = [...]string{ - "TRACE", "DEBUG", "INFO", "NOTICE", "WARNING", - "ERROR", "CRITICAL", "ALERT", "FATAL", -} - -// Name returns the name of the log level. +// Name returns the name of the log level func (l Level) Name() string { return levelNames[l] } @@ -71,8 +58,7 @@ func LevelByName(l string) (Level, error) { return Level(pos), nil } } - - return Debug, fmt.Errorf("unknown log level %q: %w", l, errInvalidLogLevel) + return Debug, fmt.Errorf("Invalid log level %s", l) } // Formatter is the types of the functions that can be used to format a log @@ -80,15 +66,14 @@ func LevelByName(l string) (Level, error) { type Formatter func(*Record) string // GetLogger returns a logger given its name. if the logger does not exist, it -// initializes one with the defaults (it logs to stdout with level INFO). -func GetLogger(name string) *Logger { +// initializes one with the defaults (it logs to stdout with level debug) +func GetLogger(name string) (l *Logger) { lock.Lock() defer lock.Unlock() if name == "" { name = "default" } - l, ok := loggers[name] if !ok { l = NewLogger(name) @@ -97,23 +82,21 @@ func GetLogger(name string) *Logger { l.SetLevel(DefaultLevel) loggers[name] = l } - return l } -func defaultFormatter(r *Record) string { +var defaultFormatter Formatter = func(r *Record) string { return fmt.Sprintf("%s [%-8s] %s: %s\n", - r.Timestamp.Format("2006/01/02 15:04:05.999999"), r.Level.Name(), r.Logger, + r.Timestamp.Format("2006/01/02 15:04:05"), r.Level.Name(), r.Logger, strings.TrimSpace(r.Message)) } -func basicFormatter(r *Record) string { +var basicFormatter Formatter = func(r *Record) string { return fmt.Sprintf("%s: %s", r.Logger, strings.TrimSpace(r.Message)) } -//nolint:gochecknoinits // init is used by design func init() { - loggers = map[string]*Logger{} + loggers = make(map[string]*Logger, 3) logger := NewLogger("default") backend := NewStdoutBackend() diff --git a/logging_test.go b/logging_test.go index 99cf3e4..1921e0e 100644 --- a/logging_test.go +++ b/logging_test.go @@ -1,40 +1,15 @@ package logging -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/assert" -) +import "testing" func Test_LevelByName(t *testing.T) { - t.Parallel() - for _, levelName := range levelNames { l, e := LevelByName(levelName) if e != nil { t.Errorf("level %s not recognized", levelName) } - if l.Name() != levelName { t.Errorf("expected '%s', got '%s'", levelName, l.Name()) } } } - -func Test_defaultFormatter(t *testing.T) { - t.Parallel() - - r := &Record{ - Timestamp: time.Date(2000, 0o1, 0o2, 0o3, 0o4, 0o5, 123456789, time.Local), - Level: Info, - Logger: "my logger", - Message: "my log line", - } - - got := defaultFormatter(r) - want := fmt.Sprintf("2000/01/02 03:04:05.123456 [INFO ] my logger: my log line\n") - - assert.Equal(t, want, got) -} diff --git a/record.go b/record.go index 297fdcb..d0b9e77 100644 --- a/record.go +++ b/record.go @@ -5,7 +5,7 @@ import ( ) // Record contains the data to be logged. It is passed to a formatter to -// generate the logged message. +// generate the logged message type Record struct { Logger string Timestamp time.Time @@ -13,12 +13,13 @@ type Record struct { Message string } -// NewRecord creates a new record, setting its timestamp to time.Now(). -func NewRecord(name string, l Level, m string) *Record { - return &Record{ +// NewRecord creates a new record, setting its timestamp to time.Now() +func NewRecord(name string, l Level, m string) (r *Record) { + r = &Record{ Logger: name, Level: l, Message: m, Timestamp: time.Now(), } + return }