diff --git a/github/data_source_github_repositories.go b/github/data_source_github_repositories.go new file mode 100644 index 0000000000..501335d265 --- /dev/null +++ b/github/data_source_github_repositories.go @@ -0,0 +1,84 @@ +package github + +import ( + "context" + "log" + + "github.com/google/go-github/github" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceGithubRepositories() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGithubRepositoriesRead, + + Schema: map[string]*schema.Schema{ + "query": { + Type: schema.TypeString, + Required: true, + }, + "full_names": { + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + "names": { + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Computed: true, + }, + }, + } +} + +func dataSourceGithubRepositoriesRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Organization).client + + query := d.Get("query").(string) + + log.Printf("[DEBUG] Searching for GitHub repositories: %q", query) + fullNames, names, err := searchGithubRepositories(client, query) + if err != nil { + return err + } + + d.SetId(query) + d.Set("full_names", fullNames) + d.Set("names", names) + + return nil +} + +func searchGithubRepositories(client *github.Client, query string) ([]string, []string, error) { + fullNames := make([]string, 0, 0) + names := make([]string, 0, 0) + + opt := &github.SearchOptions{ + ListOptions: github.ListOptions{ + PerPage: 100, + }, + } + + for { + results, resp, err := client.Search.Repositories(context.TODO(), query, opt) + if err != nil { + return fullNames, names, err + } + + for _, repo := range results.Repositories { + fullNames = append(fullNames, repo.GetFullName()) + names = append(names, repo.GetName()) + } + + if resp.NextPage == 0 { + break + } + opt.Page = resp.NextPage + } + + return fullNames, names, nil +} diff --git a/github/data_source_github_repositories_test.go b/github/data_source_github_repositories_test.go new file mode 100644 index 0000000000..7561591d50 --- /dev/null +++ b/github/data_source_github_repositories_test.go @@ -0,0 +1,56 @@ +package github + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccGithubRepositoriesDataSource_basic(t *testing.T) { + query := "org:hashicorp terraform" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGithubRepositoriesDataSourceConfig(query), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.github_repositories.test", "full_names.#"), + resource.TestCheckResourceAttr("data.github_repositories.test", "full_names.3450805659", "hashicorp/terraform"), + resource.TestCheckResourceAttrSet("data.github_repositories.test", "names.#"), + resource.TestCheckResourceAttr("data.github_repositories.test", "names.535570215", "terraform"), + ), + }, + }, + }) +} + +func TestAccGithubRepositoriesDataSource_noMatch(t *testing.T) { + query := "klsafj_23434_doesnt_exist" + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckGithubRepositoriesDataSourceConfig(query), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.github_repositories.test", "full_names.#", "0"), + resource.TestCheckResourceAttr("data.github_repositories.test", "names.#", "0"), + ), + }, + }, + }) +} + +func testAccCheckGithubRepositoriesDataSourceConfig(query string) string { + return fmt.Sprintf(` +data "github_repositories" "test" { + query = "%s" +} +`, query) +} diff --git a/github/provider.go b/github/provider.go index bce2e25b67..7798770d2a 100644 --- a/github/provider.go +++ b/github/provider.go @@ -56,10 +56,11 @@ func Provider() terraform.ResourceProvider { }, DataSourcesMap: map[string]*schema.Resource{ - "github_ip_ranges": dataSourceGithubIpRanges(), - "github_repository": dataSourceGithubRepository(), - "github_team": dataSourceGithubTeam(), - "github_user": dataSourceGithubUser(), + "github_ip_ranges": dataSourceGithubIpRanges(), + "github_repository": dataSourceGithubRepository(), + "github_repositories": dataSourceGithubRepositories(), + "github_team": dataSourceGithubTeam(), + "github_user": dataSourceGithubUser(), }, } diff --git a/website/docs/d/repositories.html.markdown b/website/docs/d/repositories.html.markdown new file mode 100644 index 0000000000..38badf7e37 --- /dev/null +++ b/website/docs/d/repositories.html.markdown @@ -0,0 +1,33 @@ +--- +layout: "github" +page_title: "GitHub: github_repositories" +sidebar_current: "docs-github-datasource-repositories" +description: |- + Search for GitHub repositories +--- + +# github_repositories + +-> **Note:** The data source will return a maximum of `1000` repositories + [as documented in official API docs](https://developer.github.com/v3/search/#about-the-search-api). + +Use this data source to retrieve a list of GitHub repositories using a search query. + +## Example Usage + +```hcl +data "github_repositories" "example" { + query = "org:hashicorp language:Go" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `query` - (Required) Search query. See [documentation for the search syntax](https://help.github.com/articles/understanding-the-search-syntax/). + +## Attributes Reference + +* `full_names` - A list of full names of found repositories (e.g. `hashicorp/terraform`) +* `names` - A list of found repository names (e.g. `terraform`) diff --git a/website/github.erb b/website/github.erb index 3a1a75e74b..94a56fe78e 100644 --- a/website/github.erb +++ b/website/github.erb @@ -16,6 +16,9 @@ > github_ip_ranges + > + github_repositories + > github_repository