Some checks failed
ci / go (push) Has been cancelled
ci / admin-ui (push) Has been cancelled
ci / runtime-sdk (push) Has been cancelled
ci / helm (push) Has been cancelled
ci / openapi (push) Has been cancelled
ci / container (push) Has been cancelled
ci / release-config (push) Has been cancelled
ci / shared styling (push) Has been cancelled
ci / security (push) Has been cancelled
ci / all green (push) Has been cancelled
275 lines
10 KiB
YAML
275 lines
10 KiB
YAML
# golangci-lint configuration.
|
|
#
|
|
# The enabled set is chosen for signal, not coverage. A linter that fires on
|
|
# stylistic preferences nobody agreed to trains the team to ignore the output, which
|
|
# costs more than the findings are worth. Every linter here catches a class of bug
|
|
# or a readability problem we actually care about; the exclusions below are
|
|
# deliberate and commented.
|
|
version: "2"
|
|
|
|
run:
|
|
timeout: 5m
|
|
# Tests are linted. A lint failure in a test is a lint failure.
|
|
tests: true
|
|
build-tags: []
|
|
modules-download-mode: readonly
|
|
issues-exit-code: 1
|
|
|
|
formatters:
|
|
enable:
|
|
- gofmt
|
|
- goimports
|
|
- gci
|
|
settings:
|
|
gci:
|
|
sections:
|
|
- standard
|
|
- default
|
|
- prefix(github.com/urpi/go-bananas)
|
|
no-lex-order: true
|
|
goimports:
|
|
local-prefixes: [github.com/urpi/go-bananas]
|
|
|
|
linters:
|
|
enable:
|
|
# --- correctness -------------------------------------------------------
|
|
- errcheck # an unchecked error is a bug waiting for a bad day
|
|
- govet
|
|
- ineffassign
|
|
- staticcheck # the staticcheck suite, at its default strictness
|
|
- unused
|
|
- bodyclose # an unclosed response body leaks a connection
|
|
- rowserrcheck # a rows.Err() not checked hides a mid-iteration failure
|
|
- sqlclosecheck
|
|
- noctx # an HTTP request without a context cannot be cancelled
|
|
- contextcheck # a context stored in a struct cannot be cancelled
|
|
- errorlint # %w and errors.Is, so wrapping and matching actually work
|
|
- nilerr # returning nil after checking err != nil is almost always wrong
|
|
|
|
# --- readability -------------------------------------------------------
|
|
- revive # exported comments, naming, control-flow clarity
|
|
- goconst # a repeated literal is a constant waiting to be named
|
|
- godot # comments end in a period
|
|
- misspell # a typo in a comment is a typo a reader will trust
|
|
- unconvert
|
|
- prealloc
|
|
- whitespace
|
|
- nolintlint # a nolint that no longer applies is misleading
|
|
- copyloopvar # Go 1.22+ loop variables; the old idiom is now a bug
|
|
|
|
# --- security ----------------------------------------------------------
|
|
- gosec # integer overflows, weak randomness, unsafe, etc.
|
|
|
|
# --- testing -----------------------------------------------------------
|
|
- thelper # t.Helper() in a test helper
|
|
- tparallel # a parallel test that does not call t.Parallel
|
|
|
|
settings:
|
|
errcheck:
|
|
# A type assertion or conversion that cannot fail needs no check.
|
|
check-type-assertions: false
|
|
# A blank assignment to an error is a deliberate, documented decision, not an
|
|
# oversight, so errcheck is asked to flag it too. The ones that remain are
|
|
# marked with an explicit nolint and a reason.
|
|
check-blank: true
|
|
exclude-functions:
|
|
# Writing to an http.ResponseWriter returns an error only when the client has
|
|
# gone away, and there is nothing a handler can do about that: the response
|
|
# is already committed and the connection is already being torn down.
|
|
- (net/http.ResponseWriter).Write
|
|
- (net/http.ResponseWriter).WriteHeader
|
|
# A Rollback after a successful Commit is expected to report
|
|
# sql.ErrTxDone, and a Rollback on the error path is immediately followed by
|
|
# returning that error. Checking either produces a branch that can only ever
|
|
# discard a result.
|
|
- (*database/sql.Tx).Rollback
|
|
# Deferred Close on a read-only database handle: the only error it can
|
|
# report is already lost by the time the process exits.
|
|
- (*database/sql.Rows).Close
|
|
- (io.Closer).Close
|
|
- (*os.File).Close
|
|
- (*bytes.Buffer).Write
|
|
- (*bytes.Buffer).WriteByte
|
|
- (*bytes.Buffer).WriteString
|
|
- (io.Writer).Write
|
|
- (hash.Hash).Write
|
|
- fmt.Fprintf
|
|
- fmt.Fprint
|
|
- fmt.Fprintln
|
|
- fmt.Print
|
|
- fmt.Println
|
|
- fmt.Sprintf
|
|
- sort.Slice
|
|
|
|
govet:
|
|
enable-all: true
|
|
disable:
|
|
# Field alignment is a micro-optimisation that makes every struct
|
|
# declaration a puzzle. It is not worth the readability cost.
|
|
- fieldalignment
|
|
# The shadow linter fires on ordinary, readable `err :=` inside an if.
|
|
- shadow
|
|
|
|
revive:
|
|
rules:
|
|
# requireDoc is deliberately not set. Every exported item in this codebase
|
|
# carries a doc comment by convention and by review, but the rule's argument
|
|
# name is not "requireDoc" in this version of revive, so setting it disables
|
|
# the whole revive rule set with a configuration error rather than enforcing
|
|
# anything.
|
|
- name: exported
|
|
arguments:
|
|
- checkPrivateReceivers
|
|
- name: package-comments
|
|
- name: blank-imports
|
|
- name: context-as-argument
|
|
- name: context-keys-type
|
|
- name: dot-imports
|
|
- name: error-return
|
|
# No arguments: the rule takes none. Passing "error-strings" as an argument
|
|
# makes revive look for a custom function of that name, fails to find it, and
|
|
# then silently disables the rule along with every other revive rule.
|
|
- name: error-strings
|
|
- name: error-naming
|
|
- name: increment-decrement
|
|
# The allowlist has to be a slice. Given as a bare string it is a
|
|
# configuration error, which stops every revive rule from loading rather
|
|
# than enabling this one.
|
|
- name: var-naming
|
|
arguments:
|
|
- [ID, VM, HTTP, URL, API, TLS, CSS, JSON, SQL, UUID, OIDC, ACL, CPU, RAM, WAC]
|
|
- name: receiver-naming
|
|
- name: indent-error-flow
|
|
- name: range
|
|
- name: unreachable-code
|
|
- name: redefines-builtin-id
|
|
|
|
goconst:
|
|
min-len: 3
|
|
# Raised from 4 to 6, and the wire vocabulary below is exempted. The strings
|
|
# that repeat in this codebase are JSON field names ("status", "version",
|
|
# "slug"), theme token vocabulary ("primary-hover", "normal") and the auth
|
|
# method "anonymous". Those are the wire and CSS contract rather than repeated
|
|
# logic, and hoisting them into Go constants would make them less greppable
|
|
# without changing anything the compiler checks.
|
|
min-occurrences: 6
|
|
ignore-string-values:
|
|
- anonymous
|
|
- none
|
|
- normal
|
|
- primary
|
|
- primary-hover
|
|
- focus-ring
|
|
- link
|
|
- version
|
|
- status
|
|
- slug
|
|
- items
|
|
- must not be empty
|
|
# Test data legitimately repeats literals like "200" and "published".
|
|
ignore-tests: true
|
|
|
|
godot:
|
|
scope: declarations
|
|
capital: false
|
|
|
|
gosec:
|
|
excludes:
|
|
# G304: a file path from configuration is intentional. The path comes from
|
|
# the operator's own configuration, not from a request.
|
|
- G304
|
|
# Everything gosec ships is enabled by default; only the exclusions above
|
|
# narrow it. G115 (integer overflow) is intentionally left on: it fires on
|
|
# the token engine's length arithmetic, and the two or three places that
|
|
# could genuinely overflow carry an explicit nolint with a reason.
|
|
|
|
staticcheck:
|
|
checks:
|
|
- all
|
|
# SA1019: deprecation notices for dependencies we control the version of.
|
|
- -SA1019
|
|
|
|
misspell:
|
|
# US, deliberately, and this is a real decision rather than a default.
|
|
#
|
|
# misspell's locale setting makes it *require* one dialect. With UK it
|
|
# rewrites the checker's idea of a correct word, which means it flags every
|
|
# occurrence of the US spelling -- including identifiers that are part of the
|
|
# published API contract: the JSON error code "unauthorized", the CSS custom
|
|
# property and colour-scheme vocabulary, the OpenAPI document.
|
|
#
|
|
# The codebase writes prose in British English, which misspell has nothing to
|
|
# say about under a US locale (it only corrects genuine misspellings, it does
|
|
# not enforce a dialect). So: British prose, US locale, and no linter
|
|
# pressure to rename a wire-format string.
|
|
locale: US
|
|
# misspell enforces one dialect even under a locale setting, so every British
|
|
# spelling in the prose has to be listed explicitly. This keeps the check
|
|
# worth having -- a genuine typo in a comment is still caught -- while
|
|
# accepting the dialect the documentation is written in.
|
|
#
|
|
# No identifier is in this list: exported names and JSON keys are American
|
|
# throughout, because they are wire and API surface rather than prose. Only
|
|
# comments, documentation and doc strings use the British forms.
|
|
ignore-rules:
|
|
- artefact
|
|
- artefacts
|
|
- authorises
|
|
- behaviour
|
|
- cancelled
|
|
- colour
|
|
- colours
|
|
- defence
|
|
- honoured
|
|
- honouring
|
|
- honours
|
|
- initialise
|
|
- licence
|
|
- localise
|
|
- marshalled
|
|
- materialise
|
|
- materialises
|
|
- materialising
|
|
- maximises
|
|
- modelled
|
|
- neutralises
|
|
- recognised
|
|
- recognises
|
|
- sanitise
|
|
- sanitised
|
|
- sanitising
|
|
- serialise
|
|
- serialised
|
|
- serialises
|
|
- summarises
|
|
|
|
exclusions:
|
|
generated: lax
|
|
presets:
|
|
- comments
|
|
- common-false-positives
|
|
- legacy
|
|
- std-error-handling
|
|
rules:
|
|
# A test function legitimately ignores the error from a deliberate failure.
|
|
- path: _test\.go
|
|
linters:
|
|
- gosec
|
|
- errcheck
|
|
# The SQL query constants and their arguments are checked by the store tests,
|
|
# which assert on behaviour rather than on the statement text.
|
|
- path: internal/store/
|
|
linters:
|
|
- goconst
|
|
paths:
|
|
- third_party$
|
|
- builtin$
|
|
- examples$
|
|
|
|
issues:
|
|
# 0 disables the cap. A linter that stops reporting after 50 findings is worse
|
|
# than one that reports everything, because the tail is where the surprises are.
|
|
max-issues-per-linter: 0
|
|
max-same-issues: 0
|
|
new: false
|
|
fix: false
|