chore: upgrade golangci-lint

This commit is contained in:
Alec Thomas
2026-05-12 16:48:00 +10:00
parent 786675b89c
commit 2cbcf7b18b
15 changed files with 220 additions and 115 deletions
+105 -72
View File
@@ -1,89 +1,122 @@
version: "2"
run:
tests: true
output:
show-stats: false
formats:
text:
print-issued-lines: false
colors: true
linters:
enable-all: true
default: all
disable:
- lll
- gocyclo
- dupl
- gochecknoglobals
- funlen
- godox
- wsl
- gocognit
- nolintlint
- testpackage
- godot
- nestif
- paralleltest
- nlreturn
- cyclop
- gci
- gofumpt
- errorlint
- exhaustive
- wrapcheck
- stylecheck
- thelper
- nonamedreturns
- revive
- dupword
- exhaustruct
- varnamelen
- forcetypeassert
- ireturn
- maintidx
- govet
- testableexamples
- musttag
- prealloc
- dupl
- godoclint
- cyclop
- depguard
- goconst
- perfsprint
- dupword
- err113
- errname
- errorlint
- exhaustruct
- forbidigo
- forcetypeassert
- funlen
- gochecknoglobals
- gocognit
- gocritic
- gocyclo
- godot
- godox
- gomoddirectives
- ireturn
- lll
- maintidx
- mnd
- nakedret
- nestif
- nilnil
- nlreturn
- nolintlint
- nonamedreturns
- paralleltest
- perfsprint
- predeclared
- recvcheck
- tenv
- err113
linters-settings:
gocyclo:
min-complexity: 10
- revive
- testpackage
- varnamelen
- wastedassign
- whitespace
- wsl
- wsl_v5
- funcorder
- noinlineerr
- tagalign
- goconst
- gochecknoinits
- durationcheck
- embeddedstructfieldcheck
- wrapcheck
- gomodguard
settings:
dupl:
threshold: 100
exhaustive:
default-signifies-exhaustive: true
goconst:
min-len: 8
min-occurrences: 3
forbidigo:
#forbid:
# - (Must)?NewLexer$
exclude_godoc_examples: false
gocyclo:
min-complexity: 10
wrapcheck:
report-internal-errors: false
ignore-package-globs:
- github.com/alecthomas/errors
exclusions:
generated: lax
rules:
- path: (.+)\.go$
text: "^(G104|G204|G307|G304):"
- path: (.+)\.go$
text: Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
- path: (.+)\.go$
text: exported method `(.*\.MarshalJSON|.*\.UnmarshalJSON|.*\.EntityURN|.*\.GoString|.*\.Pos)` should have comment or be unexported
- path: (.+)\.go$
text: uses unkeyed fields
- path: (.+)\.go$
text: declaration of "err" shadows declaration
- path: (.+)\.go$
text: bad syntax for struct tag key
- path: (.+)\.go$
text: bad syntax for struct tag pair
- path: (.+)\.go$
text: ^ST1012
- path: (.+)\.go$
text: log/slog.Logger.*must not be called
- path: (.+)_test\.go$
text: error returned from external package is unwrapped
- linters: [staticcheck]
text: QF1008
- text: "Error return value of `.*.Write` is not checked"
linters: [errcheck]
path: (.+)_test\.go$
paths:
- third_party$
- builtin$
- examples$
issues:
exclude-dirs:
- _examples
max-per-linter: 0
max-same: 0
exclude-use-default: false
exclude:
# Captured by errcheck.
- '^(G104|G204):'
# Very commonly not checked.
- 'Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
- 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON|.*\.EntityURN|.*\.GoString|.*\.Pos) should have comment or be unexported'
- 'composite literal uses unkeyed fields'
- 'declaration of "err" shadows declaration'
- 'should not use dot imports'
- 'Potential file inclusion via variable'
- 'should have comment or be unexported'
- 'comment on exported var .* should be of the form'
- 'at least one file in a package should have a package comment'
- 'string literal contains the Unicode'
- 'methods on the same type should have the same receiver name'
- '_TokenType_name should be _TokenTypeName'
- '`_TokenType_map` should be `_TokenTypeMap`'
- 'rewrite if-else to switch statement'
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
+1 -1
View File
@@ -122,7 +122,7 @@ func main() {
css, err := parser.Parse(string(source))
kingpin.FatalIfError(err, "")
context := map[string]interface{}{
context := map[string]any{
"Name": *nameArg,
"Rules": css.Rules,
}
+1 -1
View File
@@ -1 +1 @@
.golangci-lint-1.64.6.pkg
.golangci-lint-2.12.2.pkg
+1
View File
@@ -86,6 +86,7 @@ func TestColourClampBrightness(t *testing.T) {
}
func assertInDelta(t *testing.T, expected, actual float64) {
t.Helper()
const delta = 0.01 // used for brightness and hue comparisons
assert.True(t, actual > (expected-delta) && actual < (expected+delta))
}
+1 -1
View File
@@ -7,6 +7,7 @@ import (
)
func makeDelegationTestLexers(t *testing.T) (lang Lexer, root Lexer) {
t.Helper()
return mustNewLexer(t, nil, Rules{ // nolint: forbidigo
"root": {
{`\<\?`, CommentPreproc, Push("inside")},
@@ -100,7 +101,6 @@ func TestDelegate(t *testing.T) {
lang, root := makeDelegationTestLexers(t)
delegate := DelegatingLexer(root, lang)
for _, test := range testdata {
// nolint: scopelint
t.Run(test.name, func(t *testing.T) {
it, err := delegate.Tokenise(nil, test.source)
assert.NoError(t, err)
+4 -4
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"html"
"io"
"slices"
"sort"
"strconv"
"strings"
@@ -288,7 +289,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
highlightIndex++
}
if !(f.preventSurroundingPre || f.inlineCode) {
if !f.preventSurroundingPre && !f.inlineCode {
// Start of Line
fmt.Fprint(w, `<span`)
@@ -321,7 +322,7 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.
fmt.Fprint(w, html)
}
if !(f.preventSurroundingPre || f.inlineCode) {
if !f.preventSurroundingPre && !f.inlineCode {
fmt.Fprint(w, `</span>`) // End of CodeLine
fmt.Fprint(w, `</span>`) // End of Line
@@ -613,8 +614,7 @@ func (l *styleCache) get(style *chroma.Style, compress bool) map[chroma.TokenTyp
defer l.mu.Unlock()
// Look for an existing entry.
for i := len(l.cache) - 1; i >= 0; i-- {
entry := l.cache[i]
for i, entry := range slices.Backward(l.cache) {
if entry.style == style && entry.compressed == compress {
// Top of the cache, no need to adjust the order.
if i == len(l.cache)-1 {
+1 -1
View File
@@ -1,6 +1,6 @@
module github.com/alecthomas/chroma/v2
go 1.22
go 1.26
require (
github.com/alecthomas/assert/v2 v2.11.0
+1 -2
View File
@@ -1599,8 +1599,7 @@ func quote(groups []string, state *LexerState) Iterator {
var tokenStates []string
// Set tokenStates based on adverbs
adverbs := strings.Split(adverbsStr, ":")
for _, adverb := range adverbs {
for adverb := range strings.SplitSeq(adverbsStr, ":") {
switch adverb {
case "c", "closure":
tokenStates = append(tokenStates, "Q-closure")
+75
View File
@@ -16,4 +16,79 @@ func main() { }
if err != nil {
log.Fatal(err)
}
// Output:
// <html>
// <style type="text/css">
// /* Background */ .bg { color: #f8f8f2; background-color: #272822; }
// /* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; -webkit-text-size-adjust: none; }
// /* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
// /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit }
// /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
// /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
// /* LineHighlight */ .chroma .hl { background-color: #3c3d38 }
// /* LineNumbersTable */ .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
// /* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
// /* Line */ .chroma .line { display: flex; }
// /* Keyword */ .chroma .k { color: #66d9ef }
// /* KeywordConstant */ .chroma .kc { color: #66d9ef }
// /* KeywordDeclaration */ .chroma .kd { color: #66d9ef }
// /* KeywordNamespace */ .chroma .kn { color: #f92672 }
// /* KeywordPseudo */ .chroma .kp { color: #66d9ef }
// /* KeywordReserved */ .chroma .kr { color: #66d9ef }
// /* KeywordType */ .chroma .kt { color: #66d9ef }
// /* NameAttribute */ .chroma .na { color: #a6e22e }
// /* NameClass */ .chroma .nc { color: #a6e22e }
// /* NameConstant */ .chroma .no { color: #66d9ef }
// /* NameDecorator */ .chroma .nd { color: #a6e22e }
// /* NameException */ .chroma .ne { color: #a6e22e }
// /* NameOther */ .chroma .nx { color: #a6e22e }
// /* NameTag */ .chroma .nt { color: #f92672 }
// /* NameFunction */ .chroma .nf { color: #a6e22e }
// /* NameFunctionMagic */ .chroma .fm { color: #a6e22e }
// /* Literal */ .chroma .l { color: #ae81ff }
// /* LiteralDate */ .chroma .ld { color: #e6db74 }
// /* LiteralString */ .chroma .s { color: #e6db74 }
// /* LiteralStringAffix */ .chroma .sa { color: #e6db74 }
// /* LiteralStringBacktick */ .chroma .sb { color: #e6db74 }
// /* LiteralStringChar */ .chroma .sc { color: #e6db74 }
// /* LiteralStringDelimiter */ .chroma .dl { color: #e6db74 }
// /* LiteralStringDoc */ .chroma .sd { color: #e6db74 }
// /* LiteralStringDouble */ .chroma .s2 { color: #e6db74 }
// /* LiteralStringEscape */ .chroma .se { color: #ae81ff }
// /* LiteralStringHeredoc */ .chroma .sh { color: #e6db74 }
// /* LiteralStringInterpol */ .chroma .si { color: #e6db74 }
// /* LiteralStringOther */ .chroma .sx { color: #e6db74 }
// /* LiteralStringRegex */ .chroma .sr { color: #e6db74 }
// /* LiteralStringSingle */ .chroma .s1 { color: #e6db74 }
// /* LiteralStringSymbol */ .chroma .ss { color: #e6db74 }
// /* LiteralNumber */ .chroma .m { color: #ae81ff }
// /* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
// /* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
// /* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
// /* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
// /* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
// /* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
// /* Operator */ .chroma .o { color: #f92672 }
// /* OperatorWord */ .chroma .ow { color: #f92672 }
// /* OperatorReserved */ .chroma .or { color: #f92672 }
// /* Comment */ .chroma .c { color: #75715e }
// /* CommentHashbang */ .chroma .ch { color: #75715e }
// /* CommentMultiline */ .chroma .cm { color: #75715e }
// /* CommentSingle */ .chroma .c1 { color: #75715e }
// /* CommentSpecial */ .chroma .cs { color: #75715e }
// /* CommentPreproc */ .chroma .cp { color: #75715e }
// /* CommentPreprocFile */ .chroma .cpf { color: #75715e }
// /* GenericDeleted */ .chroma .gd { color: #f92672 }
// /* GenericEmph */ .chroma .ge { font-style: italic }
// /* GenericInserted */ .chroma .gi { color: #a6e22e }
// /* GenericStrong */ .chroma .gs { font-weight: bold }
// /* GenericSubheading */ .chroma .gu { color: #75715e }
// body { color:#f8f8f2;background-color:#272822;; }
// </style><body class="bg">
// <pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
// </span></span></span><span class="line"><span class="cl"><span class="w">
// </span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">}</span><span class="w">
// </span></span></span></code></pre>
// </body>
// </html>
}
+6 -7
View File
@@ -3,6 +3,7 @@ package chroma
import (
"encoding/json"
"fmt"
"maps"
"os"
"path/filepath"
"regexp"
@@ -70,9 +71,7 @@ func (r Rules) Clone() Rules {
// Merge creates a clone of "r" then merges "rules" into the clone.
func (r Rules) Merge(rules Rules) Rules {
out := r.Clone()
for k, v := range rules.Clone() {
out[k] = v
}
maps.Copy(out, rules.Clone())
return out
}
@@ -177,19 +176,19 @@ type LexerState struct {
// Named Group matches.
NamedGroups map[string]string
// Custum context for mutators.
MutatorContext map[interface{}]interface{}
MutatorContext map[any]any
iteratorStack []Iterator
options *TokeniseOptions
newlineAdded bool
}
// Set mutator context.
func (l *LexerState) Set(key interface{}, value interface{}) {
func (l *LexerState) Set(key any, value any) {
l.MutatorContext[key] = value
}
// Get mutator context.
func (l *LexerState) Get(key interface{}) interface{} {
func (l *LexerState) Get(key any) any {
return l.MutatorContext[key]
}
@@ -484,7 +483,7 @@ func (r *RegexLexer) Tokenise(options *TokeniseOptions, text string) (Iterator,
Text: []rune(text),
Stack: []string{options.State},
Rules: r.rules,
MutatorContext: map[interface{}]interface{}{},
MutatorContext: map[any]any{},
}
return state.Iterator, nil
}
+1
View File
@@ -7,6 +7,7 @@ import (
)
func mustNewLexer(t *testing.T, config *Config, rules Rules) *RegexLexer { // nolint: forbidigo
t.Helper()
lexer, err := NewLexer(config, func() Rules {
return rules
})
+3 -3
View File
@@ -440,14 +440,14 @@ func (t TokenType) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
}
// This hijinks is a bit unfortunate but without it we can't deserialise into TokenType.
func newFromTemplate(template interface{}) (value func() interface{}, target interface{}) {
func newFromTemplate(template any) (value func() any, target any) {
t := reflect.TypeOf(template)
if t.Kind() == reflect.Ptr {
if t.Kind() == reflect.Pointer {
v := reflect.New(t.Elem())
return v.Interface, v.Interface()
}
v := reflect.New(t)
return func() interface{} { return v.Elem().Interface() }, v.Interface()
return func() any { return v.Elem().Interface() }, v.Interface()
}
func (b *Emitters) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+3 -5
View File
@@ -23,7 +23,6 @@ func TestEmitterSerialisationRoundTrip(t *testing.T) {
{"TokenType", Name},
}
for _, test := range tests {
// nolint: scopelint
t.Run(test.name, func(t *testing.T) {
data, err := xml.Marshal(test.emitter)
assert.NoError(t, err)
@@ -48,7 +47,6 @@ func TestMutatorSerialisationRoundTrip(t *testing.T) {
{"Pop", Pop(1)},
}
for _, test := range tests {
// nolint: scopelint
t.Run(test.name, func(t *testing.T) {
data, err := xml.Marshal(test.mutator)
assert.NoError(t, err)
@@ -101,10 +99,10 @@ func TestMarshal(t *testing.T) {
assert.Equal(t, mustRules(t, expected), mustRules(t, actual))
}
func mustRules(t testing.TB, r *RegexLexer) Rules {
t.Helper()
func mustRules(tb testing.TB, r *RegexLexer) Rules {
tb.Helper()
rules, err := r.Rules()
assert.NoError(t, err)
assert.NoError(tb, err)
return rules
}
+11 -12
View File
@@ -4,7 +4,8 @@ import (
"encoding/xml"
"fmt"
"io"
"sort"
"maps"
"slices"
"strings"
)
@@ -31,12 +32,14 @@ func (t Trilean) String() string {
// Prefix returns s with "no" as a prefix if Trilean is no.
func (t Trilean) Prefix(s string) string {
if t == Yes {
switch t {
case Yes:
return s
} else if t == No {
case No:
return "no" + s
}
default:
return ""
}
}
// A StyleEntry in the Style map.
@@ -111,11 +114,10 @@ func (s StyleEntry) Sub(e StyleEntry) StyleEntry {
// Ancestors should be provided from oldest to newest.
func (s StyleEntry) Inherit(ancestors ...StyleEntry) StyleEntry {
out := s
for i := len(ancestors) - 1; i >= 0; i-- {
for _, ancestor := range slices.Backward(ancestors) {
if out.NoInherit {
return out
}
ancestor := ancestors[i]
if !out.Colour.IsSet() {
out.Colour = ancestor.Colour
}
@@ -157,9 +159,7 @@ func NewStyleBuilder(name string) *StyleBuilder {
}
func (s *StyleBuilder) AddAll(entries StyleEntries) *StyleBuilder {
for ttype, entry := range entries {
s.entries[ttype] = entry
}
maps.Copy(s.entries, entries)
return s
}
@@ -275,7 +275,7 @@ func (s *Style) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
for ttype := range s.entries {
sorted = append(sorted, ttype)
}
sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] })
slices.Sort(sorted)
for _, ttype := range sorted {
entry := s.entries[ttype]
el := xml.StartElement{Name: xml.Name{Local: "entry"}}
@@ -437,8 +437,7 @@ func MustParseStyleEntry(entry string) StyleEntry {
// ParseStyleEntry parses a Pygments style entry.
func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
out := StyleEntry{}
parts := strings.Fields(entry)
for _, part := range parts {
for part := range strings.FieldsSeq(entry) {
switch {
case part == "italic":
out.Italic = Yes