From 53bcc23e1f2715ce9c57a1546d20fbf7d384428a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= <thomasf@jossystem.se>
Date: Thu, 11 Feb 2016 13:04:57 +0100
Subject: [PATCH] Avoid drone->gh args race with struct

---
 main.go | 49 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/main.go b/main.go
index da4d3c2..13854f2 100644
--- a/main.go
+++ b/main.go
@@ -98,22 +98,37 @@ func main() {
 	client.BaseURL = baseURL
 	client.UploadURL = uploadURL
 
-	release, err := buildRelease(client, repo.Owner, repo.Name, filepath.Base(build.Ref))
+	rc := releaseClient{
+		Client: client,
+		Owner:  repo.Owner,
+		Repo:   repo.Name,
+		Tag:    filepath.Base(build.Ref),
+	}
+
+	release, err := rc.buildRelease()
 	if err != nil {
 		fmt.Println(err)
 		os.Exit(1)
 	}
 
-	if err := uploadFiles(client, repo.Owner, repo.Name, *release.ID, files); err != nil {
+	if err := rc.uploadFiles(*release.ID, files); err != nil {
 		fmt.Println(err)
 		os.Exit(1)
 	}
 }
 
-func buildRelease(client *github.Client, owner string, repo string, tag string) (*github.RepositoryRelease, error) {
+// Release holds ties the drone env data and github client together.
+type releaseClient struct {
+	*github.Client
+	Owner string
+	Repo  string
+	Tag   string
+}
+
+func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) {
 
 	// first attempt to get a release by that tag
-	release, err := getRelease(client, owner, repo, tag)
+	release, err := rc.getRelease()
 	if err != nil && release == nil {
 		fmt.Println(err)
 	} else if release != nil {
@@ -121,7 +136,7 @@ func buildRelease(client *github.Client, owner string, repo string, tag string)
 	}
 
 	// if no release was found by that tag, create a new one
-	release, err = newRelease(client, owner, repo, tag)
+	release, err = rc.newRelease()
 	if err != nil {
 		return nil, fmt.Errorf("Failed to retrieve or create a release: %s", err)
 	}
@@ -129,29 +144,29 @@ func buildRelease(client *github.Client, owner string, repo string, tag string)
 	return release, nil
 }
 
-func getRelease(client *github.Client, owner string, repo string, tag string) (*github.RepositoryRelease, error) {
-	release, _, err := client.Repositories.GetReleaseByTag(owner, repo, tag)
+func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) {
+	release, _, err := rc.Client.Repositories.GetReleaseByTag(rc.Owner, rc.Repo, rc.Tag)
 	if err != nil {
-		return nil, fmt.Errorf("Release %s not found", tag)
+		return nil, fmt.Errorf("Release %s not found", rc.Tag)
 	}
 
-	fmt.Printf("Successfully retrieved %s release\n", tag)
+	fmt.Printf("Successfully retrieved %s release\n", rc.Tag)
 	return release, nil
 }
 
-func newRelease(client *github.Client, owner string, repo string, tag string) (*github.RepositoryRelease, error) {
-	rr := &github.RepositoryRelease{TagName: github.String(tag)}
-	release, _, err := client.Repositories.CreateRelease(owner, repo, rr)
+func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) {
+	rr := &github.RepositoryRelease{TagName: github.String(rc.Tag)}
+	release, _, err := rc.Client.Repositories.CreateRelease(rc.Owner, rc.Repo, rr)
 	if err != nil {
 		return nil, fmt.Errorf("Failed to create release: %s", err)
 	}
 
-	fmt.Printf("Successfully created %s release\n", tag)
+	fmt.Printf("Successfully created %s release\n", rc.Tag)
 	return release, nil
 }
 
-func uploadFiles(client *github.Client, owner string, repo string, id int, files []string) error {
-	assets, _, err := client.Repositories.ListReleaseAssets(owner, repo, id, &github.ListOptions{})
+func (rc *releaseClient) uploadFiles(id int, files []string) error {
+	assets, _, err := rc.Client.Repositories.ListReleaseAssets(rc.Owner, rc.Repo, id, &github.ListOptions{})
 	if err != nil {
 		return fmt.Errorf("Failed to fetch existing assets: %s", err)
 	}
@@ -164,7 +179,7 @@ func uploadFiles(client *github.Client, owner string, repo string, id int, files
 
 		for _, asset := range assets {
 			if *asset.Name == path.Base(file) {
-				if _, err := client.Repositories.DeleteReleaseAsset(owner, repo, *asset.ID); err != nil {
+				if _, err := rc.Client.Repositories.DeleteReleaseAsset(rc.Owner, rc.Repo, *asset.ID); err != nil {
 					return fmt.Errorf("Failed to delete %s artifact: %s", file, err)
 				}
 				fmt.Printf("Successfully deleted old %s artifact\n", *asset.Name)
@@ -172,7 +187,7 @@ func uploadFiles(client *github.Client, owner string, repo string, id int, files
 		}
 
 		uo := &github.UploadOptions{Name: path.Base(file)}
-		if _, _, err = client.Repositories.UploadReleaseAsset(owner, repo, id, uo, handle); err != nil {
+		if _, _, err = rc.Client.Repositories.UploadReleaseAsset(rc.Owner, rc.Repo, id, uo, handle); err != nil {
 			return fmt.Errorf("Failed to upload %s artifact: %s", file, err)
 		}