Skip to content

Commit 7ad5ccb

Browse files
authored
dev: split ContextLoader (#4516)
1 parent 2c0a8ee commit 7ad5ccb

File tree

7 files changed

+335
-216
lines changed

7 files changed

+335
-216
lines changed

pkg/commands/run.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ type runCommand struct {
8787
debugf logutils.DebugFunc
8888
reportData *report.Data
8989

90-
contextLoader *lint.ContextLoader
91-
goenv *goutil.Env
90+
contextBuilder *lint.ContextBuilder
91+
goenv *goutil.Env
9292

9393
fileCache *fsutils.FileCache
9494
lineCache *fsutils.LineCache
@@ -182,7 +182,7 @@ func (c *runCommand) persistentPostRunE(_ *cobra.Command, _ []string) error {
182182
return nil
183183
}
184184

185-
func (c *runCommand) preRunE(_ *cobra.Command, _ []string) error {
185+
func (c *runCommand) preRunE(_ *cobra.Command, args []string) error {
186186
dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg,
187187
lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log))
188188
if err != nil {
@@ -210,8 +210,11 @@ func (c *runCommand) preRunE(_ *cobra.Command, _ []string) error {
210210
return fmt.Errorf("failed to build packages cache: %w", err)
211211
}
212212

213-
c.contextLoader = lint.NewContextLoader(c.cfg, c.log.Child(logutils.DebugKeyLoader), c.goenv,
214-
c.lineCache, c.fileCache, pkgCache, load.NewGuard())
213+
guard := load.NewGuard()
214+
215+
pkgLoader := lint.NewPackageLoader(c.log.Child(logutils.DebugKeyLoader), c.cfg, args, c.goenv, guard)
216+
217+
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, c.fileCache, pkgCache, guard)
215218

216219
if err = initHashSalt(c.buildInfo.Version, c.cfg); err != nil {
217220
return fmt.Errorf("failed to init hash salt: %w", err)
@@ -373,7 +376,7 @@ func (c *runCommand) runAnalysis(ctx context.Context, args []string) ([]result.I
373376
return nil, err
374377
}
375378

376-
lintCtx, err := c.contextLoader.Load(ctx, c.log.Child(logutils.DebugKeyLintersContext), lintersToRun)
379+
lintCtx, err := c.contextBuilder.Build(ctx, c.log.Child(logutils.DebugKeyLintersContext), lintersToRun)
377380
if err != nil {
378381
return nil, fmt.Errorf("context loading failed: %w", err)
379382
}

pkg/config/config.go

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func (c *Config) Validate() error {
3838
c.LintersSettings.Validate,
3939
c.Linters.Validate,
4040
c.Output.Validate,
41+
c.Run.Validate,
4142
}
4243

4344
for _, v := range validators {

pkg/config/run.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package config
22

3-
import "time"
3+
import (
4+
"fmt"
5+
"slices"
6+
"strings"
7+
"time"
8+
)
49

510
// Run encapsulates the config options for running the linter analysis.
611
type Run struct {
@@ -29,6 +34,17 @@ type Run struct {
2934
// Deprecated: use Output.ShowStats instead.
3035
ShowStats bool `mapstructure:"show-stats"`
3136

32-
// It's obtain by flags and use for the tests and the context loader.
37+
// Only used by skipDirs processor. TODO(ldez) remove it in next PR.
3338
Args []string // Internal needs.
3439
}
40+
41+
func (r *Run) Validate() error {
42+
// go help modules
43+
allowedMods := []string{"mod", "readonly", "vendor"}
44+
45+
if r.ModulesDownloadMode != "" && !slices.Contains(allowedMods, r.ModulesDownloadMode) {
46+
return fmt.Errorf("invalid modules download path %s, only (%s) allowed", r.ModulesDownloadMode, strings.Join(allowedMods, "|"))
47+
}
48+
49+
return nil
50+
}

pkg/config/run_test.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package config
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestRun_Validate(t *testing.T) {
10+
testCases := []struct {
11+
desc string
12+
settings *Run
13+
}{
14+
{
15+
desc: "modules-download-mode: mod",
16+
settings: &Run{
17+
ModulesDownloadMode: "mod",
18+
},
19+
},
20+
{
21+
desc: "modules-download-mode: readonly",
22+
settings: &Run{
23+
ModulesDownloadMode: "readonly",
24+
},
25+
},
26+
{
27+
desc: "modules-download-mode: vendor",
28+
settings: &Run{
29+
ModulesDownloadMode: "vendor",
30+
},
31+
},
32+
{
33+
desc: "modules-download-mode: empty",
34+
settings: &Run{
35+
ModulesDownloadMode: "",
36+
},
37+
},
38+
}
39+
40+
for _, test := range testCases {
41+
test := test
42+
t.Run(test.desc, func(t *testing.T) {
43+
t.Parallel()
44+
45+
err := test.settings.Validate()
46+
require.NoError(t, err)
47+
})
48+
}
49+
}
50+
51+
func TestRun_Validate_error(t *testing.T) {
52+
testCases := []struct {
53+
desc string
54+
settings *Run
55+
expected string
56+
}{
57+
{
58+
desc: "modules-download-mode: invalid",
59+
settings: &Run{
60+
ModulesDownloadMode: "invalid",
61+
},
62+
expected: "invalid modules download path invalid, only (mod|readonly|vendor) allowed",
63+
},
64+
}
65+
66+
for _, test := range testCases {
67+
test := test
68+
t.Run(test.desc, func(t *testing.T) {
69+
t.Parallel()
70+
71+
err := test.settings.Validate()
72+
require.EqualError(t, err, test.expected)
73+
})
74+
}
75+
}

pkg/lint/context.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package lint
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/golangci/golangci-lint/internal/pkgcache"
8+
"github.com/golangci/golangci-lint/pkg/config"
9+
"github.com/golangci/golangci-lint/pkg/exitcodes"
10+
"github.com/golangci/golangci-lint/pkg/fsutils"
11+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis/load"
12+
"github.com/golangci/golangci-lint/pkg/lint/linter"
13+
"github.com/golangci/golangci-lint/pkg/logutils"
14+
)
15+
16+
type ContextBuilder struct {
17+
cfg *config.Config
18+
19+
pkgLoader *PackageLoader
20+
21+
fileCache *fsutils.FileCache
22+
pkgCache *pkgcache.Cache
23+
24+
loadGuard *load.Guard
25+
}
26+
27+
func NewContextBuilder(cfg *config.Config, pkgLoader *PackageLoader,
28+
fileCache *fsutils.FileCache, pkgCache *pkgcache.Cache, loadGuard *load.Guard,
29+
) *ContextBuilder {
30+
return &ContextBuilder{
31+
cfg: cfg,
32+
pkgLoader: pkgLoader,
33+
fileCache: fileCache,
34+
pkgCache: pkgCache,
35+
loadGuard: loadGuard,
36+
}
37+
}
38+
39+
func (cl *ContextBuilder) Build(ctx context.Context, log logutils.Log, linters []*linter.Config) (*linter.Context, error) {
40+
pkgs, deduplicatedPkgs, err := cl.pkgLoader.Load(ctx, linters)
41+
if err != nil {
42+
return nil, fmt.Errorf("failed to load packages: %w", err)
43+
}
44+
45+
if len(deduplicatedPkgs) == 0 {
46+
return nil, exitcodes.ErrNoGoFiles
47+
}
48+
49+
ret := &linter.Context{
50+
Packages: deduplicatedPkgs,
51+
52+
// At least `unused` linters works properly only on original (not deduplicated) packages,
53+
// see https://github.com/golangci/golangci-lint/pull/585.
54+
OriginalPackages: pkgs,
55+
56+
Cfg: cl.cfg,
57+
Log: log,
58+
FileCache: cl.fileCache,
59+
PkgCache: cl.pkgCache,
60+
LoadGuard: cl.loadGuard,
61+
}
62+
63+
return ret, nil
64+
}

pkg/lint/linter/context.go

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ type Context struct {
2222

2323
Cfg *config.Config
2424
FileCache *fsutils.FileCache
25-
LineCache *fsutils.LineCache
2625
Log logutils.Log
2726

2827
PkgCache *pkgcache.Cache

0 commit comments

Comments
 (0)