Skip to content

Commit 54db6c1

Browse files
authored
product: Use version json output (consul + terraform) (#276)
1 parent 58694f3 commit 54db6c1

File tree

2 files changed

+98
-34
lines changed

2 files changed

+98
-34
lines changed

product/consul.go

+49-17
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package product
55

66
import (
77
"context"
8+
"encoding/json"
89
"fmt"
910
"os/exec"
1011
"regexp"
@@ -26,29 +27,60 @@ var Consul = Product{
2627
return "consul"
2728
},
2829
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 := consulVersionOutputRe.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 := consulJsonVersion(ctx, path)
31+
if err == nil {
32+
return v, nil
4533
}
4634

47-
return v, err
35+
// JSON output was added in 1.9.0
36+
// See https://github.com/hashicorp/consul/pull/8268
37+
// We assume that error implies older version.
38+
return legacyConsulVersion(ctx, path)
4839
},
4940
BuildInstructions: &BuildInstructions{
5041
GitRepoURL: "https://github.com/hashicorp/consul.git",
5142
PreCloneCheck: &build.GoIsInstalled{},
5243
Build: &build.GoBuild{},
5344
},
5445
}
46+
47+
type consulJsonVersionOutput struct {
48+
Version *version.Version `json:"Version"`
49+
}
50+
51+
func consulJsonVersion(ctx context.Context, path string) (*version.Version, error) {
52+
cmd := exec.CommandContext(ctx, path, "version", "-format=json")
53+
out, err := cmd.CombinedOutput()
54+
if err != nil {
55+
return nil, err
56+
}
57+
58+
var vOut consulJsonVersionOutput
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 legacyConsulVersion(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 := consulVersionOutputRe.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+
}

product/terraform.go

+49-17
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package product
55

66
import (
77
"context"
8+
"encoding/json"
89
"fmt"
910
"os/exec"
1011
"regexp"
@@ -26,29 +27,60 @@ var Terraform = Product{
2627
return "terraform"
2728
},
2829
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
4533
}
4634

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)
4839
},
4940
BuildInstructions: &BuildInstructions{
5041
GitRepoURL: "https://github.com/hashicorp/terraform.git",
5142
PreCloneCheck: &build.GoIsInstalled{},
5243
Build: &build.GoBuild{DetectVendoring: true},
5344
},
5445
}
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

Comments
 (0)