search.go

  1//
  2// Copyright 2018, Sander van Harmelen
  3//
  4// Licensed under the Apache License, Version 2.0 (the "License");
  5// you may not use this file except in compliance with the License.
  6// You may obtain a copy of the License at
  7//
  8//     http://www.apache.org/licenses/LICENSE-2.0
  9//
 10// Unless required by applicable law or agreed to in writing, software
 11// distributed under the License is distributed on an "AS IS" BASIS,
 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13// See the License for the specific language governing permissions and
 14// limitations under the License.
 15//
 16
 17package gitlab
 18
 19import (
 20	"fmt"
 21)
 22
 23// SearchService handles communication with the search related methods of the
 24// GitLab API.
 25//
 26// GitLab API docs: https://docs.gitlab.com/ce/api/search.html
 27type SearchService struct {
 28	client *Client
 29}
 30
 31// SearchOptions represents the available options for all search methods.
 32//
 33// GitLab API docs: https://docs.gitlab.com/ce/api/search.html
 34type SearchOptions ListOptions
 35
 36type searchOptions struct {
 37	SearchOptions
 38	Scope  string `url:"scope" json:"scope"`
 39	Search string `url:"search" json:"search"`
 40}
 41
 42// Projects searches the expression within projects
 43//
 44// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-projects
 45func (s *SearchService) Projects(query string, opt *SearchOptions, options ...OptionFunc) ([]*Project, *Response, error) {
 46	var ps []*Project
 47	resp, err := s.search("projects", query, &ps, opt, options...)
 48	return ps, resp, err
 49}
 50
 51// ProjectsByGroup searches the expression within projects for
 52// the specified group
 53//
 54// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#group-search-api
 55func (s *SearchService) ProjectsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Project, *Response, error) {
 56	var ps []*Project
 57	resp, err := s.searchByGroup(gid, "projects", query, &ps, opt, options...)
 58	return ps, resp, err
 59}
 60
 61// Issues searches the expression within issues
 62//
 63// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues
 64func (s *SearchService) Issues(query string, opt *SearchOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
 65	var is []*Issue
 66	resp, err := s.search("issues", query, &is, opt, options...)
 67	return is, resp, err
 68}
 69
 70// IssuesByGroup searches the expression within issues for
 71// the specified group
 72//
 73// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues
 74func (s *SearchService) IssuesByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
 75	var is []*Issue
 76	resp, err := s.searchByGroup(gid, "issues", query, &is, opt, options...)
 77	return is, resp, err
 78}
 79
 80// IssuesByProject searches the expression within issues for
 81// the specified project
 82//
 83// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues
 84func (s *SearchService) IssuesByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
 85	var is []*Issue
 86	resp, err := s.searchByProject(pid, "issues", query, &is, opt, options...)
 87	return is, resp, err
 88}
 89
 90// MergeRequests searches the expression within merge requests
 91//
 92// GitLab API docs:
 93// https://docs.gitlab.com/ce/api/search.html#scope-merge_requests
 94func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
 95	var ms []*MergeRequest
 96	resp, err := s.search("merge_requests", query, &ms, opt, options...)
 97	return ms, resp, err
 98}
 99
