diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index 66699d365084..632605787381 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -126,6 +126,7 @@ linters: - whitespace - wrapcheck - wsl + - wsl_v5 - zerologlint # Disable specific linters. @@ -236,6 +237,7 @@ linters: - whitespace - wrapcheck - wsl + - wsl_v5 - zerologlint # All available settings of specific linters. @@ -3912,6 +3914,93 @@ linters: # Default: false force-short-decl-cuddling: true + wsl_v5: + # Allow cuddling a variable if it's used first in the immediate following block, + # even if the statement with the block doesn't use the variable. + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration + # Default: true + allow-first-in-block: false + + # Same as above, + # but allows cuddling if the variable is used anywhere in the following (or nested) block. + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration + # Default: false + allow-whole-block: true + + # If a block contains more than this number of lines, + # the branch statement needs to be separated by whitespace. + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration + # Default: 2 + branch-max-lines: 4 + + # If set to a non-negative number, + # case blocks need to end with whitespace if exceeding this number + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#configuration + # Default: 0 + case-max-lines: 2 + + # Default checks to use. + # Can be `all`, `none`, `default` or empty. + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration + # Default: "" + default: all + + # Enabled checks. + # Will be additive to any presets. + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration + # Default: [] + enable: + - assign + - branch + - decl + - defer + - expr + - for + - go + - if + - inc-dec + - label + - range + - return + - select + - send + - switch + - type-switch + - append + - assign-exclusive + - assign-expr + - err + - leading-whitespace + - trailing-whitespace + + # Disable checks. + # Will be subtractive to any preset. + # https://github.com/bombsimon/wsl/tree/main?tab=readme-ov-file#checks-and-configuration + # Default: [] + disable: + - assign + - branch + - decl + - defer + - expr + - for + - go + - if + - inc-dec + - label + - range + - return + - select + - send + - switch + - type-switch + - append + - assign-exclusive + - assign-expr + - err + - leading-whitespace + - trailing-whitespace + # The custom section can be used to define linter plugins to be loaded at runtime. # See README documentation for more info. custom: diff --git a/.golangci.yml b/.golangci.yml index 87fd0e952196..23effe4b53e1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -187,6 +187,12 @@ linters: linters: - dupl + # Deprecated linters + - path: pkg/lint/lintersdb/builder_linter.go + text: "SA1019: wsl.NewV4 is deprecated: use NewV5 instead." + linters: + - staticcheck + formatters: enable: - gofmt diff --git a/go.mod b/go.mod index ef62abf3ad54..db07bb6dab09 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/bkielbasa/cyclop v1.2.3 github.com/blizzy78/varnamelen v0.8.0 github.com/bombsimon/wsl/v4 v4.7.0 + github.com/bombsimon/wsl/v5 v5.0.0 github.com/breml/bidichk v0.3.3 github.com/breml/errchkjson v0.4.1 github.com/butuzov/ireturn v0.4.0 diff --git a/go.sum b/go.sum index b92fdfee4b85..51a82b62990a 100644 --- a/go.sum +++ b/go.sum @@ -100,6 +100,8 @@ github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ= github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg= +github.com/bombsimon/wsl/v5 v5.0.0 h1:pWxP6X11o/YeF9eBVGXvS7L0FLEbHWm2kJJJGH6SeDQ= +github.com/bombsimon/wsl/v5 v5.0.0/go.mod h1:Gp8lD04z27wm3FANIUPZycXp+8huVsn0oxc+n4qfV9I= github.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE= github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE= github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg= diff --git a/jsonschema/golangci.next.jsonschema.json b/jsonschema/golangci.next.jsonschema.json index 31e7fc2ffa7a..5c867a4d8415 100644 --- a/jsonschema/golangci.next.jsonschema.json +++ b/jsonschema/golangci.next.jsonschema.json @@ -685,6 +685,32 @@ "header" ] }, + "wsl-checks": { + "enum": [ + "assign", + "branch", + "decl", + "defer", + "expr", + "for", + "go", + "if", + "inc-dec", + "label", + "range", + "return", + "select", + "send", + "switch", + "type-switch", + "append", + "assign-exclusive", + "assign-expr", + "err", + "leading-whitespace", + "trailing-whitespace" + ] + }, "relative-path-modes": { "enum": [ "gomod", @@ -829,6 +855,7 @@ "whitespace", "wrapcheck", "wsl", + "wsl_v5", "zerologlint" ] }, @@ -4090,6 +4117,44 @@ } } }, + "wslSettingsV5": { + "type": "object", + "additionalProperties": false, + "properties": { + "allow-first-in-block": { + "type": "boolean", + "default": true + }, + "allow-whole-block": { + "type": "boolean", + "default": false + }, + "branch-max-lines": { + "type": "integer", + "default": 2 + }, + "case-max-lines": { + "type": "integer", + "default": 0 + }, + "default": { + "enum": ["all", "none", "default", ""], + "default": "default" + }, + "enable": { + "type": "array", + "items": { + "$ref": "#/definitions/wsl-checks" + } + }, + "disable": { + "type": "array", + "items": { + "$ref": "#/definitions/wsl-checks" + } + } + } + }, "copyloopvarSettings": { "type": "object", "additionalProperties": false, @@ -4592,6 +4657,9 @@ "wsl": { "$ref": "#/definitions/settings/definitions/wslSettings" }, + "wsl_v5": { + "$ref": "#/definitions/settings/definitions/wslSettingsV5" + }, "copyloopvar": { "$ref": "#/definitions/settings/definitions/copyloopvarSettings" }, diff --git a/pkg/commands/internal/migrate/migrate_linters_settings.go b/pkg/commands/internal/migrate/migrate_linters_settings.go index 5accd9f593e5..4656842d6bde 100644 --- a/pkg/commands/internal/migrate/migrate_linters_settings.go +++ b/pkg/commands/internal/migrate/migrate_linters_settings.go @@ -998,8 +998,8 @@ func toWrapcheckSettings(old versionone.WrapcheckSettings) versiontwo.WrapcheckS } } -func toWSLSettings(old versionone.WSLSettings) versiontwo.WSLSettings { - return versiontwo.WSLSettings{ +func toWSLSettings(old versionone.WSLSettings) versiontwo.WSLv4Settings { + return versiontwo.WSLv4Settings{ StrictAppend: old.StrictAppend, AllowAssignAndCallCuddle: old.AllowAssignAndCallCuddle, AllowAssignAndAnythingCuddle: old.AllowAssignAndAnythingCuddle, diff --git a/pkg/commands/internal/migrate/versiontwo/linters_settings.go b/pkg/commands/internal/migrate/versiontwo/linters_settings.go index 3a0d6b7b6a2a..be35d1390304 100644 --- a/pkg/commands/internal/migrate/versiontwo/linters_settings.go +++ b/pkg/commands/internal/migrate/versiontwo/linters_settings.go @@ -5,84 +5,86 @@ package versiontwo type LintersSettings struct { FormatterSettings `yaml:"-,omitempty" toml:"-,multiline,omitempty"` - Asasalint AsasalintSettings `yaml:"asasalint,omitempty" toml:"asasalint,multiline,omitempty"` - BiDiChk BiDiChkSettings `yaml:"bidichk,omitempty" toml:"bidichk,multiline,omitempty"` - CopyLoopVar CopyLoopVarSettings `yaml:"copyloopvar,omitempty" toml:"copyloopvar,multiline,omitempty"` - Cyclop CyclopSettings `yaml:"cyclop,omitempty" toml:"cyclop,multiline,omitempty"` - Decorder DecorderSettings `yaml:"decorder,omitempty" toml:"decorder,multiline,omitempty"` - Depguard DepGuardSettings `yaml:"depguard,omitempty" toml:"depguard,multiline,omitempty"` - Dogsled DogsledSettings `yaml:"dogsled,omitempty" toml:"dogsled,multiline,omitempty"` - Dupl DuplSettings `yaml:"dupl,omitempty" toml:"dupl,multiline,omitempty"` - DupWord DupWordSettings `yaml:"dupword,omitempty" toml:"dupword,multiline,omitempty"` - Errcheck ErrcheckSettings `yaml:"errcheck,omitempty" toml:"errcheck,multiline,omitempty"` - ErrChkJSON ErrChkJSONSettings `yaml:"errchkjson,omitempty" toml:"errchkjson,multiline,omitempty"` - ErrorLint ErrorLintSettings `yaml:"errorlint,omitempty" toml:"errorlint,multiline,omitempty"` - Exhaustive ExhaustiveSettings `yaml:"exhaustive,omitempty" toml:"exhaustive,multiline,omitempty"` - Exhaustruct ExhaustructSettings `yaml:"exhaustruct,omitempty" toml:"exhaustruct,multiline,omitempty"` - Fatcontext FatcontextSettings `yaml:"fatcontext,omitempty" toml:"fatcontext,multiline,omitempty"` - Forbidigo ForbidigoSettings `yaml:"forbidigo,omitempty" toml:"forbidigo,multiline,omitempty"` - FuncOrder FuncOrderSettings `yaml:"funcorder,omitempty" toml:"funcorder,multiline,omitempty"` - Funlen FunlenSettings `yaml:"funlen,omitempty" toml:"funlen,multiline,omitempty"` - GinkgoLinter GinkgoLinterSettings `yaml:"ginkgolinter,omitempty" toml:"ginkgolinter,multiline,omitempty"` - Gocognit GocognitSettings `yaml:"gocognit,omitempty" toml:"gocognit,multiline,omitempty"` - GoChecksumType GoChecksumTypeSettings `yaml:"gochecksumtype,omitempty" toml:"gochecksumtype,multiline,omitempty"` - Goconst GoConstSettings `yaml:"goconst,omitempty" toml:"goconst,multiline,omitempty"` - Gocritic GoCriticSettings `yaml:"gocritic,omitempty" toml:"gocritic,multiline,omitempty"` - Gocyclo GoCycloSettings `yaml:"gocyclo,omitempty" toml:"gocyclo,multiline,omitempty"` - Godot GodotSettings `yaml:"godot,omitempty" toml:"godot,multiline,omitempty"` - Godox GodoxSettings `yaml:"godox,omitempty" toml:"godox,multiline,omitempty"` - Goheader GoHeaderSettings `yaml:"goheader,omitempty" toml:"goheader,multiline,omitempty"` - GoModDirectives GoModDirectivesSettings `yaml:"gomoddirectives,omitempty" toml:"gomoddirectives,multiline,omitempty"` - Gomodguard GoModGuardSettings `yaml:"gomodguard,omitempty" toml:"gomodguard,multiline,omitempty"` - Gosec GoSecSettings `yaml:"gosec,omitempty" toml:"gosec,multiline,omitempty"` - Gosmopolitan GosmopolitanSettings `yaml:"gosmopolitan,omitempty" toml:"gosmopolitan,multiline,omitempty"` - Govet GovetSettings `yaml:"govet,omitempty" toml:"govet,multiline,omitempty"` - Grouper GrouperSettings `yaml:"grouper,omitempty" toml:"grouper,multiline,omitempty"` - Iface IfaceSettings `yaml:"iface,omitempty" toml:"iface,multiline,omitempty"` - ImportAs ImportAsSettings `yaml:"importas,omitempty" toml:"importas,multiline,omitempty"` - Inamedparam INamedParamSettings `yaml:"inamedparam,omitempty" toml:"inamedparam,multiline,omitempty"` - InterfaceBloat InterfaceBloatSettings `yaml:"interfacebloat,omitempty" toml:"interfacebloat,multiline,omitempty"` - Ireturn IreturnSettings `yaml:"ireturn,omitempty" toml:"ireturn,multiline,omitempty"` - Lll LllSettings `yaml:"lll,omitempty" toml:"lll,multiline,omitempty"` - LoggerCheck LoggerCheckSettings `yaml:"loggercheck,omitempty" toml:"loggercheck,multiline,omitempty"` - MaintIdx MaintIdxSettings `yaml:"maintidx,omitempty" toml:"maintidx,multiline,omitempty"` - Makezero MakezeroSettings `yaml:"makezero,omitempty" toml:"makezero,multiline,omitempty"` - Misspell MisspellSettings `yaml:"misspell,omitempty" toml:"misspell,multiline,omitempty"` - Mnd MndSettings `yaml:"mnd,omitempty" toml:"mnd,multiline,omitempty"` - MustTag MustTagSettings `yaml:"musttag,omitempty" toml:"musttag,multiline,omitempty"` - Nakedret NakedretSettings `yaml:"nakedret,omitempty" toml:"nakedret,multiline,omitempty"` - Nestif NestifSettings `yaml:"nestif,omitempty" toml:"nestif,multiline,omitempty"` - NilNil NilNilSettings `yaml:"nilnil,omitempty" toml:"nilnil,multiline,omitempty"` - Nlreturn NlreturnSettings `yaml:"nlreturn,omitempty" toml:"nlreturn,multiline,omitempty"` - NoLintLint NoLintLintSettings `yaml:"nolintlint,omitempty" toml:"nolintlint,multiline,omitempty"` - NoNamedReturns NoNamedReturnsSettings `yaml:"nonamedreturns,omitempty" toml:"nonamedreturns,multiline,omitempty"` - ParallelTest ParallelTestSettings `yaml:"paralleltest,omitempty" toml:"paralleltest,multiline,omitempty"` - PerfSprint PerfSprintSettings `yaml:"perfsprint,omitempty" toml:"perfsprint,multiline,omitempty"` - Prealloc PreallocSettings `yaml:"prealloc,omitempty" toml:"prealloc,multiline,omitempty"` - Predeclared PredeclaredSettings `yaml:"predeclared,omitempty" toml:"predeclared,multiline,omitempty"` - Promlinter PromlinterSettings `yaml:"promlinter,omitempty" toml:"promlinter,multiline,omitempty"` - ProtoGetter ProtoGetterSettings `yaml:"protogetter,omitempty" toml:"protogetter,multiline,omitempty"` - Reassign ReassignSettings `yaml:"reassign,omitempty" toml:"reassign,multiline,omitempty"` - Recvcheck RecvcheckSettings `yaml:"recvcheck,omitempty" toml:"recvcheck,multiline,omitempty"` - Revive ReviveSettings `yaml:"revive,omitempty" toml:"revive,multiline,omitempty"` - RowsErrCheck RowsErrCheckSettings `yaml:"rowserrcheck,omitempty" toml:"rowserrcheck,multiline,omitempty"` - SlogLint SlogLintSettings `yaml:"sloglint,omitempty" toml:"sloglint,multiline,omitempty"` - Spancheck SpancheckSettings `yaml:"spancheck,omitempty" toml:"spancheck,multiline,omitempty"` - Staticcheck StaticCheckSettings `yaml:"staticcheck,omitempty" toml:"staticcheck,multiline,omitempty"` - TagAlign TagAlignSettings `yaml:"tagalign,omitempty" toml:"tagalign,multiline,omitempty"` - Tagliatelle TagliatelleSettings `yaml:"tagliatelle,omitempty" toml:"tagliatelle,multiline,omitempty"` - Testifylint TestifylintSettings `yaml:"testifylint,omitempty" toml:"testifylint,multiline,omitempty"` - Testpackage TestpackageSettings `yaml:"testpackage,omitempty" toml:"testpackage,multiline,omitempty"` - Thelper ThelperSettings `yaml:"thelper,omitempty" toml:"thelper,multiline,omitempty"` - Unconvert UnconvertSettings `yaml:"unconvert,omitempty" toml:"unconvert,multiline,omitempty"` - Unparam UnparamSettings `yaml:"unparam,omitempty" toml:"unparam,multiline,omitempty"` - Unused UnusedSettings `yaml:"unused,omitempty" toml:"unused,multiline,omitempty"` - UseStdlibVars UseStdlibVarsSettings `yaml:"usestdlibvars,omitempty" toml:"usestdlibvars,multiline,omitempty"` - UseTesting UseTestingSettings `yaml:"usetesting,omitempty" toml:"usetesting,multiline,omitempty"` - Varnamelen VarnamelenSettings `yaml:"varnamelen,omitempty" toml:"varnamelen,multiline,omitempty"` - Whitespace WhitespaceSettings `yaml:"whitespace,omitempty" toml:"whitespace,multiline,omitempty"` - Wrapcheck WrapcheckSettings `yaml:"wrapcheck,omitempty" toml:"wrapcheck,multiline,omitempty"` - WSL WSLSettings `yaml:"wsl,omitempty" toml:"wsl,multiline,omitempty"` + Asasalint AsasalintSettings `yaml:"asasalint,omitempty" toml:"asasalint,multiline,omitempty"` + BiDiChk BiDiChkSettings `yaml:"bidichk,omitempty" toml:"bidichk,multiline,omitempty"` + CopyLoopVar CopyLoopVarSettings `yaml:"copyloopvar,omitempty" toml:"copyloopvar,multiline,omitempty"` + Cyclop CyclopSettings `yaml:"cyclop,omitempty" toml:"cyclop,multiline,omitempty"` + Decorder DecorderSettings `yaml:"decorder,omitempty" toml:"decorder,multiline,omitempty"` + Depguard DepGuardSettings `yaml:"depguard,omitempty" toml:"depguard,multiline,omitempty"` + Dogsled DogsledSettings `yaml:"dogsled,omitempty" toml:"dogsled,multiline,omitempty"` + Dupl DuplSettings `yaml:"dupl,omitempty" toml:"dupl,multiline,omitempty"` + DupWord DupWordSettings `yaml:"dupword,omitempty" toml:"dupword,multiline,omitempty"` + EmbeddedStructFieldCheck EmbeddedStructFieldCheckSettings `yaml:"embeddedstructfieldcheck,omitempty" toml:"embeddedstructfieldcheck,multiline,omitempty"` + Errcheck ErrcheckSettings `yaml:"errcheck,omitempty" toml:"errcheck,multiline,omitempty"` + ErrChkJSON ErrChkJSONSettings `yaml:"errchkjson,omitempty" toml:"errchkjson,multiline,omitempty"` + ErrorLint ErrorLintSettings `yaml:"errorlint,omitempty" toml:"errorlint,multiline,omitempty"` + Exhaustive ExhaustiveSettings `yaml:"exhaustive,omitempty" toml:"exhaustive,multiline,omitempty"` + Exhaustruct ExhaustructSettings `yaml:"exhaustruct,omitempty" toml:"exhaustruct,multiline,omitempty"` + Fatcontext FatcontextSettings `yaml:"fatcontext,omitempty" toml:"fatcontext,multiline,omitempty"` + Forbidigo ForbidigoSettings `yaml:"forbidigo,omitempty" toml:"forbidigo,multiline,omitempty"` + FuncOrder FuncOrderSettings `yaml:"funcorder,omitempty" toml:"funcorder,multiline,omitempty"` + Funlen FunlenSettings `yaml:"funlen,omitempty" toml:"funlen,multiline,omitempty"` + GinkgoLinter GinkgoLinterSettings `yaml:"ginkgolinter,omitempty" toml:"ginkgolinter,multiline,omitempty"` + Gocognit GocognitSettings `yaml:"gocognit,omitempty" toml:"gocognit,multiline,omitempty"` + GoChecksumType GoChecksumTypeSettings `yaml:"gochecksumtype,omitempty" toml:"gochecksumtype,multiline,omitempty"` + Goconst GoConstSettings `yaml:"goconst,omitempty" toml:"goconst,multiline,omitempty"` + Gocritic GoCriticSettings `yaml:"gocritic,omitempty" toml:"gocritic,multiline,omitempty"` + Gocyclo GoCycloSettings `yaml:"gocyclo,omitempty" toml:"gocyclo,multiline,omitempty"` + Godot GodotSettings `yaml:"godot,omitempty" toml:"godot,multiline,omitempty"` + Godox GodoxSettings `yaml:"godox,omitempty" toml:"godox,multiline,omitempty"` + Goheader GoHeaderSettings `yaml:"goheader,omitempty" toml:"goheader,multiline,omitempty"` + GoModDirectives GoModDirectivesSettings `yaml:"gomoddirectives,omitempty" toml:"gomoddirectives,multiline,omitempty"` + Gomodguard GoModGuardSettings `yaml:"gomodguard,omitempty" toml:"gomodguard,multiline,omitempty"` + Gosec GoSecSettings `yaml:"gosec,omitempty" toml:"gosec,multiline,omitempty"` + Gosmopolitan GosmopolitanSettings `yaml:"gosmopolitan,omitempty" toml:"gosmopolitan,multiline,omitempty"` + Govet GovetSettings `yaml:"govet,omitempty" toml:"govet,multiline,omitempty"` + Grouper GrouperSettings `yaml:"grouper,omitempty" toml:"grouper,multiline,omitempty"` + Iface IfaceSettings `yaml:"iface,omitempty" toml:"iface,multiline,omitempty"` + ImportAs ImportAsSettings `yaml:"importas,omitempty" toml:"importas,multiline,omitempty"` + Inamedparam INamedParamSettings `yaml:"inamedparam,omitempty" toml:"inamedparam,multiline,omitempty"` + InterfaceBloat InterfaceBloatSettings `yaml:"interfacebloat,omitempty" toml:"interfacebloat,multiline,omitempty"` + Ireturn IreturnSettings `yaml:"ireturn,omitempty" toml:"ireturn,multiline,omitempty"` + Lll LllSettings `yaml:"lll,omitempty" toml:"lll,multiline,omitempty"` + LoggerCheck LoggerCheckSettings `yaml:"loggercheck,omitempty" toml:"loggercheck,multiline,omitempty"` + MaintIdx MaintIdxSettings `yaml:"maintidx,omitempty" toml:"maintidx,multiline,omitempty"` + Makezero MakezeroSettings `yaml:"makezero,omitempty" toml:"makezero,multiline,omitempty"` + Misspell MisspellSettings `yaml:"misspell,omitempty" toml:"misspell,multiline,omitempty"` + Mnd MndSettings `yaml:"mnd,omitempty" toml:"mnd,multiline,omitempty"` + MustTag MustTagSettings `yaml:"musttag,omitempty" toml:"musttag,multiline,omitempty"` + Nakedret NakedretSettings `yaml:"nakedret,omitempty" toml:"nakedret,multiline,omitempty"` + Nestif NestifSettings `yaml:"nestif,omitempty" toml:"nestif,multiline,omitempty"` + NilNil NilNilSettings `yaml:"nilnil,omitempty" toml:"nilnil,multiline,omitempty"` + Nlreturn NlreturnSettings `yaml:"nlreturn,omitempty" toml:"nlreturn,multiline,omitempty"` + NoLintLint NoLintLintSettings `yaml:"nolintlint,omitempty" toml:"nolintlint,multiline,omitempty"` + NoNamedReturns NoNamedReturnsSettings `yaml:"nonamedreturns,omitempty" toml:"nonamedreturns,multiline,omitempty"` + ParallelTest ParallelTestSettings `yaml:"paralleltest,omitempty" toml:"paralleltest,multiline,omitempty"` + PerfSprint PerfSprintSettings `yaml:"perfsprint,omitempty" toml:"perfsprint,multiline,omitempty"` + Prealloc PreallocSettings `yaml:"prealloc,omitempty" toml:"prealloc,multiline,omitempty"` + Predeclared PredeclaredSettings `yaml:"predeclared,omitempty" toml:"predeclared,multiline,omitempty"` + Promlinter PromlinterSettings `yaml:"promlinter,omitempty" toml:"promlinter,multiline,omitempty"` + ProtoGetter ProtoGetterSettings `yaml:"protogetter,omitempty" toml:"protogetter,multiline,omitempty"` + Reassign ReassignSettings `yaml:"reassign,omitempty" toml:"reassign,multiline,omitempty"` + Recvcheck RecvcheckSettings `yaml:"recvcheck,omitempty" toml:"recvcheck,multiline,omitempty"` + Revive ReviveSettings `yaml:"revive,omitempty" toml:"revive,multiline,omitempty"` + RowsErrCheck RowsErrCheckSettings `yaml:"rowserrcheck,omitempty" toml:"rowserrcheck,multiline,omitempty"` + SlogLint SlogLintSettings `yaml:"sloglint,omitempty" toml:"sloglint,multiline,omitempty"` + Spancheck SpancheckSettings `yaml:"spancheck,omitempty" toml:"spancheck,multiline,omitempty"` + Staticcheck StaticCheckSettings `yaml:"staticcheck,omitempty" toml:"staticcheck,multiline,omitempty"` + TagAlign TagAlignSettings `yaml:"tagalign,omitempty" toml:"tagalign,multiline,omitempty"` + Tagliatelle TagliatelleSettings `yaml:"tagliatelle,omitempty" toml:"tagliatelle,multiline,omitempty"` + Testifylint TestifylintSettings `yaml:"testifylint,omitempty" toml:"testifylint,multiline,omitempty"` + Testpackage TestpackageSettings `yaml:"testpackage,omitempty" toml:"testpackage,multiline,omitempty"` + Thelper ThelperSettings `yaml:"thelper,omitempty" toml:"thelper,multiline,omitempty"` + Unconvert UnconvertSettings `yaml:"unconvert,omitempty" toml:"unconvert,multiline,omitempty"` + Unparam UnparamSettings `yaml:"unparam,omitempty" toml:"unparam,multiline,omitempty"` + Unused UnusedSettings `yaml:"unused,omitempty" toml:"unused,multiline,omitempty"` + UseStdlibVars UseStdlibVarsSettings `yaml:"usestdlibvars,omitempty" toml:"usestdlibvars,multiline,omitempty"` + UseTesting UseTestingSettings `yaml:"usetesting,omitempty" toml:"usetesting,multiline,omitempty"` + Varnamelen VarnamelenSettings `yaml:"varnamelen,omitempty" toml:"varnamelen,multiline,omitempty"` + Whitespace WhitespaceSettings `yaml:"whitespace,omitempty" toml:"whitespace,multiline,omitempty"` + Wrapcheck WrapcheckSettings `yaml:"wrapcheck,omitempty" toml:"wrapcheck,multiline,omitempty"` + WSL WSLv4Settings `yaml:"wsl,omitempty" toml:"wsl,multiline,omitempty"` + WSLv5 WSLv5Settings `yaml:"wsl_v5,omitempty" toml:"wsl_v5,multiline,omitempty"` Custom map[string]CustomLinterSettings `yaml:"custom,omitempty" toml:"custom,multiline,omitempty"` } @@ -153,11 +155,16 @@ type DupWordSettings struct { Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"` } +type EmbeddedStructFieldCheckSettings struct { + ForbidMutex *bool `yaml:"forbid-mutex,omitempty" toml:"forbid-mutex,multiline,omitempty"` +} + type ErrcheckSettings struct { DisableDefaultExclusions *bool `yaml:"disable-default-exclusions,omitempty" toml:"disable-default-exclusions,multiline,omitempty"` CheckTypeAssertions *bool `yaml:"check-type-assertions,omitempty" toml:"check-type-assertions,multiline,omitempty"` CheckAssignToBlank *bool `yaml:"check-blank,omitempty" toml:"check-blank,multiline,omitempty"` ExcludeFunctions []string `yaml:"exclude-functions,omitempty" toml:"exclude-functions,multiline,omitempty"` + Verbose *bool `yaml:"verbose,omitempty" toml:"verbose,multiline,omitempty"` } type ErrChkJSONSettings struct { @@ -214,6 +221,7 @@ type ForbidigoPattern struct { type FuncOrderSettings struct { Constructor *bool `yaml:"constructor,omitempty,omitempty" toml:"constructor,omitempty,multiline,omitempty"` StructMethod *bool `yaml:"struct-method,omitempty,omitempty" toml:"struct-method,omitempty,multiline,omitempty"` + Alphabetical *bool `yaml:"alphabetical,omitempty,omitempty" toml:"alphabetical,omitempty,multiline,omitempty"` } type FunlenSettings struct { @@ -695,6 +703,7 @@ type UseStdlibVarsSettings struct { SQLIsolationLevel *bool `yaml:"sql-isolation-level,omitempty" toml:"sql-isolation-level,multiline,omitempty"` TLSSignatureScheme *bool `yaml:"tls-signature-scheme,omitempty" toml:"tls-signature-scheme,multiline,omitempty"` ConstantKind *bool `yaml:"constant-kind,omitempty" toml:"constant-kind,multiline,omitempty"` + TimeDateMonth *bool `yaml:"time-date-month,omitempty" toml:"time-date-month,multiline,omitempty"` } type UseTestingSettings struct { @@ -752,7 +761,7 @@ type WrapcheckSettings struct { ReportInternalErrors *bool `yaml:"report-internal-errors,omitempty" toml:"report-internal-errors,multiline,omitempty"` } -type WSLSettings struct { +type WSLv4Settings struct { StrictAppend *bool `yaml:"strict-append,omitempty" toml:"strict-append,multiline,omitempty"` AllowAssignAndCallCuddle *bool `yaml:"allow-assign-and-call,omitempty" toml:"allow-assign-and-call,multiline,omitempty"` AllowAssignAndAnythingCuddle *bool `yaml:"allow-assign-and-anything,omitempty" toml:"allow-assign-and-anything,multiline,omitempty"` @@ -769,6 +778,16 @@ type WSLSettings struct { ForceExclusiveShortDeclarations *bool `yaml:"force-short-decl-cuddling,omitempty" toml:"force-short-decl-cuddling,multiline,omitempty"` } +type WSLv5Settings struct { + AllowFirstInBlock *bool `yaml:"allow-first-in-block,omitempty" toml:"allow-first-in-block,multiline,omitempty"` + AllowWholeBlock *bool `yaml:"allow-whole-block,omitempty" toml:"allow-whole-block,multiline,omitempty"` + BranchMaxLines *int `yaml:"branch-max-lines,omitempty" toml:"branch-max-lines,multiline,omitempty"` + CaseMaxLines *int `yaml:"case-max-lines,omitempty" toml:"case-max-lines,multiline,omitempty"` + Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"` + Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` + Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"` +} + type CustomLinterSettings struct { Type *string `yaml:"type,omitempty" toml:"type,multiline,omitempty"` diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 7b3b6a12954a..67d4bf518336 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -184,7 +184,7 @@ var defaultLintersSettings = LintersSettings{ MaxDistance: 5, MinNameLength: 3, }, - WSL: WSLSettings{ + WSL: WSLv4Settings{ StrictAppend: true, AllowAssignAndCallCuddle: true, AllowAssignAndAnythingCuddle: false, @@ -200,6 +200,15 @@ var defaultLintersSettings = LintersSettings{ ErrorVariableNames: []string{"err"}, ForceExclusiveShortDeclarations: false, }, + WSLv5: WSLv5Settings{ + AllowFirstInBlock: true, + AllowWholeBlock: false, + BranchMaxLines: 2, + CaseMaxLines: 0, + Default: "default", + Enable: nil, + Disable: nil, + }, } type LintersSettings struct { @@ -283,7 +292,8 @@ type LintersSettings struct { Varnamelen VarnamelenSettings `mapstructure:"varnamelen"` Whitespace WhitespaceSettings `mapstructure:"whitespace"` Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"` - WSL WSLSettings `mapstructure:"wsl"` + WSL WSLv4Settings `mapstructure:"wsl"` // Deprecated: use WSLv5 instead. + WSLv5 WSLv5Settings `mapstructure:"wsl_v5"` Custom map[string]CustomLinterSettings `mapstructure:"custom"` } @@ -992,7 +1002,8 @@ type WrapcheckSettings struct { ReportInternalErrors bool `mapstructure:"report-internal-errors"` } -type WSLSettings struct { +// Deprecated: use WSLv5Settings instead. +type WSLv4Settings struct { StrictAppend bool `mapstructure:"strict-append"` AllowAssignAndCallCuddle bool `mapstructure:"allow-assign-and-call"` AllowAssignAndAnythingCuddle bool `mapstructure:"allow-assign-and-anything"` @@ -1009,6 +1020,16 @@ type WSLSettings struct { ForceExclusiveShortDeclarations bool `mapstructure:"force-short-decl-cuddling"` } +type WSLv5Settings struct { + AllowFirstInBlock bool `mapstructure:"allow-first-in-block"` + AllowWholeBlock bool `mapstructure:"allow-whole-block"` + BranchMaxLines int `mapstructure:"branch-max-lines"` + CaseMaxLines int `mapstructure:"case-max-lines"` + Default string `mapstructure:"default"` + Enable []string `mapstructure:"enable"` + Disable []string `mapstructure:"disable"` +} + // CustomLinterSettings encapsulates the meta-data of a private linter. type CustomLinterSettings struct { // Type plugin type. diff --git a/pkg/golinters/wsl/testdata/fix/in/wsl.go b/pkg/golinters/wsl/testdata/fix/in/wsl_v4.go similarity index 98% rename from pkg/golinters/wsl/testdata/fix/in/wsl.go rename to pkg/golinters/wsl/testdata/fix/in/wsl_v4.go index 9a1982004c2f..068695f3a8e1 100644 --- a/pkg/golinters/wsl/testdata/fix/in/wsl.go +++ b/pkg/golinters/wsl/testdata/fix/in/wsl_v4.go @@ -1,5 +1,5 @@ //golangcitest:args -Ewsl -//golangcitest:config_path testdata/wsl.yml +//golangcitest:config_path testdata/wsl_v4.yml //golangcitest:expected_exitcode 0 package testdata diff --git a/pkg/golinters/wsl/testdata/fix/in/wsl_v5.go b/pkg/golinters/wsl/testdata/fix/in/wsl_v5.go new file mode 100644 index 000000000000..60d782ec9430 --- /dev/null +++ b/pkg/golinters/wsl/testdata/fix/in/wsl_v5.go @@ -0,0 +1,78 @@ +//golangcitest:args -Ewsl_v5 +//golangcitest:expected_exitcode 0 +package testdata + +import ( + "bytes" + "encoding/json" +) + +type T struct { + I int +} + +func NewT() *T { + return &T{} +} + +func (*T) Fn() int { + return 1 +} + +func FnC(_ string, fn func() error) error { + fn() + return nil +} + +func strictAppend() { + s := []string{} + s = append(s, "a") + s = append(s, "b") + x := "c" + s = append(s, x) + y := "e" + s = append(s, "d") // want `missing whitespace above this line \(no shared variables above append\)` + s = append(s, y) +} + +func incDec() { + x := 1 + x++ + x-- + y := x + + _ = y +} + +func assignAndCall() { + t1 := NewT() + t2 := NewT() + + t1.Fn() + x := t1.Fn() + t1.Fn() + + _, _ = t2, x +} + +func closureInCall() { + buf := &bytes.Buffer{} + _ = FnC("buf", func() error { + return json.NewEncoder(buf).Encode("x") + }) +} + +func assignAfterBlock() { + x := 1 + if x > 0 { + return + } + x = 2 // want `missing whitespace above this line \(invalid statement above assign\)` +} + +func decl() { + var x string + y := "" // want `missing whitespace above this line \(invalid statement above assign\)` + + _, _ = x, y +} diff --git a/pkg/golinters/wsl/testdata/fix/out/wsl.go b/pkg/golinters/wsl/testdata/fix/out/wsl_v4.go similarity index 98% rename from pkg/golinters/wsl/testdata/fix/out/wsl.go rename to pkg/golinters/wsl/testdata/fix/out/wsl_v4.go index 68fc20f5f487..cabd8791b519 100644 --- a/pkg/golinters/wsl/testdata/fix/out/wsl.go +++ b/pkg/golinters/wsl/testdata/fix/out/wsl_v4.go @@ -1,5 +1,5 @@ //golangcitest:args -Ewsl -//golangcitest:config_path testdata/wsl.yml +//golangcitest:config_path testdata/wsl_v4.yml //golangcitest:expected_exitcode 0 package testdata diff --git a/pkg/golinters/wsl/testdata/fix/out/wsl_v5.go b/pkg/golinters/wsl/testdata/fix/out/wsl_v5.go new file mode 100644 index 000000000000..8681bdc41e95 --- /dev/null +++ b/pkg/golinters/wsl/testdata/fix/out/wsl_v5.go @@ -0,0 +1,81 @@ +//golangcitest:args -Ewsl_v5 +//golangcitest:expected_exitcode 0 +package testdata + +import ( + "bytes" + "encoding/json" +) + +type T struct { + I int +} + +func NewT() *T { + return &T{} +} + +func (*T) Fn() int { + return 1 +} + +func FnC(_ string, fn func() error) error { + fn() + return nil +} + +func strictAppend() { + s := []string{} + s = append(s, "a") + s = append(s, "b") + x := "c" + s = append(s, x) + y := "e" + + s = append(s, "d") // want `missing whitespace above this line \(no shared variables above append\)` + s = append(s, y) +} + +func incDec() { + x := 1 + x++ + x-- + y := x + + _ = y +} + +func assignAndCall() { + t1 := NewT() + t2 := NewT() + + t1.Fn() + x := t1.Fn() + t1.Fn() + + _, _ = t2, x +} + +func closureInCall() { + buf := &bytes.Buffer{} + _ = FnC("buf", func() error { + return json.NewEncoder(buf).Encode("x") + }) +} + +func assignAfterBlock() { + x := 1 + if x > 0 { + return + } + + x = 2 // want `missing whitespace above this line \(invalid statement above assign\)` +} + +func decl() { + var x string + + y := "" // want `missing whitespace above this line \(invalid statement above assign\)` + + _, _ = x, y +} diff --git a/pkg/golinters/wsl/testdata/wsl_cgo.go b/pkg/golinters/wsl/testdata/ws_v4_cgo.go similarity index 91% rename from pkg/golinters/wsl/testdata/wsl_cgo.go rename to pkg/golinters/wsl/testdata/ws_v4_cgo.go index aa4870e2f19d..09206c3fe068 100644 --- a/pkg/golinters/wsl/testdata/wsl_cgo.go +++ b/pkg/golinters/wsl/testdata/ws_v4_cgo.go @@ -3,7 +3,7 @@ // TODO(ldez) the linter doesn't support cgo. //golangcitest:args -Ewsl -//golangcitest:config_path testdata/wsl.yml +//golangcitest:config_path testdata/wsl_v4.yml package testdata /* diff --git a/pkg/golinters/wsl/testdata/wsl.go b/pkg/golinters/wsl/testdata/wsl_v4.go similarity index 98% rename from pkg/golinters/wsl/testdata/wsl.go rename to pkg/golinters/wsl/testdata/wsl_v4.go index e3b2a6066b3b..ddb49bcee4b8 100644 --- a/pkg/golinters/wsl/testdata/wsl.go +++ b/pkg/golinters/wsl/testdata/wsl_v4.go @@ -1,5 +1,5 @@ //golangcitest:args -Ewsl -//golangcitest:config_path testdata/wsl.yml +//golangcitest:config_path testdata/wsl_v4.yml package testdata import ( diff --git a/pkg/golinters/wsl/testdata/wsl.yml b/pkg/golinters/wsl/testdata/wsl_v4.yml similarity index 100% rename from pkg/golinters/wsl/testdata/wsl.yml rename to pkg/golinters/wsl/testdata/wsl_v4.yml diff --git a/pkg/golinters/wsl/testdata/wsl_v5.go b/pkg/golinters/wsl/testdata/wsl_v5.go new file mode 100644 index 000000000000..36c774f7ab59 --- /dev/null +++ b/pkg/golinters/wsl/testdata/wsl_v5.go @@ -0,0 +1,77 @@ +//golangcitest:args -Ewsl_v5 +package testdata + +import ( + "bytes" + "encoding/json" +) + +type T struct { + I int +} + +func NewT() *T { + return &T{} +} + +func (*T) Fn() int { + return 1 +} + +func FnC(_ string, fn func() error) error { + fn() + return nil +} + +func strictAppend() { + s := []string{} + s = append(s, "a") + s = append(s, "b") + x := "c" + s = append(s, x) + y := "e" + s = append(s, "d") // want `missing whitespace above this line \(no shared variables above append\)` + s = append(s, y) +} + +func incDec() { + x := 1 + x++ + x-- + y := x + + _ = y +} + +func assignAndCall() { + t1 := NewT() + t2 := NewT() + + t1.Fn() + x := t1.Fn() + t1.Fn() + + _, _ = t2, x +} + +func closureInCall() { + buf := &bytes.Buffer{} + _ = FnC("buf", func() error { + return json.NewEncoder(buf).Encode("x") + }) +} + +func assignAfterBlock() { + x := 1 + if x > 0 { + return + } + x = 2 // want `missing whitespace above this line \(invalid statement above assign\)` +} + +func decl() { + var x string + y := "" // want `missing whitespace above this line \(invalid statement above assign\)` + + _, _ = x, y +} diff --git a/pkg/golinters/wsl/testdata/wsl_v5_config.go b/pkg/golinters/wsl/testdata/wsl_v5_config.go new file mode 100644 index 000000000000..fa68c4336950 --- /dev/null +++ b/pkg/golinters/wsl/testdata/wsl_v5_config.go @@ -0,0 +1,13 @@ +//golangcitest:args -Ewsl_v5 +//golangcitest:config_path testdata/wsl_v5_config.yml +package testdata + +func fn1(s []string) { + a := "a" + s = append(s, a) // want `missing whitespace above this line \(invalid statement above assign\)` + + x := 1 + s = append(s, "s") // want `missing whitespace above this line \(invalid statement above assign\)` + + _ = x +} diff --git a/pkg/golinters/wsl/testdata/wsl_v5_config.yml b/pkg/golinters/wsl/testdata/wsl_v5_config.yml new file mode 100644 index 000000000000..cd875d452256 --- /dev/null +++ b/pkg/golinters/wsl/testdata/wsl_v5_config.yml @@ -0,0 +1,10 @@ +version: "2" + +linters: + settings: + wsl_v5: + allow-first-in-block: true + allow-whole-block: false + branch-max-lines: 2 + case-max-lines: 0 + default: all diff --git a/pkg/golinters/wsl/wsl.go b/pkg/golinters/wsl/wsl.go index c71706f5c1d3..11f0122def50 100644 --- a/pkg/golinters/wsl/wsl.go +++ b/pkg/golinters/wsl/wsl.go @@ -1,17 +1,18 @@ package wsl import ( - "github.com/bombsimon/wsl/v4" + wslv4 "github.com/bombsimon/wsl/v4" "github.com/golangci/golangci-lint/v2/pkg/config" "github.com/golangci/golangci-lint/v2/pkg/goanalysis" ) -func New(settings *config.WSLSettings) *goanalysis.Linter { - var conf *wsl.Configuration +// Deprecated: use NewV5 instead. +func NewV4(settings *config.WSLv4Settings) *goanalysis.Linter { + var conf *wslv4.Configuration if settings != nil { - conf = &wsl.Configuration{ + conf = &wslv4.Configuration{ StrictAppend: settings.StrictAppend, AllowAssignAndCallCuddle: settings.AllowAssignAndCallCuddle, AllowAssignAndAnythingCuddle: settings.AllowAssignAndAnythingCuddle, @@ -31,6 +32,6 @@ func New(settings *config.WSLSettings) *goanalysis.Linter { } return goanalysis. - NewLinterFromAnalyzer(wsl.NewAnalyzer(conf)). + NewLinterFromAnalyzer(wslv4.NewAnalyzer(conf)). WithLoadMode(goanalysis.LoadModeSyntax) } diff --git a/pkg/golinters/wsl/wsl_v5.go b/pkg/golinters/wsl/wsl_v5.go new file mode 100644 index 000000000000..cb7b2562830b --- /dev/null +++ b/pkg/golinters/wsl/wsl_v5.go @@ -0,0 +1,34 @@ +package wsl + +import ( + "github.com/bombsimon/wsl/v5" + + "github.com/golangci/golangci-lint/v2/pkg/config" + "github.com/golangci/golangci-lint/v2/pkg/goanalysis" + "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" +) + +func NewV5(settings *config.WSLv5Settings) *goanalysis.Linter { + var conf *wsl.Configuration + + if settings != nil { + checkSet, err := wsl.NewCheckSet(settings.Default, settings.Enable, settings.Disable) + if err != nil { + internal.LinterLogger.Fatalf("wsl: invalid check: %v", err) + } + + conf = &wsl.Configuration{ + IncludeGenerated: true, // force to true because golangci-lint already has a way to filter generated files. + AllowFirstInBlock: settings.AllowFirstInBlock, + AllowWholeBlock: settings.AllowWholeBlock, + BranchMaxLines: settings.BranchMaxLines, + CaseMaxLines: settings.CaseMaxLines, + Checks: checkSet, + } + } + + return goanalysis. + NewLinterFromAnalyzer(wsl.NewAnalyzer(conf)). + WithVersion(5). //nolint:mnd // It's the linter version. + WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 734aab63cd1c..60e0c6fb815f 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -691,11 +691,18 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithLoadForGoAnalysis(). WithURL("https://github.com/tomarrell/wrapcheck"), - linter.NewConfig(wsl.New(&cfg.Linters.Settings.WSL)). + linter.NewConfig(wsl.NewV4(&cfg.Linters.Settings.WSL)). + DeprecatedWarning("new major version.", "v2.2.0", "wsl_v5"). WithSince("v1.20.0"). WithAutoFix(). WithURL("https://github.com/bombsimon/wsl"), + linter.NewConfig(wsl.NewV5(&cfg.Linters.Settings.WSLv5)). + WithSince("v2.2.0"). + WithLoadForGoAnalysis(). + WithAutoFix(). + WithURL("https://github.com/bombsimon/wsl"), + linter.NewConfig(zerologlint.New()). WithSince("v1.53.0"). WithLoadForGoAnalysis().