@@ -2,6 +2,7 @@ package command
22
33import (
44 "bytes"
5+ "encoding/json"
56 "fmt"
67 "sort"
78)
@@ -16,6 +17,13 @@ type VersionCommand struct {
1617 CheckFunc VersionCheckFunc
1718}
1819
20+ type VersionOutput struct {
21+ Version string `json:"terraform_version"`
22+ VersionPrerelease string `json:"terraform_version_prerelease"`
23+ Revision string `json:"terraform_revision"`
24+ ProviderSelections map [string ]string `json:"provider_selections"`
25+ }
26+
1927// VersionCheckFunc is the callback called by the Version command to
2028// check if there is a new version of Terraform.
2129type VersionCheckFunc func () (VersionCheckInfo , error )
@@ -36,6 +44,14 @@ func (c *VersionCommand) Help() string {
3644func (c * VersionCommand ) Run (args []string ) int {
3745 var versionString bytes.Buffer
3846 args = c .Meta .process (args )
47+ var jsonOutput bool
48+ cmdFlags := c .Meta .defaultFlagSet ("version" )
49+ cmdFlags .BoolVar (& jsonOutput , "json" , false , "json" )
50+ if err := cmdFlags .Parse (args ); err != nil {
51+ c .Ui .Error (fmt .Sprintf ("Error parsing command-line flags: %s\n " , err .Error ()))
52+ return 1
53+ }
54+
3955 fmt .Fprintf (& versionString , "Terraform v%s" , c .Version )
4056 if c .VersionPrerelease != "" {
4157 fmt .Fprintf (& versionString , "-%s" , c .VersionPrerelease )
@@ -45,8 +61,6 @@ func (c *VersionCommand) Run(args []string) int {
4561 }
4662 }
4763
48- c .Ui .Output (versionString .String ())
49-
5064 // We'll also attempt to print out the selected plugin versions. We can
5165 // do this only if "terraform init" was already run and thus we've committed
5266 // to a specific set of plugins. If not, the plugins lock will be empty
@@ -70,28 +84,52 @@ func (c *VersionCommand) Run(args []string) int {
7084 pluginVersions = append (pluginVersions , fmt .Sprintf ("+ provider %s v%s" , providerAddr , version ))
7185 }
7286 }
73- if len (pluginVersions ) != 0 {
74- sort .Strings (pluginVersions )
75- for _ , str := range pluginVersions {
76- c .Ui .Output (str )
87+
88+ if jsonOutput {
89+ selectionsOutput := make (map [string ]string )
90+ for providerAddr , cached := range providerSelections {
91+ version := cached .Version .String ()
92+ selectionsOutput [providerAddr .String ()] = version
7793 }
78- }
7994
80- // If we have a version check function, then let's check for
81- // the latest version as well.
82- if c .CheckFunc != nil {
95+ output := VersionOutput {
96+ Version : c .Version ,
97+ VersionPrerelease : c .VersionPrerelease ,
98+ Revision : c .Revision ,
99+ ProviderSelections : selectionsOutput ,
100+ }
83101
84- // Check the latest version
85- info , err := c .CheckFunc ()
102+ jsonOutput , err := json .MarshalIndent (output , "" , " " )
86103 if err != nil {
87- c .Ui .Error (fmt .Sprintf (
88- " \n Error checking latest version: %s" , err ))
104+ c .Ui .Error (fmt .Sprintf (" \n Error marshalling JSON: %s" , err ))
105+ return 1
89106 }
90- if info .Outdated {
91- c .Ui .Output (fmt .Sprintf (
92- "\n Your version of Terraform is out of date! The latest version\n " +
93- "is %s. You can update by downloading from https://www.terraform.io/downloads.html" ,
94- info .Latest ))
107+ c .Ui .Output (string (jsonOutput ))
108+ return 0
109+ } else {
110+ c .Ui .Output (versionString .String ())
111+ if len (pluginVersions ) != 0 {
112+ sort .Strings (pluginVersions )
113+ for _ , str := range pluginVersions {
114+ c .Ui .Output (str )
115+ }
116+ }
117+ // If we have a version check function, then let's check for
118+ // the latest version as well.
119+ if c .CheckFunc != nil {
120+
121+ // Check the latest version
122+ info , err := c .CheckFunc ()
123+ if err != nil {
124+ c .Ui .Error (fmt .Sprintf (
125+ "\n Error checking latest version: %s" , err ))
126+ }
127+ if info .Outdated {
128+ c .Ui .Output (fmt .Sprintf (
129+ "\n Your version of Terraform is out of date! The latest version\n " +
130+ "is %s. You can update by downloading from https://www.terraform.io/downloads.html" ,
131+ info .Latest ))
132+ }
95133 }
96134 }
97135
0 commit comments