github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/command/version.go (about) 1 package command 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 ) 8 9 // VersionCommand is a Command implementation prints the version. 10 type VersionCommand struct { 11 Meta 12 13 Revision string 14 Version string 15 VersionPrerelease string 16 CheckFunc VersionCheckFunc 17 } 18 19 // VersionCheckFunc is the callback called by the Version command to 20 // check if there is a new version of Terraform. 21 type VersionCheckFunc func() (VersionCheckInfo, error) 22 23 // VersionCheckInfo is the return value for the VersionCheckFunc callback 24 // and tells the Version command information about the latest version 25 // of Terraform. 26 type VersionCheckInfo struct { 27 Outdated bool 28 Latest string 29 Alerts []string 30 } 31 32 func (c *VersionCommand) Help() string { 33 return "" 34 } 35 36 func (c *VersionCommand) Run(args []string) int { 37 var versionString bytes.Buffer 38 args, err := c.Meta.process(args, false) 39 if err != nil { 40 return 1 41 } 42 43 fmt.Fprintf(&versionString, "Terraform v%s", c.Version) 44 if c.VersionPrerelease != "" { 45 fmt.Fprintf(&versionString, "-%s", c.VersionPrerelease) 46 47 if c.Revision != "" { 48 fmt.Fprintf(&versionString, " (%s)", c.Revision) 49 } 50 } 51 52 c.Ui.Output(versionString.String()) 53 54 // We'll also attempt to print out the selected plugin versions. We can 55 // do this only if "terraform init" was already run and thus we've committed 56 // to a specific set of plugins. If not, the plugins lock will be empty 57 // and so we'll show _no_ providers. 58 // 59 // Generally-speaking this is a best-effort thing that will give us a good 60 // result in the usual case where the user successfully ran "terraform init" 61 // and then hit a problem running _another_ command. 62 providerPlugins := c.providerPluginSet() 63 pluginsLockFile := c.providerPluginsLock() 64 pluginsLock := pluginsLockFile.Read() 65 var pluginVersions []string 66 for meta := range providerPlugins { 67 name := meta.Name 68 wantHash, wanted := pluginsLock[name] 69 if !wanted { 70 // Ignore providers that aren't used by the current config at all 71 continue 72 } 73 gotHash, err := meta.SHA256() 74 if err != nil { 75 // if we can't read the file to hash it, ignore it. 76 continue 77 } 78 if !bytes.Equal(gotHash, wantHash) { 79 // Not the plugin we've locked, so ignore it. 80 continue 81 } 82 83 // If we get here then we've found a selected plugin, so we'll print 84 // out its details. 85 if meta.Version == "0.0.0" { 86 pluginVersions = append(pluginVersions, fmt.Sprintf("+ provider.%s (unversioned)", name)) 87 } else { 88 pluginVersions = append(pluginVersions, fmt.Sprintf("+ provider.%s v%s", name, meta.Version)) 89 } 90 } 91 if len(pluginVersions) != 0 { 92 sort.Strings(pluginVersions) 93 for _, str := range pluginVersions { 94 c.Ui.Output(str) 95 } 96 } 97 98 // If we have a version check function, then let's check for 99 // the latest version as well. 100 if c.CheckFunc != nil { 101 102 // Check the latest version 103 info, err := c.CheckFunc() 104 if err != nil { 105 c.Ui.Error(fmt.Sprintf( 106 "\nError checking latest version: %s", err)) 107 } 108 if info.Outdated { 109 c.Ui.Output(fmt.Sprintf( 110 "\nYour version of Terraform is out of date! The latest version\n"+ 111 "is %s. You can update by downloading from https://www.terraform.io/downloads.html", 112 info.Latest)) 113 } 114 } 115 116 return 0 117 } 118 119 func (c *VersionCommand) Synopsis() string { 120 return "Prints the Terraform version" 121 }