From bb00604d650cf333cc3fcbc195983a1c3d73233e Mon Sep 17 00:00:00 2001 From: Juan Ariza Toledano Date: Thu, 30 Nov 2023 09:40:17 +0100 Subject: [PATCH] feat: add support for collections (#2) --- README.md | 19 +++++- pkg/version/version_collection.go | 17 ++++++ pkg/version/version_collection_test.go | 80 ++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 pkg/version/version_collection.go create mode 100644 pkg/version/version_collection_test.go diff --git a/README.md b/README.md index d10bb93..579d603 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # go-version [![Go Report Card](https://goreportcard.com/badge/github.com/bitnami/go-version)](https://goreportcard.com/report/github.com/bitnami/go-version) -[![CI](https://github.com/bitnami/gonit/actions/workflows/go.yml/badge.svg)](https://github.com/bitnami/gonit/actions/workflows/go.yml) +[![CI](https://github.com/bitnami/go-version/actions/workflows/go.yml/badge.svg)](https://github.com/bitnami/go-version/actions/workflows/go.yml) go-version is a library for parsing Bitnami packages versions and version constraints, and verifying versions against a set of constraints. @@ -10,6 +10,7 @@ go-version is a library for parsing Bitnami packages versions and version constr - [Usage](#usage) - [Version parsing and comparison](#version-parsing-and-comparison) + - [Sorting](#sorting) - [Version constraints](#version-constraints) - [Version revision](#version-revision) - [Missing major/minor/patch versions](#missing-majorminorpatch-versions) @@ -37,6 +38,22 @@ if v1.LessThan(v2) { } ``` +### Sorting + +Collections of versions can be sorted using the `sort.Sort` function from the standard library. + +```go +versionsRaw := []string{"1.1.0", "0.7.1", "1.4.0", "1.4.0-alpha", "1.4.1-beta", "1.4.0-alpha.2+20130313144700"} +versions := make(version.Collection, len(versionsRaw)) +for i, raw := range versionsRaw { + v, _ := version.Parse(raw) + versions[i] = v +} + +// After this, the versions are properly sorted +sort.Sort(versions) +``` + ### Version constraints Comma-separated version constraints are considered an `AND`. For example, `>= 1.2.3, < 2.0.0` means the version needs to be greater than or equal to `1.2` and less than `3.0.0`. diff --git a/pkg/version/version_collection.go b/pkg/version/version_collection.go new file mode 100644 index 0000000..1384e5b --- /dev/null +++ b/pkg/version/version_collection.go @@ -0,0 +1,17 @@ +package version + +// Collection is a type that implements the sort.Interface interface +// so that versions can be sorted. +type Collection []Version + +func (v Collection) Len() int { + return len(v) +} + +func (v Collection) Less(i, j int) bool { + return v[i].LessThan(v[j]) +} + +func (v Collection) Swap(i, j int) { + v[i], v[j] = v[j], v[i] +} diff --git a/pkg/version/version_collection_test.go b/pkg/version/version_collection_test.go new file mode 100644 index 0000000..bef33b6 --- /dev/null +++ b/pkg/version/version_collection_test.go @@ -0,0 +1,80 @@ +package version + +import ( + "sort" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCollection(t *testing.T) { + tests := []struct { + name string + versions []string + want []string + }{ + { + name: "happy path", + versions: []string{ + "1.1.1", + "1.0.0", + "1.2.0", + "2.0.0", + "0.7.1", + }, + want: []string{ + "0.7.1", + "1.0.0", + "1.1.1", + "1.2.0", + "2.0.0", + }, + }, + { + name: "revisions", + versions: []string{ + "1.0.0-1.1", + "1.0.0-3.1", + "1.0.0", + "1.0.0-2.2", + "1.0.0-2.11", + "1.0.0-1", + "1.0.0-1.2", + "1.0.0-2", + }, + want: []string{ + "1.0.0", + "1.0.0-1", + "1.0.0-1.1", + "1.0.0-1.2", + "1.0.0-2", + "1.0.0-2.2", + "1.0.0-2.11", + "1.0.0-3.1", + }, + }, + } + t.Parallel() + for _, testToRun := range tests { + test := testToRun + t.Run(test.name, func(tt *testing.T) { + tt.Parallel() + versions := make(Collection, len(test.versions)) + for i, raw := range test.versions { + v, err := Parse(raw) + require.NoError(tt, err) + versions[i] = v + } + + sort.Sort(versions) + + got := make([]string, len(versions)) + for i, v := range versions { + got[i] = v.String() + } + + assert.Equal(tt, test.want, got) + }) + } +}