Skip to content

Commit

Permalink
Drop the hashicorp/go-version dependency (#14)
Browse files Browse the repository at this point in the history
* Drop the hashicorp/go-version dependency

Signed-off-by: Kimmo Lehto <[email protected]>

* Older go does not allow double-wrapping

Signed-off-by: Kimmo Lehto <[email protected]>

* Doc-comments

Signed-off-by: Kimmo Lehto <[email protected]>

* Roll back _test package renames to simplify the PR

Signed-off-by: Kimmo Lehto <[email protected]>

* Remove the useless ErrInvalidVersion

Signed-off-by: Kimmo Lehto <[email protected]>

* Small readability fix

Signed-off-by: Kimmo Lehto <[email protected]>

* A couple of comments

Signed-off-by: Kimmo Lehto <[email protected]>

* Actually, no need to change go version

Signed-off-by: Kimmo Lehto <[email protected]>

* Add mention about non-k0s versions

Signed-off-by: Kimmo Lehto <[email protected]>

* Add more examples to README

Signed-off-by: Kimmo Lehto <[email protected]>

---------

Signed-off-by: Kimmo Lehto <[email protected]>
  • Loading branch information
kke authored Jan 17, 2024
1 parent 37d3f0b commit 02d6454
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 204 deletions.
71 changes: 70 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# version

A go-language package for managing [k0s](https://github.com/k0sproject/k0s) version numbers. It is based on [hashicorp/go-version](https://github.com/hashicorp/go-version) but adds sorting and comparison capabilities for the k0s version numbering scheme which requires additional sorting by the build tag.
A go-language package for parsing, comparing, sorting and constraint-checking [k0s](https://github.com/k0sproject/k0s) version numbers. The API is modeled after [hashicorp/go-version](https://github.com/hashicorp/go-version).

K0s versioning follows [semver](https://semver.org/) v2.0 with the exception that there is a special metadata field for the k0s build version like `v1.23.4+k0s.1` which affects precedence while sorting or comparing version numbers.

The library should work fine for performing the same operations on non-k0s version numbers as long as there are maximum of 3 numeric segments (1.2.3), but this is not a priority.

## Usage

Expand All @@ -9,6 +13,7 @@ A go-language package for managing [k0s](https://github.com/k0sproject/k0s) vers
```go
import (
"fmt"

"github.com/k0sproject/version"
)

Expand All @@ -29,6 +34,70 @@ a is less than b: true
a is equal to b: false
```

### Constraints

```go
import (
"fmt"

"github.com/k0sproject/version"
)

func main() {
v := version.MustParse("1.23.3+k0s.1")
c := version.MustConstraint("> 1.23")
fmt.Printf("constraint %s satisfied by %s: %t\n", c, v, c.Check(v))
}
```

Outputs:

```text
constraint > 1.2.3 satisfied by v1.23.3+k0s.1: true
```

### Sorting

```go
import (
"fmt"
"sort"

"github.com/k0sproject/version"
)

func main() {
versions := []*version.Version{
version.MustParse("v1.23.3+k0s.2"),
version.MustParse("1.23.2+k0s.3"),
version.MustParse("1.23.3+k0s.1"),
}

fmt.Println("Before:")
for _, v range versions {
fmt.Println(v)
}
sort.Sort(versions)
fmt.Println("After:")
for _, v range versions {
fmt.Println(v)
}
}
```

Outputs:

```text
Before:
v1.23.3+k0s.2
v1.23.2+k0s.3
v1.23.3+k0s.1
After:
v1.23.2+k0s.3
v1.23.3+k0s.1
v1.23.3+k0s.2
```

### Check online for latest version

```go
Expand Down
58 changes: 0 additions & 58 deletions collection.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package version

import (
"encoding/json"
"fmt"
)

Expand Down Expand Up @@ -32,60 +31,3 @@ func (c Collection) Less(i, j int) bool {
func (c Collection) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}

func (c *Collection) marshal() ([]string, error) {
strSlice := make([]string, len(*c))
for i, v := range *c {
s, err := v.MarshalJSON()
if err != nil {
return nil, err
}
strSlice[i] = string(s)
}
return strSlice, nil
}

func (c *Collection) unmarshal(strSlice []string) error {
coll := make(Collection, len(strSlice))
for i, s := range strSlice {
v, err := NewVersion(s)
if err != nil {
return err
}
coll[i] = v
}
*c = coll
return nil
}

// UnmarshalText implements the json.Marshaler interface.
func (c *Collection) MarshalJSON() ([]byte, error) {
strSlice, err := c.marshal()
if err != nil {
return nil, err
}
return json.Marshal(strSlice)
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (c *Collection) UnmarshalJSON(data []byte) error {
var strSlice []string
if err := json.Unmarshal(data, &strSlice); err != nil {
return fmt.Errorf("failed to decode JSON input: %w", err)
}
return c.unmarshal(strSlice)
}

// MarshalYAML implements the yaml.Marshaler interface.
func (c *Collection) MarshalYAML() (interface{}, error) {
return c.marshal()
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *Collection) UnmarshalYAML(unmarshal func(interface{}) error) error {
var strSlice []string
if err := unmarshal(&strSlice); err != nil {
return fmt.Errorf("failed to decode YAML input: %w", err)
}
return c.unmarshal(strSlice)
}
40 changes: 8 additions & 32 deletions collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewCollection(t *testing.T) {
c, err := NewCollection("1.23.3+k0s.1", "1.23.4+k0s.1")
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, "v1.23.3+k0s.1", c[0].String())
assert.Equal(t, "v1.23.4+k0s.1", c[1].String())
assert.Len(t, c, 2)
Expand All @@ -20,55 +21,39 @@ func TestNewCollection(t *testing.T) {

func TestSorting(t *testing.T) {
c, err := NewCollection(
"1.22.3+k0s.0",
"1.21.2+k0s.0",
"1.21.2-beta.1+k0s.0",
"1.21.1+k0s.1",
"0.13.1",
"v1.21.1+k0s.2",
)
assert.NoError(t, err)
require.NoError(t, err)
sort.Sort(c)
assert.Equal(t, "v0.13.1", c[0].String())
assert.Equal(t, "v1.21.1+k0s.1", c[1].String())
assert.Equal(t, "v1.21.1+k0s.2", c[2].String())
assert.Equal(t, "v1.21.2-beta.1+k0s.0", c[3].String())
assert.Equal(t, "v1.21.2+k0s.0", c[4].String())
assert.Equal(t, "v1.22.3+k0s.0", c[5].String())
}

func TestCollectionMarshalling(t *testing.T) {
c, err := NewCollection("v1.0.0+k0s.0", "v1.0.1+k0s.0")
assert.NoError(t, err)
require.NoError(t, err)

t.Run("JSON", func(t *testing.T) {
jsonData, err := json.Marshal(c)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, `["v1.0.0+k0s.0","v1.0.1+k0s.0"]`, string(jsonData))
})

t.Run("YAML", func(t *testing.T) {
yamlData, err := c.MarshalYAML()
assert.NoError(t, err)
assert.Equal(t, []string{`"v1.0.0+k0s.0"`, `"v1.0.1+k0s.0"`}, yamlData)
})
}

func TestCollectionUnmarshalling(t *testing.T) {
t.Run("JSON", func(t *testing.T) {
var c Collection
err := json.Unmarshal([]byte(`["v1.0.0+k0s.1","v1.0.1+k0s.1"]`), &c)
assert.NoError(t, err)
assert.Equal(t, "v1.0.0+k0s.1", c[0].String())
assert.Equal(t, "v1.0.1+k0s.1", c[1].String())
})

t.Run("YAML", func(t *testing.T) {
var c Collection

err := c.UnmarshalYAML(func(i interface{}) error {
*(i.(*[]string)) = []string{"v1.0.0+k0s.1", "v1.0.1+k0s.1"}
return nil
})
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, "v1.0.0+k0s.1", c[0].String())
assert.Equal(t, "v1.0.1+k0s.1", c[1].String())
})
Expand All @@ -82,13 +67,4 @@ func TestFailingCollectionUnmarshalling(t *testing.T) {
err = json.Unmarshal([]byte(`["invalid_version"]`), &c)
assert.Error(t, err)
})

t.Run("YAML", func(t *testing.T) {
var c Collection
err := c.UnmarshalYAML(func(i interface{}) error {
*(i.(*[]string)) = []string{"invalid\n"}
return nil
})
assert.Error(t, err)
})
}
9 changes: 4 additions & 5 deletions constraint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ func TestConstraint(t *testing.T) {

for expected, versions := range tc.truthTable {
t.Run(fmt.Sprintf("%t", expected), func(t *testing.T) {
for _, version := range versions {
t.Run(version, func(t *testing.T) {
assert.Equal(t, expected, c.Check(MustParse(version)))
for _, v := range versions {
t.Run(v, func(t *testing.T) {
assert.Equal(t, expected, c.Check(MustParse(v)))
})
}
})
Expand All @@ -138,7 +138,7 @@ func TestInvalidConstraint(t *testing.T) {
}

for _, invalidConstraint := range invalidConstraints {
_, err := newConstraint(invalidConstraint)
_, err := NewConstraint(invalidConstraint)
assert.Error(t, err, "Expected error for invalid constraint: "+invalidConstraint)
}
}
Expand All @@ -158,4 +158,3 @@ func TestString(t *testing.T) {

assert.Equal(t, ">= 1.0.0, < 2.0.0", c.String())
}

5 changes: 1 addition & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ module github.com/k0sproject/version

go 1.17

require (
github.com/hashicorp/go-version v1.6.0
github.com/stretchr/testify v1.8.4
)
require github.com/stretchr/testify v1.8.4

require (
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
9 changes: 0 additions & 9 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading

0 comments on commit 02d6454

Please sign in to comment.