From e5b30649e61619f86325dd7bf26397979e4ff7ce Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Thu, 2 Mar 2023 00:34:22 +0100 Subject: [PATCH] dev: add Go version to version information (#3625) --- cmd/golangci-lint/main.go | 22 ++++++++++++++- cmd/golangci-lint/mod_version.go | 17 ------------ pkg/commands/executor.go | 19 ++++++++----- pkg/commands/root.go | 4 +-- pkg/commands/version.go | 47 +++++++++++++++++++++++--------- pkg/config/config.go | 1 + 6 files changed, 70 insertions(+), 40 deletions(-) delete mode 100644 cmd/golangci-lint/mod_version.go diff --git a/cmd/golangci-lint/main.go b/cmd/golangci-lint/main.go index 282d794b..9d1daa81 100644 --- a/cmd/golangci-lint/main.go +++ b/cmd/golangci-lint/main.go @@ -3,12 +3,15 @@ package main import ( "fmt" "os" + "runtime/debug" "github.com/golangci/golangci-lint/pkg/commands" "github.com/golangci/golangci-lint/pkg/exitcodes" ) var ( + goVersion = "unknown" + // Populated by goreleaser during build version = "master" commit = "?" @@ -16,7 +19,24 @@ var ( ) func main() { - e := commands.NewExecutor(version, commit, date) + if buildInfo, available := debug.ReadBuildInfo(); available { + goVersion = buildInfo.GoVersion + + if date == "" { + version = buildInfo.Main.Version + commit = fmt.Sprintf("(unknown, mod sum: %q)", buildInfo.Main.Sum) + date = "(unknown)" + } + } + + info := commands.BuildInfo{ + GoVersion: goVersion, + Version: version, + Commit: commit, + Date: date, + } + + e := commands.NewExecutor(info) if err := e.Execute(); err != nil { fmt.Fprintf(os.Stderr, "failed executing command with error %v\n", err) diff --git a/cmd/golangci-lint/mod_version.go b/cmd/golangci-lint/mod_version.go deleted file mode 100644 index 119a8a60..00000000 --- a/cmd/golangci-lint/mod_version.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "fmt" - "runtime/debug" -) - -//nolint:gochecknoinits -func init() { - if info, available := debug.ReadBuildInfo(); available { - if date == "" { - version = info.Main.Version - commit = fmt.Sprintf("(unknown, mod sum: %q)", info.Main.Sum) - date = "(unknown)" - } - } -} diff --git a/pkg/commands/executor.go b/pkg/commands/executor.go index 347a0d19..109edcb9 100644 --- a/pkg/commands/executor.go +++ b/pkg/commands/executor.go @@ -30,13 +30,20 @@ import ( "github.com/golangci/golangci-lint/pkg/timeutils" ) +type BuildInfo struct { + GoVersion string `json:"goVersion"` + Version string `json:"version"` + Commit string `json:"commit"` + Date string `json:"date"` +} + type Executor struct { rootCmd *cobra.Command runCmd *cobra.Command lintersCmd *cobra.Command - exitCode int - version, commit, date string + exitCode int + buildInfo BuildInfo cfg *config.Config // cfg is the unmarshaled data from the golangci config file. log logutils.Log @@ -56,13 +63,11 @@ type Executor struct { } // NewExecutor creates and initializes a new command executor. -func NewExecutor(version, commit, date string) *Executor { +func NewExecutor(buildInfo BuildInfo) *Executor { startedAt := time.Now() e := &Executor{ cfg: config.NewDefault(), - version: version, - commit: commit, - date: date, + buildInfo: buildInfo, DBManager: lintersdb.NewManager(nil, nil), debugf: logutils.Debug(logutils.DebugKeyExec), } @@ -135,7 +140,7 @@ func NewExecutor(version, commit, date string) *Executor { e.loadGuard = load.NewGuard() e.contextLoader = lint.NewContextLoader(e.cfg, e.log.Child(logutils.DebugKeyLoader), e.goenv, e.lineCache, e.fileCache, e.pkgCache, e.loadGuard) - if err = e.initHashSalt(version); err != nil { + if err = e.initHashSalt(buildInfo.Version); err != nil { e.log.Fatalf("Failed to init hash salt: %s", err) } e.debugf("Initialized executor in %s", time.Since(startedAt)) diff --git a/pkg/commands/root.go b/pkg/commands/root.go index 0fdcccff..5fe4c784 100644 --- a/pkg/commands/root.go +++ b/pkg/commands/root.go @@ -24,7 +24,7 @@ const ( func (e *Executor) persistentPreRun(_ *cobra.Command, _ []string) error { if e.cfg.Run.PrintVersion { - _, _ = fmt.Fprintf(logutils.StdOut, "golangci-lint has version %s built from %s on %s\n", e.version, e.commit, e.date) + _ = printVersion(logutils.StdOut, e.buildInfo) os.Exit(exitcodes.Success) // a return nil is not enough to stop the process because we are inside the `preRun`. } @@ -145,7 +145,7 @@ func (e *Executor) initRoot() { } func (e *Executor) needVersionOption() bool { - return e.date != "" + return e.buildInfo.Date != "" } func initRootFlagSet(fs *pflag.FlagSet, cfg *config.Config, needVersionOption bool) { diff --git a/pkg/commands/version.go b/pkg/commands/version.go index 93e4a8ed..bb773225 100644 --- a/pkg/commands/version.go +++ b/pkg/commands/version.go @@ -3,7 +3,9 @@ package commands import ( "encoding/json" "fmt" + "io" "os" + "runtime/debug" "strings" "github.com/spf13/cobra" @@ -12,10 +14,9 @@ import ( "github.com/golangci/golangci-lint/pkg/config" ) -type jsonVersion struct { - Version string `json:"version"` - Commit string `json:"commit"` - Date string `json:"date"` +type versionInfo struct { + Info BuildInfo + BuildInfo *debug.BuildInfo } func (e *Executor) initVersionConfiguration(cmd *cobra.Command) { @@ -28,6 +29,7 @@ func initVersionFlagSet(fs *pflag.FlagSet, cfg *config.Config) { // Version config vc := &cfg.Version fs.StringVar(&vc.Format, "format", "", wh("The version's format can be: 'short', 'json'")) + fs.BoolVar(&vc.Debug, "debug", false, wh("Add build information")) } func (e *Executor) initVersion() { @@ -37,22 +39,35 @@ func (e *Executor) initVersion() { Args: cobra.NoArgs, ValidArgsFunction: cobra.NoFileCompletions, RunE: func(cmd *cobra.Command, _ []string) error { + if e.cfg.Version.Debug { + info, ok := debug.ReadBuildInfo() + if !ok { + return nil + } + + switch strings.ToLower(e.cfg.Version.Format) { + case "json": + return json.NewEncoder(os.Stdout).Encode(versionInfo{ + Info: e.buildInfo, + BuildInfo: info, + }) + + default: + fmt.Println(info.String()) + return printVersion(os.Stdout, e.buildInfo) + } + } + switch strings.ToLower(e.cfg.Version.Format) { case "short": - fmt.Println(e.version) + fmt.Println(e.buildInfo.Version) return nil case "json": - ver := jsonVersion{ - Version: e.version, - Commit: e.commit, - Date: e.date, - } - return json.NewEncoder(os.Stdout).Encode(&ver) + return json.NewEncoder(os.Stdout).Encode(e.buildInfo) default: - fmt.Printf("golangci-lint has version %s built from %s on %s\n", e.version, e.commit, e.date) - return nil + return printVersion(os.Stdout, e.buildInfo) } }, } @@ -60,3 +75,9 @@ func (e *Executor) initVersion() { e.rootCmd.AddCommand(versionCmd) e.initVersionConfiguration(versionCmd) } + +func printVersion(w io.Writer, buildInfo BuildInfo) error { + _, err := fmt.Fprintf(w, "golangci-lint has version %s built with %s from %s on %s\n", + buildInfo.Version, buildInfo.GoVersion, buildInfo.Commit, buildInfo.Date) + return err +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 9536c80c..af40c63b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -38,6 +38,7 @@ func NewDefault() *Config { type Version struct { Format string `mapstructure:"format"` + Debug bool `mapstructure:"debug"` } func IsGreaterThanOrEqualGo118(v string) bool {