-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Pavel Savchenko <asfaltboy@gmail.com>
- Loading branch information
Showing
3 changed files
with
187 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Table: github_tree | ||
|
||
A Git tree object creates the hierarchy between files in a Git repository. You | ||
can use the Git tree object to create the relationship between directories and | ||
the files they contain. | ||
|
||
A single tree object contains one or more entries, each of which is the SHA-1 | ||
hash of a blob or subtree with its associated mode, type, and filename. | ||
|
||
The `github_tree` table can be used to query information about any tree, and | ||
**you must specify which repository and tree SHA** in the where or join clause | ||
using the `repository_full_name` and `tree_sha` columns. By default, recursive | ||
entries are not returned, but can be with the `recursive` column. | ||
|
||
## Examples | ||
|
||
### List tree entries non-recursively | ||
|
||
```sql | ||
select | ||
tree_sha, | ||
truncated, | ||
path, | ||
mode, | ||
type, | ||
sha | ||
from | ||
github_tree | ||
where | ||
repository_full_name = 'turbot/steampipe' | ||
and tree_sha = '0f200416c44b8b85277d973bff933efa8ef7803a'; | ||
``` | ||
|
||
### List tree entries for a subtree recursively | ||
|
||
```sql | ||
select | ||
tree_sha, | ||
truncated, | ||
path, | ||
mode, | ||
type, | ||
sha | ||
from | ||
github_tree | ||
where | ||
repository_full_name = 'turbot/steampipe' | ||
and tree_sha = '5622172b528cd38438c52ecfa3c20ac3f71dd2df' | ||
and recursive = true; | ||
``` | ||
|
||
### List executable files | ||
|
||
```sql | ||
select | ||
tree_sha, | ||
truncated, | ||
path, | ||
mode, | ||
size, | ||
sha | ||
from | ||
github_tree | ||
where | ||
repository_full_name = 'turbot/steampipe' | ||
and tree_sha = '0f200416c44b8b85277d973bff933efa8ef7803a' | ||
and recursive = true | ||
and mode = '100755'; | ||
``` | ||
|
||
### List JSON files | ||
|
||
```sql | ||
select | ||
tree_sha, | ||
truncated, | ||
path, | ||
mode, | ||
size, | ||
sha | ||
from | ||
github_tree | ||
where | ||
repository_full_name = 'turbot/steampipe' | ||
and tree_sha = '0f200416c44b8b85277d973bff933efa8ef7803a' | ||
and recursive = true | ||
and path like '%.json'; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
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 tableGitHubTree(ctx context.Context) *plugin.Table { | ||
return &plugin.Table{ | ||
Name: "github_tree", | ||
Description: "Lists directories and files in the given repository's git tree.", | ||
List: &plugin.ListConfig{ | ||
Hydrate: tableGitHubTreeList, | ||
ShouldIgnoreError: isNotFoundError([]string{"404"}), | ||
KeyColumns: []*plugin.KeyColumn{ | ||
{Name: "repository_full_name", Require: plugin.Required}, | ||
{Name: "tree_sha", Require: plugin.Required}, | ||
{Name: "recursive", Require: plugin.Optional, CacheMatch: "exact"}, | ||
}, | ||
}, | ||
Columns: []*plugin.Column{ | ||
// Top columns | ||
{Name: "repository_full_name", Type: proto.ColumnType_STRING, Transform: transform.FromQual("repository_full_name"), Description: "Full name of the repository that contains the tree."}, | ||
{Name: "tree_sha", Type: proto.ColumnType_STRING, Transform: transform.FromQual("tree_sha"), Description: "SHA1 of the tree."}, | ||
// Other columns | ||
{Name: "recursive", Type: proto.ColumnType_BOOL, Description: "If set to true, return objects or subtrees referenced by the tree. Defaults to false."}, | ||
{Name: "truncated", Type: proto.ColumnType_BOOL, Description: "True if the entires were truncated because the number of items in the tree exceeded Github's maximum limit."}, | ||
{Name: "mode", Type: proto.ColumnType_STRING, Transform: transform.FromField("TreeEntry.Mode"), Description: "File mode. Valid values are 100644 (blob file), 100755 (blob executable), 040000 (tree subdirectory), 160000 (commit submodule), 120000 (blob that specifies path of a symlink)."}, | ||
{Name: "path", Type: proto.ColumnType_STRING, Transform: transform.FromField("TreeEntry.Path"), Description: "The file referenced in the tree."}, | ||
{Name: "sha", Type: proto.ColumnType_STRING, Transform: transform.FromField("TreeEntry.SHA"), Description: "SHA1 checksum ID of the object in the tree."}, | ||
{Name: "size", Type: proto.ColumnType_STRING, Transform: transform.FromField("TreeEntry.Size"), Description: "Size of the blob."}, | ||
{Name: "type", Type: proto.ColumnType_STRING, Transform: transform.FromField("TreeEntry.Type"), Description: "Either blob, tree, or commit."}, | ||
{Name: "url", Type: proto.ColumnType_STRING, Transform: transform.FromField("TreeEntry.URL"), Description: "URL to the file referenced in the tree."}, | ||
}, | ||
} | ||
} | ||
|
||
type treeEntry struct { | ||
TreeEntry *github.TreeEntry | ||
Recursive bool | ||
Truncated *bool | ||
} | ||
|
||
//// GET FUNCTION | ||
|
||
func tableGitHubTreeList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
logger := plugin.Logger(ctx) | ||
client := connect(ctx, d) | ||
|
||
quals := d.KeyColumnQuals | ||
fullName := quals["repository_full_name"].GetStringValue() | ||
sha := quals["tree_sha"].GetStringValue() | ||
recursive := quals["recursive"].GetBoolValue() | ||
|
||
owner, repo := parseRepoFullName(fullName) | ||
|
||
type GetResponse struct { | ||
tree *github.Tree | ||
resp *github.Response | ||
} | ||
|
||
getTree := func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
tree, resp, err := client.Git.GetTree(ctx, owner, repo, sha, recursive) | ||
return GetResponse{ | ||
tree: tree, | ||
resp: resp, | ||
}, err | ||
} | ||
getResponse, err := plugin.RetryHydrate(ctx, d, h, getTree, &plugin.RetryConfig{ShouldRetryError: shouldRetryError}) | ||
|
||
if err != nil { | ||
logger.Error("github_tree.tableGitHubTreeList", "api_error", err) | ||
return nil, err | ||
} | ||
|
||
getResp := getResponse.(GetResponse) | ||
tree := getResp.tree | ||
entries := tree.Entries | ||
|
||
for _, entry := range entries { | ||
entryRow := treeEntry{ | ||
TreeEntry: entry, | ||
Recursive: recursive, | ||
Truncated: tree.Truncated, | ||
} | ||
d.StreamListItem(ctx, entryRow) | ||
} | ||
|
||
return nil, nil | ||
} |