From 4031f5e24bd7644e38b60df8b31a26c86ba02f3d Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 24 May 2014 23:22:08 +0200 Subject: [PATCH] Fix version comparison in upgrade --- cmd/syncthing/{upgrade_unix.go => upgrade.go} | 37 +++++++++++++++---- cmd/syncthing/upgrade_test.go | 27 ++++++++++++++ cmd/syncthing/upgrade_windows.go | 9 ----- 3 files changed, 56 insertions(+), 17 deletions(-) rename cmd/syncthing/{upgrade_unix.go => upgrade.go} (84%) create mode 100644 cmd/syncthing/upgrade_test.go delete mode 100644 cmd/syncthing/upgrade_windows.go diff --git a/cmd/syncthing/upgrade_unix.go b/cmd/syncthing/upgrade.go similarity index 84% rename from cmd/syncthing/upgrade_unix.go rename to cmd/syncthing/upgrade.go index 226334b69..545080dbf 100644 --- a/cmd/syncthing/upgrade_unix.go +++ b/cmd/syncthing/upgrade.go @@ -1,11 +1,10 @@ -// +build !windows - package main import ( "archive/tar" "compress/gzip" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -14,8 +13,10 @@ import ( "path" "path/filepath" "runtime" + "strconv" "strings" + "bytes" "bitbucket.org/kardianos/osext" ) @@ -33,6 +34,10 @@ type githubAsset struct { var GoArchExtra string // "", "v5", "v6", "v7" func upgrade() error { + if runtime.GOOS == "windows" { + return errors.New("Upgrade currently unsupported on Windows") + } + path, err := osext.Executable() if err != nil { return err @@ -52,14 +57,15 @@ func upgrade() error { } rel := rels[0] - if rel.Tag > Version { - l.Infof("Attempting upgrade to %s...", rel.Tag) - } else if rel.Tag == Version { - l.Okf("Already running the latest version, %s. Not upgrading.", Version) - return nil - } else { + switch compareVersions(rel.Tag, Version) { + case -1: l.Okf("Current version %s is newer than latest release %s. Not upgrading.", Version, rel.Tag) return nil + case 0: + l.Okf("Already running the latest version, %s. Not upgrading.", Version) + return nil + default: + l.Infof("Attempting upgrade to %s...", rel.Tag) } expectedRelease := fmt.Sprintf("syncthing-%s-%s%s-%s.", runtime.GOOS, runtime.GOARCH, GoArchExtra, rel.Tag) @@ -147,3 +153,18 @@ func readTarGZ(url string, dir string) (string, error) { return "", fmt.Errorf("No upgrade found") } + +func compareVersions(a, b string) int { + return bytes.Compare(versionParts(a), versionParts(b)) +} + +func versionParts(v string) []byte { + parts := strings.Split(v, "-") + fields := strings.Split(parts[0], ".") + res := make([]byte, len(fields)) + for i, s := range fields { + v, _ := strconv.Atoi(s) + res[i] = byte(v) + } + return res +} diff --git a/cmd/syncthing/upgrade_test.go b/cmd/syncthing/upgrade_test.go new file mode 100644 index 000000000..43e3728ae --- /dev/null +++ b/cmd/syncthing/upgrade_test.go @@ -0,0 +1,27 @@ +package main + +import "testing" + +var testcases = []struct { + a, b string + r int +}{ + {"0.1.2", "0.1.2", 0}, + {"0.1.3", "0.1.2", 1}, + {"0.1.1", "0.1.2", -1}, + {"0.3.0", "0.1.2", 1}, + {"0.0.9", "0.1.2", -1}, + {"1.1.2", "0.1.2", 1}, + {"0.1.2", "1.1.2", -1}, + {"0.1.10", "0.1.9", 1}, + {"0.10.0", "0.2.0", 1}, + {"30.10.0", "4.9.0", 1}, +} + +func TestCompareVersions(t *testing.T) { + for _, tc := range testcases { + if r := compareVersions(tc.a, tc.b); r != tc.r { + t.Errorf("compareVersions(%q, %q): %d != %d", tc.a, tc.b, r, tc.r) + } + } +} diff --git a/cmd/syncthing/upgrade_windows.go b/cmd/syncthing/upgrade_windows.go deleted file mode 100644 index 5f5e001ef..000000000 --- a/cmd/syncthing/upgrade_windows.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build windows - -package main - -import "errors" - -func upgrade() error { - return errors.New("Upgrade currently unsupported on Windows") -}