@@ -5,6 +5,7 @@ package product
5
5
6
6
import (
7
7
"context"
8
+ "encoding/json"
8
9
"fmt"
9
10
"os/exec"
10
11
"regexp"
@@ -26,29 +27,60 @@ var Terraform = Product{
26
27
return "terraform"
27
28
},
28
29
GetVersion : func (ctx context.Context , path string ) (* version.Version , error ) {
29
- cmd := exec .CommandContext (ctx , path , "version" )
30
-
31
- out , err := cmd .Output ()
32
- if err != nil {
33
- return nil , err
34
- }
35
-
36
- stdout := strings .TrimSpace (string (out ))
37
-
38
- submatches := terraformVersionOutputRe .FindStringSubmatch (stdout )
39
- if len (submatches ) != 2 {
40
- return nil , fmt .Errorf ("unexpected number of version matches %d for %s" , len (submatches ), stdout )
41
- }
42
- v , err := version .NewVersion (submatches [1 ])
43
- if err != nil {
44
- return nil , fmt .Errorf ("unable to parse version %q: %w" , submatches [1 ], err )
30
+ v , err := terraformJsonVersion (ctx , path )
31
+ if err == nil {
32
+ return v , nil
45
33
}
46
34
47
- return v , err
35
+ // JSON output was added in 0.13.0
36
+ // See https://github.com/hashicorp/terraform/pull/25252
37
+ // We assume that error implies older version.
38
+ return legacyTerraformVersion (ctx , path )
48
39
},
49
40
BuildInstructions : & BuildInstructions {
50
41
GitRepoURL : "https://github.com/hashicorp/terraform.git" ,
51
42
PreCloneCheck : & build.GoIsInstalled {},
52
43
Build : & build.GoBuild {DetectVendoring : true },
53
44
},
54
45
}
46
+
47
+ type terraformJsonVersionOutput struct {
48
+ Version * version.Version `json:"terraform_version"`
49
+ }
50
+
51
+ func terraformJsonVersion (ctx context.Context , path string ) (* version.Version , error ) {
52
+ cmd := exec .CommandContext (ctx , path , "version" , "-json" )
53
+ out , err := cmd .CombinedOutput ()
54
+ if err != nil {
55
+ return nil , err
56
+ }
57
+
58
+ var vOut terraformJsonVersionOutput
59
+ err = json .Unmarshal (out , & vOut )
60
+ if err != nil {
61
+ return nil , err
62
+ }
63
+
64
+ return vOut .Version , nil
65
+ }
66
+
67
+ func legacyTerraformVersion (ctx context.Context , path string ) (* version.Version , error ) {
68
+ cmd := exec .CommandContext (ctx , path , "version" )
69
+ out , err := cmd .Output ()
70
+ if err != nil {
71
+ return nil , err
72
+ }
73
+
74
+ stdout := strings .TrimSpace (string (out ))
75
+
76
+ submatches := terraformVersionOutputRe .FindStringSubmatch (stdout )
77
+ if len (submatches ) != 2 {
78
+ return nil , fmt .Errorf ("unexpected number of version matches %d for %s" , len (submatches ), stdout )
79
+ }
80
+ v , err := version .NewVersion (submatches [1 ])
81
+ if err != nil {
82
+ return nil , fmt .Errorf ("unable to parse version %q: %w" , submatches [1 ], err )
83
+ }
84
+
85
+ return v , err
86
+ }
0 commit comments