From f811294572daedb751efd3c45ff9dec0325e5bd6 Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Sat, 17 Oct 2015 17:37:36 -0700 Subject: [PATCH 1/9] added json marshal/unsmarshal support --- version.go | 25 +++++++++++++++++++++++++ version_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/version.go b/version.go index d0e0b0c..bc31e79 100644 --- a/version.go +++ b/version.go @@ -2,6 +2,7 @@ package version import ( "bytes" + "encoding/json" "fmt" "reflect" "regexp" @@ -249,3 +250,27 @@ func (v *Version) String() string { return buf.String() } + +// MarshalJSON - implement the json-Marshaler interface +func (v *Version) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalJSON - implement the json-Unmarshaler interface +func (v *Version) UnmarshalJSON(data []byte) (err error) { + var verStr string + var nv *Version + + err = json.Unmarshal(data, &verStr) + if err != nil { + return + } + + nv, err = NewVersion(verStr) + if err != nil { + return + } + *v = *nv + + return +} diff --git a/version_test.go b/version_test.go index cc96a04..cec689e 100644 --- a/version_test.go +++ b/version_test.go @@ -1,6 +1,7 @@ package version import ( + "encoding/json" "reflect" "testing" ) @@ -206,3 +207,36 @@ func TestVersionString(t *testing.T) { } } } + +func TestJsonMarshal(t *testing.T) { + type MyStruct struct { + Ver *Version + } + ver, _ := NewVersion("1.2.3") + data := MyStruct{Ver: ver} + expected := `{"Ver":"1.2.3"}` + b, err := json.Marshal(&data) + if err != nil { + t.Fatalf("expected: json.Marshal to succed\nactual: failed with error: %v", err) + } + actual := string(b) + if actual != expected { + t.Fatalf("expected: %v\nactual: %v", expected, actual) + } +} + +func TestJsonUnmarshal(t *testing.T) { + type MyStruct struct { + Ver *Version + } + ver, _ := NewVersion("1.2.3") + expected := MyStruct{Ver: ver} + data := []byte(`{"Ver":"1.2.3"}`) + var actual MyStruct + if err := json.Unmarshal(data, &actual); err != nil { + t.Fatalf("expected: json.Unmarshal to succeed\nactual: failed with error: %v", err) + } + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("expected: %v\nactual: %v", expected, actual) + } +} From d80b6f1e818da92bf65cf23fc310af46f90e98ba Mon Sep 17 00:00:00 2001 From: burl Date: Sat, 17 Oct 2015 17:37:36 -0700 Subject: [PATCH 2/9] added json marshal/unsmarshal support --- version.go | 25 +++++++++++++++++++++++++ version_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/version.go b/version.go index d0e0b0c..bc31e79 100644 --- a/version.go +++ b/version.go @@ -2,6 +2,7 @@ package version import ( "bytes" + "encoding/json" "fmt" "reflect" "regexp" @@ -249,3 +250,27 @@ func (v *Version) String() string { return buf.String() } + +// MarshalJSON - implement the json-Marshaler interface +func (v *Version) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalJSON - implement the json-Unmarshaler interface +func (v *Version) UnmarshalJSON(data []byte) (err error) { + var verStr string + var nv *Version + + err = json.Unmarshal(data, &verStr) + if err != nil { + return + } + + nv, err = NewVersion(verStr) + if err != nil { + return + } + *v = *nv + + return +} diff --git a/version_test.go b/version_test.go index cc96a04..cec689e 100644 --- a/version_test.go +++ b/version_test.go @@ -1,6 +1,7 @@ package version import ( + "encoding/json" "reflect" "testing" ) @@ -206,3 +207,36 @@ func TestVersionString(t *testing.T) { } } } + +func TestJsonMarshal(t *testing.T) { + type MyStruct struct { + Ver *Version + } + ver, _ := NewVersion("1.2.3") + data := MyStruct{Ver: ver} + expected := `{"Ver":"1.2.3"}` + b, err := json.Marshal(&data) + if err != nil { + t.Fatalf("expected: json.Marshal to succed\nactual: failed with error: %v", err) + } + actual := string(b) + if actual != expected { + t.Fatalf("expected: %v\nactual: %v", expected, actual) + } +} + +func TestJsonUnmarshal(t *testing.T) { + type MyStruct struct { + Ver *Version + } + ver, _ := NewVersion("1.2.3") + expected := MyStruct{Ver: ver} + data := []byte(`{"Ver":"1.2.3"}`) + var actual MyStruct + if err := json.Unmarshal(data, &actual); err != nil { + t.Fatalf("expected: json.Unmarshal to succeed\nactual: failed with error: %v", err) + } + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("expected: %v\nactual: %v", expected, actual) + } +} From 494804d4f4e6808218ffccaaff580d6fffd215c5 Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Sun, 18 Oct 2015 21:11:09 -0700 Subject: [PATCH 3/9] added json marshaling interface for constraints; added round-trip json-marshal/unmarshal tests for both version and constraints --- constraint.go | 25 +++++++++++++++++++++++++ constraint_test.go | 27 +++++++++++++++++++++++++++ version_test.go | 39 ++++++++++++++++----------------------- 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/constraint.go b/constraint.go index 96f6d83..7f0cbf9 100644 --- a/constraint.go +++ b/constraint.go @@ -1,6 +1,7 @@ package version import ( + "encoding/json" "fmt" "regexp" "strings" @@ -156,3 +157,27 @@ func constraintPessimistic(v, c *Version) bool { return true } + +// MarshalJSON - implement the json-Marshaler interface +func (c *Constraints) MarshalJSON() ([]byte, error) { + return json.Marshal(c.String()) +} + +// UnmarshalJSON - implement the json-Unmarshaler interface +func (c *Constraints) UnmarshalJSON(data []byte) (err error) { + var constraintStr string + var nc Constraints + + err = json.Unmarshal(data, &constraintStr) + if err != nil { + return + } + + nc, err = NewConstraint(constraintStr) + if err != nil { + return + } + *c = nc + + return +} diff --git a/constraint_test.go b/constraint_test.go index 6581df0..18a2b77 100644 --- a/constraint_test.go +++ b/constraint_test.go @@ -1,6 +1,8 @@ package version import ( + "bytes" + "encoding/json" "testing" ) @@ -98,3 +100,28 @@ func TestConstraintsString(t *testing.T) { } } } + +func TestConstraintsJson(t *testing.T) { + type MyStruct struct { + MustVer Constraints + } + var ( + vc MyStruct + err error + ) + jsBytes := []byte(`{"MustVer":"=1.2, =1.3"}`) + // data -> struct + err = json.Unmarshal(jsBytes, &vc) + if err != nil { + t.Fatalf("expected: json.Unmarshal to succeed\nactual: failed with error %v", err) + } + // struct -> data + data, err := json.Marshal(&vc) + if err != nil { + t.Fatalf("expected: json.Marshal to succeed\nactual: failed with error %v", err) + } + + if !bytes.Equal(data, jsBytes) { + t.Fatalf("expected: %s\nactual: %s", jsBytes, data) + } +} diff --git a/version_test.go b/version_test.go index cec689e..4631420 100644 --- a/version_test.go +++ b/version_test.go @@ -1,6 +1,7 @@ package version import ( + "bytes" "encoding/json" "reflect" "testing" @@ -208,35 +209,27 @@ func TestVersionString(t *testing.T) { } } -func TestJsonMarshal(t *testing.T) { +func TestVersionJson(t *testing.T) { type MyStruct struct { Ver *Version } - ver, _ := NewVersion("1.2.3") - data := MyStruct{Ver: ver} - expected := `{"Ver":"1.2.3"}` - b, err := json.Marshal(&data) + var ( + ver MyStruct + err error + ) + jsBytes := []byte(`{"Ver":"1.2.3"}`) + // data -> struct + err = json.Unmarshal(jsBytes, &ver) if err != nil { - t.Fatalf("expected: json.Marshal to succed\nactual: failed with error: %v", err) + t.Fatalf("expected: json.Unmarshal to succeed\nactual: failed with error %v", err) } - actual := string(b) - if actual != expected { - t.Fatalf("expected: %v\nactual: %v", expected, actual) + // struct -> data + data, err := json.Marshal(&ver) + if err != nil { + t.Fatalf("expected: json.Marshal to succeed\nactual: failed with error %v", err) } -} -func TestJsonUnmarshal(t *testing.T) { - type MyStruct struct { - Ver *Version - } - ver, _ := NewVersion("1.2.3") - expected := MyStruct{Ver: ver} - data := []byte(`{"Ver":"1.2.3"}`) - var actual MyStruct - if err := json.Unmarshal(data, &actual); err != nil { - t.Fatalf("expected: json.Unmarshal to succeed\nactual: failed with error: %v", err) - } - if !reflect.DeepEqual(expected, actual) { - t.Fatalf("expected: %v\nactual: %v", expected, actual) + if !bytes.Equal(data, jsBytes) { + t.Fatalf("expected: %s\nactual: %s", jsBytes, data) } } From d133270df8dfa6ff1611bf46624fcc37ef326628 Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Fri, 23 Oct 2015 13:43:56 -0700 Subject: [PATCH 4/9] added BumpVersion() and unit test for it --- version.go | 26 ++++++++++++++++++++++++++ version_test.go | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/version.go b/version.go index bc31e79..40a1db1 100644 --- a/version.go +++ b/version.go @@ -20,6 +20,20 @@ const VersionRegexpRaw string = `([0-9]+(\.[0-9]+){0,2})` + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + `?` +type VersionPart int + +const ( + MajorPart VersionPart = iota + MinorPart + PatchPart + PreReleasePart + MetadataPart +) + +var partNames = [...]string{ + "major", "minor", "patch", "prerelease", "metadata", +} + // Version represents a single version. type Version struct { metadata string @@ -251,6 +265,18 @@ func (v *Version) String() string { return buf.String() } +// BumpVersion - increment the indicated part by one +// part may be one of: MajorPart, MinorPart or PatchPart +func (v *Version) BumpVersion(part VersionPart) (err error) { + switch part { + case MajorPart, MinorPart, PatchPart: + v.segments[part]++ + default: + err = fmt.Errorf("unable to bump version part %s", partNames[part]) + } + return +} + // MarshalJSON - implement the json-Marshaler interface func (v *Version) MarshalJSON() ([]byte, error) { return json.Marshal(v.String()) diff --git a/version_test.go b/version_test.go index 4631420..5caba17 100644 --- a/version_test.go +++ b/version_test.go @@ -209,7 +209,43 @@ func TestVersionString(t *testing.T) { } } -func TestVersionJson(t *testing.T) { +func TestBumpVersion(t *testing.T) { + cases := []struct { + version string + part VersionPart + result string + err bool + }{ + {"1.1.1", MajorPart, "2.1.1", false}, + {"1.1.1", MinorPart, "1.2.1", false}, + {"1.1.1", PatchPart, "1.1.2", false}, + {"2", MinorPart, "2.1.0", false}, + {"2.2", PatchPart, "2.2.1", false}, + {"1.1.0-beta1", MinorPart, "1.2.0-beta1", false}, + {"1.1.0-beta1", PreReleasePart, "", true}, + {"1.1.0-beta1+foo", MetadataPart, "", true}, + } + + for _, tc := range cases { + v, err := NewVersion(tc.version) + if err != nil { + t.Fatalf("error parsing version %s", tc.version) + } + err = v.BumpVersion(tc.part) + if tc.err && err == nil { + t.Fatalf("expected error for version: %s", tc.version) + } else if !tc.err && err != nil { + t.Fatalf("error for version %s: %s", tc.version, err) + } + if !tc.err { + if v.String() != tc.result { + t.Fatalf("BumpVersion %d, expecting: %s\nfound %s", tc.part, tc.result, v.String()) + } + } + } +} + +func TestVersionJSON(t *testing.T) { type MyStruct struct { Ver *Version } From 1de0e6314c9996f0bf47b0aa440ba0b1ae35a94c Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Sat, 21 May 2016 08:55:54 -0700 Subject: [PATCH 5/9] fixed encoding issue with JSON Marshaler, added a YAML Marshaller --- version.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/version.go b/version.go index 40a1db1..cfbe97a 100644 --- a/version.go +++ b/version.go @@ -279,7 +279,7 @@ func (v *Version) BumpVersion(part VersionPart) (err error) { // MarshalJSON - implement the json-Marshaler interface func (v *Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) + return []byte(fmt.Sprintf(`"%s"`, v.String())), nil } // UnmarshalJSON - implement the json-Unmarshaler interface @@ -300,3 +300,21 @@ func (v *Version) UnmarshalJSON(data []byte) (err error) { return } + +// MarshalYAML - implement the YAML-Marshaler interface (gopkg.in/yaml.v2) +func (v *Version) MarshalYAML() ([]byte, error) { + return []byte(v.String()), nil +} + +// UnmarshalYAML - implement the yaml-Unmarshaler interface (gopkg.in/yaml.v2) +func (v *Version) UnmarshalYAML(data []byte) (err error) { + var nv *Version + verStr := string(data) + nv, err = NewVersion(verStr) + if err != nil { + return + } + *v = *nv + + return +} From 5b68f654db99ea4e35d4d545de63aaef6d333772 Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Sat, 21 May 2016 08:58:38 -0700 Subject: [PATCH 6/9] updated --- version.go | 1 + 1 file changed, 1 insertion(+) diff --git a/version.go b/version.go index cfbe97a..2f18771 100644 --- a/version.go +++ b/version.go @@ -310,6 +310,7 @@ func (v *Version) MarshalYAML() ([]byte, error) { func (v *Version) UnmarshalYAML(data []byte) (err error) { var nv *Version verStr := string(data) + fmt.Println("verstr is ", verStr) nv, err = NewVersion(verStr) if err != nil { return From bc31dc9ca71d08c0a57d689f53c6edc6a4c308b4 Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Sat, 21 May 2016 09:54:25 -0700 Subject: [PATCH 7/9] fixed interface for yaml {un}marshal support for Version --- version.go | 21 ++++++++++++--------- version_test.go | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/version.go b/version.go index 2f18771..cd217c6 100644 --- a/version.go +++ b/version.go @@ -302,20 +302,23 @@ func (v *Version) UnmarshalJSON(data []byte) (err error) { } // MarshalYAML - implement the YAML-Marshaler interface (gopkg.in/yaml.v2) -func (v *Version) MarshalYAML() ([]byte, error) { - return []byte(v.String()), nil +func (v *Version) MarshalYAML() (str interface{}, err error) { + str = v.String() + return } // UnmarshalYAML - implement the yaml-Unmarshaler interface (gopkg.in/yaml.v2) -func (v *Version) UnmarshalYAML(data []byte) (err error) { - var nv *Version - verStr := string(data) - fmt.Println("verstr is ", verStr) - nv, err = NewVersion(verStr) - if err != nil { +func (v *Version) UnmarshalYAML(unmarshal func(interface{}) error) (err error) { + var ( + verStr string + nv *Version + ) + if err = unmarshal(&verStr); err != nil { + return + } + if nv, err = NewVersion(verStr); err != nil { return } *v = *nv - return } diff --git a/version_test.go b/version_test.go index 5caba17..f0168c7 100644 --- a/version_test.go +++ b/version_test.go @@ -5,6 +5,8 @@ import ( "encoding/json" "reflect" "testing" + + "gopkg.in/yaml.v2" ) func TestNewVersion(t *testing.T) { @@ -269,3 +271,23 @@ func TestVersionJSON(t *testing.T) { t.Fatalf("expected: %s\nactual: %s", jsBytes, data) } } + +func TestVersionYAML(t *testing.T) { + type MyStruct struct { + Ver *Version `yaml:"version"` + } + var thing MyStruct + yamlText := []byte(`version: 1.1.1`) + err := yaml.Unmarshal(yamlText, &thing) + if err != nil { + t.Fatalf("failed to unmarshal yaml: %v", err) + } + thing.Ver.BumpVersion(PatchPart) + data, err := yaml.Marshal(&thing) + if err != nil { + t.Fatalf("yaml.UnMarshal did not succeed: %v", err) + } + if !bytes.Equal(data, []byte("version: 1.1.2\n")) { + t.Fatalf("expected: version: 1.1.2\\n, actual: %s", string(data)) + } +} From 317f51b9537ec3b8f3248f2775ea8b0f1c6179ea Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Mon, 23 May 2016 15:34:51 -0700 Subject: [PATCH 8/9] added YAML marshalling/unmarshalling for constraints --- constraint.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/constraint.go b/constraint.go index 7f0cbf9..c2099f9 100644 --- a/constraint.go +++ b/constraint.go @@ -181,3 +181,27 @@ func (c *Constraints) UnmarshalJSON(data []byte) (err error) { return } + +// MarshalYAML - implement the YAML-Marshaler interface (gopkg.in/yaml.v2) +func (c *Constraints) MarshalYAML() (str interface{}, err error) { + str = c.String() + return +} + +// UnmarshalYAML - implement the yaml-Unmarshaler interface (gopkg.in/yaml.v2) +func (c *Constraints) UnmarshalYAML(unmarshal func(interface{}) error) (err error) { + var constraintStr string + var nc Constraints + + if err = unmarshal(&constraintStr); err != nil { + return + } + + nc, err = NewConstraint(constraintStr) + if err != nil { + return + } + *c = nc + + return +} From 758edfbba225edb42eac4bcc91094304c3971b21 Mon Sep 17 00:00:00 2001 From: Burl Nyswonger Date: Wed, 8 Jun 2016 21:29:20 -0700 Subject: [PATCH 9/9] removing yaml test for now --- version_test.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/version_test.go b/version_test.go index f0168c7..5caba17 100644 --- a/version_test.go +++ b/version_test.go @@ -5,8 +5,6 @@ import ( "encoding/json" "reflect" "testing" - - "gopkg.in/yaml.v2" ) func TestNewVersion(t *testing.T) { @@ -271,23 +269,3 @@ func TestVersionJSON(t *testing.T) { t.Fatalf("expected: %s\nactual: %s", jsBytes, data) } } - -func TestVersionYAML(t *testing.T) { - type MyStruct struct { - Ver *Version `yaml:"version"` - } - var thing MyStruct - yamlText := []byte(`version: 1.1.1`) - err := yaml.Unmarshal(yamlText, &thing) - if err != nil { - t.Fatalf("failed to unmarshal yaml: %v", err) - } - thing.Ver.BumpVersion(PatchPart) - data, err := yaml.Marshal(&thing) - if err != nil { - t.Fatalf("yaml.UnMarshal did not succeed: %v", err) - } - if !bytes.Equal(data, []byte("version: 1.1.2\n")) { - t.Fatalf("expected: version: 1.1.2\\n, actual: %s", string(data)) - } -}