From 2a8edd82d75d0d6420275a0eb744352e32f12b83 Mon Sep 17 00:00:00 2001 From: decentral1se Date: Mon, 6 Sep 2021 12:20:06 +0200 Subject: [PATCH] feat: support asc/dec sorting Closes https://git.coopcloud.tech/coop-cloud/tagcmp/issues/1. --- README.md | 2 +- godoc.md | 56 ++++++++++++++++++++++++++++++++++++++------------ tagcmp.go | 19 ++++++++++++----- tagcmp_test.go | 47 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 100 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7f7c132..5a32dda 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ func main() { } } - sort.Sort(tagcmp.ByTag(compatible)) + sort.Sort(tagcmp.ByTagAsc(compatible)) fmt.Println(compatible) } diff --git a/godoc.md b/godoc.md index 54d2d60..ae64511 100644 --- a/godoc.md +++ b/godoc.md @@ -12,10 +12,14 @@ Package tagcmp provides image tag comparison operations\. - [Variables](<#variables>) - [func IsParsable(tag string) bool](<#func-isparsable>) -- [type ByTag](<#type-bytag>) - - [func (t ByTag) Len() int](<#func-bytag-len>) - - [func (t ByTag) Less(i, j int) bool](<#func-bytag-less>) - - [func (t ByTag) Swap(i, j int)](<#func-bytag-swap>) +- [type ByTagAsc](<#type-bytagasc>) + - [func (t ByTagAsc) Len() int](<#func-bytagasc-len>) + - [func (t ByTagAsc) Less(i, j int) bool](<#func-bytagasc-less>) + - [func (t ByTagAsc) Swap(i, j int)](<#func-bytagasc-swap>) +- [type ByTagDesc](<#type-bytagdesc>) + - [func (t ByTagDesc) Len() int](<#func-bytagdesc-len>) + - [func (t ByTagDesc) Less(i, j int) bool](<#func-bytagdesc-less>) + - [func (t ByTagDesc) Swap(i, j int)](<#func-bytagdesc-swap>) - [type Tag](<#type-tag>) - [func Parse(tag string) (Tag, error)](<#func-parse>) - [func (t Tag) Equals(tag Tag) bool](<#func-tag-equals>) @@ -65,30 +69,56 @@ func IsParsable(tag string) bool IsParsable determines if a tag is supported by this library -## type ByTag +## type ByTagAsc -ByTag sorts tags in asc/desc order where the last element is the latest tag\. +ByTagAsc sorts tags in ascending order where the last element is the latest tag\. ```go -type ByTag []Tag +type ByTagAsc []Tag ``` -### func \(ByTag\) Len +### func \(ByTagAsc\) Len ```go -func (t ByTag) Len() int +func (t ByTagAsc) Len() int ``` -### func \(ByTag\) Less +### func \(ByTagAsc\) Less ```go -func (t ByTag) Less(i, j int) bool +func (t ByTagAsc) Less(i, j int) bool ``` -### func \(ByTag\) Swap +### func \(ByTagAsc\) Swap ```go -func (t ByTag) Swap(i, j int) +func (t ByTagAsc) Swap(i, j int) +``` + +## type ByTagDesc + +ByTagDesc sorts tags in descending order where the first element is the latest tag\. + +```go +type ByTagDesc []Tag +``` + +### func \(ByTagDesc\) Len + +```go +func (t ByTagDesc) Len() int +``` + +### func \(ByTagDesc\) Less + +```go +func (t ByTagDesc) Less(i, j int) bool +``` + +### func \(ByTagDesc\) Swap + +```go +func (t ByTagDesc) Swap(i, j int) ``` ## type Tag diff --git a/tagcmp.go b/tagcmp.go index 430d85e..c898c55 100644 --- a/tagcmp.go +++ b/tagcmp.go @@ -18,15 +18,24 @@ type Tag struct { UsesV bool // whether or not the tag uses the "v" prefix } -// ByTag sorts tags in asc/desc order where the last element is the latest tag. -type ByTag []Tag +// ByTagAsc sorts tags in ascending order where the last element is the latest tag. +type ByTagAsc []Tag -func (t ByTag) Len() int { return len(t) } -func (t ByTag) Swap(i, j int) { t[i], t[j] = t[j], t[i] } -func (t ByTag) Less(i, j int) bool { +func (t ByTagAsc) Len() int { return len(t) } +func (t ByTagAsc) Swap(i, j int) { t[i], t[j] = t[j], t[i] } +func (t ByTagAsc) Less(i, j int) bool { return t[i].IsLessThan(t[j]) } +// ByTagDesc sorts tags in descending order where the first element is the latest tag. +type ByTagDesc []Tag + +func (t ByTagDesc) Len() int { return len(t) } +func (t ByTagDesc) Swap(i, j int) { t[j], t[i] = t[i], t[j] } +func (t ByTagDesc) Less(i, j int) bool { + return t[j].IsLessThan(t[i]) +} + // IsGreaterThan tests if a tag is greater than another. There are some // tag-isms to take into account here, shorter is bigger (i.e. 2.1 > 2.1.1 == // true, 2 > 2.1 == true). diff --git a/tagcmp_test.go b/tagcmp_test.go index 42eec1d..bf1981c 100644 --- a/tagcmp_test.go +++ b/tagcmp_test.go @@ -617,7 +617,7 @@ func TestIsCompatible(t *testing.T) { } } -func TestSort1(t *testing.T) { +func TestSortAsc1(t *testing.T) { rawTags := []string{ "v1.4.8", "v1.3.9", @@ -637,7 +637,7 @@ func TestSort1(t *testing.T) { tags = append(tags, tag) } - sort.Sort(tagcmp.ByTag(tags)) + sort.Sort(tagcmp.ByTagAsc(tags)) expected := []string{ "v0.0.1", @@ -656,7 +656,7 @@ func TestSort1(t *testing.T) { } } -func TestSort2(t *testing.T) { +func TestSortAsc2(t *testing.T) { rawTags := []string{ "10.0", "10.6", @@ -675,7 +675,7 @@ func TestSort2(t *testing.T) { tags = append(tags, tag) } - sort.Sort(tagcmp.ByTag(tags)) + sort.Sort(tagcmp.ByTagAsc(tags)) expected := []string{ "5.5", @@ -693,6 +693,43 @@ func TestSort2(t *testing.T) { } } +func TestSortDesc(t *testing.T) { + rawTags := []string{ + "10.0", + "10.6", + "10.2", + "10.1", + "10.5", + "5.5", + } + + var tags []tagcmp.Tag + for _, rawTag := range rawTags { + tag, err := tagcmp.Parse(rawTag) + if err != nil { + t.Errorf("'%s' should have parsed but didn't: %s", tag, err) + } + tags = append(tags, tag) + } + + sort.Sort(tagcmp.ByTagDesc(tags)) + + expected := []string{ + "10.6", + "10.5", + "10.2", + "10.1", + "10.0", + "5.5", + } + + for idx, tag := range tags { + if tag.String() != expected[idx] { + t.Errorf("'%s' sorted out of order, saw '%s', expected '%s'", tag, tags, expected) + } + } +} + func TestString(t *testing.T) { for _, tag := range supported { p, err := tagcmp.Parse(tag) @@ -730,7 +767,7 @@ func TestGiteaFilterCompatible(t *testing.T) { } } - sort.Sort(tagcmp.ByTag(filtered)) + sort.Sort(tagcmp.ByTagAsc(filtered)) for idx, tag := range filtered { if tag.String() != expected[idx] {