Skip to content

Commit 3b59f32

Browse files
sahildua2305gmlewis
authored andcommitted
Add support for Commit Search endpoint
Added support for this new preview endpoint which lets users search for commits based on various conditions. GitHub announcement - https://developer.github.com/changes/2017-01-05-commit-search-api/ Docs - https://developer.github.com/v3/search/#search-commits Fixes #508. Closes #520. Change-Id: I2210fafe3da530716075f9113851e09e3bc671f8
1 parent f7b63ba commit 3b59f32

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

github/github.go

+3
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ const (
9393

9494
// https://developer.github.com/changes/2016-11-28-preview-org-membership/
9595
mediaTypeOrgMembershipPreview = "application/vnd.github.korra-preview+json"
96+
97+
// https://developer.github.com/changes/2017-01-05-commit-search-api/
98+
mediaTypeCommitSearchPreview = "application/vnd.github.cloak-preview+json"
9699
)
97100

98101
// A Client manages communication with the GitHub API.

github/search.go

+39-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type SearchService service
2121
type SearchOptions struct {
2222
// How to sort the search results. Possible values are:
2323
// - for repositories: stars, fork, updated
24+
// - for commits: author-date, committer-date
2425
// - for code: indexed
2526
// - for issues: comments, created, updated
2627
// - for users: followers, repositories, joined
@@ -54,6 +55,37 @@ func (s *SearchService) Repositories(query string, opt *SearchOptions) (*Reposit
5455
return result, resp, err
5556
}
5657

58+
// CommitsSearchResult represents the result of a commits search.
59+
type CommitsSearchResult struct {
60+
Total *int `json:"total_count,omitempty"`
61+
IncompleteResults *bool `json:"incomplete_results,omitempty"`
62+
Commits []*CommitResult `json:"items,omitempty"`
63+
}
64+
65+
// CommitResult represents a commit object as returned in commit search endpoint response.
66+
type CommitResult struct {
67+
Hash *string `json:"hash,omitempty"`
68+
Message *string `json:"message,omitempty"`
69+
AuthorID *int `json:"author_id,omitempty"`
70+
AuthorName *string `json:"author_name,omitempty"`
71+
AuthorEmail *string `json:"author_email,omitempty"`
72+
AuthorDate *Timestamp `json:"author_date,omitempty"`
73+
CommitterID *int `json:"committer_id,omitempty"`
74+
CommitterName *string `json:"committer_name,omitempty"`
75+
CommitterEmail *string `json:"committer_email,omitempty"`
76+
CommitterDate *Timestamp `json:"committer_date,omitempty"`
77+
Repository *Repository `json:"repository,omitempty"`
78+
}
79+
80+
// Commits searches commits via various criteria.
81+
//
82+
// GitHub API Docs: https://developer.github.com/v3/search/#search-commits
83+
func (s *SearchService) Commits(query string, opt *SearchOptions) (*CommitsSearchResult, *Response, error) {
84+
result := new(CommitsSearchResult)
85+
resp, err := s.search("commits", query, opt, result)
86+
return result, resp, err
87+
}
88+
5789
// IssuesSearchResult represents the result of an issues search.
5890
type IssuesSearchResult struct {
5991
Total *int `json:"total_count,omitempty"`
@@ -136,7 +168,7 @@ func (s *SearchService) Code(query string, opt *SearchOptions) (*CodeSearchResul
136168
}
137169

138170
// Helper function that executes search queries against different
139-
// GitHub search types (repositories, code, issues, users)
171+
// GitHub search types (repositories, commits, code, issues, users)
140172
func (s *SearchService) search(searchType string, query string, opt *SearchOptions, result interface{}) (*Response, error) {
141173
params, err := qs.Values(opt)
142174
if err != nil {
@@ -150,7 +182,12 @@ func (s *SearchService) search(searchType string, query string, opt *SearchOptio
150182
return nil, err
151183
}
152184

153-
if opt != nil && opt.TextMatch {
185+
switch {
186+
case searchType == "commits":
187+
// Accept header for search commits preview endpoint
188+
// TODO: remove custom Accept header when this API fully launches.
189+
req.Header.Set("Accept", mediaTypeCommitSearchPreview)
190+
case opt != nil && opt.TextMatch:
154191
// Accept header defaults to "application/vnd.github.v3+json"
155192
// We change it here to fetch back text-match metadata
156193
req.Header.Set("Accept", "application/vnd.github.v3.text-match+json")

github/search_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,37 @@ func TestSearchService_Repositories(t *testing.T) {
4646
}
4747
}
4848

49+
func TestSearchService_Commits(t *testing.T) {
50+
setup()
51+
defer teardown()
52+
53+
mux.HandleFunc("/search/commits", func(w http.ResponseWriter, r *http.Request) {
54+
testMethod(t, r, "GET")
55+
testFormValues(t, r, values{
56+
"q": "blah",
57+
"sort": "author-date",
58+
"order": "desc",
59+
})
60+
61+
fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"hash":"random_hash1"},{"hash":"random_hash2"}]}`)
62+
})
63+
64+
opts := &SearchOptions{Sort: "author-date", Order: "desc"}
65+
result, _, err := client.Search.Commits("blah", opts)
66+
if err != nil {
67+
t.Errorf("Search.Commits returned error: %v", err)
68+
}
69+
70+
want := &CommitsSearchResult{
71+
Total: Int(4),
72+
IncompleteResults: Bool(false),
73+
Commits: []*CommitResult{{Hash: String("random_hash1")}, {Hash: String("random_hash2")}},
74+
}
75+
if !reflect.DeepEqual(result, want) {
76+
t.Errorf("Search.Commits returned %+v, want %+v", result, want)
77+
}
78+
}
79+
4980
func TestSearchService_Issues(t *testing.T) {
5081
setup()
5182
defer teardown()

0 commit comments

Comments
 (0)