diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index 9801a5c3ff87..8a4fc69e22b1 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -385,6 +385,11 @@ linters: ignore: - "0C0C" + embeddedstructfieldcheck: + # Checks that sync.Mutex and sync.RWMutex are not used as embedded fields. + # Default: false + forbid-mutex: true + errcheck: # Report about not checking of errors in type assertions: `a := b.(MyStruct)`. # Such cases aren't reported by default. diff --git a/go.mod b/go.mod index ca6b23a4880b..e654b3fbfed0 100644 --- a/go.mod +++ b/go.mod @@ -74,7 +74,7 @@ require ( github.com/ldez/usetesting v0.4.3 github.com/leonklingele/grouper v1.1.2 github.com/macabu/inamedparam v0.2.0 - github.com/manuelarte/embeddedstructfieldcheck v0.2.1 + github.com/manuelarte/embeddedstructfieldcheck v0.3.0 github.com/manuelarte/funcorder v0.5.0 github.com/maratori/testableexamples v1.0.0 github.com/maratori/testpackage v1.1.1 diff --git a/go.sum b/go.sum index 6c6f2bf9639b..37d1cda13c14 100644 --- a/go.sum +++ b/go.sum @@ -391,8 +391,8 @@ github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddB github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/manuelarte/embeddedstructfieldcheck v0.2.1 h1:oKexdVGs8Jy31IzOD/EMKfZmgogFhAaDbHb1o0qmA1Q= -github.com/manuelarte/embeddedstructfieldcheck v0.2.1/go.mod h1:LSo/IQpPfx1dXMcX4ibZCYA7Yy6ayZHIaOGM70+1Wy8= +github.com/manuelarte/embeddedstructfieldcheck v0.3.0 h1:VhGqK8gANDvFYDxQkjPbv7/gDJtsGU9k6qj/hC2hgso= +github.com/manuelarte/embeddedstructfieldcheck v0.3.0/go.mod h1:LSo/IQpPfx1dXMcX4ibZCYA7Yy6ayZHIaOGM70+1Wy8= github.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8= github.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= diff --git a/jsonschema/golangci.next.jsonschema.json b/jsonschema/golangci.next.jsonschema.json index e98d54dc4dc4..ef1c956ef1c4 100644 --- a/jsonschema/golangci.next.jsonschema.json +++ b/jsonschema/golangci.next.jsonschema.json @@ -1089,6 +1089,17 @@ } } }, + "embeddedstructfieldcheckSettings": { + "type": "object", + "additionalProperties": false, + "properties": { + "forbid-mutex": { + "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.", + "type": "boolean", + "default": false + } + } + }, "errcheckSettings": { "type": "object", "additionalProperties": false, @@ -4356,6 +4367,9 @@ "dupl": { "$ref": "#/definitions/settings/definitions/duplSettings" }, + "embeddedstructfieldcheck": { + "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings" + }, "errcheck": { "$ref": "#/definitions/settings/definitions/errcheckSettings" }, diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index cadb4a765914..2398186d3812 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -205,84 +205,85 @@ var defaultLintersSettings = LintersSettings{ type LintersSettings struct { FormatterSettings `mapstructure:"-"` - Asasalint AsasalintSettings `mapstructure:"asasalint"` - BiDiChk BiDiChkSettings `mapstructure:"bidichk"` - CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"` - Cyclop CyclopSettings `mapstructure:"cyclop"` - Decorder DecorderSettings `mapstructure:"decorder"` - Depguard DepGuardSettings `mapstructure:"depguard"` - Dogsled DogsledSettings `mapstructure:"dogsled"` - Dupl DuplSettings `mapstructure:"dupl"` - DupWord DupWordSettings `mapstructure:"dupword"` - Errcheck ErrcheckSettings `mapstructure:"errcheck"` - ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"` - ErrorLint ErrorLintSettings `mapstructure:"errorlint"` - Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"` - Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"` - Fatcontext FatcontextSettings `mapstructure:"fatcontext"` - Forbidigo ForbidigoSettings `mapstructure:"forbidigo"` - FuncOrder FuncOrderSettings `mapstructure:"funcorder"` - Funlen FunlenSettings `mapstructure:"funlen"` - GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"` - Gocognit GocognitSettings `mapstructure:"gocognit"` - GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"` - Goconst GoConstSettings `mapstructure:"goconst"` - Gocritic GoCriticSettings `mapstructure:"gocritic"` - Gocyclo GoCycloSettings `mapstructure:"gocyclo"` - Godot GodotSettings `mapstructure:"godot"` - Godox GodoxSettings `mapstructure:"godox"` - Goheader GoHeaderSettings `mapstructure:"goheader"` - GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"` - Gomodguard GoModGuardSettings `mapstructure:"gomodguard"` - Gosec GoSecSettings `mapstructure:"gosec"` - Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"` - Govet GovetSettings `mapstructure:"govet"` - Grouper GrouperSettings `mapstructure:"grouper"` - Iface IfaceSettings `mapstructure:"iface"` - ImportAs ImportAsSettings `mapstructure:"importas"` - Inamedparam INamedParamSettings `mapstructure:"inamedparam"` - InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"` - Ireturn IreturnSettings `mapstructure:"ireturn"` - Lll LllSettings `mapstructure:"lll"` - LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"` - MaintIdx MaintIdxSettings `mapstructure:"maintidx"` - Makezero MakezeroSettings `mapstructure:"makezero"` - Misspell MisspellSettings `mapstructure:"misspell"` - Mnd MndSettings `mapstructure:"mnd"` - MustTag MustTagSettings `mapstructure:"musttag"` - Nakedret NakedretSettings `mapstructure:"nakedret"` - Nestif NestifSettings `mapstructure:"nestif"` - NilNil NilNilSettings `mapstructure:"nilnil"` - Nlreturn NlreturnSettings `mapstructure:"nlreturn"` - NoLintLint NoLintLintSettings `mapstructure:"nolintlint"` - NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"` - ParallelTest ParallelTestSettings `mapstructure:"paralleltest"` - PerfSprint PerfSprintSettings `mapstructure:"perfsprint"` - Prealloc PreallocSettings `mapstructure:"prealloc"` - Predeclared PredeclaredSettings `mapstructure:"predeclared"` - Promlinter PromlinterSettings `mapstructure:"promlinter"` - ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"` - Reassign ReassignSettings `mapstructure:"reassign"` - Recvcheck RecvcheckSettings `mapstructure:"recvcheck"` - Revive ReviveSettings `mapstructure:"revive"` - RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"` - SlogLint SlogLintSettings `mapstructure:"sloglint"` - Spancheck SpancheckSettings `mapstructure:"spancheck"` - Staticcheck StaticCheckSettings `mapstructure:"staticcheck"` - TagAlign TagAlignSettings `mapstructure:"tagalign"` - Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"` - Testifylint TestifylintSettings `mapstructure:"testifylint"` - Testpackage TestpackageSettings `mapstructure:"testpackage"` - Thelper ThelperSettings `mapstructure:"thelper"` - Unconvert UnconvertSettings `mapstructure:"unconvert"` - Unparam UnparamSettings `mapstructure:"unparam"` - Unused UnusedSettings `mapstructure:"unused"` - UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"` - UseTesting UseTestingSettings `mapstructure:"usetesting"` - Varnamelen VarnamelenSettings `mapstructure:"varnamelen"` - Whitespace WhitespaceSettings `mapstructure:"whitespace"` - Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"` - WSL WSLSettings `mapstructure:"wsl"` + Asasalint AsasalintSettings `mapstructure:"asasalint"` + BiDiChk BiDiChkSettings `mapstructure:"bidichk"` + CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"` + Cyclop CyclopSettings `mapstructure:"cyclop"` + Decorder DecorderSettings `mapstructure:"decorder"` + Depguard DepGuardSettings `mapstructure:"depguard"` + Dogsled DogsledSettings `mapstructure:"dogsled"` + Dupl DuplSettings `mapstructure:"dupl"` + DupWord DupWordSettings `mapstructure:"dupword"` + EmbeddedStructFieldCheck EmbeddedStructFieldCheckSettings `mapstructure:"embeddedstructfieldcheck"` + Errcheck ErrcheckSettings `mapstructure:"errcheck"` + ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"` + ErrorLint ErrorLintSettings `mapstructure:"errorlint"` + Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"` + Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"` + Fatcontext FatcontextSettings `mapstructure:"fatcontext"` + Forbidigo ForbidigoSettings `mapstructure:"forbidigo"` + FuncOrder FuncOrderSettings `mapstructure:"funcorder"` + Funlen FunlenSettings `mapstructure:"funlen"` + GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"` + Gocognit GocognitSettings `mapstructure:"gocognit"` + GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"` + Goconst GoConstSettings `mapstructure:"goconst"` + Gocritic GoCriticSettings `mapstructure:"gocritic"` + Gocyclo GoCycloSettings `mapstructure:"gocyclo"` + Godot GodotSettings `mapstructure:"godot"` + Godox GodoxSettings `mapstructure:"godox"` + Goheader GoHeaderSettings `mapstructure:"goheader"` + GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"` + Gomodguard GoModGuardSettings `mapstructure:"gomodguard"` + Gosec GoSecSettings `mapstructure:"gosec"` + Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"` + Govet GovetSettings `mapstructure:"govet"` + Grouper GrouperSettings `mapstructure:"grouper"` + Iface IfaceSettings `mapstructure:"iface"` + ImportAs ImportAsSettings `mapstructure:"importas"` + Inamedparam INamedParamSettings `mapstructure:"inamedparam"` + InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"` + Ireturn IreturnSettings `mapstructure:"ireturn"` + Lll LllSettings `mapstructure:"lll"` + LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"` + MaintIdx MaintIdxSettings `mapstructure:"maintidx"` + Makezero MakezeroSettings `mapstructure:"makezero"` + Misspell MisspellSettings `mapstructure:"misspell"` + Mnd MndSettings `mapstructure:"mnd"` + MustTag MustTagSettings `mapstructure:"musttag"` + Nakedret NakedretSettings `mapstructure:"nakedret"` + Nestif NestifSettings `mapstructure:"nestif"` + NilNil NilNilSettings `mapstructure:"nilnil"` + Nlreturn NlreturnSettings `mapstructure:"nlreturn"` + NoLintLint NoLintLintSettings `mapstructure:"nolintlint"` + NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"` + ParallelTest ParallelTestSettings `mapstructure:"paralleltest"` + PerfSprint PerfSprintSettings `mapstructure:"perfsprint"` + Prealloc PreallocSettings `mapstructure:"prealloc"` + Predeclared PredeclaredSettings `mapstructure:"predeclared"` + Promlinter PromlinterSettings `mapstructure:"promlinter"` + ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"` + Reassign ReassignSettings `mapstructure:"reassign"` + Recvcheck RecvcheckSettings `mapstructure:"recvcheck"` + Revive ReviveSettings `mapstructure:"revive"` + RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"` + SlogLint SlogLintSettings `mapstructure:"sloglint"` + Spancheck SpancheckSettings `mapstructure:"spancheck"` + Staticcheck StaticCheckSettings `mapstructure:"staticcheck"` + TagAlign TagAlignSettings `mapstructure:"tagalign"` + Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"` + Testifylint TestifylintSettings `mapstructure:"testifylint"` + Testpackage TestpackageSettings `mapstructure:"testpackage"` + Thelper ThelperSettings `mapstructure:"thelper"` + Unconvert UnconvertSettings `mapstructure:"unconvert"` + Unparam UnparamSettings `mapstructure:"unparam"` + Unused UnusedSettings `mapstructure:"unused"` + UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"` + UseTesting UseTestingSettings `mapstructure:"usetesting"` + Varnamelen VarnamelenSettings `mapstructure:"varnamelen"` + Whitespace WhitespaceSettings `mapstructure:"whitespace"` + Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"` + WSL WSLSettings `mapstructure:"wsl"` Custom map[string]CustomLinterSettings `mapstructure:"custom"` } @@ -367,6 +368,10 @@ type DupWordSettings struct { Ignore []string `mapstructure:"ignore"` } +type EmbeddedStructFieldCheckSettings struct { + ForbidMutex bool `mapstructure:"forbid-mutex"` +} + type ErrcheckSettings struct { DisableDefaultExclusions bool `mapstructure:"disable-default-exclusions"` CheckTypeAssertions bool `mapstructure:"check-type-assertions"` diff --git a/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go b/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go index 0932ac4fed66..c9df5038c064 100644 --- a/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go +++ b/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go @@ -3,11 +3,21 @@ package embeddedstructfieldcheck import ( "github.com/manuelarte/embeddedstructfieldcheck/analyzer" + "github.com/golangci/golangci-lint/v2/pkg/config" "github.com/golangci/golangci-lint/v2/pkg/goanalysis" ) -func New() *goanalysis.Linter { +func New(settings *config.EmbeddedStructFieldCheckSettings) *goanalysis.Linter { + var cfg map[string]any + + if settings != nil { + cfg = map[string]any{ + analyzer.ForbidMutexName: settings.ForbidMutex, + } + } + return goanalysis. NewLinterFromAnalyzer(analyzer.NewAnalyzer()). + WithConfig(cfg). WithLoadMode(goanalysis.LoadModeSyntax) } diff --git a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_comments.go b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_comments.go index 12a6a4fa1ddf..8dd119ede62a 100644 --- a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_comments.go +++ b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_comments.go @@ -1,5 +1,5 @@ //golangcitest:args -Eembeddedstructfieldcheck -package simple +package testdata import "time" diff --git a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.go b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.go new file mode 100644 index 000000000000..e0a586ef6f02 --- /dev/null +++ b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.go @@ -0,0 +1,29 @@ +//golangcitest:args -Eembeddedstructfieldcheck +//golangcitest:config_path testdata/embeddedstructfieldcheck_mutex.yml +package testdata + +import "sync" + +type MutextEmbedded struct { + sync.Mutex // want `sync.Mutex should not be embedded` +} + +type MutextNotEmbedded struct { + mu sync.Mutex +} + +type PointerMutextEmbedded struct { + *sync.Mutex // want `sync.Mutex should not be embedded` +} + +type RWMutextEmbedded struct { + sync.RWMutex // want `sync.RWMutex should not be embedded` +} + +type RWMutextNotEmbedded struct { + mu sync.RWMutex +} + +type PointerRWMutextEmbedded struct { + *sync.RWMutex // want `sync.RWMutex should not be embedded` +} diff --git a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.yml b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.yml new file mode 100644 index 000000000000..ff5e68bc81e3 --- /dev/null +++ b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_mutex.yml @@ -0,0 +1,6 @@ +version: "2" + +linters: + settings: + embeddedstructfieldcheck: + forbid-mutex: true diff --git a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_simple.go b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_simple.go index 47b155e5f52a..da13d29c95f7 100644 --- a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_simple.go +++ b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_simple.go @@ -1,5 +1,5 @@ //golangcitest:args -Eembeddedstructfieldcheck -package simple +package testdata import ( "context" diff --git a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_special_cases.go b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_special_cases.go index 95b5356b5824..b9ae5f3e187c 100644 --- a/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_special_cases.go +++ b/pkg/golinters/embeddedstructfieldcheck/testdata/embeddedstructfieldcheck_special_cases.go @@ -1,5 +1,5 @@ //golangcitest:args -Eembeddedstructfieldcheck -package simple +package testdata import "time" diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 37f18bdc9eae..48a64375f53c 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -213,7 +213,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithLoadForGoAnalysis(). WithURL("https://github.com/charithe/durationcheck"), - linter.NewConfig(embeddedstructfieldcheck.New()). + linter.NewConfig(embeddedstructfieldcheck.New(&cfg.Linters.Settings.EmbeddedStructFieldCheck)). WithSince("v2.2.0"). WithURL("https://github.com/manuelarte/embeddedstructfieldcheck"),