From 90a0d5a669a6759d4a7198c583619bd1141fe3a2 Mon Sep 17 00:00:00 2001 From: Paul Tyng Date: Tue, 29 May 2018 20:19:23 -0400 Subject: [PATCH] Handle topics in extra API call --- github/resource_github_repository.go | 26 ++++++++-- github/resource_github_repository_test.go | 60 ++++++++++++++++++++--- github/util.go | 19 +++++++ 3 files changed, 94 insertions(+), 11 deletions(-) diff --git a/github/resource_github_repository.go b/github/resource_github_repository.go index 0f60ae6504..04ae67802b 100644 --- a/github/resource_github_repository.go +++ b/github/resource_github_repository.go @@ -142,7 +142,7 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository { licenseTemplate := d.Get("license_template").(string) gitIgnoreTemplate := d.Get("gitignore_template").(string) archived := d.Get("archived").(bool) - topics := d.Get("topics").([]string) + topics := expandStringList(d.Get("topics").([]interface{})) repo := &github.Repository{ Name: &name, @@ -168,6 +168,7 @@ func resourceGithubRepositoryObject(d *schema.ResourceData) *github.Repository { func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Organization).client + ctx := context.TODO() if _, ok := d.GetOk("default_branch"); ok { return fmt.Errorf("Cannot set the default branch on a new repository.") @@ -175,12 +176,20 @@ func resourceGithubRepositoryCreate(d *schema.ResourceData, meta interface{}) er repoReq := resourceGithubRepositoryObject(d) log.Printf("[DEBUG] create github repository %s/%s", meta.(*Organization).name, *repoReq.Name) - repo, _, err := client.Repositories.Create(context.TODO(), meta.(*Organization).name, repoReq) + repo, _, err := client.Repositories.Create(ctx, meta.(*Organization).name, repoReq) if err != nil { return err } d.SetId(*repo.Name) + topics := repoReq.Topics + if len(topics) > 0 { + _, _, err = client.Repositories.ReplaceAllTopics(ctx, meta.(*Organization).name, *repoReq.Name, topics) + if err != nil { + return err + } + } + return resourceGithubRepositoryUpdate(d, meta) } @@ -221,12 +230,13 @@ func resourceGithubRepositoryRead(d *schema.ResourceData, meta interface{}) erro d.Set("git_clone_url", repo.GitURL) d.Set("http_clone_url", repo.CloneURL) d.Set("archived", repo.Archived) - d.Set("topics", repo.Topics) + d.Set("topics", flattenStringList(repo.Topics)) return nil } func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*Organization).client + ctx := context.TODO() repoReq := resourceGithubRepositoryObject(d) // Can only set `default_branch` on an already created repository with the target branches ref already in-place if v, ok := d.GetOk("default_branch"); ok { @@ -239,12 +249,20 @@ func resourceGithubRepositoryUpdate(d *schema.ResourceData, meta interface{}) er repoName := d.Id() log.Printf("[DEBUG] update github repository %s/%s", meta.(*Organization).name, repoName) - repo, _, err := client.Repositories.Edit(context.TODO(), meta.(*Organization).name, repoName, repoReq) + repo, _, err := client.Repositories.Edit(ctx, meta.(*Organization).name, repoName, repoReq) if err != nil { return err } d.SetId(*repo.Name) + if d.HasChange("topics") { + topics := repoReq.Topics + _, _, err = client.Repositories.ReplaceAllTopics(ctx, meta.(*Organization).name, *repo.Name, topics) + if err != nil { + return err + } + } + return resourceGithubRepositoryRead(d, meta) } diff --git a/github/resource_github_repository_test.go b/github/resource_github_repository_test.go index a2c6a5ba32..3513869521 100644 --- a/github/resource_github_repository_test.go +++ b/github/resource_github_repository_test.go @@ -314,7 +314,7 @@ func TestAccGithubRepository_topics(t *testing.T) { CheckDestroy: testAccCheckGithubRepositoryDestroy, Steps: []resource.TestStep{ { - Config: testAccGithubRepositoryConfigTopics(randString), + Config: testAccGithubRepositoryConfigTopics(randString, `"topic1", "topic2"`), Check: resource.ComposeTestCheckFunc( testAccCheckGithubRepositoryExists("github_repository.foo", &repo), testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{ @@ -322,6 +322,48 @@ func TestAccGithubRepository_topics(t *testing.T) { Description: description, Homepage: "http://example.com/", Topics: []string{"topic1", "topic2"}, + + // non-zero defaults + DefaultBranch: "master", + AllowMergeCommit: true, + AllowSquashMerge: true, + AllowRebaseMerge: true, + }), + ), + }, + { + Config: testAccGithubRepositoryConfigTopics(randString, `"topic1", "topic2", "topic3"`), + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubRepositoryExists("github_repository.foo", &repo), + testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{ + Name: name, + Description: description, + Homepage: "http://example.com/", + Topics: []string{"topic1", "topic2", "topic3"}, + + // non-zero defaults + DefaultBranch: "master", + AllowMergeCommit: true, + AllowSquashMerge: true, + AllowRebaseMerge: true, + }), + ), + }, + { + Config: testAccGithubRepositoryConfigTopics(randString, ``), + Check: resource.ComposeTestCheckFunc( + testAccCheckGithubRepositoryExists("github_repository.foo", &repo), + testAccCheckGithubRepositoryAttributes(&repo, &testAccGithubRepositoryExpectedAttributes{ + Name: name, + Description: description, + Homepage: "http://example.com/", + Topics: []string{}, + + // non-zero defaults + DefaultBranch: "master", + AllowMergeCommit: true, + AllowSquashMerge: true, + AllowRebaseMerge: true, }), ), }, @@ -405,10 +447,14 @@ func testAccCheckGithubRepositoryAttributes(repo *github.Repository, want *testA if *repo.HasDownloads != want.HasDownloads { return fmt.Errorf("got has downloads %#v; want %#v", *repo.HasDownloads, want.HasDownloads) } - if &repo.Topics != &want.Topics { - return fmt.Errorf("got has topics %#v; want %#v", &repo.Topics, &want.Topics) + if len(want.Topics) != len(repo.Topics) { + return fmt.Errorf("got topics %#v; want %#v", repo.Topics, want.Topics) + } + for i := range want.Topics { + if repo.Topics[i] != want.Topics[i] { + return fmt.Errorf("got topics %#v; want %#v", repo.Topics, want.Topics) + } } - if *repo.DefaultBranch != want.DefaultBranch { return fmt.Errorf("got default branch %q; want %q", *repo.DefaultBranch, want.DefaultBranch) } @@ -660,7 +706,7 @@ resource "github_repository" "foo" { `, randString, randString) } -func testAccGithubRepositoryConfigTopics(randString string) string { +func testAccGithubRepositoryConfigTopics(randString string, topicList string) string { return fmt.Sprintf(` resource "github_repository" "foo" { name = "tf-acc-test-%s" @@ -671,7 +717,7 @@ resource "github_repository" "foo" { # with no billing private = false - topics = ["topic1", "topic2"] + topics = [%s] } -`, randString, randString) +`, randString, randString, topicList) } diff --git a/github/util.go b/github/util.go index 6eb7600b82..8e9085e884 100644 --- a/github/util.go +++ b/github/util.go @@ -64,3 +64,22 @@ func validateTwoPartID(id string) error { func buildTwoPartID(a, b *string) string { return fmt.Sprintf("%s:%s", *a, *b) } + +func expandStringList(configured []interface{}) []string { + vs := make([]string, 0, len(configured)) + for _, v := range configured { + val, ok := v.(string) + if ok && val != "" { + vs = append(vs, val) + } + } + return vs +} + +func flattenStringList(v []string) []interface{} { + c := make([]interface{}, 0, len(v)) + for _, s := range v { + c = append(c, s) + } + return c +}