From 827d1ff50cf04371f61c1766f8e5b30513835d3e Mon Sep 17 00:00:00 2001 From: jasonwalsh <2184329+jasonwalsh@users.noreply.github.com> Date: Fri, 18 Mar 2022 12:26:21 -0400 Subject: [PATCH] feat: add `tree` data source (#1027) * feat: add `tree` data source Returns a single tree using the SHA1 value for that tree. * test: add acceptance test for `github_tree` * syle: run `make fmt` command * docs: add documentation for new data source * docs: add link to website --- github/data_source_github_tree.go | 89 ++++++++++++++++++++++++++ github/data_source_github_tree_test.go | 72 +++++++++++++++++++++ github/provider.go | 1 + website/docs/d/tree.html.markdown | 44 +++++++++++++ website/github.erb | 3 + 5 files changed, 209 insertions(+) create mode 100644 github/data_source_github_tree.go create mode 100644 github/data_source_github_tree_test.go create mode 100644 website/docs/d/tree.html.markdown diff --git a/github/data_source_github_tree.go b/github/data_source_github_tree.go new file mode 100644 index 0000000000..bf1fee9f65 --- /dev/null +++ b/github/data_source_github_tree.go @@ -0,0 +1,89 @@ +package github + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func dataSourceGithubTree() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGithubTreeRead, + Schema: map[string]*schema.Schema{ + "recursive": { + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "repository": { + Type: schema.TypeString, + Required: true, + }, + "entries": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Computed: true, + }, + "mode": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "size": { + Type: schema.TypeInt, + Computed: true, + }, + "sha": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "tree_sha": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func dataSourceGithubTreeRead(d *schema.ResourceData, meta interface{}) error { + owner := meta.(*Owner).name + repository := d.Get("repository").(string) + sha := d.Get("tree_sha").(string) + recursive := d.Get("recursive").(bool) + + client := meta.(*Owner).v3client + ctx := context.Background() + + tree, _, err := client.Git.GetTree(ctx, owner, repository, sha, recursive) + + if err != nil { + return err + } + + entries := make([]interface{}, 0, len(tree.Entries)) + + for _, entry := range tree.Entries { + entries = append(entries, map[string]interface{}{ + "path": entry.Path, + "mode": entry.Mode, + "type": entry.Type, + "size": entry.Size, + "sha": entry.SHA, + }) + } + + d.SetId(tree.GetSHA()) + d.Set("entries", entries) + + return nil +} diff --git a/github/data_source_github_tree_test.go b/github/data_source_github_tree_test.go new file mode 100644 index 0000000000..74ee06a0eb --- /dev/null +++ b/github/data_source_github_tree_test.go @@ -0,0 +1,72 @@ +package github + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccGithubTreeDataSource(t *testing.T) { + randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum) + + t.Run("get tree", func(t *testing.T) { + config := fmt.Sprintf(` + resource "github_repository" "this" { + auto_init = true + name = "tf-acc-test-%s" + } + + data "github_branch" "this" { + branch = "main" + repository = github_repository.this.name + } + + data "github_tree" "this" { + recursive = false + repository = github_repository.this.name + tree_sha = data.github_branch.this.sha + } + `, randomID) + + check := resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "data.github_tree.this", "entries.#", + ), + resource.TestCheckResourceAttr( + "data.github_tree.this", "entries.0.path", + "README.md", + ), + resource.TestCheckResourceAttr( + "data.github_tree.this", "entries.0.type", + "blob", + ), + ) + + testCase := func(t *testing.T, mode string) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipUnlessMode(t, mode) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: check, + }, + }, + }) + } + + t.Run("with an anonymous account", func(t *testing.T) { + testCase(t, anonymous) + }) + + t.Run("with an individual account", func(t *testing.T) { + testCase(t, individual) + }) + + t.Run("with an organization account", func(t *testing.T) { + testCase(t, organization) + }) + }) +} diff --git a/github/provider.go b/github/provider.go index 24b554940e..47016cc215 100644 --- a/github/provider.go +++ b/github/provider.go @@ -139,6 +139,7 @@ func Provider() terraform.ResourceProvider { "github_repository_pull_request": dataSourceGithubRepositoryPullRequest(), "github_repository_pull_requests": dataSourceGithubRepositoryPullRequests(), "github_team": dataSourceGithubTeam(), + "github_tree": dataSourceGithubTree(), "github_user": dataSourceGithubUser(), "github_users": dataSourceGithubUsers(), }, diff --git a/website/docs/d/tree.html.markdown b/website/docs/d/tree.html.markdown new file mode 100644 index 0000000000..6c254b9f22 --- /dev/null +++ b/website/docs/d/tree.html.markdown @@ -0,0 +1,44 @@ +--- +layout: "github" +page_title: "GitHub: github_tree" +description: |- + Returns a single tree using the SHA1 value for that tree. +--- + +# github_tree + +Use this data source to retrieve information about a single tree. + +## Example Usage + +```hcl +data "github_repository" "this" { + name = "example" +} + +data "github_branch" "this" { + branch = data.github_repository.this.default_branch + repository = data.github_repository.this.name +} + +data "github_tree" "this" { + recursive = false + repository = data.github_repository.this.name + tree_sha = data.github_branch.this.sha +} + +output "entries" { + value = data.github_tree.this.entries +} + +``` + +## Argument Reference + +- `recursive` - (Optional) Setting this parameter to `true` returns the objects or subtrees referenced by the tree specified in `tree_sha`. +- `repository` - (Required) The name of the repository. +- `tree_sha` - (Required) The SHA1 value for the tree. + +## Attributes Reference + +- `entries` - Objects (of `path`, `mode`, `type`, `size`, and `sha`) specifying a tree structure. diff --git a/website/github.erb b/website/github.erb index d53d211e51..4cfee612f2 100644 --- a/website/github.erb +++ b/website/github.erb @@ -61,6 +61,9 @@
  • github_users
  • +
  • + github_tree +