Skip to content

Commit

Permalink
feat: add tree data source (#1027)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jasonwalsh authored Mar 18, 2022
1 parent ba9456e commit 00481c0
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 0 deletions.
89 changes: 89 additions & 0 deletions github/data_source_github_tree.go
Original file line number Diff line number Diff line change
@@ -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
}
72 changes: 72 additions & 0 deletions github/data_source_github_tree_test.go
Original file line number Diff line number Diff line change
@@ -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)
})
})
}
1 change: 1 addition & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,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(),
},
Expand Down
44 changes: 44 additions & 0 deletions website/docs/d/tree.html.markdown
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions website/github.erb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
<li>
<a href="/docs/providers/github/d/users.html">github_users</a>
</li>
<li>
<a href="/docs/providers/github/d/tree.html">github_tree</a>
</li>
</ul>
</li>

Expand Down

0 comments on commit 00481c0

Please sign in to comment.