Skip to content
49 changes: 49 additions & 0 deletions constraint.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package version

import (
"encoding/json"
"fmt"
"regexp"
"strings"
Expand Down Expand Up @@ -156,3 +157,51 @@ 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 {
Comment on lines +171 to +177

Choose a reason for hiding this comment

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

Suggested change
err = json.Unmarshal(data, &constraintStr)
if err != nil {
return
}
nc, err = NewConstraint(constraintStr)
if err != nil {
if err = json.Unmarshal(data, &constraintStr); err != nil {
return
}
if nc, err = NewConstraint(constraintStr); err != nil {

return
}
*c = nc

return
}

// MarshalYAML - implement the YAML-Marshaler interface (gopkg.in/yaml.v2)
func (c *Constraints) MarshalYAML() (str interface{}, err error) {
str = c.String()
return
Comment on lines +186 to +188

Choose a reason for hiding this comment

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

Suggested change
func (c *Constraints) MarshalYAML() (str interface{}, err error) {
str = c.String()
return
func (c *Constraints) MarshalYAML() (interface{}, error) {
return c.String(), nil

}

// 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 {
Comment on lines +200 to +201

Choose a reason for hiding this comment

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

Suggested change
nc, err = NewConstraint(constraintStr)
if err != nil {
if nc, err = NewConstraint(constraintStr); err != nil {

return
}
*c = nc

return
}
27 changes: 27 additions & 0 deletions constraint_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package version

import (
"bytes"
"encoding/json"
"testing"
)

Expand Down Expand Up @@ -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)
}
}
73 changes: 73 additions & 0 deletions version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package version

import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"regexp"
Expand All @@ -19,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
Expand Down Expand Up @@ -249,3 +264,61 @@ 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 []byte(fmt.Sprintf(`"%s"`, v.String())), nil
}

// 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 {
Comment on lines +290 to +296

Choose a reason for hiding this comment

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

Suggested change
err = json.Unmarshal(data, &verStr)
if err != nil {
return
}
nv, err = NewVersion(verStr)
if err != nil {
if err = json.Unmarshal(data, &verStr); err != nil {
return
}
if nv, err = NewVersion(verStr); err != nil {

return
}
*v = *nv

return
}

// MarshalYAML - implement the YAML-Marshaler interface (gopkg.in/yaml.v2)
func (v *Version) MarshalYAML() (str interface{}, err error) {
str = v.String()
return
}
Comment on lines +305 to +308

Choose a reason for hiding this comment

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

Suggested change
func (v *Version) MarshalYAML() (str interface{}, err error) {
str = v.String()
return
}
func (v *Version) MarshalYAML() (interface{}, error) {
return v.String(), nil
}


// UnmarshalYAML - implement the yaml-Unmarshaler interface (gopkg.in/yaml.v2)
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
}
63 changes: 63 additions & 0 deletions version_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package version

import (
"bytes"
"encoding/json"
"reflect"
"testing"
)
Expand Down Expand Up @@ -206,3 +208,64 @@ func TestVersionString(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
}
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.Unmarshal to succeed\nactual: failed with error %v", err)
}
// struct -> data
data, err := json.Marshal(&ver)
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)
}
}