diff --git a/github/data_source_github_repository_file.go b/github/data_source_github_repository_file.go index d2d8a4a59e..c9ad137c3f 100644 --- a/github/data_source_github_repository_file.go +++ b/github/data_source_github_repository_file.go @@ -95,7 +95,7 @@ func dataSourceGithubRepositoryFileRead(d *schema.ResourceData, meta interface{} opts.Ref = branch.(string) } - fc, _, _, err := client.Repositories.GetContents(ctx, owner, repo, file, opts) + fc, dc, _, err := client.Repositories.GetContents(ctx, owner, repo, file, opts) if err != nil { if err, ok := err.(*github.ErrorResponse); ok { if err.Response.StatusCode == http.StatusNotFound { @@ -107,15 +107,22 @@ func dataSourceGithubRepositoryFileRead(d *schema.ResourceData, meta interface{} return err } + d.Set("repository", repo) + d.SetId(fmt.Sprintf("%s/%s", repo, file)) + d.Set("file", file) + + // If the repo is a directory, then there is nothing else we can include in + // the schema. + if dc != nil { + return nil + } + content, err := fc.GetContent() if err != nil { return err } - d.SetId(fmt.Sprintf("%s/%s", repo, file)) d.Set("content", content) - d.Set("repository", repo) - d.Set("file", file) d.Set("sha", fc.GetSHA()) parsedUrl, err := url.Parse(fc.GetURL()) diff --git a/github/data_source_github_repository_file_test.go b/github/data_source_github_repository_file_test.go index 8fffb1fbfe..edd5c3adec 100644 --- a/github/data_source_github_repository_file_test.go +++ b/github/data_source_github_repository_file_test.go @@ -420,4 +420,68 @@ func TestDataSourceGithubRepositoryFileRead(t *testing.T) { }) }) + + repoContentDirectoryRespBody := marshal(t, []github.RepositoryContent{ + { + Encoding: &enc, + Content: &b64FileContent, + SHA: &sha, + URL: &apiUrl, + }, + }) + + t.Run("extract only non-file data if the path is for a directory", func(t *testing.T) { + // test setup + repositoryFullName := fmt.Sprintf("%s/%s", org, repo) + + expectedID := fmt.Sprintf("%s/%s", repo, fileName) + expectedRepo := "test-repo" + + ts := githubApiMock([]*mockResponse{ + { + ExpectedUri: fmt.Sprintf("/repos/%s/%s/contents/%s?ref=%s", org, repo, fileName, branch), + ResponseBody: repoContentDirectoryRespBody, + StatusCode: http.StatusOK, + }, + }) + defer ts.Close() + + httpCl := http.DefaultClient + httpCl.Transport = http.DefaultTransport + + client := github.NewClient(httpCl) + u, _ := url.Parse(ts.URL + "/") + client.BaseURL = u + + meta := &Owner{ + name: owner, + v3client: client, + } + + testSchema := map[string]*schema.Schema{ + "repository": {Type: schema.TypeString}, + "file": {Type: schema.TypeString}, + "branch": {Type: schema.TypeString}, + "commit_sha": {Type: schema.TypeString}, + "content": {Type: schema.TypeString}, + "id": {Type: schema.TypeString}, + } + + schema := schema.TestResourceDataRaw(t, testSchema, map[string]interface{}{ + "repository": repositoryFullName, + "file": fileName, + "branch": branch, + "commit_sha": sha, + }) + + // actual call + err := dataSourceGithubRepositoryFileRead(schema, meta) + + // assertions + assert.Nil(t, err) + assert.Equal(t, expectedRepo, schema.Get("repository")) + assert.Equal(t, expectedID, schema.Get("id")) + assert.Equal(t, "", schema.Get("content")) + assert.Equal(t, nil, schema.Get("sha")) + }) }