diff --git a/backend/mock/service/githubmock/githubmock.go b/backend/mock/service/githubmock/githubmock.go index 32444ecb52..667aa2c612 100644 --- a/backend/mock/service/githubmock/githubmock.go +++ b/backend/mock/service/githubmock/githubmock.go @@ -111,6 +111,23 @@ func (s svc) CreateCommit(ctx context.Context, ref *github.RemoteRef, message st }, nil } +func (s *svc) SearchCode(ctx context.Context, query string, opts *githubv3.SearchOptions) (*githubv3.CodeSearchResult, error) { + var codeResults []*githubv3.CodeResult + + codeResults = append(codeResults, &githubv3.CodeResult{ + Name: githubv3.String("file.go"), + Path: githubv3.String("path/to/file.go"), + SHA: githubv3.String("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"), + HTMLURL: githubv3.String("https://github.com/owner/repo/path/to/file.go"), + Repository: nil, + }) + return &githubv3.CodeSearchResult{ + Total: githubv3.Int(1), + IncompleteResults: githubv3.Bool(false), + CodeResults: codeResults, + }, nil +} + func NewAsService(*any.Any, *zap.Logger, tally.Scope) (service.Service, error) { return New(), nil } diff --git a/backend/service/github/github.go b/backend/service/github/github.go index 98384f2bda..7120fdeecb 100644 --- a/backend/service/github/github.go +++ b/backend/service/github/github.go @@ -128,6 +128,7 @@ type Client interface { GetPullRequest(ctx context.Context, owner, repo string, number int) (*githubv3.PullRequest, error) DeleteFile(ctx context.Context, ref *RemoteRef, path, sha, message string) (*githubv3.RepositoryContentResponse, error) CreateCommit(ctx context.Context, ref *RemoteRef, message string, files FileMap) (*Commit, error) + SearchCode(ctx context.Context, query string, opts *githubv3.SearchOptions) (*githubv3.CodeSearchResult, error) } // This func can be used to create comments for PRs or Issues @@ -401,11 +402,12 @@ func newService(config *githubv1.Config, scope tally.Scope, logger *zap.Logger) restClient := githubv3.NewClient(httpClient) ret.rest = v3client{ - Repositories: restClient.Repositories, - PullRequests: restClient.PullRequests, Issues: restClient.Issues, - Users: restClient.Users, Organizations: restClient.Organizations, + PullRequests: restClient.PullRequests, + Repositories: restClient.Repositories, + Search: restClient.Search, + Users: restClient.Users, } ret.graphQL = githubv4.NewClient(httpClient) @@ -661,3 +663,13 @@ func (s *svc) createWorktreeCommit(ctx context.Context, ref *RemoteRef, message return &hash, nil } + +func (s *svc) SearchCode(ctx context.Context, query string, opts *githubv3.SearchOptions) (*githubv3.CodeSearchResult, error) { + results, _, err := s.rest.Search.Code(ctx, query, opts) + + if err != nil { + return nil, err + } + + return results, nil +} diff --git a/backend/service/github/iface.go b/backend/service/github/iface.go index 24c569c906..dffdd475fa 100644 --- a/backend/service/github/iface.go +++ b/backend/service/github/iface.go @@ -11,33 +11,12 @@ import ( // testing strategy (wrap the struct) than most libraries (mock the interface) // See https://github.com/google/go-github/issues/113#issuecomment-46023864 type v3client struct { - Repositories v3repositories - PullRequests v3pullrequests Issues v3issues - Users v3users Organizations v3organizations -} - -// Interface for struct defined in https://github.com/google/go-github/blob/master/github/repos.go. -// Method comments below reproduced directly from original definition linked above. -type v3repositories interface { - // Create a new repository. If an org is specified, the new repository will be created under that org. If the empty string is specified, it will be created for the authenticated user. - Create(ctx context.Context, org string, repo *githubv3.Repository) (*githubv3.Repository, *githubv3.Response, error) - GetContents(ctx context.Context, owner, repo, path string, opt *githubv3.RepositoryContentGetOptions) (*githubv3.RepositoryContent, []*githubv3.RepositoryContent, *githubv3.Response, error) - CompareCommits(ctx context.Context, owner, repo string, base, head string, opts *githubv3.ListOptions) (*githubv3.CommitsComparison, *githubv3.Response, error) - GetCommit(ctx context.Context, owner, repo, sha string, opts *githubv3.ListOptions) (*githubv3.RepositoryCommit, *githubv3.Response, error) - DeleteFile(ctx context.Context, owner, repo, path string, opts *githubv3.RepositoryContentFileOptions) (*githubv3.RepositoryContentResponse, *githubv3.Response, error) -} - -// Interface for struct defined in https://github.com/google/go-github/blob/master/github/pulls.go. -// Method comments below reproduced directly from original definition linked above. -type v3pullrequests interface { - // Create a new pull request on the specified repository. - Create(ctx context.Context, owner string, repo string, pull *githubv3.NewPullRequest) (*githubv3.PullRequest, *githubv3.Response, error) - // ListPullRequestsWithCommit returns pull requests associated with a commit SHA. - ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *githubv3.ListOptions) ([]*githubv3.PullRequest, *githubv3.Response, error) - // GetPullRequest returns a single pull request specified by the PR number - Get(ctx context.Context, owner, repo string, number int) (*githubv3.PullRequest, *githubv3.Response, error) + PullRequests v3pullrequests + Repositories v3repositories + Search v3search + Users v3users } type v4client interface { @@ -45,7 +24,10 @@ type v4client interface { Mutate(ctx context.Context, m interface{}, input githubv4.Input, variables map[string]interface{}) error } +// Interface for struct defined in https://github.com/google/go-github/blob/master/github/issues_comments.go. +// Method comments below reproduced directly from original definition linked above. type v3issues interface { + // CreateComment creates a new comment on the specified issue. CreateComment( ctx context.Context, owner string, @@ -55,12 +37,69 @@ type v3issues interface { ) (*githubv3.IssueComment, *githubv3.Response, error) } -type v3users interface { - Get(ctx context.Context, user string) (*githubv3.User, *githubv3.Response, error) -} - +// Interface for structs defined in +// https://github.com/google/go-github/blob/master/github/orgs.go +// && +// https://github.com/google/go-github/blob/master/github/orgs_members.go +// Method comments below reproduced directly from original definition(s) linked above. type v3organizations interface { + // Get fetches an organization by name. Get(ctx context.Context, org string) (*githubv3.Organization, *githubv3.Response, error) + // List the organizations for a user. Passing the empty string will list organizations for the authenticated user. List(ctx context.Context, user string, opts *githubv3.ListOptions) ([]*githubv3.Organization, *githubv3.Response, error) + // GetOrgMembership gets the membership for a user in a specified organization. + // Passing an empty string for user will get the membership for the + // authenticated user. GetOrgMembership(ctx context.Context, user, org string) (*githubv3.Membership, *githubv3.Response, error) } + +// Interface for struct defined in https://github.com/google/go-github/blob/master/github/pulls.go. +// Method comments below reproduced directly from original definition linked above. +type v3pullrequests interface { + // Create a new pull request on the specified repository. + Create(ctx context.Context, owner string, repo string, pull *githubv3.NewPullRequest) (*githubv3.PullRequest, *githubv3.Response, error) + // Get a single pull request. + Get(ctx context.Context, owner string, repo string, number int) (*githubv3.PullRequest, *githubv3.Response, error) + // ListPullRequestsWithCommit returns pull requests associated with a commit SHA. + ListPullRequestsWithCommit(ctx context.Context, owner, repo, sha string, opts *githubv3.ListOptions) ([]*githubv3.PullRequest, *githubv3.Response, error) +} + +// Interface for structs defined in +// https://github.com/google/go-github/blob/master/github/repos.go +// && +// https://github.com/google/go-github/blob/master/github/repos_commits.go +// && +// https://github.com/google/go-github/blob/master/github/repos_contents.go +// Method comments below reproduced directly from original definition(s) linked above. +type v3repositories interface { + // Create a new repository. If an org is specified, the new repository will be created under that org. If the empty string is specified, it will be created for the authenticated user. + Create(ctx context.Context, org string, repo *githubv3.Repository) (*githubv3.Repository, *githubv3.Response, error) + // GetContents can return either the metadata and content of a single file + // (when path references a file) or the metadata of all the files and/or + // subdirectories of a directory (when path references a directory). To make it + // easy to distinguish between both result types and to mimic the API as much + // as possible, both result types will be returned but only one will contain a + // value and the other will be nil. + GetContents(ctx context.Context, owner, repo, path string, opt *githubv3.RepositoryContentGetOptions) (*githubv3.RepositoryContent, []*githubv3.RepositoryContent, *githubv3.Response, error) + // CompareCommits compares a range of commits with each other. + CompareCommits(ctx context.Context, owner, repo string, base, head string, opts *githubv3.ListOptions) (*githubv3.CommitsComparison, *githubv3.Response, error) + // GetCommit fetches the specified commit, including all details about it. + GetCommit(ctx context.Context, owner, repo, sha string, opts *githubv3.ListOptions) (*githubv3.RepositoryCommit, *githubv3.Response, error) + // DeleteFile deletes a file from a repository and returns the commit. + // Requires the blob SHA of the file to be deleted. + DeleteFile(ctx context.Context, owner, repo, path string, opts *githubv3.RepositoryContentFileOptions) (*githubv3.RepositoryContentResponse, *githubv3.Response, error) +} + +// Interface for struct defined in https://github.com/google/go-github/blob/master/github/search.go. +// Method comments below reproduced directly from original definition linked above. +type v3search interface { + // Code searches code via various criteria. + Code(ctx context.Context, query string, opts *githubv3.SearchOptions) (*githubv3.CodeSearchResult, *githubv3.Response, error) +} + +// Interface for struct defined in https://github.com/google/go-github/blob/master/github/users.go. +// Method comments below reproduced directly from original definition linked above. +type v3users interface { + // Get fetches a user. Passing the empty string will fetch the authenticated user. + Get(ctx context.Context, user string) (*githubv3.User, *githubv3.Response, error) +}