Skip to content

Commit

Permalink
product: Use version json output (consul + terraform) (#276)
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko authored Jan 9, 2025
1 parent 58694f3 commit 54db6c1
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 34 deletions.
66 changes: 49 additions & 17 deletions product/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package product

import (
"context"
"encoding/json"
"fmt"
"os/exec"
"regexp"
Expand All @@ -26,29 +27,60 @@ var Consul = Product{
return "consul"
},
GetVersion: func(ctx context.Context, path string) (*version.Version, error) {
cmd := exec.CommandContext(ctx, path, "version")

out, err := cmd.Output()
if err != nil {
return nil, err
}

stdout := strings.TrimSpace(string(out))

submatches := consulVersionOutputRe.FindStringSubmatch(stdout)
if len(submatches) != 2 {
return nil, fmt.Errorf("unexpected number of version matches %d for %s", len(submatches), stdout)
}
v, err := version.NewVersion(submatches[1])
if err != nil {
return nil, fmt.Errorf("unable to parse version %q: %w", submatches[1], err)
v, err := consulJsonVersion(ctx, path)
if err == nil {
return v, nil
}

return v, err
// JSON output was added in 1.9.0
// See https://github.com/hashicorp/consul/pull/8268
// We assume that error implies older version.
return legacyConsulVersion(ctx, path)
},
BuildInstructions: &BuildInstructions{
GitRepoURL: "https://github.com/hashicorp/consul.git",
PreCloneCheck: &build.GoIsInstalled{},
Build: &build.GoBuild{},
},
}

type consulJsonVersionOutput struct {
Version *version.Version `json:"Version"`
}

func consulJsonVersion(ctx context.Context, path string) (*version.Version, error) {
cmd := exec.CommandContext(ctx, path, "version", "-format=json")
out, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}

var vOut consulJsonVersionOutput
err = json.Unmarshal(out, &vOut)
if err != nil {
return nil, err
}

return vOut.Version, nil
}

func legacyConsulVersion(ctx context.Context, path string) (*version.Version, error) {
cmd := exec.CommandContext(ctx, path, "version")
out, err := cmd.Output()
if err != nil {
return nil, err
}

stdout := strings.TrimSpace(string(out))

submatches := consulVersionOutputRe.FindStringSubmatch(stdout)
if len(submatches) != 2 {
return nil, fmt.Errorf("unexpected number of version matches %d for %s", len(submatches), stdout)
}
v, err := version.NewVersion(submatches[1])
if err != nil {
return nil, fmt.Errorf("unable to parse version %q: %w", submatches[1], err)
}

return v, err
}
66 changes: 49 additions & 17 deletions product/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package product

import (
"context"
"encoding/json"
"fmt"
"os/exec"
"regexp"
Expand All @@ -26,29 +27,60 @@ var Terraform = Product{
return "terraform"
},
GetVersion: func(ctx context.Context, path string) (*version.Version, error) {
cmd := exec.CommandContext(ctx, path, "version")

out, err := cmd.Output()
if err != nil {
return nil, err
}

stdout := strings.TrimSpace(string(out))

submatches := terraformVersionOutputRe.FindStringSubmatch(stdout)
if len(submatches) != 2 {
return nil, fmt.Errorf("unexpected number of version matches %d for %s", len(submatches), stdout)
}
v, err := version.NewVersion(submatches[1])
if err != nil {
return nil, fmt.Errorf("unable to parse version %q: %w", submatches[1], err)
v, err := terraformJsonVersion(ctx, path)
if err == nil {
return v, nil
}

return v, err
// JSON output was added in 0.13.0
// See https://github.com/hashicorp/terraform/pull/25252
// We assume that error implies older version.
return legacyTerraformVersion(ctx, path)
},
BuildInstructions: &BuildInstructions{
GitRepoURL: "https://github.com/hashicorp/terraform.git",
PreCloneCheck: &build.GoIsInstalled{},
Build: &build.GoBuild{DetectVendoring: true},
},
}

type terraformJsonVersionOutput struct {
Version *version.Version `json:"terraform_version"`
}

func terraformJsonVersion(ctx context.Context, path string) (*version.Version, error) {
cmd := exec.CommandContext(ctx, path, "version", "-json")
out, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}

var vOut terraformJsonVersionOutput
err = json.Unmarshal(out, &vOut)
if err != nil {
return nil, err
}

return vOut.Version, nil
}

func legacyTerraformVersion(ctx context.Context, path string) (*version.Version, error) {
cmd := exec.CommandContext(ctx, path, "version")
out, err := cmd.Output()
if err != nil {
return nil, err
}

stdout := strings.TrimSpace(string(out))

submatches := terraformVersionOutputRe.FindStringSubmatch(stdout)
if len(submatches) != 2 {
return nil, fmt.Errorf("unexpected number of version matches %d for %s", len(submatches), stdout)
}
v, err := version.NewVersion(submatches[1])
if err != nil {
return nil, fmt.Errorf("unable to parse version %q: %w", submatches[1], err)
}

return v, err
}

0 comments on commit 54db6c1

Please sign in to comment.