command/version: Report the current platform

Along with all of the other information we previously reported in the
"terraform version" output, we'll now include the name of the current
platform as our provider mechanisms represent it.

This is addressing a long-standing minor annoyance where we often can't
tell from an incomplete bug report which platform Terraform was running
on, and incomplete bug reporters do tend to at least include the
"terraform version" output even if they don't also include the requested
full trace log.

However, what motivated doing it _now_ is that anyone building a provider
registry or mirror needs to have some awareness of these platform
identifiers which have been, until v0.13, mostly an implementation detail.
This additional information is a small thing we can do to help registry
builders find out what the platform identifier ought to be for each of
the platforms they aim to support, even if some of them are platforms
which the Go compiler allows but which HashiCorp doesn't officially
support.

The new information is on a line of its own in the output as a pragmatic
way to avoid breaking anyone who might be using something like
$(terraform version | head -n1) to print a brief Terraform version
identifier into some logs. That's not an interface we officially support
for machine consumption, but it's easy to avoid breaking it here and so we
won't do so.
This commit is contained in:
Martin Atkins 2020-11-18 15:43:27 -08:00
parent 24d6c74e97
commit 0a596d2a12
3 changed files with 21 additions and 6 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/internal/depsfile" "github.com/hashicorp/terraform/internal/depsfile"
"github.com/hashicorp/terraform/internal/getproviders"
) )
// VersionCommand is a Command implementation prints the version. // VersionCommand is a Command implementation prints the version.
@ -19,11 +20,13 @@ type VersionCommand struct {
Version string Version string
VersionPrerelease string VersionPrerelease string
CheckFunc VersionCheckFunc CheckFunc VersionCheckFunc
Platform getproviders.Platform
} }
type VersionOutput struct { type VersionOutput struct {
Version string `json:"terraform_version"` Version string `json:"terraform_version"`
Revision string `json:"terraform_revision"` Revision string `json:"terraform_revision"`
Platform string `json:"platform"`
ProviderSelections map[string]string `json:"provider_selections"` ProviderSelections map[string]string `json:"provider_selections"`
Outdated bool `json:"terraform_outdated"` Outdated bool `json:"terraform_outdated"`
} }
@ -137,6 +140,7 @@ func (c *VersionCommand) Run(args []string) int {
output := VersionOutput{ output := VersionOutput{
Version: versionOutput, Version: versionOutput,
Revision: c.Revision, Revision: c.Revision,
Platform: c.Platform.String(),
ProviderSelections: selectionsOutput, ProviderSelections: selectionsOutput,
Outdated: outdated, Outdated: outdated,
} }
@ -150,6 +154,8 @@ func (c *VersionCommand) Run(args []string) int {
return 0 return 0
} else { } else {
c.Ui.Output(versionString.String()) c.Ui.Output(versionString.String())
c.Ui.Output(fmt.Sprintf("on %s", c.Platform))
if len(providerVersions) != 0 { if len(providerVersions) != 0 {
sort.Strings(providerVersions) sort.Strings(providerVersions)
for _, str := range providerVersions { for _, str := range providerVersions {

View File

@ -49,6 +49,7 @@ func TestVersion(t *testing.T) {
}, },
Version: "4.5.6", Version: "4.5.6",
VersionPrerelease: "foo", VersionPrerelease: "foo",
Platform: getproviders.Platform{OS: "aros", Arch: "riscv64"},
} }
if err := c.replaceLockedDependencies(locks); err != nil { if err := c.replaceLockedDependencies(locks); err != nil {
t.Fatal(err) t.Fatal(err)
@ -58,7 +59,7 @@ func TestVersion(t *testing.T) {
} }
actual := strings.TrimSpace(ui.OutputWriter.String()) actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "Terraform v4.5.6-foo\n+ provider registry.terraform.io/hashicorp/test1 v7.8.9-beta.2\n+ provider registry.terraform.io/hashicorp/test2 v1.2.3" expected := "Terraform v4.5.6-foo\non aros_riscv64\n+ provider registry.terraform.io/hashicorp/test1 v7.8.9-beta.2\n+ provider registry.terraform.io/hashicorp/test2 v1.2.3"
if actual != expected { if actual != expected {
t.Fatalf("wrong output\ngot:\n%s\nwant:\n%s", actual, expected) t.Fatalf("wrong output\ngot:\n%s\nwant:\n%s", actual, expected)
} }
@ -76,6 +77,7 @@ func TestVersion_flags(t *testing.T) {
Meta: m, Meta: m,
Version: "4.5.6", Version: "4.5.6",
VersionPrerelease: "foo", VersionPrerelease: "foo",
Platform: getproviders.Platform{OS: "aros", Arch: "riscv64"},
} }
if code := c.Run([]string{"-v", "-version"}); code != 0 { if code := c.Run([]string{"-v", "-version"}); code != 0 {
@ -83,7 +85,7 @@ func TestVersion_flags(t *testing.T) {
} }
actual := strings.TrimSpace(ui.OutputWriter.String()) actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "Terraform v4.5.6-foo" expected := "Terraform v4.5.6-foo\non aros_riscv64"
if actual != expected { if actual != expected {
t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected) t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected)
} }
@ -99,6 +101,7 @@ func TestVersion_outdated(t *testing.T) {
Meta: m, Meta: m,
Version: "4.5.6", Version: "4.5.6",
CheckFunc: mockVersionCheckFunc(true, "4.5.7"), CheckFunc: mockVersionCheckFunc(true, "4.5.7"),
Platform: getproviders.Platform{OS: "aros", Arch: "riscv64"},
} }
if code := c.Run([]string{}); code != 0 { if code := c.Run([]string{}); code != 0 {
@ -106,7 +109,7 @@ func TestVersion_outdated(t *testing.T) {
} }
actual := strings.TrimSpace(ui.OutputWriter.String()) actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "Terraform v4.5.6\n\nYour version of Terraform is out of date! The latest version\nis 4.5.7. You can update by downloading from https://www.terraform.io/downloads.html" expected := "Terraform v4.5.6\non aros_riscv64\n\nYour version of Terraform is out of date! The latest version\nis 4.5.7. You can update by downloading from https://www.terraform.io/downloads.html"
if actual != expected { if actual != expected {
t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected) t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected)
} }
@ -129,6 +132,7 @@ func TestVersion_json(t *testing.T) {
c := &VersionCommand{ c := &VersionCommand{
Meta: meta, Meta: meta,
Version: "4.5.6", Version: "4.5.6",
Platform: getproviders.Platform{OS: "aros", Arch: "riscv64"},
} }
if code := c.Run([]string{"-json"}); code != 0 { if code := c.Run([]string{"-json"}); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
@ -139,6 +143,7 @@ func TestVersion_json(t *testing.T) {
{ {
"terraform_version": "4.5.6", "terraform_version": "4.5.6",
"terraform_revision": "", "terraform_revision": "",
"platform": "aros_riscv64",
"provider_selections": {}, "provider_selections": {},
"terraform_outdated": false "terraform_outdated": false
} }
@ -172,6 +177,7 @@ func TestVersion_json(t *testing.T) {
Meta: meta, Meta: meta,
Version: "4.5.6", Version: "4.5.6",
VersionPrerelease: "foo", VersionPrerelease: "foo",
Platform: getproviders.Platform{OS: "aros", Arch: "riscv64"},
} }
if err := c.replaceLockedDependencies(locks); err != nil { if err := c.replaceLockedDependencies(locks); err != nil {
t.Fatal(err) t.Fatal(err)
@ -185,6 +191,7 @@ func TestVersion_json(t *testing.T) {
{ {
"terraform_version": "4.5.6-foo", "terraform_version": "4.5.6-foo",
"terraform_revision": "", "terraform_revision": "",
"platform": "aros_riscv64",
"provider_selections": { "provider_selections": {
"registry.terraform.io/hashicorp/test1": "7.8.9-beta.2", "registry.terraform.io/hashicorp/test1": "7.8.9-beta.2",
"registry.terraform.io/hashicorp/test2": "1.2.3" "registry.terraform.io/hashicorp/test2": "1.2.3"
@ -208,6 +215,7 @@ func TestVersion_jsonoutdated(t *testing.T) {
Meta: m, Meta: m,
Version: "4.5.6", Version: "4.5.6",
CheckFunc: mockVersionCheckFunc(true, "4.5.7"), CheckFunc: mockVersionCheckFunc(true, "4.5.7"),
Platform: getproviders.Platform{OS: "aros", Arch: "riscv64"},
} }
if code := c.Run([]string{"-json"}); code != 0 { if code := c.Run([]string{"-json"}); code != 0 {
@ -215,7 +223,7 @@ func TestVersion_jsonoutdated(t *testing.T) {
} }
actual := strings.TrimSpace(ui.OutputWriter.String()) actual := strings.TrimSpace(ui.OutputWriter.String())
expected := "{\n \"terraform_version\": \"4.5.6\",\n \"terraform_revision\": \"\",\n \"provider_selections\": {},\n \"terraform_outdated\": true\n}" expected := "{\n \"terraform_version\": \"4.5.6\",\n \"terraform_revision\": \"\",\n \"platform\": \"aros_riscv64\",\n \"provider_selections\": {},\n \"terraform_outdated\": true\n}"
if actual != expected { if actual != expected {
t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected) t.Fatalf("wrong output\ngot: %#v\nwant: %#v", actual, expected)
} }

View File

@ -284,6 +284,7 @@ func initCommands(
Revision: GitCommit, Revision: GitCommit,
Version: Version, Version: Version,
VersionPrerelease: VersionPrerelease, VersionPrerelease: VersionPrerelease,
Platform: getproviders.CurrentPlatform,
CheckFunc: commandVersionCheck, CheckFunc: commandVersionCheck,
}, nil }, nil
}, },