implement check command

This commit is contained in:
Chris Brown
2015-02-01 12:37:29 +00:00
parent b841ce205a
commit 0deda9939c
8 changed files with 265 additions and 59 deletions

62
check_command.go Normal file
View File

@@ -0,0 +1,62 @@
package resource
import (
"errors"
"github.com/google/go-github/github"
)
type CheckCommand struct {
github GitHub
}
func NewCheckCommand(github GitHub) *CheckCommand {
return &CheckCommand{
github: github,
}
}
func (c *CheckCommand) Run(request CheckRequest) ([]Version, error) {
releases, err := c.github.ListReleases()
if err != nil {
return []Version{}, err
}
if len(releases) == 0 {
return []Version{}, errors.New("repository had no releases")
}
latestVersion := *releases[0].TagName
if request.Version.Tag == "" {
return []Version{
{Tag: latestVersion},
}, nil
}
if latestVersion == request.Version.Tag {
return []Version{}, nil
}
upToLatest := false
reversedVersions := []Version{}
for _, release := range reverse(releases) {
version := *release.TagName
if upToLatest {
reversedVersions = append(reversedVersions, Version{Tag: version})
} else {
upToLatest = request.Version.Tag == version
}
}
return reversedVersions, nil
}
func reverse(s []github.RepositoryRelease) []github.RepositoryRelease {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}

120
check_command_test.go Normal file
View File

@@ -0,0 +1,120 @@
package resource_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/google/go-github/github"
"github.com/concourse/github-release-resource"
"github.com/concourse/github-release-resource/fakes"
)
var _ = Describe("Check Command", func() {
var (
githubClient *fakes.FakeGitHub
command *resource.CheckCommand
returnedReleases []github.RepositoryRelease
)
BeforeEach(func() {
githubClient = &fakes.FakeGitHub{}
command = resource.NewCheckCommand(githubClient)
returnedReleases = []github.RepositoryRelease{}
})
JustBeforeEach(func() {
githubClient.ListReleasesReturns(returnedReleases, nil)
})
Context("when this is the first time that the resource has been run", func() {
Context("when there are no releases", func() {
BeforeEach(func() {
returnedReleases = []github.RepositoryRelease{}
})
It("returns an error when there are no releases", func() {
_, err := command.Run(resource.CheckRequest{})
Ω(err).Should(HaveOccurred())
})
})
Context("when there are releases", func() {
BeforeEach(func() {
returnedReleases = []github.RepositoryRelease{
{TagName: github.String("0.4.0")},
{TagName: github.String("0.1.3")},
{TagName: github.String("0.1.2")},
}
})
It("outputs the most recent version only", func() {
command := resource.NewCheckCommand(githubClient)
response, err := command.Run(resource.CheckRequest{})
Ω(err).ShouldNot(HaveOccurred())
Ω(response).Should(HaveLen(1))
Ω(response[0]).Should(Equal(resource.Version{
Tag: "0.4.0",
}))
})
})
})
Context("when there are prior versions", func() {
Context("when there are no releases", func() {
BeforeEach(func() {
returnedReleases = []github.RepositoryRelease{}
})
It("returns an error when there are no releases", func() {
_, err := command.Run(resource.CheckRequest{})
Ω(err).Should(HaveOccurred())
})
})
Context("when there are releases", func() {
BeforeEach(func() {
returnedReleases = []github.RepositoryRelease{
{TagName: github.String("0.4.0")},
{TagName: github.String("0.1.4")},
{TagName: github.String("0.1.3")},
{TagName: github.String("0.1.2")},
}
})
It("returns an empty list if the lastet version has been checked", func() {
command := resource.NewCheckCommand(githubClient)
response, err := command.Run(resource.CheckRequest{
Version: resource.Version{
Tag: "0.4.0",
},
})
Ω(err).ShouldNot(HaveOccurred())
Ω(response).Should(BeEmpty())
})
It("all of the versions that are newer", func() {
command := resource.NewCheckCommand(githubClient)
response, err := command.Run(resource.CheckRequest{
Version: resource.Version{
Tag: "0.1.3",
},
})
Ω(err).ShouldNot(HaveOccurred())
Ω(response).Should(HaveLen(2))
Ω(response).Should(Equal([]resource.Version{
{Tag: "0.1.4"},
{Tag: "0.4.0"},
}))
})
})
})
})

View File

@@ -1,7 +1,34 @@
package main
import "fmt"
import (
"encoding/json"
"os"
"github.com/concourse/github-release-resource"
)
func main() {
fmt.Println("[]")
var request resource.CheckRequest
inputRequest(&request)
github := resource.NewGitHubClient(request.Source)
command := resource.NewCheckCommand(github)
response, err := command.Run(request)
if err != nil {
resource.Fatal("running command", err)
}
outputResponse(response)
}
func inputRequest(request *resource.CheckRequest) {
if err := json.NewDecoder(os.Stdin).Decode(request); err != nil {
resource.Fatal("reading request from stdin", err)
}
}
func outputResponse(response []resource.Version) {
if err := json.NewEncoder(os.Stdout).Encode(response); err != nil {
resource.Fatal("writing response to stdout", err)
}
}

