mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
c94a6102df
The short description of our commands (as shown in the main help output from "terraform") was previously very inconsistent, using different tense/mood for different commands. Some of the commands were also using some terminology choices inconsistent with how we currently talk about the related ideas in our documentation. Here I've tried to add some consistency by first rewriting them all in the imperative mood (except the ones that just are just subcommand groupings), and tweaking some of the terminology to hopefully gel better with how we present similar ideas in our recently-updated docs. While working on this I inevitably spotted some similar inconsistencies in the longer-form help output of some of the commands. I've not reviewed all of these for consistency, but I did update some where the wording was either left inconsstent with the short form changes I'd made or where the prose stood out to me as particularly inconsistent with our current usual documentation language style. All of this is subjective, so I expect we'll continue to tweak these over time as we continue to develop our documentation writing style based on user questions and feedback.
174 lines
4.9 KiB
Go
174 lines
4.9 KiB
Go
package command
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
"github.com/hashicorp/terraform/internal/depsfile"
|
|
)
|
|
|
|
// VersionCommand is a Command implementation prints the version.
|
|
type VersionCommand struct {
|
|
Meta
|
|
|
|
Revision string
|
|
Version string
|
|
VersionPrerelease string
|
|
CheckFunc VersionCheckFunc
|
|
}
|
|
|
|
type VersionOutput struct {
|
|
Version string `json:"terraform_version"`
|
|
Revision string `json:"terraform_revision"`
|
|
ProviderSelections map[string]string `json:"provider_selections"`
|
|
Outdated bool `json:"terraform_outdated"`
|
|
}
|
|
|
|
// VersionCheckFunc is the callback called by the Version command to
|
|
// check if there is a new version of Terraform.
|
|
type VersionCheckFunc func() (VersionCheckInfo, error)
|
|
|
|
// VersionCheckInfo is the return value for the VersionCheckFunc callback
|
|
// and tells the Version command information about the latest version
|
|
// of Terraform.
|
|
type VersionCheckInfo struct {
|
|
Outdated bool
|
|
Latest string
|
|
Alerts []string
|
|
}
|
|
|
|
func (c *VersionCommand) Help() string {
|
|
helpText := `
|
|
Usage: terraform version [options]
|
|
|
|
Displays the version of Terraform and all installed plugins
|
|
|
|
Options:
|
|
|
|
-json Output the version information as a JSON object.
|
|
`
|
|
return strings.TrimSpace(helpText)
|
|
}
|
|
|
|
func (c *VersionCommand) Run(args []string) int {
|
|
var outdated bool
|
|
var latest string
|
|
var versionString bytes.Buffer
|
|
args = c.Meta.process(args)
|
|
var jsonOutput bool
|
|
cmdFlags := c.Meta.defaultFlagSet("version")
|
|
cmdFlags.BoolVar(&jsonOutput, "json", false, "json")
|
|
// Enable but ignore the global version flags. In main.go, if any of the
|
|
// arguments are -v, -version, or --version, this command will be called
|
|
// with the rest of the arguments, so we need to be able to cope with
|
|
// those.
|
|
cmdFlags.Bool("v", true, "version")
|
|
cmdFlags.Bool("version", true, "version")
|
|
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
|
if err := cmdFlags.Parse(args); err != nil {
|
|
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
|
|
return 1
|
|
}
|
|
|
|
fmt.Fprintf(&versionString, "Terraform v%s", c.Version)
|
|
if c.VersionPrerelease != "" {
|
|
fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease)
|
|
|
|
if c.Revision != "" {
|
|
fmt.Fprintf(&versionString, " (%s)", c.Revision)
|
|
}
|
|
}
|
|
|
|
// We'll also attempt to print out the selected plugin versions. We do
|
|
// this based on the dependency lock file, and so the result might be
|
|
// empty or incomplete if the user hasn't successfully run "terraform init"
|
|
// since the most recent change to dependencies.
|
|
//
|
|
// Generally-speaking this is a best-effort thing that will give us a good
|
|
// result in the usual case where the user successfully ran "terraform init"
|
|
// and then hit a problem running _another_ command.
|
|
var providerVersions []string
|
|
var providerLocks map[addrs.Provider]*depsfile.ProviderLock
|
|
if locks, err := c.lockedDependencies(); err == nil {
|
|
providerLocks = locks.AllProviders()
|
|
for providerAddr, lock := range providerLocks {
|
|
version := lock.Version().String()
|
|
if version == "0.0.0" {
|
|
providerVersions = append(providerVersions, fmt.Sprintf("+ provider %s (unversioned)", providerAddr))
|
|
} else {
|
|
providerVersions = append(providerVersions, fmt.Sprintf("+ provider %s v%s", providerAddr, version))
|
|
}
|
|
}
|
|
}
|
|
|
|
// If we have a version check function, then let's check for
|
|
// the latest version as well.
|
|
if c.CheckFunc != nil {
|
|
// Check the latest version
|
|
info, err := c.CheckFunc()
|
|
if err != nil && !jsonOutput {
|
|
c.Ui.Error(fmt.Sprintf(
|
|
"\nError checking latest version: %s", err))
|
|
}
|
|
if info.Outdated {
|
|
outdated = true
|
|
latest = info.Latest
|
|
}
|
|
}
|
|
|
|
if jsonOutput {
|
|
selectionsOutput := make(map[string]string)
|
|
for providerAddr, lock := range providerLocks {
|
|
version := lock.Version().String()
|
|
selectionsOutput[providerAddr.String()] = version
|
|
}
|
|
|
|
var versionOutput string
|
|
if c.VersionPrerelease != "" {
|
|
versionOutput = c.Version + "-" + c.VersionPrerelease
|
|
} else {
|
|
versionOutput = c.Version
|
|
}
|
|
|
|
output := VersionOutput{
|
|
Version: versionOutput,
|
|
Revision: c.Revision,
|
|
ProviderSelections: selectionsOutput,
|
|
Outdated: outdated,
|
|
}
|
|
|
|
jsonOutput, err := json.MarshalIndent(output, "", " ")
|
|
if err != nil {
|
|
c.Ui.Error(fmt.Sprintf("\nError marshalling JSON: %s", err))
|
|
return 1
|
|
}
|
|
c.Ui.Output(string(jsonOutput))
|
|
return 0
|
|
} else {
|
|
c.Ui.Output(versionString.String())
|
|
if len(providerVersions) != 0 {
|
|
sort.Strings(providerVersions)
|
|
for _, str := range providerVersions {
|
|
c.Ui.Output(str)
|
|
}
|
|
}
|
|
if outdated {
|
|
c.Ui.Output(fmt.Sprintf(
|
|
"\nYour version of Terraform is out of date! The latest version\n"+
|
|
"is %s. You can update by downloading from https://www.terraform.io/downloads.html",
|
|
latest))
|
|
}
|
|
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func (c *VersionCommand) Synopsis() string {
|
|
return "Show the current Terraform version"
|
|
}
|