Skip to content

Commit

Permalink
feat: add github_repository_content table
Browse files Browse the repository at this point in the history
  • Loading branch information
aminvielledebatAtBedrock committed Oct 5, 2022
1 parent 150a7e5 commit c0f1fd4
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions github/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"github_rate_limit": tableGitHubRateLimit(ctx),
"github_release": tableGitHubRelease(ctx),
"github_repository": tableGitHubRepository(),
"github_repository_content": tableGitHubRepositoryContent(),
"github_search_code": tableGitHubSearchCode(ctx),
"github_search_commit": tableGitHubSearchCommit(ctx),
"github_search_issue": tableGitHubSearchIssue(ctx),
Expand Down
98 changes: 98 additions & 0 deletions github/table_github_repository_content.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package github

import (
"context"
"github.com/google/go-github/v45/github"
"github.com/turbot/steampipe-plugin-sdk/v4/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v4/plugin"
"github.com/turbot/steampipe-plugin-sdk/v4/plugin/transform"
)

//// TABLE DEFINITION

func tableGitHubRepositoryContent() *plugin.Table {
return &plugin.Table{
Name: "github_repository_content",
Description: "List the content in a repository (list directory, or get file content",
List: &plugin.ListConfig{
Hydrate: tableGitHubRepositoryContentList,
KeyColumns: []*plugin.KeyColumn{
{Name: "repository_full_name", Require: plugin.Required},
{Name: "requested_path", Require: plugin.Optional},
},
},
Columns: []*plugin.Column{
{Name: "repository_full_name", Description: "The full name of the repository (login/repo-name).", Type: proto.ColumnType_STRING, Transform: transform.FromQual("repository_full_name")},
{Name: "type", Description: "The file type (directory or file).", Type: proto.ColumnType_STRING},
{Name: "name", Description: "The file name.", Type: proto.ColumnType_STRING},
{Name: "requested_path", Description: "The requested path in repository search.", Type: proto.ColumnType_STRING, Transform: transform.FromQual("requested_path")},
{Name: "path", Description: "The path of the file.", Type: proto.ColumnType_STRING},
{Name: "size", Description: "The size of the file.", Type: proto.ColumnType_INT},
{Name: "content", Description: "The decoded file content (if the element is a file).", Type: proto.ColumnType_STRING, Transform: transform.FromMethod("GetContent")},
{Name: "target", Description: "Target is only set if the type is \"symlink\" and the target is not a normal file. If Target is set, Path will be the symlink path.", Type: proto.ColumnType_STRING},
{Name: "sha", Description: "The sha of the file.", Type: proto.ColumnType_STRING, Transform: transform.FromField("SHA")},
{Name: "url", Description: "Url of file's metadata", Type: proto.ColumnType_STRING},
{Name: "git_url", Description: "Git url (with SHA) of the file", Type: proto.ColumnType_STRING},
{Name: "html_url", Description: "Raw file url in GitHub", Type: proto.ColumnType_STRING},
{Name: "download_url", Description: "Download URL : it expires and can be be used just once.", Type: proto.ColumnType_STRING},
},
}
}

//// LIST FUNCTION

func tableGitHubRepositoryContentList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
plugin.Logger(ctx).Trace("github_repository_content.tableGitHubRepositoryContentList")

owner, repo := parseRepoFullName(d.KeyColumnQuals["repository_full_name"].GetStringValue())
var requestedPath string
if d.KeyColumnQuals["requested_path"] != nil {
requestedPath = d.KeyColumnQuals["requested_path"].GetStringValue()
}

type ListPageResponse struct {
repositoryContent []*github.RepositoryContent
resp *github.Response
}
client := connect(ctx, d)
opt := &github.RepositoryContentGetOptions{}
listPage := func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
fileContent, directoryContent, resp, err := client.Repositories.GetContents(ctx, owner, repo, requestedPath, opt)

if err != nil {
return nil, err
}

if fileContent != nil {
directoryContent = []*github.RepositoryContent{fileContent}
}

return ListPageResponse{
repositoryContent: directoryContent,
resp: resp,
}, err
}

for {
listPageResponse, err := retryHydrate(ctx, d, h, listPage)
if err != nil {
return nil, err
}

for _, i := range listPageResponse.(ListPageResponse).repositoryContent {
if i != nil {
d.StreamListItem(ctx, i)
}

// Context can be cancelled due to manual cancellation or the limit has been hit
if d.QueryStatus.RowsRemaining(ctx) == 0 {
return nil, nil
}
}

if listPageResponse.(ListPageResponse).resp.NextPage == 0 {
break
}
}
return nil, nil
}

0 comments on commit c0f1fd4

Please sign in to comment.