100// MergeRequestsByGroup searches the expression within merge requests for
101// the specified group
102//
103// GitLab API docs:
104// https://docs.gitlab.com/ce/api/search.html#scope-merge_requests
105func (s *SearchService) MergeRequestsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
106	var ms []*MergeRequest
107	resp, err := s.searchByGroup(gid, "merge_requests", query, &ms, opt, options...)
108	return ms, resp, err
109}
110
111// MergeRequestsByProject searches the expression within merge requests for
112// the specified project
113//
114// GitLab API docs:
115// https://docs.gitlab.com/ce/api/search.html#scope-merge_requests
116func (s *SearchService) MergeRequestsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
117	var ms []*MergeRequest
118	resp, err := s.searchByProject(pid, "merge_requests", query, &ms, opt, options...)
119	return ms, resp, err
120}
121
122// Milestones searches the expression within milestones
123//
124// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones
125func (s *SearchService) Milestones(query string, opt *SearchOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
126	var ms []*Milestone
127	resp, err := s.search("milestones", query, &ms, opt, options...)
128	return ms, resp, err
129}
130
131// MilestonesByGroup searches the expression within milestones for
132// the specified group
133//
134// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones
135func (s *SearchService) MilestonesByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
136	var ms []*Milestone
137	resp, err := s.searchByGroup(gid, "milestones", query, &ms, opt, options...)
138	return ms, resp, err
139}
140
141// MilestonesByProject searches the expression within milestones for
142// the specified project
143//
144// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones
145func (s *SearchService) MilestonesByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
146	var ms []*Milestone
147	resp, err := s.searchByProject(pid, "milestones", query, &ms, opt, options...)
148	return ms, resp, err
149}
150
151// SnippetTitles searches the expression within snippet titles
152//
153// GitLab API docs:
154// https://docs.gitlab.com/ce/api/search.html#scope-snippet_titles
155func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options ...OptionFunc) ([]*Snippet, *Response, error) {
156	var ss []*Snippet
157	resp, err := s.search("snippet_titles", query, &ss, opt, options...)
158	return ss, resp, err
159}
160
161// SnippetBlobs searches the expression within snippet blobs
162//
163// GitLab API docs:
164// https://docs.gitlab.com/ce/api/search.html#scope-snippet_blobs
165func (s *SearchService) SnippetBlobs(query string, opt *SearchOptions, options ...OptionFunc) ([]*Snippet, *Response, error) {
166	var ss []*Snippet
167	resp, err := s.search("snippet_blobs", query, &ss, opt, options...)
168	return ss, resp, err
169}
170
171// NotesByProject searches the expression within notes for the specified
172// project
173//
174// GitLab API docs: // https://docs.gitlab.com/ce/api/search.html#scope-notes
175func (s *SearchService) NotesByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Note, *Response, error) {
176	var ns []*Note
177	resp, err := s.searchByProject(pid, "notes", query, &ns, opt, options...)
178	return ns, resp, err
179}
180
181// WikiBlobs searches the expression within all wiki blobs
182//
183// GitLab API docs:
184// https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs
185func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...OptionFunc) ([]*Wiki, *Response, error) {
186	var ws []*Wiki
187	resp, err := s.search("wiki_blobs", query, &ws, opt, options...)
188	return ws, resp, err
189}
190
191// WikiBlobsByGroup searches the expression within wiki blobs for
192// specified group
193//
194// GitLab API docs:
195// https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs
196func (s *SearchService) WikiBlobsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Wiki, *Response, error) {
197	var ws []*Wiki
198	resp, err := s.searchByGroup(gid, "wiki_blobs", query, &ws, opt, options...)
199	return ws, resp, err
200}
201
202// WikiBlobsByProject searches the expression within wiki blobs for
203// the specified project
204//
205// GitLab API docs:
206// https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs
207func (s *SearchService) WikiBlobsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Wiki, *Response, error) {
208	var ws []*Wiki
209	resp, err := s.searchByProject(pid, "wiki_blobs", query, &ws, opt, options...)
210	return ws, resp, err
211}
212
213// Commits searches the expression within all commits
214//
215// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits
216func (s *SearchService) Commits(query string, opt *SearchOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
217	var cs []*Commit
218	resp, err := s.search("commits", query, &cs, opt, options...)
219	return cs, resp, err
220}
221
222// CommitsByGroup searches the expression within commits for the specified
223// group
224//
225// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits
226func (s *SearchService) CommitsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
227	var cs []*Commit
228	resp, err := s.searchByGroup(gid, "commits", query, &cs, opt, options...)
229	return cs, resp, err
230}
231
232// CommitsByProject searches the expression within commits for the
233// specified project
234//
235// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits
236func (s *SearchService) CommitsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
237	var cs []*Commit
238	resp, err := s.searchByProject(pid, "commits", query, &cs, opt, options...)
239	return cs, resp, err
240}
241
242// Blob represents a single blob.
243type Blob struct {
244	Basename  string `json:"basename"`
245	Data      string `json:"data"`
246	Filename  string `json:"filename"`
247	ID        int    `json:"id"`
248	Ref       string `json:"ref"`
249	Startline int    `json:"startline"`
250	ProjectID int    `json:"project_id"`
251}
252
253// Blobs searches the expression within all blobs
254//
255// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs
256func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...OptionFunc) ([]*Blob, *Response, error) {
257	var bs []*Blob
258	resp, err := s.search("blobs", query, &bs, opt, options...)
259	return bs, resp, err
260}
261
262// BlobsByGroup searches the expression within blobs for the specified
263// group
264//
265// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs
266func (s *SearchService) BlobsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Blob, *Response, error) {
267	var bs []*Blob
268	resp, err := s.searchByGroup(gid, "blobs", query, &bs, opt, options...)
269	return bs, resp, err
270}
271
272// BlobsByProject searches the expression within blobs for the specified
273// project
274//
275// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs
276func (s *SearchService) BlobsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Blob, *Response, error) {
277	var bs []*Blob
278	resp, err := s.searchByProject(pid, "blobs", query, &bs, opt, options...)
279	return bs, resp, err
280}
281
282func (s *SearchService) search(scope, query string, result interface{}, opt *SearchOptions, options ...OptionFunc) (*Response, error) {
283	opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query}
284
285	req, err := s.client.NewRequest("GET", "search", opts, options)
286	if err != nil {
287		return nil, err
288	}
289
290	return s.client.Do(req, result)
291}
292
293func (s *SearchService) searchByGroup(gid interface{}, scope, query string, result interface{}, opt *SearchOptions, options ...OptionFunc) (*Response, error) {
294	group, err := parseID(gid)
295	if err != nil {
296		return nil, err
297	}
298	u := fmt.Sprintf("groups/%s/-/search", pathEscape(group))
299
300	opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query}
301
302	req, err := s.client.NewRequest("GET", u, opts, options)
303	if err != nil {
304		return nil, err
305	}
306
307	return s.client.Do(req, result)
308}
309
310func (s *SearchService) searchByProject(pid interface{}, scope, query string, result interface{}, opt *SearchOptions, options ...OptionFunc) (*Response, error) {
311	project, err := parseID(pid)
312	if err != nil {
313		return nil, err
314	}
315	u := fmt.Sprintf("projects/%s/-/search", pathEscape(project))
316
317	opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query}
318
319	req, err := s.client.NewRequest("GET", u, opts, options)
320	if err != nil {
321		return nil, err
322	}
323
324	return s.client.Do(req, result)
325}