implement /in
fetches a given list of globs from the assets. also be durable to 'v' prefixing version tags Signed-off-by: Alex Suraci <asuraci@pivotal.io>
This commit is contained in:
18
README.md
18
README.md
@@ -14,15 +14,23 @@ Fetches and creates versioned GitHub resources.
|
|||||||
|
|
||||||
## Behavior
|
## Behavior
|
||||||
|
|
||||||
### `check`: Extract versions from the bucket.
|
### `check`: Check for released versions.
|
||||||
|
|
||||||
*TODO*
|
Releases are listed and sorted by their tag, using
|
||||||
|
[semver](http://semver.org) semantics if possible.
|
||||||
|
|
||||||
### `in`: Fetch an object from the bucket.
|
### `in`: Fetch assets from a release.
|
||||||
|
|
||||||
*TODO*
|
Fetches artifacts from the given release version. If the version is not
|
||||||
|
specified, the latest version is chosen using [semver](http://semver.org)
|
||||||
|
semantics.
|
||||||
|
|
||||||
### `out`: Upload an object to the bucket.
|
#### Parameters
|
||||||
|
|
||||||
|
* `globs`: *Optional.* A list of globs for files that will be downloaded from
|
||||||
|
the release. If not specified, all assets will be fetched.
|
||||||
|
|
||||||
|
### `out`: Publish a release.
|
||||||
|
|
||||||
Given a name specified in `name`, a body specified in `body`, and the tag to use
|
Given a name specified in `name`, a body specified in `body`, and the tag to use
|
||||||
specified in `tag`, this creates a release on GitHub then uploads the files
|
specified in `tag`, this creates a release on GitHub then uploads the files
|
||||||
|
@@ -72,12 +72,12 @@ func (r byVersion) Less(i, j int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
first, err := semver.New(*r[i].TagName)
|
first, err := semver.New(dropLeadingAlpha(*r[i].TagName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
second, err := semver.New(*r[j].TagName)
|
second, err := semver.New(dropLeadingAlpha(*r[j].TagName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@@ -44,9 +44,9 @@ var _ = Describe("Check Command", func() {
|
|||||||
Context("when there are releases", func() {
|
Context("when there are releases", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
returnedReleases = []github.RepositoryRelease{
|
returnedReleases = []github.RepositoryRelease{
|
||||||
{TagName: github.String("0.4.0")},
|
{TagName: github.String("v0.4.0")},
|
||||||
{TagName: github.String("0.1.3")},
|
{TagName: github.String("0.1.3")},
|
||||||
{TagName: github.String("0.1.2")},
|
{TagName: github.String("v0.1.2")},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ var _ = Describe("Check Command", func() {
|
|||||||
|
|
||||||
Ω(response).Should(HaveLen(1))
|
Ω(response).Should(HaveLen(1))
|
||||||
Ω(response[0]).Should(Equal(resource.Version{
|
Ω(response[0]).Should(Equal(resource.Version{
|
||||||
Tag: "0.4.0",
|
Tag: "v0.4.0",
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -79,9 +79,9 @@ var _ = Describe("Check Command", func() {
|
|||||||
Context("when there are releases", func() {
|
Context("when there are releases", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
returnedReleases = []github.RepositoryRelease{
|
returnedReleases = []github.RepositoryRelease{
|
||||||
{TagName: github.String("0.1.4")},
|
{TagName: github.String("v0.1.4")},
|
||||||
{TagName: github.String("0.4.0")},
|
{TagName: github.String("0.4.0")},
|
||||||
{TagName: github.String("0.1.3")},
|
{TagName: github.String("v0.1.3")},
|
||||||
{TagName: github.String("0.1.2")},
|
{TagName: github.String("0.1.2")},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -104,13 +104,13 @@ var _ = Describe("Check Command", func() {
|
|||||||
|
|
||||||
response, err := command.Run(resource.CheckRequest{
|
response, err := command.Run(resource.CheckRequest{
|
||||||
Version: resource.Version{
|
Version: resource.Version{
|
||||||
Tag: "0.1.3",
|
Tag: "v0.1.3",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
Ω(err).ShouldNot(HaveOccurred())
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
Ω(response).Should(Equal([]resource.Version{
|
Ω(response).Should(Equal([]resource.Version{
|
||||||
{Tag: "0.1.4"},
|
{Tag: "v0.1.4"},
|
||||||
{Tag: "0.4.0"},
|
{Tag: "0.4.0"},
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
41
cmd/in/in.go
Normal file
41
cmd/in/in.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/concourse/github-release-resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
resource.Sayf("usage: %s <sources directory>\n", os.Args[0])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var request resource.InRequest
|
||||||
|
inputRequest(&request)
|
||||||
|
|
||||||
|
destDir := os.Args[1]
|
||||||
|
|
||||||
|
github := resource.NewGitHubClient(request.Source)
|
||||||
|
command := resource.NewInCommand(github)
|
||||||
|
response, err := command.Run(destDir, request)
|
||||||
|
if err != nil {
|
||||||
|
resource.Fatal("running command", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
outputResponse(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func inputRequest(request *resource.InRequest) {
|
||||||
|
if err := json.NewDecoder(os.Stdin).Decode(request); err != nil {
|
||||||
|
resource.Fatal("reading request from stdin", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func outputResponse(response resource.InResponse) {
|
||||||
|
if err := json.NewEncoder(os.Stdout).Encode(response); err != nil {
|
||||||
|
resource.Fatal("writing response to stdout", err)
|
||||||
|
}
|
||||||
|
}
|
@@ -26,6 +26,15 @@ type FakeGitHub struct {
|
|||||||
result1 *github.RepositoryRelease
|
result1 *github.RepositoryRelease
|
||||||
result2 error
|
result2 error
|
||||||
}
|
}
|
||||||
|
ListReleaseAssetsStub func(release *github.RepositoryRelease) ([]github.ReleaseAsset, error)
|
||||||
|
listReleaseAssetsMutex sync.RWMutex
|
||||||
|
listReleaseAssetsArgsForCall []struct {
|
||||||
|
release *github.RepositoryRelease
|
||||||
|
}
|
||||||
|
listReleaseAssetsReturns struct {
|
||||||
|
result1 []github.ReleaseAsset
|
||||||
|
result2 error
|
||||||
|
}
|
||||||
UploadReleaseAssetStub func(release *github.RepositoryRelease, name string, file *os.File) error
|
UploadReleaseAssetStub func(release *github.RepositoryRelease, name string, file *os.File) error
|
||||||
uploadReleaseAssetMutex sync.RWMutex
|
uploadReleaseAssetMutex sync.RWMutex
|
||||||
uploadReleaseAssetArgsForCall []struct {
|
uploadReleaseAssetArgsForCall []struct {
|
||||||
@@ -96,6 +105,39 @@ func (fake *FakeGitHub) CreateReleaseReturns(result1 *github.RepositoryRelease,
|
|||||||
}{result1, result2}
|
}{result1, result2}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fake *FakeGitHub) ListReleaseAssets(release *github.RepositoryRelease) ([]github.ReleaseAsset, error) {
|
||||||
|
fake.listReleaseAssetsMutex.Lock()
|
||||||
|
fake.listReleaseAssetsArgsForCall = append(fake.listReleaseAssetsArgsForCall, struct {
|
||||||
|
release *github.RepositoryRelease
|
||||||
|
}{release})
|
||||||
|
fake.listReleaseAssetsMutex.Unlock()
|
||||||
|
if fake.ListReleaseAssetsStub != nil {
|
||||||
|
return fake.ListReleaseAssetsStub(release)
|
||||||
|
} else {
|
||||||
|
return fake.listReleaseAssetsReturns.result1, fake.listReleaseAssetsReturns.result2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *FakeGitHub) ListReleaseAssetsCallCount() int {
|
||||||
|
fake.listReleaseAssetsMutex.RLock()
|
||||||
|
defer fake.listReleaseAssetsMutex.RUnlock()
|
||||||
|
return len(fake.listReleaseAssetsArgsForCall)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *FakeGitHub) ListReleaseAssetsArgsForCall(i int) *github.RepositoryRelease {
|
||||||
|
fake.listReleaseAssetsMutex.RLock()
|
||||||
|
defer fake.listReleaseAssetsMutex.RUnlock()
|
||||||
|
return fake.listReleaseAssetsArgsForCall[i].release
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fake *FakeGitHub) ListReleaseAssetsReturns(result1 []github.ReleaseAsset, result2 error) {
|
||||||
|
fake.ListReleaseAssetsStub = nil
|
||||||
|
fake.listReleaseAssetsReturns = struct {
|
||||||
|
result1 []github.ReleaseAsset
|
||||||
|
result2 error
|
||||||
|
}{result1, result2}
|
||||||
|
}
|
||||||
|
|
||||||
func (fake *FakeGitHub) UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error {
|
func (fake *FakeGitHub) UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error {
|
||||||
fake.uploadReleaseAssetMutex.Lock()
|
fake.uploadReleaseAssetMutex.Lock()
|
||||||
fake.uploadReleaseAssetArgsForCall = append(fake.uploadReleaseAssetArgsForCall, struct {
|
fake.uploadReleaseAssetArgsForCall = append(fake.uploadReleaseAssetArgsForCall, struct {
|
||||||
|
11
github.go
11
github.go
@@ -13,6 +13,8 @@ import (
|
|||||||
type GitHub interface {
|
type GitHub interface {
|
||||||
ListReleases() ([]github.RepositoryRelease, error)
|
ListReleases() ([]github.RepositoryRelease, error)
|
||||||
CreateRelease(release *github.RepositoryRelease) (*github.RepositoryRelease, error)
|
CreateRelease(release *github.RepositoryRelease) (*github.RepositoryRelease, error)
|
||||||
|
|
||||||
|
ListReleaseAssets(release *github.RepositoryRelease) ([]github.ReleaseAsset, error)
|
||||||
UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error
|
UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +59,15 @@ func (g *GitHubClient) CreateRelease(release *github.RepositoryRelease) (*github
|
|||||||
return createdRelease, nil
|
return createdRelease, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GitHubClient) ListReleaseAssets(release *github.RepositoryRelease) ([]github.ReleaseAsset, error) {
|
||||||
|
assets, _, err := g.client.Repositories.ListReleaseAssets(g.user, g.repository, *release.ID, nil)
|
||||||
|
if err != nil {
|
||||||
|
return []github.ReleaseAsset{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return assets, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GitHubClient) UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error {
|
func (g *GitHubClient) UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error {
|
||||||
_, _, err := g.client.Repositories.UploadReleaseAsset(
|
_, _, err := g.client.Repositories.UploadReleaseAsset(
|
||||||
g.user,
|
g.user,
|
||||||
|
116
in_command.go
Normal file
116
in_command.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InCommand struct {
|
||||||
|
github GitHub
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInCommand(github GitHub) *InCommand {
|
||||||
|
return &InCommand{
|
||||||
|
github: github,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *InCommand) Run(destDir string, request InRequest) (InResponse, error) {
|
||||||
|
releases, err := c.github.ListReleases()
|
||||||
|
if err != nil {
|
||||||
|
return InResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(byVersion(releases))
|
||||||
|
|
||||||
|
if len(releases) == 0 {
|
||||||
|
return InResponse{}, errors.New("no releases")
|
||||||
|
}
|
||||||
|
|
||||||
|
var foundRelease *github.RepositoryRelease
|
||||||
|
|
||||||
|
if request.Version == nil {
|
||||||
|
foundRelease = &releases[len(releases)-1]
|
||||||
|
} else {
|
||||||
|
for _, release := range releases {
|
||||||
|
if *release.TagName == request.Version.Tag {
|
||||||
|
foundRelease = &release
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if foundRelease == nil {
|
||||||
|
return InResponse{}, fmt.Errorf("could not find release with tag: %s", request.Version.Tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
assets, err := c.github.ListReleaseAssets(foundRelease)
|
||||||
|
if err != nil {
|
||||||
|
return InResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, asset := range assets {
|
||||||
|
url := *asset.BrowserDownloadURL
|
||||||
|
path := filepath.Join(destDir, *asset.Name)
|
||||||
|
|
||||||
|
var matchFound bool
|
||||||
|
if len(request.Params.Globs) == 0 {
|
||||||
|
matchFound = true
|
||||||
|
} else {
|
||||||
|
for _, glob := range request.Params.Globs {
|
||||||
|
matches, err := filepath.Match(glob, *asset.Name)
|
||||||
|
if err != nil {
|
||||||
|
return InResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches {
|
||||||
|
matchFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matchFound {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.downloadFile(url, path)
|
||||||
|
if err != nil {
|
||||||
|
return InResponse{}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return InResponse{
|
||||||
|
Version: Version{
|
||||||
|
Tag: *foundRelease.TagName,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *InCommand) downloadFile(url, destPath string) error {
|
||||||
|
out, err := os.Create(destPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
206
in_command_test.go
Normal file
206
in_command_test.go
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
package resource_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/onsi/gomega/ghttp"
|
||||||
|
|
||||||
|
"github.com/concourse/github-release-resource"
|
||||||
|
"github.com/concourse/github-release-resource/fakes"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("In Command", func() {
|
||||||
|
var (
|
||||||
|
command *resource.InCommand
|
||||||
|
githubClient *fakes.FakeGitHub
|
||||||
|
server *ghttp.Server
|
||||||
|
|
||||||
|
inRequest resource.InRequest
|
||||||
|
|
||||||
|
inResponse resource.InResponse
|
||||||
|
inErr error
|
||||||
|
|
||||||
|
destDir string
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
githubClient = &fakes.FakeGitHub{}
|
||||||
|
command = resource.NewInCommand(githubClient)
|
||||||
|
|
||||||
|
destDir, err = ioutil.TempDir("", "github-release")
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
server = ghttp.NewServer()
|
||||||
|
server.RouteToHandler("GET", "/example.txt", ghttp.RespondWith(200, "example.txt"))
|
||||||
|
server.RouteToHandler("GET", "/example.rtf", ghttp.RespondWith(200, "example.rtf"))
|
||||||
|
server.RouteToHandler("GET", "/example.wtf", ghttp.RespondWith(200, "example.wtf"))
|
||||||
|
|
||||||
|
inRequest = resource.InRequest{}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
inResponse, inErr = command.Run(destDir, inRequest)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
server.Close()
|
||||||
|
Ω(os.RemoveAll(destDir)).Should(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
buildRelease := func(id int, tag string) github.RepositoryRelease {
|
||||||
|
return github.RepositoryRelease{
|
||||||
|
ID: &id,
|
||||||
|
TagName: &tag,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildAsset := func(name string) github.ReleaseAsset {
|
||||||
|
url := server.URL() + "/" + name
|
||||||
|
|
||||||
|
return github.ReleaseAsset{
|
||||||
|
Name: &name,
|
||||||
|
BrowserDownloadURL: &url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context("when there are releases", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
githubClient.ListReleasesReturns([]github.RepositoryRelease{
|
||||||
|
buildRelease(2, "v0.35.0"),
|
||||||
|
buildRelease(1, "v0.34.0"),
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
githubClient.ListReleaseAssetsReturns([]github.ReleaseAsset{
|
||||||
|
buildAsset("example.txt"),
|
||||||
|
buildAsset("example.rtf"),
|
||||||
|
buildAsset("example.wtf"),
|
||||||
|
}, nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when a present version is specified", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
inRequest.Version = &resource.Version{
|
||||||
|
Tag: "v0.35.0",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when valid asset filename globs are given", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
inRequest.Params = resource.InParams{
|
||||||
|
Globs: []string{"*.txt", "*.rtf"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("succeeds", func() {
|
||||||
|
Ω(inErr).ShouldNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns the fetched version", func() {
|
||||||
|
Ω(inResponse.Version).Should(Equal(resource.Version{Tag: "v0.35.0"}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("downloads only the files that match the globs", func() {
|
||||||
|
_, err := os.Stat(filepath.Join(destDir, "example.txt"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = os.Stat(filepath.Join(destDir, "example.rtf"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = os.Stat(filepath.Join(destDir, "example.wtf"))
|
||||||
|
Ω(err).Should(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when an invalid asset filename glob is given", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
inRequest.Params = resource.InParams{
|
||||||
|
Globs: []string{`[`},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns an error", func() {
|
||||||
|
Ω(inErr).Should(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when no globs are specified", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
inRequest.Source = resource.Source{}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("succeeds", func() {
|
||||||
|
Ω(inErr).ShouldNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns the fetched version", func() {
|
||||||
|
Ω(inResponse.Version).Should(Equal(resource.Version{Tag: "v0.35.0"}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("downloads all of the files", func() {
|
||||||
|
_, err := os.Stat(filepath.Join(destDir, "example.txt"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = os.Stat(filepath.Join(destDir, "example.rtf"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = os.Stat(filepath.Join(destDir, "example.wtf"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when the specified version is not available", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
inRequest.Version = &resource.Version{
|
||||||
|
Tag: "v0.36.0",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns an error", func() {
|
||||||
|
Ω(inErr).Should(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when the version is not specified", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
inRequest.Version = nil
|
||||||
|
})
|
||||||
|
|
||||||
|
It("succeeds", func() {
|
||||||
|
Ω(inErr).ShouldNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns the fetched version", func() {
|
||||||
|
Ω(inResponse.Version).Should(Equal(resource.Version{Tag: "v0.35.0"}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("fetches from the latest release", func() {
|
||||||
|
_, err := os.Stat(filepath.Join(destDir, "example.txt"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = os.Stat(filepath.Join(destDir, "example.rtf"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = os.Stat(filepath.Join(destDir, "example.wtf"))
|
||||||
|
Ω(err).ShouldNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when no releases are present", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
githubClient.ListReleasesReturns([]github.RepositoryRelease{}, nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns an error", func() {
|
||||||
|
Ω(inErr).Should(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
15
resources.go
15
resources.go
@@ -12,6 +12,21 @@ type CheckRequest struct {
|
|||||||
Version Version `json:"version"`
|
Version Version `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InRequest struct {
|
||||||
|
Source Source `json:"source"`
|
||||||
|
Version *Version `json:"version"`
|
||||||
|
Params InParams `json:"params"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InParams struct {
|
||||||
|
Globs []string `json:"globs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InResponse struct {
|
||||||
|
Version Version `json:"version"`
|
||||||
|
Metadata []MetadataPair `json:"metadata"`
|
||||||
|
}
|
||||||
|
|
||||||
type OutRequest struct {
|
type OutRequest struct {
|
||||||
Source Source `json:"source"`
|
Source Source `json:"source"`
|
||||||
Params OutParams `json:"params"`
|
Params OutParams `json:"params"`
|
||||||
|
13
strings.go
Normal file
13
strings.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package resource
|
||||||
|
|
||||||
|
import "unicode"
|
||||||
|
|
||||||
|
func dropLeadingAlpha(s string) string {
|
||||||
|
for i, r := range s {
|
||||||
|
if !unicode.IsLetter(r) {
|
||||||
|
return s[i:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
Reference in New Issue
Block a user