-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
97fbaa2
commit 77e69e8
Showing
3 changed files
with
250 additions
and
0 deletions.
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,115 @@ | ||
# Table: github_search_issue | ||
|
||
The `github_search_issue` table helps to find issues by state and keyword. You can search for issues globally across all of GitHub, or search for issues within a particular organization. | ||
|
||
**You must always include at least one search term when searching source code** in the where or join clause using the `query` column. You can narrow the results using these search qualifiers in any combination. | ||
|
||
## Examples | ||
|
||
### List issues by the title, body, or comments | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
state, | ||
created_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'github_search_commit in:title in:body in:comments'; | ||
``` | ||
|
||
### List issues in open state assigned to a specific user | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
state, | ||
created_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'is:open assignee:c0d3r-arnab repo:turbot/steampipe-plugin-github'; | ||
``` | ||
|
||
### List issues with public visibility assigned to a specific user | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
state, | ||
created_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'is:public assignee:c0d3r-arnab repo:turbot/steampipe-plugin-github'; | ||
``` | ||
|
||
### List issues not linked to a pull request | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
state, | ||
created_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'is:open -linked:pr repo:turbot/steampipe-plugin-github'; | ||
``` | ||
|
||
### List blocked issues | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
state, | ||
created_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'label:blocked repo:turbot/steampipe-plugin-github'; | ||
``` | ||
|
||
### List issues with over 10 comments | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
comments, | ||
state, | ||
created_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'org:turbot comments:>10'; | ||
``` | ||
|
||
### List issues that took more than 30 days to close | ||
|
||
```sql | ||
select | ||
title, | ||
id, | ||
state, | ||
created_at, | ||
closed_at, | ||
html_url | ||
from | ||
github_search_issue | ||
where | ||
query = 'org:turbot state:closed' | ||
and closed_at > (created_at + interval '30' day); | ||
``` |
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,134 @@ | ||
package github | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/google/go-github/v33/github" | ||
"github.com/turbot/steampipe-plugin-sdk/grpc/proto" | ||
"github.com/turbot/steampipe-plugin-sdk/plugin" | ||
"github.com/turbot/steampipe-plugin-sdk/plugin/transform" | ||
) | ||
|
||
//// TABLE DEFINITION | ||
|
||
func tableGitHubSearchIssue(ctx context.Context) *plugin.Table { | ||
return &plugin.Table{ | ||
Name: "github_search_issue", | ||
Description: "Find issues by state and keyword.", | ||
List: &plugin.ListConfig{ | ||
KeyColumns: plugin.SingleColumn("query"), | ||
Hydrate: tableGitHubSearchIssueList, | ||
}, | ||
Columns: []*plugin.Column{ | ||
{Name: "title", Type: proto.ColumnType_STRING, Description: "The title of the issue."}, | ||
{Name: "id", Type: proto.ColumnType_INT, Transform: transform.FromField("ID"), Description: "The ID of the issue."}, | ||
{Name: "query", Type: proto.ColumnType_STRING, Transform: transform.FromQual("query"), Description: "The query used to match the issue."}, | ||
{Name: "state", Type: proto.ColumnType_STRING, Description: "The state of the issue."}, | ||
{Name: "active_lock_reason", Type: proto.ColumnType_STRING, Description: "The active lock reason of the issue."}, | ||
{Name: "author_association", Type: proto.ColumnType_STRING, Description: "The author association of the issue."}, | ||
{Name: "body", Type: proto.ColumnType_STRING, Description: "The body of the issue."}, | ||
{Name: "closed_at", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp the issue closed at."}, | ||
{Name: "comments", Type: proto.ColumnType_INT, Description: "The number of comments on the issue."}, | ||
{Name: "comments_url", Type: proto.ColumnType_STRING, Description: "The API URL of the comments for the issue."}, | ||
{Name: "created_at", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp the issue created at."}, | ||
{Name: "events_url", Type: proto.ColumnType_STRING, Description: "The API URL of the events for the issue."}, | ||
{Name: "html_url", Type: proto.ColumnType_STRING, Description: "The complete URL of the issue."}, | ||
{Name: "labels_url", Type: proto.ColumnType_STRING, Description: "The API URL of the labels for the issue."}, | ||
{Name: "locked", Type: proto.ColumnType_BOOL, Default: false, Description: "Whether the issue is locked."}, | ||
{Name: "node_id", Type: proto.ColumnType_STRING, Description: "The node ID of the issue."}, | ||
{Name: "number", Type: proto.ColumnType_INT, Description: "The number of the issue."}, | ||
{Name: "repository_url", Type: proto.ColumnType_STRING, Description: "The API URL of the repository for the issue."}, | ||
{Name: "updated_at", Type: proto.ColumnType_TIMESTAMP, Description: "The timestamp the issue updated at."}, | ||
{Name: "url", Type: proto.ColumnType_STRING, Transform: transform.FromField("URL"), Description: "The API URL of the issue."}, | ||
{Name: "assignee", Type: proto.ColumnType_JSON, Description: "The assignee details."}, | ||
{Name: "assignees", Type: proto.ColumnType_JSON, Description: "The assignees details."}, | ||
{Name: "closed_by", Type: proto.ColumnType_JSON, Description: "The details of the user that closed the issue."}, | ||
{Name: "labels", Type: proto.ColumnType_JSON, Description: "The label details."}, | ||
{Name: "milestone", Type: proto.ColumnType_JSON, Description: "The milestone details."}, | ||
{Name: "reactions", Type: proto.ColumnType_JSON, Description: "The reaction details."}, | ||
{Name: "repository", Type: proto.ColumnType_JSON, Description: "The repository details."}, | ||
{Name: "text_matches", Type: proto.ColumnType_JSON, Description: "The text match details."}, | ||
{Name: "user", Type: proto.ColumnType_JSON, Description: "The user details."}, | ||
}, | ||
} | ||
} | ||
|
||
//// LIST FUNCTION | ||
|
||
func tableGitHubSearchIssueList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
logger := plugin.Logger(ctx) | ||
logger.Trace("tableGitHubSearchIssueList") | ||
|
||
quals := d.KeyColumnQuals | ||
query := quals["query"].GetStringValue() | ||
|
||
if query == "" { | ||
return nil, nil | ||
} | ||
|
||
query = query + " is:issue" | ||
|
||
opt := &github.SearchOptions{ | ||
ListOptions: github.ListOptions{PerPage: 100}, | ||
TextMatch: true, | ||
} | ||
|
||
type ListPageResponse struct { | ||
result *github.IssuesSearchResult | ||
resp *github.Response | ||
} | ||
|
||
client := connect(ctx, d) | ||
|
||
// Reduce the basic request limit down if the user has only requested a small number of rows | ||
limit := d.QueryContext.Limit | ||
if limit != nil { | ||
if *limit < int64(opt.ListOptions.PerPage) { | ||
opt.ListOptions.PerPage = int(*limit) | ||
} | ||
} | ||
|
||
listPage := func(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
result, resp, err := client.Search.Issues(ctx, query, opt) | ||
|
||
if err != nil { | ||
logger.Error("tableGitHubSearchIssueList", "error_Search.Issues", err) | ||
return nil, err | ||
} | ||
|
||
return ListPageResponse{ | ||
result: result, | ||
resp: resp, | ||
}, nil | ||
} | ||
|
||
for { | ||
listPageResponse, err := plugin.RetryHydrate(ctx, d, h, listPage, &plugin.RetryConfig{ShouldRetryError: shouldRetryError}) | ||
|
||
if err != nil { | ||
logger.Error("tableGitHubSearchIssueList", "error_RetryHydrate", err) | ||
return nil, err | ||
} | ||
|
||
listResponse := listPageResponse.(ListPageResponse) | ||
issues := listResponse.result.Issues | ||
resp := listResponse.resp | ||
|
||
for _, i := range issues { | ||
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 resp.NextPage == 0 { | ||
break | ||
} | ||
|
||
opt.Page = resp.NextPage | ||
} | ||
|
||
return nil, nil | ||
} |
77e69e8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay!