version: "2"

linters:
  default: none
  enable:
    - depguard
    - errcheck
    - govet
    - ineffassign
    - staticcheck
    - unused

  settings:
    depguard:
      rules:
        # Enforce: service must not depend on repository.
        service-no-repository:
          list-mode: original
          files:
            - "**/internal/service/**"
          deny:
            - pkg: github.com/Wei-Shaw/sub2api/internal/repository
              desc: "service must not import repository"
            - pkg: gorm.io/gorm
              desc: "service must not import gorm"
            - pkg: github.com/redis/go-redis/v9
              desc: "service must not import redis"
        handler-no-repository:
          list-mode: original
          files:
            - "**/internal/handler/**"
          deny:
            - pkg: github.com/Wei-Shaw/sub2api/internal/repository
              desc: "handler must not import repository"
            - pkg: gorm.io/gorm
              desc: "handler must not import gorm"
            - pkg: github.com/redis/go-redis/v9
              desc: "handler must not import redis"
    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: false
      # 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: true
      # 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/ioutil.ReadFile
        - io.Copy(*bytes.Buffer)
        - io.Copy(os.Stdout)
        - fmt.Println
        - fmt.Print
        - fmt.Printf
        - fmt.Fprint
        - fmt.Fprintf
        - fmt.Fprintln
      # Display function signature instead of selector.
      # Default: false
      verbose: true
    ineffassign:
      # Check escaping variables of type error, may cause false positives.
      # Default: false
      check-escaping-errors: true
    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: [ "200", "400", "404", "500" ]
      # SAxxxx checks in https://staticcheck.dev/docs/configuration/options/#checks
      # Example (to disable some checks): [ "all", "-SA1000", "-SA1001"]
      # Run `GL_DEBUG=staticcheck golangci-lint run --enable=staticcheck` to see all available checks and enabled by config checks.
      # 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
    unused:
      # Mark all struct fields that have been written to as used.
      # Default: true
      field-writes-are-uses: false
      # 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: false
      # 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: false

formatters:
  enable:
    - gofmt
  settings:
    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:]'