Skip to content

Commit

Permalink
Add table github_search_code. Closes #100 (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
c0d3r-arnab committed Dec 6, 2021
1 parent fd46cea commit 39d1c0a
Show file tree
Hide file tree
Showing 3 changed files with 276 additions and 0 deletions.
165 changes: 165 additions & 0 deletions docs/tables/github_search_code.md
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';
```
1 change: 1 addition & 0 deletions github/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"github_rate_limit": tableGitHubRateLimit(ctx),
"github_release": tableGitHubRelease(ctx),
"github_repository": tableGitHubRepository(),
"github_search_code": tableGitHubSearchCode(ctx),
"github_search_topic": tableGitHubSearchTopic(ctx),
"github_stargazer": tableGitHubStargazer(ctx),
"github_tag": tableGitHubTag(ctx),
Expand Down
110 changes: 110 additions & 0 deletions github/table_github_search_code.go
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
}

0 comments on commit 39d1c0a

Please sign in to comment.