From d2e12bf84bd22d2f76ff9af7e6d2f9b13b19bdc1 Mon Sep 17 00:00:00 2001 From: Benedikt Lang Date: Tue, 1 Jul 2014 22:11:26 +0200 Subject: [PATCH] First draft --- semver.go | 147 +++++++++++++++++++++++++++++++++++++++++++++++++ semver_test.go | 58 +++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 semver.go create mode 100644 semver_test.go diff --git a/semver.go b/semver.go new file mode 100644 index 0000000..69c9810 --- /dev/null +++ b/semver.go @@ -0,0 +1,147 @@ +package semver + +import ( + "bytes" + "errors" + "strconv" +) + +var SEMVER_SPEC_VERSION = Version{ + Major: 2, + Minor: 0, + Patch: 0, +} + +type Version struct { + Major int + Minor int + Patch int + Pre []PRVersion + Build []string //No Precendence +} + +func (v Version) String() string { + var buf bytes.Buffer + var DOT = []byte(".") + var HYPHEN = []byte("-") + var PLUS = []byte("+") + buf.WriteString(strconv.Itoa(v.Major)) + buf.Write(DOT) + buf.WriteString(strconv.Itoa(v.Minor)) + buf.Write(DOT) + buf.WriteString(strconv.Itoa(v.Patch)) + if len(v.Pre) > 0 { + buf.Write(HYPHEN) + for i, pre := range v.Pre { + if i > 0 { + buf.Write(DOT) + } + buf.WriteString(pre.String()) + } + } + if len(v.Build) > 0 { + buf.Write(PLUS) + for i, build := range v.Build { + if i > 0 { + buf.Write(DOT) + } + buf.WriteString(build) + } + } + return buf.String() +} + +func (v *Version) compare(o *Version) int { + if v.Major != o.Major { + if v.Major > o.Major { + return 1 + } else { + return -1 + } + } + if v.Minor != o.Minor { + if v.Minor > o.Minor { + return 1 + } else { + return -1 + } + } + if v.Patch != o.Patch { + if v.Patch > o.Patch { + return 1 + } else { + return -1 + } + } + + if len(v.Pre) == 0 && len(o.Pre) == 0 { + return 0 + } else if len(v.Pre) == 0 && len(o.Pre) > 0 { + return -1 + } else if len(v.Pre) > 0 && len(o.Pre) == 0 { + return 1 + } else { + //Deep PreRelease Version comparison + + return -2 //TODO: Not yet implemented + + } + +} + +func Parse(s string) (*Version, error) { + return nil, errors.New("Not implemented yet") +} + +// PreRelease Version +type PRVersion interface { + compare(*PRVersion) int + String() string //fmt.Stringer + IsNumeric() bool +} + +// Alphabetical PreRelease Version +type AlphaPRVersion struct { + Version string +} + +func (v *AlphaPRVersion) IsNumeric() bool { + return false +} + +func (v *AlphaPRVersion) compare(o *AlphaPRVersion) int { + if v.Version == o.Version { + return 0 + } else if v.Version > o.Version { + return 1 + } else { + return -1 + } +} + +func (v AlphaPRVersion) String() string { + return v.Version +} + +// Numeric PreRelease Version +type NumPRVersion struct { + Version int +} + +func (v *NumPRVersion) compare(o *NumPRVersion) int { + if v.Version == o.Version { + return 0 + } else if v.Version > o.Version { + return 1 + } else { + return -1 + } +} + +func (v NumPRVersion) String() string { + return strconv.Itoa(v.Version) +} + +func (v *NumPRVersion) IsNumeric() bool { + return true +} diff --git a/semver_test.go b/semver_test.go new file mode 100644 index 0000000..37868c1 --- /dev/null +++ b/semver_test.go @@ -0,0 +1,58 @@ +package semver + +import ( + "testing" +) + +func TestParse(t *testing.T) { + +} + +type stringerTest struct { + v Version + result string +} + +var stringerTests = []stringerTest{ + {Version{1, 2, 3, nil, nil}, "1.2.3"}, + {Version{0, 0, 1, nil, nil}, "0.0.1"}, +} + +func TestStringer(t *testing.T) { + for _, test := range stringerTests { + if res := test.v.String(); res != test.result { + t.Errorf("Stringer, expected %q but got %q", test.result, res) + } + } +} + +type compareTest struct { + v1 Version + v2 Version + result int +} + +var compareTests = []compareTest{ + {Version{1, 0, 0, nil, nil}, Version{1, 0, 0, nil, nil}, 0}, + {Version{2, 0, 0, nil, nil}, Version{1, 0, 0, nil, nil}, 1}, + {Version{0, 1, 0, nil, nil}, Version{0, 1, 0, nil, nil}, 0}, + {Version{0, 2, 0, nil, nil}, Version{0, 1, 0, nil, nil}, 1}, + {Version{0, 0, 1, nil, nil}, Version{0, 0, 1, nil, nil}, 0}, + {Version{0, 0, 2, nil, nil}, Version{0, 0, 1, nil, nil}, 1}, + {Version{1, 2, 3, nil, nil}, Version{1, 2, 3, nil, nil}, 0}, + {Version{2, 2, 4, nil, nil}, Version{1, 2, 4, nil, nil}, 1}, + {Version{1, 3, 3, nil, nil}, Version{1, 2, 3, nil, nil}, 1}, + {Version{1, 2, 4, nil, nil}, Version{1, 2, 3, nil, nil}, 1}, +} + +func TestCompare(t *testing.T) { + for _, test := range compareTests { + if res := test.v1.compare(&test.v2); res != test.result { + t.Errorf("Comparing %q : %q, expected %d but got %d", test.v1, test.v2, test.result, res) + } + //Test counterpart + if res := test.v2.compare(&test.v1); res != -test.result { + t.Errorf("Comparing %q : %q, expected %d but got %d", test.v2, test.v1, -test.result, res) + } + } +}