github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/version.go (about) 1 package command 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "sort" 8 "strings" 9 10 "github.com/hashicorp/terraform/internal/addrs" 11 "github.com/hashicorp/terraform/internal/depsfile" 12 "github.com/hashicorp/terraform/internal/getproviders" 13 ) 14 15 // VersionCommand is a Command implementation prints the version. 16 type VersionCommand struct { 17 Meta 18 19 Version string 20 VersionPrerelease string 21 CheckFunc VersionCheckFunc 22 Platform getproviders.Platform 23 } 24 25 type VersionOutput struct { 26 Version string `json:"terraform_version"` 27 Platform string `json:"platform"` 28 ProviderSelections map[string]string `json:"provider_selections"` 29 Outdated bool `json:"terraform_outdated"` 30 } 31 32 // VersionCheckFunc is the callback called by the Version command to 33 // check if there is a new version of Terraform. 34 type VersionCheckFunc func() (VersionCheckInfo, error) 35 36 // VersionCheckInfo is the return value for the VersionCheckFunc callback 37 // and tells the Version command information about the latest version 38 // of Terraform. 39 type VersionCheckInfo struct { 40 Outdated bool 41 Latest string 42 Alerts []string 43 } 44 45 func (c *VersionCommand) Help() string { 46 helpText := ` 47 Usage: terraform [global options] version [options] 48 49 Displays the version of Terraform and all installed plugins 50 51 Options: 52 53 -json Output the version information as a JSON object. 54 ` 55 return strings.TrimSpace(helpText) 56 } 57 58 func (c *VersionCommand) Run(args []string) int { 59 var outdated bool 60 var latest string 61 var versionString bytes.Buffer 62 args = c.Meta.process(args) 63 var jsonOutput bool 64 cmdFlags := c.Meta.defaultFlagSet("version") 65 cmdFlags.BoolVar(&jsonOutput, "json", false, "json") 66 // Enable but ignore the global version flags. In main.go, if any of the 67 // arguments are -v, -version, or --version, this command will be called 68 // with the rest of the arguments, so we need to be able to cope with 69 // those. 70 cmdFlags.Bool("v", true, "version") 71 cmdFlags.Bool("version", true, "version") 72 cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } 73 if err := cmdFlags.Parse(args); err != nil { 74 c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error())) 75 return 1 76 } 77 78 fmt.Fprintf(&versionString, "Terraform v%s", c.Version) 79 if c.VersionPrerelease != "" { 80 fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease) 81 } 82 83 // We'll also attempt to print out the selected plugin versions. We do 84 // this based on the dependency lock file, and so the result might be 85 // empty or incomplete if the user hasn't successfully run "terraform init" 86 // since the most recent change to dependencies. 87 // 88 // Generally-speaking this is a best-effort thing that will give us a good 89 // result in the usual case where the user successfully ran "terraform init" 90 // and then hit a problem running _another_ command. 91 var providerVersions []string 92 var providerLocks map[addrs.Provider]*depsfile.ProviderLock 93 if locks, err := c.lockedDependencies(); err == nil { 94 providerLocks = locks.AllProviders() 95 for providerAddr, lock := range providerLocks { 96 version := lock.Version().String() 97 if version == "0.0.0" { 98 providerVersions = append(providerVersions, fmt.Sprintf("+ provider %s (unversioned)", providerAddr)) 99 } else { 100 providerVersions = append(providerVersions, fmt.Sprintf("+ provider %s v%s", providerAddr, version)) 101 } 102 } 103 } 104 105 // If we have a version check function, then let's check for 106 // the latest version as well. 107 if c.CheckFunc != nil { 108 // Check the latest version 109 info, err := c.CheckFunc() 110 if err != nil && !jsonOutput { 111 c.Ui.Error(fmt.Sprintf( 112 "\nError checking latest version: %s", err)) 113 } 114 if info.Outdated { 115 outdated = true 116 latest = info.Latest 117 } 118 } 119 120 if jsonOutput { 121 selectionsOutput := make(map[string]string) 122 for providerAddr, lock := range providerLocks { 123 version := lock.Version().String() 124 selectionsOutput[providerAddr.String()] = version 125 } 126 127 var versionOutput string 128 if c.VersionPrerelease != "" { 129 versionOutput = c.Version + "-" + c.VersionPrerelease 130 } else { 131 versionOutput = c.Version 132 } 133 134 output := VersionOutput{ 135 Version: versionOutput, 136 Platform: c.Platform.String(), 137 ProviderSelections: selectionsOutput, 138 Outdated: outdated, 139 } 140 141 jsonOutput, err := json.MarshalIndent(output, "", " ") 142 if err != nil { 143 c.Ui.Error(fmt.Sprintf("\nError marshalling JSON: %s", err)) 144 return 1 145 } 146 c.Ui.Output(string(jsonOutput)) 147 return 0 148 } else { 149 c.Ui.Output(versionString.String()) 150 c.Ui.Output(fmt.Sprintf("on %s", c.Platform)) 151 152 if len(providerVersions) != 0 { 153 sort.Strings(providerVersions) 154 for _, str := range providerVersions { 155 c.Ui.Output(str) 156 } 157 } 158 if outdated { 159 c.Ui.Output(fmt.Sprintf( 160 "\nYour version of Terraform is out of date! The latest version\n"+ 161 "is %s. You can update by downloading from https://www.terraform.io/downloads.html", 162 latest)) 163 } 164 165 } 166 167 return 0 168 } 169 170 func (c *VersionCommand) Synopsis() string { 171 return "Show the current Terraform version" 172 }