Skip to content

Commit

Permalink
Allow filtering versions below a specified version
Browse files Browse the repository at this point in the history
[Fixes concourse#67]
  • Loading branch information
Akshay Mankar committed Feb 8, 2018
1 parent 351c6d0 commit 5b53b0b
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 1 deletion.
2 changes: 1 addition & 1 deletion check_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (c *CheckCommand) Run(request CheckRequest) ([]Version, error) {
)
}

return reversedVersions, nil
return FilterVersions(reversedVersions, request.Source.VersionFilter)
}

type byVersion []*github.RepositoryRelease
Expand Down
26 changes: 26 additions & 0 deletions check_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,32 @@ var _ = Describe("Check Command", func() {
})
})

Context("when version_filter is specified", func() {
BeforeEach(func() {
returnedReleases = []*github.RepositoryRelease{
newRepositoryRelease(1, "v0.1.4"),
newRepositoryRelease(2, "0.4.0"),
newRepositoryRelease(3, "v0.1.3"),
newRepositoryRelease(4, "0.1.2"),
}
})
It("returns only version not matching the filter", func() {
command = resource.NewCheckCommand(githubClient)

response, err := command.Run(resource.CheckRequest{
Version: resource.Version{Tag: "0.1.2"},
Source: resource.Source{VersionFilter: "< 0.2.0"},
})
Ω(err).ShouldNot(HaveOccurred())

Ω(response).Should(Equal([]resource.Version{
{Tag: "0.1.2"},
{Tag: "v0.1.3"},
{Tag: "v0.1.4"},
}))
})
})

Context("when there are prior versions", func() {
Context("when there are no releases", func() {
BeforeEach(func() {
Expand Down
1 change: 1 addition & 0 deletions resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Source struct {
PreRelease bool `json:"pre_release"`
Release bool `json:"release"`
Insecure bool `json:"insecure"`
VersionFilter string `json:"version_filter"`
}

type CheckRequest struct {
Expand Down
66 changes: 66 additions & 0 deletions version_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package resource

import (
"errors"
"regexp"

"github.com/cppforlife/go-semi-semantic/version"
)

func FilterVersions(versions []Version, predicateString string) ([]Version, error) {
if predicateString == "" {
return versions, nil
}

predicate, err := ParsePredicate(predicateString)
if err != nil {
return []Version{}, err
}

var filteredVersions []Version

for _, version := range versions {
if predicate.Apply(version) {
filteredVersions = append(filteredVersions, version)
}
}

return filteredVersions, err
}

type VersionPredicate struct {
Condition string
Version string
}

func ParsePredicate(filter string) (VersionPredicate, error) {
re, err := regexp.Compile(`(<)\s*(.*)`)
if err != nil {
return VersionPredicate{}, err
}

matches := re.FindAllStringSubmatch(filter, -1)
if len(matches) != 1 || len(matches[0]) != 3 {
return VersionPredicate{}, errors.New("Invalid version filter")
}

return VersionPredicate{Condition: matches[0][1], Version: matches[0][2]}, nil
}

func (p VersionPredicate) Apply(version Version) bool {
return lessThan(version, Version{Tag: p.Version})
}

func lessThan(v1, v2 Version) bool {
first, err := version.NewVersionFromString(determineVersionFromTag(v1.Tag))
if err != nil {
return true
}

second, err := version.NewVersionFromString(determineVersionFromTag(v2.Tag))
if err != nil {
return false
}

return first.IsLt(second)
}
44 changes: 44 additions & 0 deletions version_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package resource_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

. "github.com/concourse/github-release-resource"
)

var _ = Describe("VersionUtils", func() {
Describe("FilterVersion", func() {
It("should filter list of versions by tag", func() {
inputVersions := []Version{{Tag: "0.1.1"}, {Tag: "0.2.1"}, {Tag: "0.3.0"}, {Tag: "0.3.1"}}
versions, err := FilterVersions(inputVersions, "< 0.3.0")
Expect(err).ToNot(HaveOccurred())
Expect(versions).To(Equal([]Version{{Tag: "0.1.1"}, {Tag: "0.2.1"}}))
})
Context("When filter is blank", func() {
It("should return the input versions", func() {
inputVersions := []Version{{Tag: "0.1.1"}, {Tag: "0.2.1"}, {Tag: "0.3.0"}, {Tag: "0.3.1"}}
versions, err := FilterVersions(inputVersions, "")
Expect(err).ToNot(HaveOccurred())
Expect(versions).To(Equal(inputVersions))
})
})
})

Describe("VersionFilter", func() {
Describe("ParsePredicate", func() {
It("should parse a '<' filter", func() {
filter, err := ParsePredicate("< 3.1.1")
Expect(err).ToNot(HaveOccurred())
Expect(filter).To(Equal(VersionPredicate{Condition: "<", Version: "3.1.1"}))
})
})
})

Describe("Apply", func() {
It("should determine if the given versions bool value", func() {
predicate := VersionPredicate{Condition: "<", Version: "4.0.0"}
Expect(predicate.Apply(Version{Tag: "3.9.9"})).To(Equal(true))
})
})
})

0 comments on commit 5b53b0b

Please sign in to comment.