Skip to content

Commit

Permalink
baur: exit with an error if baur_version does not match baur version
Browse files Browse the repository at this point in the history
Exit with an error if the baur_version string in the baur.toml file has
a different major or minor version then the baur version that is run.
This should ensure that users run an uptodate baur version.

In the future when we change to major version 1, configs should stay
compatible between the same major version. The check will be reworked.
  • Loading branch information
fho committed Jun 13, 2018
1 parent 2b13c82 commit 7cd6ad2
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 25 deletions.
9 changes: 9 additions & 0 deletions cfg/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"io/ioutil"
"os"
"testing"

"github.com/simplesurance/baur/version"
)

func Test_ExampleRepository_IsValid(t *testing.T) {
Expand All @@ -14,6 +16,13 @@ func Test_ExampleRepository_IsValid(t *testing.T) {
}

func Test_ExampleRepository_WrittenAndReadCfgIsValid(t *testing.T) {
version.Version = "0.0.0"
sver, err := version.SemVerFromString(version.Version)
if err != nil {
t.Fatal("setting version failed")
}
version.CurSemVer = *sver

tmpfileFD, err := ioutil.TempFile("", "baur")
if err != nil {
t.Fatal("opening tmpfile failed: ", err)
Expand Down
2 changes: 1 addition & 1 deletion command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
var rootCmd = &cobra.Command{
Use: "baur",
Short: "baur manages builds and artifacts in mono repositories.",
Version: version.FullVerNr(),
Version: version.CurSemVer.String(),
PersistentPreRun: initSb,
}

Expand Down
7 changes: 3 additions & 4 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func Actionln(v ...interface{}) {
lock.Lock()
defer lock.Unlock()

v = append([]interface{}{actionPrefix}, v)
v = append([]interface{}{actionPrefix}, v...)
fmt.Println(v...)
}

Expand Down Expand Up @@ -62,7 +62,7 @@ func Fatalln(v ...interface{}) {
lock.Lock()
defer lock.Unlock()

v = append([]interface{}{errorPrefix}, v)
v = append([]interface{}{errorPrefix}, v...)
fmt.Fprintln(os.Stderr, v...)

os.Exit(1)
Expand All @@ -73,7 +73,6 @@ func Fatalf(format string, v ...interface{}) {
lock.Lock()
defer lock.Unlock()

fmt.Fprintf(os.Stderr, format, v...)
fmt.Fprintf(os.Stderr, errorPrefix+format, v...)
os.Exit(1)
}
Expand All @@ -83,7 +82,7 @@ func Errorln(v ...interface{}) {
lock.Lock()
defer lock.Unlock()

v = append([]interface{}{errorPrefix}, v)
v = append([]interface{}{errorPrefix}, v...)
fmt.Fprintln(os.Stderr, v...)
}

Expand Down
44 changes: 31 additions & 13 deletions repository.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package baur

import (
"fmt"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -40,16 +41,35 @@ func FindRepository() (*Repository, error) {
return NewRepository(rootPath)
}

func ensureRepositoryCFGHasVersion(cfg *cfg.Repository, cfgPath string) error {
if cfg.BaurVersion == "" {
cfg.BaurVersion = version.Version
func writeVersionToCfg(cfg *cfg.Repository, cfgPath string) error {
cfg.BaurVersion = version.Version

err := cfg.ToFile(cfgPath, true)
if err != nil {
err := cfg.ToFile(cfgPath, true)
if err != nil {
return errors.Wrapf(err, "updating baur_version in %q failed", cfgPath)
}

log.Debugf("baur version written to %q\n", cfgPath)

return nil
}

func checkCfgVersion(cfg *cfg.Repository, cfgPath string) error {
if cfg.BaurVersion == "" {
if err := writeVersionToCfg(cfg, cfgPath); err != nil {
return err
}
}

log.Debugf("written baur version to repository config %s\n", cfgPath)
cfgVer, err := version.SemVerFromString(cfg.BaurVersion)
if err != nil {
return errors.Wrapf(err, "could not parse baur_version value %q from %q", cfg.BaurVersion, cfgPath)
}

if cfgVer.Major != version.CurSemVer.Major || cfgVer.Minor != version.CurSemVer.Minor {
return fmt.Errorf("repository config is for a different baur version, "+
"%q vs %q",
cfgVer.Short(), version.CurSemVer.Short())
}

return nil
Expand All @@ -63,16 +83,14 @@ func NewRepository(cfgPath string) (*Repository, error) {
"reading repository config %s failed", cfgPath)
}

err = ensureRepositoryCFGHasVersion(cfg, cfgPath)
if err != nil {
return nil, errors.Wrapf(err, "updating baur_version in %s failed", cfgPath)
}

err = cfg.Validate()
if err != nil {
return nil, errors.Wrapf(err,
"validating repository config %s failed",
cfgPath)
"validating repository config %q failed", cfgPath)
}

if err := checkCfgVersion(cfg, cfgPath); err != nil {
return nil, err
}

r := Repository{
Expand Down
9 changes: 8 additions & 1 deletion repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import (
)

func Test_ensureRepositoryCFGHasVersion(t *testing.T) {
version.Version = "0.0.0"
sver, err := version.SemVerFromString(version.Version)
if err != nil {
t.Fatal("setting version failed")
}
version.CurSemVer = *sver

tmpfileFD, err := ioutil.TempFile("", "example")
if err != nil {
t.Fatal("opening tmpfile failed: ", err)
Expand All @@ -22,7 +29,7 @@ func Test_ensureRepositoryCFGHasVersion(t *testing.T) {
r := cfg.ExampleRepository()
r.BaurVersion = ""

err = ensureRepositoryCFGHasVersion(r, tmpfileName)
err = checkCfgVersion(r, tmpfileName)
if err != nil {
t.Fatal(err)
}
Expand Down
87 changes: 81 additions & 6 deletions version/version.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package version

import "fmt"
import (
"errors"
"fmt"
"strconv"
"strings"
)

var (
// GitCommit contains the git commit of this version.
Expand All @@ -14,13 +19,83 @@ var (
// Appendix is appended after a hypen to the version number. It can be
// used to mark a build as a prerelease.
Appendix = ""

// CurSemVer is the current version
CurSemVer = SemVer{}
)

// FullVerNr returns a string containing Version and GitDescribe
func FullVerNr() string {
if Appendix == "" {
return fmt.Sprintf("%s (%s)", Version, GitCommit)
func init() {
s, err := SemVerFromString(Version)
if err == nil {
CurSemVer = *s
}

CurSemVer.GitCommit = GitCommit
}

// SemVer holds a semantic version
type SemVer struct {
Major int
Minor int
Patch int
Appendix string
GitCommit string
}

// String returns the string representation
func (s *SemVer) String() string {
ver := s.Short()

if s.GitCommit != "" {
ver += fmt.Sprintf(" (%s)", s.GitCommit)
}

return ver
}

// Short returns the version without GitCommit
func (s *SemVer) Short() string {
ver := fmt.Sprintf("%d.%d.%d", s.Major, s.Minor, s.Patch)

if s.Appendix != "" {
ver += "-" + s.Appendix
}
return ver
}

// SemVerFromString returns the SemVer representation of a string
func SemVerFromString(ver string) (*SemVer, error) {
var appendix string

spl := strings.Split(ver, ".")
if len(spl) < 3 {
return nil, errors.New("invalid format, should be <Major>.<Minor>.<Patch>[-appendix]")
}

major, err := strconv.ParseInt(spl[0], 10, 32)
if err != nil {
return nil, errors.New("could not convert major nr to int")
}

minor, err := strconv.ParseInt(spl[1], 10, 32)
if err != nil {
return nil, errors.New("could not convert minor nr to int")
}

patch, err := strconv.ParseInt(spl[2], 10, 32)
if err != nil {
return nil, errors.New("could not convert patch nr to int")
}

spl = strings.SplitN(ver, "-", 2)
if len(spl) > 1 {
appendix = spl[1]
}

return fmt.Sprintf("%s-%s (%s)", Version, Appendix, GitCommit)
return &SemVer{
Major: int(major),
Minor: int(minor),
Patch: int(patch),
Appendix: appendix,
}, nil
}

0 comments on commit 7cd6ad2

Please sign in to comment.