diff --git a/.golangci.example.yml b/.golangci.example.yml index 2aa9c0e1..50a88a03 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -36,6 +36,16 @@ run: - ".*\\.my\\.go$" - lib/bad.go + # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": + # If invoked with -mod=readonly, the go command is disallowed from the implicit + # automatic updating of go.mod described above. Instead, it fails when any changes + # to go.mod are needed. This setting is most useful to check that go.mod does + # not need updates, such as in a continuous integration and testing system. + # If invoked with -mod=vendor, the go command assumes that the vendor + # directory holds the correct copies of dependencies and ignores + # the dependency descriptions in go.mod. + modules-download-mode: readonly|release|vendor + # output configuration options output: diff --git a/README.md b/README.md index 70271df3..024df052 100644 --- a/README.md +++ b/README.md @@ -432,7 +432,6 @@ Flags: --print-linter-name Print linter name in issue line (default true) --issues-exit-code int Exit code when issues were found (default 1) --build-tags strings Build tags - --mod string module download mode to use: readonly or vendor (passed to go list) --deadline duration Deadline for total work (default 1m0s) --tests Analyze tests (*_test.go) (default true) --print-resources-usage Print avg and max memory usage of golangci-lint and total time @@ -552,6 +551,16 @@ run: - ".*\\.my\\.go$" - lib/bad.go + # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": + # If invoked with -mod=readonly, the go command is disallowed from the implicit + # automatic updating of go.mod described above. Instead, it fails when any changes + # to go.mod are needed. This setting is most useful to check that go.mod does + # not need updates, such as in a continuous integration and testing system. + # If invoked with -mod=vendor, the go command assumes that the vendor + # directory holds the correct copies of dependencies and ignores + # the dependency descriptions in go.mod. + modules-download-mode: readonly|release|vendor + # output configuration options output: diff --git a/pkg/commands/run.go b/pkg/commands/run.go index dc893efe..46bfa29e 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -63,7 +63,6 @@ func initFlagSet(fs *pflag.FlagSet, cfg *config.Config, m *lintersdb.Manager) { fs.IntVar(&rc.ExitCodeIfIssuesFound, "issues-exit-code", exitcodes.IssuesFound, wh("Exit code when issues were found")) fs.StringSliceVar(&rc.BuildTags, "build-tags", nil, wh("Build tags")) - fs.StringVar(&rc.Mod, "mod", "", wh("module download mode to use: readonly or vendor (passed to go list)")) fs.DurationVar(&rc.Deadline, "deadline", time.Minute, wh("Deadline for total work")) fs.BoolVar(&rc.AnalyzeTests, "tests", true, wh("Analyze tests (*_test.go)")) fs.BoolVar(&rc.PrintResourcesUsage, "print-resources-usage", false, diff --git a/pkg/config/config.go b/pkg/config/config.go index 8ec2b077..3d1f28a8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -109,8 +109,8 @@ type Run struct { Args []string - BuildTags []string `mapstructure:"build-tags"` - Mod string `mapstructure:"mod"` + BuildTags []string `mapstructure:"build-tags"` + ModulesDownloadMode string `mapstructure:"modules-download-mode"` ExitCodeIfIssuesFound int `mapstructure:"issues-exit-code"` AnalyzeTests bool `mapstructure:"tests"` diff --git a/pkg/lint/load.go b/pkg/lint/load.go index f8cbb4aa..c3cc7217 100644 --- a/pkg/lint/load.go +++ b/pkg/lint/load.go @@ -193,6 +193,35 @@ func (cl ContextLoader) buildArgs() []string { return retArgs } +func (cl ContextLoader) makeBuildFlags() ([]string, error) { + var buildFlags []string + + if len(cl.cfg.Run.BuildTags) != 0 { + // go help build + buildFlags = append(buildFlags, "-tags", strings.Join(cl.cfg.Run.BuildTags, " ")) + } + + mod := cl.cfg.Run.ModulesDownloadMode + if mod != "" { + // go help modules + allowedMods := []string{"release", "readonly", "vendor"} + var ok bool + for _, am := range allowedMods { + if am == mod { + ok = true + break + } + } + if !ok { + return nil, fmt.Errorf("invalid modules download path %s, only (%s) allowed", mod, strings.Join(allowedMods, "|")) + } + + buildFlags = append(buildFlags, fmt.Sprintf("-mod=%s", cl.cfg.Run.ModulesDownloadMode)) + } + + return buildFlags, nil +} + func (cl ContextLoader) loadPackages(ctx context.Context, loadMode packages.LoadMode) ([]*packages.Package, error) { defer func(startedAt time.Time) { cl.log.Infof("Go packages loading at mode %s took %s", stringifyLoadMode(loadMode), time.Since(startedAt)) @@ -200,16 +229,9 @@ func (cl ContextLoader) loadPackages(ctx context.Context, loadMode packages.Load cl.prepareBuildContext() - var buildFlags []string - - if len(cl.cfg.Run.BuildTags) != 0 { - // go help build - buildFlags = []string{"-tags", strings.Join(cl.cfg.Run.BuildTags, " ")} - } - - if cl.cfg.Run.Mod != "" { - // go help module - buildFlags = append(buildFlags, fmt.Sprintf("-mod=%s", cl.cfg.Run.Mod)) + buildFlags, err := cl.makeBuildFlags() + if err != nil { + return nil, errors.Wrap(err, "failed to make build flags for go list") } conf := &packages.Config{