Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] check for version mis-match on apply #144

Merged
merged 3 commits into from
Sep 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"path/filepath"
Expand All @@ -26,7 +27,14 @@ import (

const rootPath = "terraform"

func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T) error {
func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T, upgrade bool) error {
if !upgrade {
toolVersion, _ := util.VersionString()
versionChange, repoVersion, _ := checkToolVersions(fs, toolVersion)
if versionChange {
return fmt.Errorf("fogg version (%s) is different than version currently used to manage repo (%s). To upgrade add --upgrade.", toolVersion, repoVersion)
}
}
p, err := plan.Eval(conf, false)
if err != nil {
return errors.Wrap(err, "unable to evaluate plan")
Expand Down Expand Up @@ -56,6 +64,38 @@ func Apply(fs afero.Fs, conf *config.Config, tmp *templates.T) error {
return errors.Wrap(e, "unable to apply modules")
}

func checkToolVersions(fs afero.Fs, current string) (bool, string, error) {
f, e := fs.Open(".fogg-version")
if e != nil {
return false, "", errors.Wrap(e, "unable to open .fogg-version file")
}
reader := io.ReadCloser(f)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if you need this

defer reader.Close()

b, e := ioutil.ReadAll(reader)
if e != nil {
return false, "", errors.Wrap(e, "unable to read .fogg-version file")
}
repoVersion := string(b)
changed, e := versionIsChanged(repoVersion, current)
return changed, repoVersion, e
}

func versionIsChanged(repo string, tool string) (bool, error) {
repoVersion, repoSha, repoDirty := util.ParseVersion(repo)
toolVersion, toolSha, toolDirty := util.ParseVersion(tool)

if repoDirty || toolDirty {
return true, nil
}

if (repoSha != "" || toolSha != "") && repoSha != toolSha {
return true, nil
}

return toolVersion.NE(repoVersion), nil
}

func applyRepo(fs afero.Fs, p *plan.Plan, repoTemplates *packr.Box) error {
e := applyTree(fs, repoTemplates, "", p)
if e != nil {
Expand Down
44 changes: 43 additions & 1 deletion apply/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func TestApplySmokeTest(t *testing.T) {
c, e := config.ReadConfig(ioutil.NopCloser(strings.NewReader(json)))
assert.Nil(t, e)

e = Apply(fs, c, templates.Templates)
e = Apply(fs, c, templates.Templates, false)
assert.Nil(t, e)
}

Expand Down Expand Up @@ -274,6 +274,48 @@ func TestCalculateLocalPath(t *testing.T) {
}
}

var versionTests = []struct {
current string
tool string
result bool
}{
{"0.0.0", "0.1.0", true},
{"0.1.0", "0.0.0", true},
{"0.1.0", "0.1.0", false},
{"0.1.0", "0.1.0-abcdef", true},
{"0.1.0", "0.1.0-abcdef-dirty", true},
{"0.1.0-abcdef-dirty", "0.1.0", true},
{"0.1.0-abc", "0.1.0-def", true},
{"0.1.0-abc", "0.1.0-abc", false},
}

func TestCheckToolVersions(t *testing.T) {
a := assert.New(t)

for _, tc := range versionTests {
t.Run("", func(t *testing.T) {
fs := afero.NewMemMapFs()
writeFile(fs, ".fogg-version", tc.current)

v, _, e := checkToolVersions(fs, tc.tool)
a.NoError(e)
a.Equal(tc.result, v)
})
}
}

func TestVersionIsChanged(t *testing.T) {
a := assert.New(t)

for _, test := range versionTests {
t.Run("", func(t *testing.T) {
b, e := versionIsChanged(test.current, test.tool)
a.NoError(e)
a.Equal(test.result, b)
})
}
}

func readFile(fs afero.Fs, path string) (string, error) {
f, e := fs.Open(path)
if e != nil {
Expand Down
8 changes: 7 additions & 1 deletion cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
func init() {
applyCmd.Flags().StringP("config", "c", "fogg.json", "Use this to override the fogg config file.")
applyCmd.Flags().BoolP("verbose", "v", false, "use this to turn on verbose output")
applyCmd.Flags().BoolP("upgrade", "u", false, "use this when running a new version of fogg")
rootCmd.AddCommand(applyCmd)
}

Expand Down Expand Up @@ -47,6 +48,11 @@ var applyCmd = &cobra.Command{
log.Panic(e)
}

upgrade, e := cmd.Flags().GetBool("upgrade")
if e != nil {
log.Panic(e)
}

// check that we are at root of initialized git repo
openGitOrExit(pwd)

Expand All @@ -55,7 +61,7 @@ var applyCmd = &cobra.Command{
exitOnConfigErrors(err)

// apply
e = apply.Apply(fs, config, templates.Templates)
e = apply.Apply(fs, config, templates.Templates, upgrade)
if e != nil {
log.Panic(e)
}
Expand Down
19 changes: 19 additions & 0 deletions util/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package util
import (
"fmt"
"strconv"
"strings"

"github.com/blang/semver"
"github.com/pkg/errors"
Expand Down Expand Up @@ -39,6 +40,24 @@ func VersionCacheKey() string {
return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}

func ParseVersion(version string) (semver.Version, string, bool) {
var dirty bool
var sha string
v := version
if strings.HasSuffix(v, "-dirty") {
dirty = true
v = strings.TrimSuffix(v, "-dirty")
}
if strings.Contains(v, "-") {
tmp := strings.Split(v, "-")
v = tmp[0]
sha = tmp[1]
}

semVersion, _ := semver.Parse(v)
return semVersion, sha, dirty
}

func versionString(version, sha string, release, dirty bool) string {
if release {
return version
Expand Down
27 changes: 27 additions & 0 deletions util/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package util
import (
"testing"

"github.com/blang/semver"
"github.com/stretchr/testify/assert"
)

Expand All @@ -17,3 +18,29 @@ func TestVersionString(t *testing.T) {
assert.Equal(t, "0.1.0-abcdef-dirty", s)

}

func TestParse(t *testing.T) {
a := assert.New(t)

testCases := []struct {
input string
version string
sha string
dirty bool
}{
{"0.1.0", "0.1.0", "", false},
{"0.1.0-abcdef", "0.1.0", "abcdef", false},
{"0.1.0-abcdef-dirty", "0.1.0", "abcdef", true},
}
for _, tc := range testCases {
t.Run("", func(t *testing.T) {
v, sha, dirty := ParseVersion(tc.input)
semVersion, e := semver.Parse(tc.version)
a.NoError(e)
a.Equal(semVersion, v)
a.Equal(tc.sha, sha)
a.Equal(tc.dirty, dirty)
})
}

}