From d8e22f1804fcb99fc70dfbb4f54b9de28a92ebc2 Mon Sep 17 00:00:00 2001 From: Katy Moe Date: Mon, 15 Jun 2020 18:54:49 +0100 Subject: [PATCH] add terraform version -json --- command/version.go | 80 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/command/version.go b/command/version.go index 2a3c1056a..321340b21 100644 --- a/command/version.go +++ b/command/version.go @@ -2,6 +2,7 @@ package command import ( "bytes" + "encoding/json" "fmt" "sort" ) @@ -16,6 +17,13 @@ type VersionCommand struct { CheckFunc VersionCheckFunc } +type VersionOutput struct { + Version string `json:"terraform_version"` + Revision string `json:"terraform_revision"` + ProviderSelections map[string]string `json:"provider_selections"` + Outdated bool `json:"terraform_outdated"` +} + // VersionCheckFunc is the callback called by the Version command to // check if there is a new version of Terraform. type VersionCheckFunc func() (VersionCheckInfo, error) @@ -34,8 +42,17 @@ func (c *VersionCommand) Help() string { } func (c *VersionCommand) Run(args []string) int { + var outdated bool var versionString bytes.Buffer args = c.Meta.process(args) + var jsonOutput bool + cmdFlags := c.Meta.defaultFlagSet("version") + cmdFlags.BoolVar(&jsonOutput, "json", false, "json") + if err := cmdFlags.Parse(args); err != nil { + c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error())) + return 1 + } + fmt.Fprintf(&versionString, "Terraform v%s", c.Version) if c.VersionPrerelease != "" { fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease) @@ -45,8 +62,6 @@ func (c *VersionCommand) Run(args []string) int { } } - c.Ui.Output(versionString.String()) - // We'll also attempt to print out the selected plugin versions. We can // do this only if "terraform init" was already run and thus we've committed // to a specific set of plugins. If not, the plugins lock will be empty @@ -70,31 +85,66 @@ func (c *VersionCommand) Run(args []string) int { pluginVersions = append(pluginVersions, fmt.Sprintf("+ provider %s v%s", providerAddr, version)) } } - if len(pluginVersions) != 0 { - sort.Strings(pluginVersions) - for _, str := range pluginVersions { - c.Ui.Output(str) - } - } - // If we have a version check function, then let's check for // the latest version as well. if c.CheckFunc != nil { - // Check the latest version info, err := c.CheckFunc() - if err != nil { + if err != nil && !jsonOutput { c.Ui.Error(fmt.Sprintf( "\nError checking latest version: %s", err)) } if info.Outdated { - c.Ui.Output(fmt.Sprintf( - "\nYour version of Terraform is out of date! The latest version\n"+ - "is %s. You can update by downloading from https://www.terraform.io/downloads.html", - info.Latest)) + outdated = true + if !jsonOutput { + c.Ui.Output(fmt.Sprintf( + "\nYour version of Terraform is out of date! The latest version\n"+ + "is %s. You can update by downloading from https://www.terraform.io/downloads.html", + info.Latest)) + } + } } + if jsonOutput { + selectionsOutput := make(map[string]string) + for providerAddr, cached := range providerSelections { + version := cached.Version.String() + selectionsOutput[providerAddr.String()] = version + } + + var versionOutput string + if c.VersionPrerelease != "" { + versionOutput = c.Version + "-" + c.VersionPrerelease + } else { + versionOutput = c.Version + } + + output := VersionOutput{ + Version: versionOutput, + Revision: c.Revision, + ProviderSelections: selectionsOutput, + Outdated: outdated, + } + + jsonOutput, err := json.MarshalIndent(output, "", " ") + if err != nil { + c.Ui.Error(fmt.Sprintf("\nError marshalling JSON: %s", err)) + return 1 + } + c.Ui.Output(string(jsonOutput)) + return 0 + } else { + c.Ui.Output(versionString.String()) + if len(pluginVersions) != 0 { + sort.Strings(pluginVersions) + for _, str := range pluginVersions { + c.Ui.Output(str) + } + } + + } + return 0 }