View File

@@ -1,27 +0,0 @@
package main_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
)
var checkPath string
func TestCheck(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Check Suite")
}
var _ = BeforeSuite(func() {
var err error
checkPath, err = gexec.Build("github.com/concourse/github-release-resource/cmd/check")
Ω(err).ShouldNot(HaveOccurred())
})
var _ = AfterSuite(func() {
gexec.CleanupBuildArtifacts()
})

View File

@@ -1,23 +0,0 @@
package main_test
import (
"os/exec"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
)
var _ = Describe("Check", func() {
It("outputs an empty JSON array", func() {
command := exec.Command(checkPath)
check, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Ω(err).ShouldNot(HaveOccurred())
Eventually(check).Should(gbytes.Say(`\[\]`))
Eventually(check).Should(gexec.Exit(0))
})
})

View File

@@ -10,6 +10,13 @@ import (
)
type FakeGitHub struct {
ListReleasesStub func() ([]github.RepositoryRelease, error)
listReleasesMutex sync.RWMutex
listReleasesArgsForCall []struct{}
listReleasesReturns struct {
result1 []github.RepositoryRelease
result2 error
}
CreateReleaseStub func(release *github.RepositoryRelease) (*github.RepositoryRelease, error)
createReleaseMutex sync.RWMutex
createReleaseArgsForCall []struct {
@@ -31,6 +38,31 @@ type FakeGitHub struct {
}
}
func (fake *FakeGitHub) ListReleases() ([]github.RepositoryRelease, error) {
fake.listReleasesMutex.Lock()
fake.listReleasesArgsForCall = append(fake.listReleasesArgsForCall, struct{}{})
fake.listReleasesMutex.Unlock()
if fake.ListReleasesStub != nil {
return fake.ListReleasesStub()
} else {
return fake.listReleasesReturns.result1, fake.listReleasesReturns.result2
}
}
func (fake *FakeGitHub) ListReleasesCallCount() int {
fake.listReleasesMutex.RLock()
defer fake.listReleasesMutex.RUnlock()
return len(fake.listReleasesArgsForCall)
}
func (fake *FakeGitHub) ListReleasesReturns(result1 []github.RepositoryRelease, result2 error) {
fake.ListReleasesStub = nil
fake.listReleasesReturns = struct {
result1 []github.RepositoryRelease
result2 error
}{result1, result2}
}
func (fake *FakeGitHub) CreateRelease(release *github.RepositoryRelease) (*github.RepositoryRelease, error) {
fake.createReleaseMutex.Lock()
fake.createReleaseArgsForCall = append(fake.createReleaseArgsForCall, struct {

View File

@@ -11,6 +11,7 @@ import (
//go:generate counterfeiter . GitHub
type GitHub interface {
ListReleases() ([]github.RepositoryRelease, error)
CreateRelease(release *github.RepositoryRelease) (*github.RepositoryRelease, error)
UploadReleaseAsset(release *github.RepositoryRelease, name string, file *os.File) error
}
@@ -22,7 +23,7 @@ type GitHubClient struct {
repository string
}
func NewGitHubClient(source OutSource) *GitHubClient {
func NewGitHubClient(source Source) *GitHubClient {
transport := &oauth.Transport{
Token: &oauth.Token{
AccessToken: source.AccessToken,
@@ -38,6 +39,15 @@ func NewGitHubClient(source OutSource) *GitHubClient {
}
}
func (g *GitHubClient) ListReleases() ([]github.RepositoryRelease, error) {
releases, _, err := g.client.Repositories.ListReleases(g.user, g.repository, nil)
if err != nil {
return []github.RepositoryRelease{}, err
}
return releases, nil
}
func (g *GitHubClient) CreateRelease(release *github.RepositoryRelease) (*github.RepositoryRelease, error) {
createdRelease, _, err := g.client.Repositories.CreateRelease(g.user, g.repository, release)
if err != nil {

View File

@@ -1,17 +1,22 @@
package resource
type OutRequest struct {
Source OutSource `json:"source"`
Params OutParams `json:"params"`
}
type OutSource struct {
type Source struct {
AccessToken string `json:"access_token"`
User string `json:"user"`
Repository string `json:"repository"`
}
type CheckRequest struct {
Source Source `json:"source"`
Version Version `json:"version"`
}
type OutRequest struct {
Source Source `json:"source"`
Params OutParams `json:"params"`
}
type OutParams struct {
NamePath string `json:"name"`
BodyPath string `json:"body"`