diff --git a/cmd/version.go b/cmd/version.go index a9e967cca..c4897452e 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,14 +1,19 @@ package cmd import ( + "encoding/json" "fmt" + "os" "github.com/anchore/syft/internal" + "github.com/anchore/syft/internal/version" + "github.com/anchore/syft/syft/presenter" "github.com/spf13/cobra" ) var showVerboseVersionInfo bool +var outputFormat string var versionCmd = &cobra.Command{ Use: "version", @@ -18,22 +23,44 @@ var versionCmd = &cobra.Command{ func init() { versionCmd.Flags().BoolVarP(&showVerboseVersionInfo, "verbose", "v", false, "show additional version information") - + versionCmd.Flags().StringVarP(&outputFormat, "output", "o", string(presenter.TextPresenter), "format to show version information (available=[text, json])") rootCmd.AddCommand(versionCmd) } func printVersion(_ *cobra.Command, _ []string) { versionInfo := version.FromBuild() - if showVerboseVersionInfo { - fmt.Println("Application: ", internal.ApplicationName) - fmt.Println("Version: ", versionInfo.Version) - fmt.Println("BuildDate: ", versionInfo.BuildDate) - fmt.Println("GitCommit: ", versionInfo.GitCommit) - fmt.Println("GitTreeState: ", versionInfo.GitTreeState) - fmt.Println("Platform: ", versionInfo.Platform) - fmt.Println("GoVersion: ", versionInfo.GoVersion) - fmt.Println("Compiler: ", versionInfo.Compiler) - } else { - fmt.Printf("%s %s\n", internal.ApplicationName, versionInfo.Version) + + switch outputFormat { + case "text": + if showVerboseVersionInfo { + fmt.Println("Application: ", internal.ApplicationName) + fmt.Println("Version: ", versionInfo.Version) + fmt.Println("BuildDate: ", versionInfo.BuildDate) + fmt.Println("GitCommit: ", versionInfo.GitCommit) + fmt.Println("GitTreeState: ", versionInfo.GitTreeState) + fmt.Println("Platform: ", versionInfo.Platform) + fmt.Println("GoVersion: ", versionInfo.GoVersion) + fmt.Println("Compiler: ", versionInfo.Compiler) + } else { + fmt.Printf("%s %s\n", internal.ApplicationName, versionInfo.Version) + } + case "json": + enc := json.NewEncoder(os.Stdout) + enc.SetEscapeHTML(false) + enc.SetIndent("", " ") + err := enc.Encode(&struct { + version.Version + Application string `json:"application"` + }{ + Version: versionInfo, + Application: internal.ApplicationName, + }) + if err != nil { + fmt.Printf("failed to show version information: %+v\n", err) + os.Exit(1) + } + default: + fmt.Printf("unsupported output format: %s\n", outputFormat) + os.Exit(1) } } diff --git a/internal/version/build.go b/internal/version/build.go index 139fa5539..e0c960228 100644 --- a/internal/version/build.go +++ b/internal/version/build.go @@ -16,13 +16,13 @@ var platform = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) // Version defines the application version details (generally from build information) type Version struct { - Version string // application semantic version - GitCommit string // git SHA at build-time - GitTreeState string // indication of git tree (either "clean" or "dirty") at build-time - BuildDate string // date of the build - GoVersion string // go runtime version at build-time - Compiler string // compiler used at build-time - Platform string // GOOS and GOARCH at build-time + Version string `json:"version"` // application semantic version + GitCommit string `json:"gitCommit"` // git SHA at build-time + GitTreeState string `json:"gitTreeState"` // indication of git tree (either "clean" or "dirty") at build-time + BuildDate string `json:"buildDate"` // date of the build + GoVersion string `json:"goVersion"` // go runtime version at build-time + Compiler string `json:"compiler"` // compiler used at build-time + Platform string `json:"platform"` // GOOS and GOARCH at build-time } // FromBuild provides all version details