From b13281a6c53077ed6fc0af3c9d7e3a4912f74b3c Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Mon, 29 Apr 2019 12:22:52 +1000 Subject: [PATCH] Add support for basic version requirements With any project, eventually you get to a stage where you have configuration defined that works on a specific version of your software. Upgrading between versions usually requires some effort but it's rolled out when it's needed. This becomes even more difficult working in a team where people can have different versions of the software that you use based on how often they like to update their systems. To handle these scenarios, you introduce some sort of versioning that defines what versions you want the configuration to operate with and the users then need to meet those requirements. This introduces a basic concept of the versioning for IAMy. The logic is pretty straight forward. - If you find a `.iamy-version` file, use the version defined in it. If not, continue on. - If the `.iamy-version` file contains a version number, compare it to the local version and ensure that the version in use meets the minimum requirements to operate. If it doesn't, inform the user of the discrepancy and what is required. #62 proposes quite a few more coditions to restrain the version however I don't think that's required for majority of use cases. I think defining a minimum version covers most of the sharp edges we've encountered. But, we can always make this more perscriptive if needed. Closes #62 --- go.mod | 1 + go.sum | 2 ++ iamy.go | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e0c1042..d4a5c31 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,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 v3.5.1+incompatible 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 c457fe0..5271195 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/aws/aws-sdk-go v0.0.0-20190104231327-923b7b1b0525 h1:qc2jx43HwaJSlY5U github.com/aws/aws-sdk-go v0.0.0-20190104231327-923b7b1b0525/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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 v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= 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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/iamy.go b/iamy.go index 6a3b970..333ef78 100644 --- a/iamy.go +++ b/iamy.go @@ -1,18 +1,25 @@ package main import ( + "fmt" "io/ioutil" "log" "os" "path/filepath" + "regexp" + "github.com/blang/semver" "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.` + var ( - Version string = "dev" - defaultDir string - dryRun *bool + Version string = "dev" + defaultDir string + dryRun *bool + versionFileName string = ".iamy-version" ) type logWriter struct{ *log.Logger } @@ -60,6 +67,8 @@ func main() { log.SetOutput(ioutil.Discard) } + performVersionChecks() + switch cmd { case push.FullCommand(): PushCommand(ui, PushCommandInput{ @@ -85,3 +94,29 @@ func init() { } defaultDir = filepath.Clean(dir) } + +func performVersionChecks() { + currentIAMyVersion, _ := semver.Make(Version) + log.Printf("current version is %s", 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`) + match := re.FindStringSubmatch(fileContents) + localDesiredVersion, _ := semver.Make(match[0]) + log.Printf("local project wants version %s", 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" && currentIAMyVersion.LE(localDesiredVersion) { + fmt.Printf(versionTooOldError, currentIAMyVersion, localDesiredVersion) + os.Exit(1) + } + } + } +}