-
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
fd46cea
commit 39d1c0a
Showing
3 changed files
with
276 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,165 @@ | ||
# Table: github_search_code | ||
|
||
The `github_search_code` table helps to search for the specific item you want to find inside of a file. You can search globally across all of GitHub, or scope your search to a particular repository or organization. | ||
|
||
**You must always include at least one search term when searching source code** in the where or join clause using the `query` column. The `query` contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. | ||
|
||
## Examples | ||
|
||
### List searched codes by file name | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'filename:table_github_my_organization RowsRemaining'; | ||
``` | ||
|
||
### List searched codes by file location | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'github_rate_limit path:docs/tables'; | ||
``` | ||
|
||
### List searched codes by extension | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'github_rate_limit path:docs/tables extension:md'; | ||
``` | ||
|
||
### List searched codes within organization's repositories | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'github_stargazer org:turbot extension:go'; | ||
``` | ||
|
||
### List searched codes within a user's repositories | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'Stargazers user:turbot extension:go'; | ||
``` | ||
|
||
### List searched codes within a user's specific repository | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'Stargazers repo:turbot/steampipe-plugin-github extension:go'; | ||
``` | ||
|
||
### List searched codes by language | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'github_tag org:turbot language:markdown'; | ||
``` | ||
|
||
### List searched codes while file size is greater than 40 KB | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'org:turbot size:>40000 language:markdown'; | ||
``` | ||
|
||
### List searched codes by the file contents or file path | ||
|
||
```sql | ||
select | ||
name, | ||
query, | ||
html_url, | ||
sha | ||
from | ||
github_search_code | ||
where | ||
query = 'Stargazers org:turbot in:file,path extension:go'; | ||
``` | ||
|
||
### List text match details | ||
|
||
```sql | ||
select | ||
name, | ||
jsonb_pretty(match -> 'matches') as matches, | ||
match ->> 'fragment' as fragment, | ||
match ->> 'property' as property, | ||
match ->> 'object_url' as object_url, | ||
match ->> 'object_type' as object_type | ||
from | ||
github_search_code, | ||
jsonb_array_elements(text_matches) as match | ||
where | ||
query = 'filename:table_github_my_organization RowsRemaining'; | ||
``` | ||
|
||
### List repository details | ||
|
||
```sql | ||
select | ||
name, | ||
repository -> 'id' as repo_id, | ||
repository ->> 'name' as repo_name, | ||
repository ->> 'url' as repo_url, | ||
jsonb_pretty(repository -> 'owner') as repo_owner | ||
from | ||
github_search_code | ||
where | ||
query = 'filename:table_github_my_organization RowsRemaining'; | ||
``` |
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,110 @@ | ||
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 tableGitHubSearchCode(ctx context.Context) *plugin.Table { | ||
return &plugin.Table{ | ||
Name: "github_search_code", | ||
Description: "Searches for query terms inside of a file.", | ||
List: &plugin.ListConfig{ | ||
KeyColumns: plugin.SingleColumn("query"), | ||
Hydrate: tableGitHubSearchCodeList, | ||
}, | ||
Columns: []*plugin.Column{ | ||
{Name: "name", Type: proto.ColumnType_STRING, Description: "The name of the file where the match has been found."}, | ||
{Name: "query", Type: proto.ColumnType_STRING, Transform: transform.FromQual("query"), Description: "The query used to match the code."}, | ||
{Name: "html_url", Type: proto.ColumnType_STRING, Description: "The complete URL of the file where the match has been found."}, | ||
{Name: "sha", Type: proto.ColumnType_STRING, Transform: transform.FromField("SHA"), Description: "The SHA of the file where the match has been found."}, | ||
{Name: "path", Type: proto.ColumnType_STRING, Description: "The path of the file where the match has been found."}, | ||
{Name: "repository", Type: proto.ColumnType_JSON, Description: "The repository details of the file where the match has been found."}, | ||
{Name: "text_matches", Type: proto.ColumnType_JSON, Description: "The text match details."}, | ||
}, | ||
} | ||
} | ||
|
||
//// LIST FUNCTION | ||
|
||
func tableGitHubSearchCodeList(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
logger := plugin.Logger(ctx) | ||
logger.Trace("tableGitHubSearchCodeList") | ||
|
||
quals := d.KeyColumnQuals | ||
query := quals["query"].GetStringValue() | ||
|
||
if query == "" { | ||
return nil, nil | ||
} | ||
|
||
opt := &github.SearchOptions{ | ||
ListOptions: github.ListOptions{PerPage: 100}, | ||
TextMatch: true, | ||
} | ||
|
||
type ListPageResponse struct { | ||
result *github.CodeSearchResult | ||
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.Code(ctx, query, opt) | ||
|
||
if err != nil { | ||
logger.Error("tableGitHubSearchCodeList", "error_Search.Code", 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("tableGitHubSearchCodeList", "error_RetryHydrate", err) | ||
return nil, err | ||
} | ||
|
||
listResponse := listPageResponse.(ListPageResponse) | ||
codeResults := listResponse.result.CodeResults | ||
resp := listResponse.resp | ||
|
||
for _, i := range codeResults { | ||
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 | ||
} |