Skip to content

Commit 79c78d6

Browse files
authored
feat: explain typecheck and remove it from the linter list (#3929)
1 parent a303529 commit 79c78d6

File tree

13 files changed

+96
-19
lines changed

13 files changed

+96
-19
lines changed

docs/src/docs/usage/faq.mdx

+19
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,22 @@ The same as the Go team (the 2 last minor versions)
3232

3333
Because the first run caches type information. All subsequent runs will be fast.
3434
Usually this options is used during development on local machine and compilation was already performed.
35+
36+
## Why do you have `typecheck` errors?
37+
38+
`typecheck` is like the front-end of a Go compiler, parses and type-checks Go code, it manages compilation errors.
39+
40+
It cannot be disabled because of that.
41+
42+
Of course, this is just as good as the compiler itself and a lot of compilation issues will not properly show where in the code your error lies.
43+
44+
`typecheck` is not a real linter, it's just a way to parse compiling errors (produced by the `types.Checker`) and some linter errors.
45+
46+
If there are `typecheck` errors, golangci-lint will not able to produce other reports because that kind of error doesn't allow it to perform analysis.
47+
48+
How to troubleshoot:
49+
50+
- [ ] Ensure the version of `golangci-lint` is built with a compatible version of Go.
51+
- [ ] Ensure dependencies are up-to-date with `go mod tidy`.
52+
- [ ] Ensure building works with `go run ./...`/`go build ./...` - whole package.
53+
- [ ] If using CGO, ensure all require system libraries are installed.

pkg/commands/help.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func printLinterConfigs(lcs []*linter.Config) {
6363
func (e *Executor) executeLintersHelp(_ *cobra.Command, _ []string) {
6464
var enabledLCs, disabledLCs []*linter.Config
6565
for _, lc := range e.DBManager.GetAllSupportedLinterConfigs() {
66+
if lc.Internal {
67+
continue
68+
}
69+
6670
if lc.EnabledByDefault {
6771
enabledLCs = append(enabledLCs, lc)
6872
} else {
@@ -78,8 +82,12 @@ func (e *Executor) executeLintersHelp(_ *cobra.Command, _ []string) {
7882
color.Green("\nLinters presets:")
7983
for _, p := range e.DBManager.AllPresets() {
8084
linters := e.DBManager.GetAllLinterConfigsForPreset(p)
81-
linterNames := make([]string, 0, len(linters))
85+
var linterNames []string
8286
for _, lc := range linters {
87+
if lc.Internal {
88+
continue
89+
}
90+
8391
linterNames = append(linterNames, lc.Name())
8492
}
8593
sort.Strings(linterNames)

pkg/commands/linters.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,22 @@ func (e *Executor) executeLinters(_ *cobra.Command, _ []string) error {
2929
}
3030

3131
color.Green("Enabled by your configuration linters:\n")
32-
enabledLinters := make([]*linter.Config, 0, len(enabledLintersMap))
33-
for _, linter := range enabledLintersMap {
34-
enabledLinters = append(enabledLinters, linter)
32+
var enabledLinters []*linter.Config
33+
for _, lc := range enabledLintersMap {
34+
if lc.Internal {
35+
continue
36+
}
37+
38+
enabledLinters = append(enabledLinters, lc)
3539
}
3640
printLinterConfigs(enabledLinters)
3741

3842
var disabledLCs []*linter.Config
3943
for _, lc := range e.DBManager.GetAllSupportedLinterConfigs() {
44+
if lc.Internal {
45+
continue
46+
}
47+
4048
if enabledLintersMap[lc.Name()] == nil {
4149
disabledLCs = append(disabledLCs, lc)
4250
}

pkg/lint/linter/config.go

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type Config struct {
4242
AlternativeNames []string
4343

4444
OriginalURL string // URL of original (not forked) repo, needed for autogenerated README
45+
Internal bool // Internal linters cannot be disabled (ex: typecheck).
4546
CanAutoFix bool
4647
IsSlow bool
4748
DoesChangeTypes bool
@@ -55,6 +56,11 @@ func (lc *Config) WithEnabledByDefault() *Config {
5556
return lc
5657
}
5758

59+
func (lc *Config) WithInternal() *Config {
60+
lc.Internal = true
61+
return lc
62+
}
63+
5864
func (lc *Config) ConsiderSlow() *Config {
5965
lc.IsSlow = true
6066
return lc

pkg/lint/lintersdb/enabled_set.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ func NewEnabledSet(m *Manager, v *Validator, log logutils.Log, cfg *config.Confi
3131
}
3232
}
3333

34+
//nolint:gocyclo // the complexity cannot be reduced.
3435
func (es EnabledSet) build(lcfg *config.Linters, enabledByDefaultLinters []*linter.Config) map[string]*linter.Config {
3536
es.debugf("Linters config: %#v", lcfg)
37+
3638
resultLintersSet := map[string]*linter.Config{}
3739
switch {
3840
case len(lcfg.Presets) != 0:
@@ -78,6 +80,14 @@ func (es EnabledSet) build(lcfg *config.Linters, enabledByDefaultLinters []*lint
7880
}
7981
}
8082

83+
// typecheck is not a real linter and cannot be disabled.
84+
if _, ok := resultLintersSet["typecheck"]; !ok && (es.cfg == nil || !es.cfg.InternalCmdTest) {
85+
for _, lc := range es.m.GetLinterConfigs("typecheck") {
86+
// it's important to use lc.Name() nor name because name can be alias
87+
resultLintersSet[lc.Name()] = lc
88+
}
89+
}
90+
8191
return resultLintersSet
8292
}
8393

@@ -134,8 +144,8 @@ func (es EnabledSet) GetOptimizedLinters() ([]*linter.Config, error) {
134144
func (es EnabledSet) combineGoAnalysisLinters(linters map[string]*linter.Config) {
135145
var goanalysisLinters []*goanalysis.Linter
136146
goanalysisPresets := map[string]bool{}
137-
for _, linter := range linters {
138-
lnt, ok := linter.Linter.(*goanalysis.Linter)
147+
for _, lc := range linters {
148+
lnt, ok := lc.Linter.(*goanalysis.Linter)
139149
if !ok {
140150
continue
141151
}
@@ -144,7 +154,7 @@ func (es EnabledSet) combineGoAnalysisLinters(linters map[string]*linter.Config)
144154
continue
145155
}
146156
goanalysisLinters = append(goanalysisLinters, lnt)
147-
for _, p := range linter.InPresets {
157+
for _, p := range lc.InPresets {
148158
goanalysisPresets[p] = true
149159
}
150160
}
@@ -197,6 +207,10 @@ func (es EnabledSet) combineGoAnalysisLinters(linters map[string]*linter.Config)
197207
func (es EnabledSet) verbosePrintLintersStatus(lcs map[string]*linter.Config) {
198208
var linterNames []string
199209
for _, lc := range lcs {
210+
if lc.Internal {
211+
continue
212+
}
213+
200214
linterNames = append(linterNames, lc.Name())
201215
}
202216
sort.StringSlice(linterNames).Sort()

pkg/lint/lintersdb/enabled_set_test.go

+14-9
Original file line numberDiff line numberDiff line change
@@ -16,81 +16,86 @@ func TestGetEnabledLintersSet(t *testing.T) {
1616
def []string // enabled by default linters
1717
exp []string // alphabetically ordered enabled linter names
1818
}
19+
1920
allMegacheckLinterNames := []string{"gosimple", "staticcheck", "unused"}
21+
2022
cases := []cs{
2123
{
2224
cfg: config.Linters{
2325
Disable: []string{"megacheck"},
2426
},
2527
name: "disable all linters from megacheck",
2628
def: allMegacheckLinterNames,
27-
exp: nil, // all disabled
29+
exp: []string{"typecheck"}, // all disabled
2830
},
2931
{
3032
cfg: config.Linters{
3133
Disable: []string{"staticcheck"},
3234
},
3335
name: "disable only staticcheck",
3436
def: allMegacheckLinterNames,
35-
exp: []string{"gosimple", "unused"},
37+
exp: []string{"gosimple", "typecheck", "unused"},
3638
},
3739
{
3840
name: "don't merge into megacheck",
3941
def: allMegacheckLinterNames,
40-
exp: allMegacheckLinterNames,
42+
exp: []string{"gosimple", "staticcheck", "typecheck", "unused"},
4143
},
4244
{
4345
name: "expand megacheck",
4446
cfg: config.Linters{
4547
Enable: []string{"megacheck"},
4648
},
4749
def: nil,
48-
exp: allMegacheckLinterNames,
50+
exp: []string{"gosimple", "staticcheck", "typecheck", "unused"},
4951
},
5052
{
5153
name: "don't disable anything",
52-
def: []string{"gofmt", "govet"},
53-
exp: []string{"gofmt", "govet"},
54+
def: []string{"gofmt", "govet", "typecheck"},
55+
exp: []string{"gofmt", "govet", "typecheck"},
5456
},
5557
{
5658
name: "enable gosec by gas alias",
5759
cfg: config.Linters{
5860
Enable: []string{"gas"},
5961
},
60-
exp: []string{"gosec"},
62+
exp: []string{"gosec", "typecheck"},
6163
},
6264
{
6365
name: "enable gosec by primary name",
6466
cfg: config.Linters{
6567
Enable: []string{"gosec"},
6668
},
67-
exp: []string{"gosec"},
69+
exp: []string{"gosec", "typecheck"},
6870
},
6971
{
7072
name: "enable gosec by both names",
7173
cfg: config.Linters{
7274
Enable: []string{"gosec", "gas"},
7375
},
74-
exp: []string{"gosec"},
76+
exp: []string{"gosec", "typecheck"},
7577
},
7678
{
7779
name: "disable gosec by gas alias",
7880
cfg: config.Linters{
7981
Disable: []string{"gas"},
8082
},
8183
def: []string{"gosec"},
84+
exp: []string{"typecheck"},
8285
},
8386
{
8487
name: "disable gosec by primary name",
8588
cfg: config.Linters{
8689
Disable: []string{"gosec"},
8790
},
8891
def: []string{"gosec"},
92+
exp: []string{"typecheck"},
8993
},
9094
}
9195

9296
m := NewManager(nil, nil)
9397
es := NewEnabledSet(m, NewValidator(m), nil, nil)
98+
9499
for _, c := range cases {
95100
c := c
96101
t.Run(c.name, func(t *testing.T) {

pkg/lint/lintersdb/manager.go

+1
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
804804
WithURL("https://github.com/moricho/tparallel"),
805805

806806
linter.NewConfig(golinters.NewTypecheck()).
807+
WithInternal().
807808
WithEnabledByDefault().
808809
WithSince("v1.3.0").
809810
WithLoadForGoAnalysis().

pkg/result/processors/nolint_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,15 @@ func TestNolintUnused(t *testing.T) {
279279
createProcessor := func(t *testing.T, log *logutils.MockLog, enabledLinters []string) *Nolint {
280280
enabledSetLog := logutils.NewMockLog()
281281
enabledSetLog.On("Infof", "Active %d linters: %s", len(enabledLinters), enabledLinters)
282+
282283
cfg := &config.Config{Linters: config.Linters{DisableAll: true, Enable: enabledLinters}}
283284
dbManager := lintersdb.NewManager(cfg, nil)
285+
284286
enabledLintersSet := lintersdb.NewEnabledSet(dbManager, lintersdb.NewValidator(dbManager), enabledSetLog, cfg)
287+
285288
enabledLintersMap, err := enabledLintersSet.GetEnabledLintersMap()
286289
assert.NoError(t, err)
290+
287291
return NewNolint(log, dbManager, enabledLintersMap)
288292
}
289293

scripts/expand_website_templates/main.go

+4
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ func getLintersListMarkdown(enabled bool) string {
238238
var neededLcs []*linter.Config
239239
lcs := lintersdb.NewManager(nil, nil).GetAllSupportedLinterConfigs()
240240
for _, lc := range lcs {
241+
if lc.Internal {
242+
continue
243+
}
244+
241245
if lc.EnabledByDefault == enabled {
242246
neededLcs = append(neededLcs, lc)
243247
}

test/enabled_linters_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ func getEnabledByDefaultLinters() []string {
170170
ebdl := lintersdb.NewManager(nil, nil).GetAllEnabledByDefaultLinters()
171171
var ret []string
172172
for _, lc := range ebdl {
173+
if lc.Internal {
174+
continue
175+
}
176+
173177
ret = append(ret, lc.Name())
174178
}
175179

test/run_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func TestLineDirective(t *testing.T) {
243243
},
244244
configPath: "testdata/linedirective/gomodguard.yml",
245245
targetPath: "linedirective",
246-
expected: "import of package `github.com/ryancurrah/gomodguard` is blocked because the module is not " +
246+
expected: "import of package `golang.org/x/tools/go/analysis` is blocked because the module is not " +
247247
"in the allowed modules list. (gomodguard)",
248248
},
249249
{

test/testdata/linedirective/gomodguard.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ linters-settings:
22
gomodguard:
33
allowed:
44
domains:
5-
- golang.org
5+
- github.com

test/testdata/linedirective/hello.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
package main
44

55
import (
6-
"github.com/ryancurrah/gomodguard"
6+
"golang.org/x/tools/go/analysis"
77
)
88

99
func _() {
@@ -26,6 +26,10 @@ func b() {
2626
fmt.Println("foo")
2727
}
2828

29+
func c(){
30+
_ = analysis.Analyzer{}
31+
}
32+
2933
func wsl() bool {
3034

3135
return true

0 commit comments

Comments
 (0)