11package cmd
22
33import (
4+ "context"
5+ "errors"
46 "fmt"
57 "log"
68
9+ "github.com/google/go-github/v35/github"
10+ "github.com/hashicorp/go-version"
711 "github.com/spf13/afero"
812 "github.com/terraform-linters/tflint/plugin"
913 "github.com/terraform-linters/tflint/tflint"
@@ -12,6 +16,8 @@ import (
1216func (cli * CLI ) printVersion (opts Options ) int {
1317 fmt .Fprintf (cli .outStream , "TFLint version %s\n " , tflint .Version )
1418
19+ cli .printLatestReleaseVersion ()
20+
1521 workingDirs , err := findWorkingDirs (opts )
1622 if err != nil {
1723 cli .formatter .Print (tflint.Issues {}, fmt .Errorf ("Failed to find workspaces; %w" , err ), map [string ][]byte {})
@@ -81,3 +87,35 @@ func getPluginVersions(opts Options) []string {
8187
8288 return versions
8389}
90+
91+ // Checks GitHub releases and prints new version, if current version is outdated.
92+ // requires GitHub releases to follow semver.
93+ func (cli * CLI ) printLatestReleaseVersion () {
94+ latest , err := getLatestVersion ()
95+ if err != nil {
96+ cli .formatter .Print (tflint.Issues {}, fmt .Errorf ("Failed to check updates; %w" , err ), map [string ][]byte {})
97+ }
98+ latestVersion , err := version .NewSemver (* latest .Name )
99+ compare := tflint .Version .Compare (latestVersion )
100+ if compare < 0 {
101+ fmt .Fprintf (cli .outStream , "New version available: %s\n " , * latest .HTMLURL )
102+ }
103+ }
104+
105+ func getLatestVersion () (* github.RepositoryRelease , error ) {
106+ ghClient := github .NewClient (nil )
107+ releases , _ , err := ghClient .Repositories .ListReleases (context .Background (),
108+ "terraform-linters" , "tflint" , & github.ListOptions {})
109+ if err != nil {
110+ return nil , err
111+ }
112+
113+ // GitHub sorts releases results. Select first non-prerelease version and return it.
114+ for i := range releases {
115+ release := releases [i ]
116+ if ! * release .Prerelease {
117+ return release , nil
118+ }
119+ }
120+ return nil , errors .New ("not found" )
121+ }
0 commit comments