search.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. package gitlab
  17. import (
  18. "fmt"
  19. "net/url"
  20. )
  21. // SearchService handles communication with the search related methods of the
  22. // GitLab API.
  23. //
  24. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html
  25. type SearchService struct {
  26. client *Client
  27. }
  28. // SearchOptions represents the available options for all search methods.
  29. //
  30. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html
  31. type SearchOptions ListOptions
  32. type searchOptions struct {
  33. SearchOptions
  34. Scope string `url:"scope" json:"scope"`
  35. Search string `url:"search" json:"search"`
  36. }
  37. // Projects searches the expression within projects
  38. //
  39. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-projects
  40. func (s *SearchService) Projects(query string, opt *SearchOptions, options ...OptionFunc) ([]*Project, *Response, error) {
  41. var ps []*Project
  42. resp, err := s.search("projects", query, &ps, opt, options...)
  43. return ps, resp, err
  44. }
  45. // ProjectsByGroup searches the expression within projects for
  46. // the specified group
  47. //
  48. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#group-search-api
  49. func (s *SearchService) ProjectsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Project, *Response, error) {
  50. var ps []*Project
  51. resp, err := s.searchByGroup(gid, "projects", query, &ps, opt, options...)
  52. return ps, resp, err
  53. }
  54. // Issues searches the expression within issues
  55. //
  56. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues
  57. func (s *SearchService) Issues(query string, opt *SearchOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
  58. var is []*Issue
  59. resp, err := s.search("issues", query, &is, opt, options...)
  60. return is, resp, err
  61. }
  62. // IssuesByGroup searches the expression within issues for
  63. // the specified group
  64. //
  65. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues
  66. func (s *SearchService) IssuesByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
  67. var is []*Issue
  68. resp, err := s.searchByGroup(gid, "issues", query, &is, opt, options...)
  69. return is, resp, err
  70. }
  71. // IssuesByProject searches the expression within issues for
  72. // the specified project
  73. //
  74. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues
  75. func (s *SearchService) IssuesByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
  76. var is []*Issue
  77. resp, err := s.searchByProject(pid, "issues", query, &is, opt, options...)
  78. return is, resp, err
  79. }
  80. // MergeRequests searches the expression within merge requests
  81. //
  82. // GitLab API docs:
  83. // https://docs.gitlab.com/ce/api/search.html#scope-merge_requests
  84. func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
  85. var ms []*MergeRequest
  86. resp, err := s.search("merge_requests", query, &ms, opt, options...)
  87. return ms, resp, err
  88. }
  89. // MergeRequestsByGroup searches the expression within merge requests for
  90. // the specified group
  91. //
  92. // GitLab API docs:
  93. // https://docs.gitlab.com/ce/api/search.html#scope-merge_requests
  94. func (s *SearchService) MergeRequestsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
  95. var ms []*MergeRequest
  96. resp, err := s.searchByGroup(gid, "merge_requests", query, &ms, opt, options...)
  97. return ms, resp, err
  98. }
  99. // MergeRequestsByProject searches the expression within merge requests for
  100. // the specified project
  101. //
  102. // GitLab API docs:
  103. // https://docs.gitlab.com/ce/api/search.html#scope-merge_requests
  104. func (s *SearchService) MergeRequestsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
  105. var ms []*MergeRequest
  106. resp, err := s.searchByProject(pid, "merge_requests", query, &ms, opt, options...)
  107. return ms, resp, err
  108. }
  109. // Milestones searches the expression within milestones
  110. //
  111. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones
  112. func (s *SearchService) Milestones(query string, opt *SearchOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
  113. var ms []*Milestone
  114. resp, err := s.search("milestones", query, &ms, opt, options...)
  115. return ms, resp, err
  116. }
  117. // MilestonesByGroup searches the expression within milestones for
  118. // the specified group
  119. //
  120. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones
  121. func (s *SearchService) MilestonesByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
  122. var ms []*Milestone
  123. resp, err := s.searchByGroup(gid, "milestones", query, &ms, opt, options...)
  124. return ms, resp, err
  125. }
  126. // MilestonesByProject searches the expression within milestones for
  127. // the specified project
  128. //
  129. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones
  130. func (s *SearchService) MilestonesByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
  131. var ms []*Milestone
  132. resp, err := s.searchByProject(pid, "milestones", query, &ms, opt, options...)
  133. return ms, resp, err
  134. }
  135. // SnippetTitles searches the expression within snippet titles
  136. //
  137. // GitLab API docs:
  138. // https://docs.gitlab.com/ce/api/search.html#scope-snippet_titles
  139. func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options ...OptionFunc) ([]*Snippet, *Response, error) {
  140. var ss []*Snippet
  141. resp, err := s.search("snippet_titles", query, &ss, opt, options...)
  142. return ss, resp, err
  143. }
  144. // SnippetBlobs searches the expression within snippet blobs
  145. //
  146. // GitLab API docs:
  147. // https://docs.gitlab.com/ce/api/search.html#scope-snippet_blobs
  148. func (s *SearchService) SnippetBlobs(query string, opt *SearchOptions, options ...OptionFunc) ([]*Snippet, *Response, error) {
  149. var ss []*Snippet
  150. resp, err := s.search("snippet_blobs", query, &ss, opt, options...)
  151. return ss, resp, err
  152. }
  153. // NotesByProject searches the expression within notes for the specified
  154. // project
  155. //
  156. // GitLab API docs: // https://docs.gitlab.com/ce/api/search.html#scope-notes
  157. func (s *SearchService) NotesByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Note, *Response, error) {
  158. var ns []*Note
  159. resp, err := s.searchByProject(pid, "notes", query, &ns, opt, options...)
  160. return ns, resp, err
  161. }
  162. // WikiBlobs searches the expression within all wiki blobs
  163. //
  164. // GitLab API docs:
  165. // https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs
  166. func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...OptionFunc) ([]*Wiki, *Response, error) {
  167. var ws []*Wiki
  168. resp, err := s.search("wiki_blobs", query, &ws, opt, options...)
  169. return ws, resp, err
  170. }
  171. // WikiBlobsByGroup searches the expression within wiki blobs for
  172. // specified group
  173. //
  174. // GitLab API docs:
  175. // https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs
  176. func (s *SearchService) WikiBlobsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Wiki, *Response, error) {
  177. var ws []*Wiki
  178. resp, err := s.searchByGroup(gid, "wiki_blobs", query, &ws, opt, options...)
  179. return ws, resp, err
  180. }
  181. // WikiBlobsByProject searches the expression within wiki blobs for
  182. // the specified project
  183. //
  184. // GitLab API docs:
  185. // https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs
  186. func (s *SearchService) WikiBlobsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Wiki, *Response, error) {
  187. var ws []*Wiki
  188. resp, err := s.searchByProject(pid, "wiki_blobs", query, &ws, opt, options...)
  189. return ws, resp, err
  190. }
  191. // Commits searches the expression within all commits
  192. //
  193. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits
  194. func (s *SearchService) Commits(query string, opt *SearchOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
  195. var cs []*Commit
  196. resp, err := s.search("commits", query, &cs, opt, options...)
  197. return cs, resp, err
  198. }
  199. // CommitsByGroup searches the expression within commits for the specified
  200. // group
  201. //
  202. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits
  203. func (s *SearchService) CommitsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
  204. var cs []*Commit
  205. resp, err := s.searchByGroup(gid, "commits", query, &cs, opt, options...)
  206. return cs, resp, err
  207. }
  208. // CommitsByProject searches the expression within commits for the
  209. // specified project
  210. //
  211. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits
  212. func (s *SearchService) CommitsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
  213. var cs []*Commit
  214. resp, err := s.searchByProject(pid, "commits", query, &cs, opt, options...)
  215. return cs, resp, err
  216. }
  217. // Blob represents a single blob.
  218. type Blob struct {
  219. Basename string `json:"basename"`
  220. Data string `json:"data"`
  221. Filename string `json:"filename"`
  222. ID int `json:"id"`
  223. Ref string `json:"ref"`
  224. Startline int `json:"startline"`
  225. ProjectID int `json:"project_id"`
  226. }
  227. // Blobs searches the expression within all blobs
  228. //
  229. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs
  230. func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...OptionFunc) ([]*Blob, *Response, error) {
  231. var bs []*Blob
  232. resp, err := s.search("blobs", query, &bs, opt, options...)
  233. return bs, resp, err
  234. }
  235. // BlobsByGroup searches the expression within blobs for the specified
  236. // group
  237. //
  238. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs
  239. func (s *SearchService) BlobsByGroup(gid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Blob, *Response, error) {
  240. var bs []*Blob
  241. resp, err := s.searchByGroup(gid, "blobs", query, &bs, opt, options...)
  242. return bs, resp, err
  243. }
  244. // BlobsByProject searches the expression within blobs for the specified
  245. // project
  246. //
  247. // GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs
  248. func (s *SearchService) BlobsByProject(pid interface{}, query string, opt *SearchOptions, options ...OptionFunc) ([]*Blob, *Response, error) {
  249. var bs []*Blob
  250. resp, err := s.searchByProject(pid, "blobs", query, &bs, opt, options...)
  251. return bs, resp, err
  252. }
  253. func (s *SearchService) search(scope, query string, result interface{}, opt *SearchOptions, options ...OptionFunc) (*Response, error) {
  254. opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query}
  255. req, err := s.client.NewRequest("GET", "search", opts, options)
  256. if err != nil {
  257. return nil, err
  258. }
  259. return s.client.Do(req, result)
  260. }
  261. func (s *SearchService) searchByGroup(gid interface{}, scope, query string, result interface{}, opt *SearchOptions, options ...OptionFunc) (*Response, error) {
  262. group, err := parseID(gid)
  263. if err != nil {
  264. return nil, err
  265. }
  266. u := fmt.Sprintf("groups/%s/-/search", url.QueryEscape(group))
  267. opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query}
  268. req, err := s.client.NewRequest("GET", u, opts, options)
  269. if err != nil {
  270. return nil, err
  271. }
  272. return s.client.Do(req, result)
  273. }
  274. func (s *SearchService) searchByProject(pid interface{}, scope, query string, result interface{}, opt *SearchOptions, options ...OptionFunc) (*Response, error) {
  275. project, err := parseID(pid)
  276. if err != nil {
  277. return nil, err
  278. }
  279. u := fmt.Sprintf("projects/%s/-/search", url.QueryEscape(project))
  280. opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query}
  281. req, err := s.client.NewRequest("GET", u, opts, options)
  282. if err != nil {
  283. return nil, err
  284. }
  285. return s.client.Do(req, result)
  286. }