Skip to content

Commit

Permalink
add regex support for product version [#162275259]
Browse files Browse the repository at this point in the history
Signed-off-by: Jesse Alford <[email protected]>
  • Loading branch information
fredwangwang authored and anEXPer committed Jan 3, 2019
1 parent 0024559 commit 9608d4a
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 12 deletions.
37 changes: 35 additions & 2 deletions commands/download_product.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import (
"io"
"os"
"path"
"regexp"
"sort"
"strconv"
"strings"

"github.com/hashicorp/go-version"
"github.com/pivotal-cf/go-pivnet"
pivnetlog "github.com/pivotal-cf/go-pivnet/logger"
"github.com/pivotal-cf/jhanda"
Expand Down Expand Up @@ -87,7 +90,7 @@ func (c DownloadProduct) Execute(args []string) error {
return fmt.Errorf("could not parse download-product flags: %s", err)
}

if c.Options.ProductVersionRegex != "" {
if c.Options.ProductVersionRegex != "" && c.Options.ProductVersion != "" {
return fmt.Errorf("cannot use both --product-version and --product-version-regex; please choose one or the other")
}

Expand All @@ -96,7 +99,37 @@ func (c DownloadProduct) Execute(args []string) error {

c.init()

releaseID, productFileName, err = c.downloadProductFile(c.Options.ProductSlug, c.Options.ProductVersion, c.Options.FileGlob)
productVersion := c.Options.ProductVersion
if c.Options.ProductVersionRegex != "" {
re, err := regexp.Compile(c.Options.ProductVersionRegex)
if err != nil {
return fmt.Errorf("could not compile regex: %s: %s", c.Options.ProductVersionRegex, err)
}

releases, err := c.client.ReleasesForProductSlug(c.Options.ProductSlug)
if err != nil {
return err
}

var versions []*version.Version
for _, release := range releases {
if !re.MatchString(release.Version) {
continue
}

v, err := version.NewVersion(release.Version)
if err != nil {
return fmt.Errorf("could not parse version: %s: %s", release.Version, err)
}
versions = append(versions, v)
}

sort.Sort(version.Collection(versions))

productVersion = versions[len(versions)-1].Original()
}

releaseID, productFileName, err = c.downloadProductFile(c.Options.ProductSlug, productVersion, c.Options.FileGlob)
if err != nil {
return fmt.Errorf("could not download product: %s", err)
}
Expand Down
93 changes: 83 additions & 10 deletions commands/download_product_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ var _ = Describe("DownloadProduct", func() {
})
Expect(err).NotTo(HaveOccurred())

Expect(fakePivnetDownloader.ReleasesForProductSlugCallCount()).To(Equal(0))
Expect(fakePivnetDownloader.ReleaseForVersionCallCount()).To(Equal(1))
Expect(fakePivnetDownloader.ProductFilesForReleaseCallCount()).To(Equal(1))
Expect(fakePivnetDownloader.DownloadProductFileCallCount()).To(Equal(1))
Expand All @@ -102,24 +103,81 @@ var _ = Describe("DownloadProduct", func() {
Expect(string(fileContent)).To(MatchJSON(fmt.Sprintf(`{"product_path": "%s", "product_slug": "elastic-runtime" }`, file.Name())))
})

PContext("when the version is given as a regex", func() {
It("downloads the highest version matching that regex", func(){
Context("when the version is given as a regex", func() {
BeforeEach(func() {
fakePivnetDownloader.ReleasesForProductSlugReturns([]pivnet.Release{
{
ID: 5,
Version: "3.0.0",
},
{
ID: 4,
Version: "1.1.11",
},
{
ID: 3,
Version: "2.1.2",
},
{
ID: 2,
Version: "2.1.1",
},
{
ID: 1,
Version: "2.0.1",
},
}, nil)

fakePivnetDownloader.ProductFilesForReleaseReturnsOnCall(0, []pivnet.ProductFile{
{
ID: 54321,
AWSObjectKey: "/some-account/some-bucket/cf-2.1-build.11.pivotal",
Name: "Example Cloud Foundry",
},
}, nil)

fakePivnetDownloader.ReleaseForVersionReturnsOnCall(0, pivnet.Release{
ID: 4,
}, nil)
})
})

Context("when both product-version and product-version-regex are set", func() {
It("fails with an error saying that the user must pick one or the other", func(){
It("downloads the highest version matching that regex", func() {
err := command.Execute([]string{
"--pivnet-api-token", "token",
"--pivnet-file-glob", "*.pivotal",
"--pivnet-product-slug", "elastic-runtime",
"--product-version", "2.0.0",
"--product-version-regex", ".*",
"--product-version-regex", `2\..\..*`,
"--output-directory", tempDir,
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("cannot use both --product-version and --product-version-regex; please choose one or the other"))
Expect(err).NotTo(HaveOccurred())

Expect(fakePivnetDownloader.ReleasesForProductSlugCallCount()).To(Equal(1))
Expect(fakePivnetDownloader.ReleaseForVersionCallCount()).To(Equal(1))
Expect(fakePivnetDownloader.ProductFilesForReleaseCallCount()).To(Equal(1))
Expect(fakePivnetDownloader.DownloadProductFileCallCount()).To(Equal(1))

slug := fakePivnetDownloader.ReleasesForProductSlugArgsForCall(0)
Expect(slug).To(Equal("elastic-runtime"))

slug, version := fakePivnetDownloader.ReleaseForVersionArgsForCall(0)
Expect(slug).To(Equal("elastic-runtime"))
Expect(version).To(Equal("2.1.2"))

slug, releaseID := fakePivnetDownloader.ProductFilesForReleaseArgsForCall(0)
Expect(slug).To(Equal("elastic-runtime"))
Expect(releaseID).To(Equal(4))

file, slug, releaseID, productFileID, _ := fakePivnetDownloader.DownloadProductFileArgsForCall(0)
Expect(file.Name()).To(Equal(path.Join(tempDir, "cf-2.1-build.11.pivotal")))
Expect(slug).To(Equal("elastic-runtime"))
Expect(releaseID).To(Equal(4))
Expect(productFileID).To(Equal(54321))

fileName := path.Join(tempDir, commands.DownloadProductOutputFilename)
fileContent, err := ioutil.ReadFile(fileName)
Expect(err).NotTo(HaveOccurred())
Expect(fileName).To(BeAnExistingFile())
Expect(string(fileContent)).To(MatchJSON(fmt.Sprintf(`{"product_path": "%s", "product_slug": "elastic-runtime" }`, file.Name())))
})
})

Expand Down Expand Up @@ -258,7 +316,7 @@ var _ = Describe("DownloadProduct", func() {
}`, productFile.Name(), stemcellFile.Name())))
})

Context("when the product is not a tile", func() {
Context("when the product is not a tile and download-stemcell flag is set", func() {
BeforeEach(func() {
fakePivnetDownloader.ReleaseForVersionReturnsOnCall(0, pivnet.Release{
ID: 12345,
Expand Down Expand Up @@ -439,6 +497,21 @@ output-directory: %s
})
})

Context("when both product-version and product-version-regex are set", func() {
It("fails with an error saying that the user must pick one or the other", func() {
err := command.Execute([]string{
"--pivnet-api-token", "token",
"--pivnet-file-glob", "*.pivotal",
"--pivnet-product-slug", "elastic-runtime",
"--product-version", "2.0.0",
"--product-version-regex", ".*",
"--output-directory", tempDir,
})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("cannot use both --product-version and --product-version-regex; please choose one or the other"))
})
})

Context("when the release specified is not available", func() {
BeforeEach(func() {
fakePivnetDownloader.ReleaseForVersionReturns(pivnet.Release{}, fmt.Errorf("some-error"))
Expand Down

0 comments on commit 9608d4a

Please sign in to comment.