diff --git a/go.mod b/go.mod index 3a6943e..b787db7 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/aws/aws-sdk-go v1.16.23 + github.com/blang/semver/v4 v4.0.0 github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.7.0 github.com/ghodss/yaml v1.0.0 diff --git a/go.sum b/go.sum index 7ddc201..50aef8c 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZq github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aws/aws-sdk-go v1.16.23 h1:MwBOBeez0XEFVh6DCc888X+nHVBCjUDLnnWXSGGWUgM= github.com/aws/aws-sdk-go v1.16.23/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/iamy.go b/iamy.go index 0814e13..722f508 100644 --- a/iamy.go +++ b/iamy.go @@ -1,18 +1,29 @@ package main import ( + "fmt" "io/ioutil" "log" "os" "path/filepath" + "reflect" + "regexp" + "strings" + "github.com/blang/semver/v4" "gopkg.in/alecthomas/kingpin.v2" ) +const versionTooOldError = `Your version of IAMy (%s) is out of date compared to what the local +project expects. You should upgrade to %s to use this project.` +const buildVersionMismatch = `Your version of IAMy (%s) does not match have the build tag the +local project expects. You should upgrade to %s to use this project.` + var ( - Version string = "dev" - defaultDir string - dryRun *bool + Version string = "dev" + defaultDir string + dryRun *bool + versionFileName string = ".iamy-version" ) type logWriter struct{ *log.Logger } @@ -61,6 +72,8 @@ func main() { log.SetOutput(ioutil.Discard) } + performVersionChecks() + switch cmd { case push.FullCommand(): PushCommand(ui, PushCommandInput{ @@ -87,3 +100,36 @@ func init() { } defaultDir = filepath.Clean(dir) } + +func performVersionChecks() { + currentIAMyVersion, _ := semver.Make(strings.TrimPrefix(Version, "v")) + log.Printf("current versions is %s\n", currentIAMyVersion) + + if _, err := os.Stat(versionFileName); !os.IsNotExist(err) { + log.Printf("%s found", versionFileName) + fileBytes, _ := ioutil.ReadFile(versionFileName) + fileContents := string(fileBytes) + + if fileContents != "" { + re := regexp.MustCompile(`\d\.\d+\.\d\+?\w*`) + match := re.FindStringSubmatch(fileContents) + localDesiredVersion, _ := semver.Make(match[0]) + log.Printf("local project wants version %s\n", localDesiredVersion) + + // We don't want to notify users if the `Version` is "dev" as it's not + // actually too old. It could be that they are running non-released + // versions. + if Version != "dev" { + if currentIAMyVersion.LT(localDesiredVersion) { + fmt.Printf(versionTooOldError, currentIAMyVersion, localDesiredVersion) + os.Exit(1) + } + // Pay attention to build tags as well + if !reflect.DeepEqual(localDesiredVersion.Build, currentIAMyVersion.Build) { + fmt.Printf(buildVersionMismatch, currentIAMyVersion, localDesiredVersion) + os.Exit(1) + } + } + } + } +}