4
0

discussions.go 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112
  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. "time"
  21. )
  22. // DiscussionsService handles communication with the discussions related
  23. // methods of the GitLab API.
  24. //
  25. // GitLab API docs: https://docs.gitlab.com/ce/api/discussions.html
  26. type DiscussionsService struct {
  27. client *Client
  28. }
  29. // Discussion represents a GitLab discussion.
  30. //
  31. // GitLab API docs: https://docs.gitlab.com/ce/api/discussions.html
  32. type Discussion struct {
  33. ID string `json:"id"`
  34. IndividualNote bool `json:"individual_note"`
  35. Notes []*Note `json:"notes"`
  36. }
  37. func (d Discussion) String() string {
  38. return Stringify(d)
  39. }
  40. // ListIssueDiscussionsOptions represents the available ListIssueDiscussions()
  41. // options.
  42. //
  43. // GitLab API docs:
  44. // https://docs.gitlab.com/ce/api/discussions.html#list-project-issue-discussions
  45. type ListIssueDiscussionsOptions ListOptions
  46. // ListIssueDiscussions gets a list of all discussions for a single
  47. // issue.
  48. //
  49. // GitLab API docs:
  50. // https://docs.gitlab.com/ce/api/discussions.html#list-project-issue-discussions
  51. func (s *DiscussionsService) ListIssueDiscussions(pid interface{}, issue int, opt *ListIssueDiscussionsOptions, options ...OptionFunc) ([]*Discussion, *Response, error) {
  52. project, err := parseID(pid)
  53. if err != nil {
  54. return nil, nil, err
  55. }
  56. u := fmt.Sprintf("projects/%s/issues/%d/discussions", url.QueryEscape(project), issue)
  57. req, err := s.client.NewRequest("GET", u, opt, options)
  58. if err != nil {
  59. return nil, nil, err
  60. }
  61. var ds []*Discussion
  62. resp, err := s.client.Do(req, &ds)
  63. if err != nil {
  64. return nil, resp, err
  65. }
  66. return ds, resp, err
  67. }
  68. // GetIssueDiscussion returns a single discussion for a specific project issue.
  69. //
  70. // GitLab API docs:
  71. // https://docs.gitlab.com/ce/api/discussions.html#get-single-issue-discussion
  72. func (s *DiscussionsService) GetIssueDiscussion(pid interface{}, issue int, discussion string, options ...OptionFunc) (*Discussion, *Response, error) {
  73. project, err := parseID(pid)
  74. if err != nil {
  75. return nil, nil, err
  76. }
  77. u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s",
  78. url.QueryEscape(project),
  79. issue,
  80. discussion,
  81. )
  82. req, err := s.client.NewRequest("GET", u, nil, options)
  83. if err != nil {
  84. return nil, nil, err
  85. }
  86. d := new(Discussion)
  87. resp, err := s.client.Do(req, d)
  88. if err != nil {
  89. return nil, resp, err
  90. }
  91. return d, resp, err
  92. }
  93. // CreateIssueDiscussionOptions represents the available CreateIssueDiscussion()
  94. // options.
  95. //
  96. // GitLab API docs:
  97. // https://docs.gitlab.com/ce/api/discussions.html#create-new-issue-discussion
  98. type CreateIssueDiscussionOptions struct {
  99. Body *string `url:"body,omitempty" json:"body,omitempty"`
  100. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  101. }
  102. // CreateIssueDiscussion creates a new discussion to a single project issue.
  103. //
  104. // GitLab API docs:
  105. // https://docs.gitlab.com/ce/api/discussions.html#create-new-issue-discussion
  106. func (s *DiscussionsService) CreateIssueDiscussion(pid interface{}, issue int, opt *CreateIssueDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  107. project, err := parseID(pid)
  108. if err != nil {
  109. return nil, nil, err
  110. }
  111. u := fmt.Sprintf("projects/%s/issues/%d/discussions", url.QueryEscape(project), issue)
  112. req, err := s.client.NewRequest("POST", u, opt, options)
  113. if err != nil {
  114. return nil, nil, err
  115. }
  116. d := new(Discussion)
  117. resp, err := s.client.Do(req, d)
  118. if err != nil {
  119. return nil, resp, err
  120. }
  121. return d, resp, err
  122. }
  123. // AddIssueDiscussionNoteOptions represents the available AddIssueDiscussionNote()
  124. // options.
  125. //
  126. // GitLab API docs:
  127. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-issue-discussion
  128. type AddIssueDiscussionNoteOptions struct {
  129. Body *string `url:"body,omitempty" json:"body,omitempty"`
  130. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  131. }
  132. // AddIssueDiscussionNote creates a new discussion to a single project issue.
  133. //
  134. // GitLab API docs:
  135. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-issue-discussion
  136. func (s *DiscussionsService) AddIssueDiscussionNote(pid interface{}, issue int, discussion string, opt *AddIssueDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  137. project, err := parseID(pid)
  138. if err != nil {
  139. return nil, nil, err
  140. }
  141. u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes",
  142. url.QueryEscape(project),
  143. issue,
  144. discussion,
  145. )
  146. req, err := s.client.NewRequest("POST", u, opt, options)
  147. if err != nil {
  148. return nil, nil, err
  149. }
  150. d := new(Discussion)
  151. resp, err := s.client.Do(req, d)
  152. if err != nil {
  153. return nil, resp, err
  154. }
  155. return d, resp, err
  156. }
  157. // UpdateIssueDiscussionNoteOptions represents the available
  158. // UpdateIssueDiscussion() options.
  159. //
  160. // GitLab API docs:
  161. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-issue-discussion-note
  162. type UpdateIssueDiscussionNoteOptions struct {
  163. Body *string `url:"body,omitempty" json:"body,omitempty"`
  164. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  165. }
  166. // UpdateIssueDiscussionNote modifies existing discussion of an issue.
  167. //
  168. // GitLab API docs:
  169. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-issue-discussion-note
  170. func (s *DiscussionsService) UpdateIssueDiscussionNote(pid interface{}, issue int, discussion string, note int, opt *UpdateIssueDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  171. project, err := parseID(pid)
  172. if err != nil {
  173. return nil, nil, err
  174. }
  175. u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes/%d",
  176. url.QueryEscape(project),
  177. issue,
  178. discussion,
  179. note,
  180. )
  181. req, err := s.client.NewRequest("PUT", u, opt, options)
  182. if err != nil {
  183. return nil, nil, err
  184. }
  185. d := new(Discussion)
  186. resp, err := s.client.Do(req, d)
  187. if err != nil {
  188. return nil, resp, err
  189. }
  190. return d, resp, err
  191. }
  192. // DeleteIssueDiscussionNote deletes an existing discussion of an issue.
  193. //
  194. // GitLab API docs:
  195. // https://docs.gitlab.com/ce/api/discussions.html#delete-an-issue-discussion-note
  196. func (s *DiscussionsService) DeleteIssueDiscussionNote(pid interface{}, issue int, discussion string, note int, options ...OptionFunc) (*Response, error) {
  197. project, err := parseID(pid)
  198. if err != nil {
  199. return nil, err
  200. }
  201. u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes/%d",
  202. url.QueryEscape(project),
  203. issue,
  204. discussion,
  205. note,
  206. )
  207. req, err := s.client.NewRequest("DELETE", u, nil, options)
  208. if err != nil {
  209. return nil, err
  210. }
  211. return s.client.Do(req, nil)
  212. }
  213. // ListSnippetDiscussionsOptions represents the available ListSnippetDiscussions()
  214. // options.
  215. //
  216. // GitLab API docs:
  217. // https://docs.gitlab.com/ce/api/discussions.html#list-all-snippet-discussions
  218. type ListSnippetDiscussionsOptions ListOptions
  219. // ListSnippetDiscussions gets a list of all discussions for a single
  220. // snippet. Snippet discussions are comments users can post to a snippet.
  221. //
  222. // GitLab API docs:
  223. // https://docs.gitlab.com/ce/api/discussions.html#list-all-snippet-discussions
  224. func (s *DiscussionsService) ListSnippetDiscussions(pid interface{}, snippet int, opt *ListSnippetDiscussionsOptions, options ...OptionFunc) ([]*Discussion, *Response, error) {
  225. project, err := parseID(pid)
  226. if err != nil {
  227. return nil, nil, err
  228. }
  229. u := fmt.Sprintf("projects/%s/snippets/%d/discussions", url.QueryEscape(project), snippet)
  230. req, err := s.client.NewRequest("GET", u, opt, options)
  231. if err != nil {
  232. return nil, nil, err
  233. }
  234. var ds []*Discussion
  235. resp, err := s.client.Do(req, &ds)
  236. if err != nil {
  237. return nil, resp, err
  238. }
  239. return ds, resp, err
  240. }
  241. // GetSnippetDiscussion returns a single discussion for a given snippet.
  242. //
  243. // GitLab API docs:
  244. // https://docs.gitlab.com/ce/api/discussions.html#get-single-snippet-discussion
  245. func (s *DiscussionsService) GetSnippetDiscussion(pid interface{}, snippet int, discussion string, options ...OptionFunc) (*Discussion, *Response, error) {
  246. project, err := parseID(pid)
  247. if err != nil {
  248. return nil, nil, err
  249. }
  250. u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s",
  251. url.QueryEscape(project),
  252. snippet,
  253. discussion,
  254. )
  255. req, err := s.client.NewRequest("GET", u, nil, options)
  256. if err != nil {
  257. return nil, nil, err
  258. }
  259. d := new(Discussion)
  260. resp, err := s.client.Do(req, d)
  261. if err != nil {
  262. return nil, resp, err
  263. }
  264. return d, resp, err
  265. }
  266. // CreateSnippetDiscussionOptions represents the available
  267. // CreateSnippetDiscussion() options.
  268. //
  269. // GitLab API docs:
  270. // https://docs.gitlab.com/ce/api/discussions.html#create-new-snippet-discussion
  271. type CreateSnippetDiscussionOptions struct {
  272. Body *string `url:"body,omitempty" json:"body,omitempty"`
  273. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  274. }
  275. // CreateSnippetDiscussion creates a new discussion for a single snippet.
  276. // Snippet discussions are comments users can post to a snippet.
  277. //
  278. // GitLab API docs:
  279. // https://docs.gitlab.com/ce/api/discussions.html#create-new-snippet-discussion
  280. func (s *DiscussionsService) CreateSnippetDiscussion(pid interface{}, snippet int, opt *CreateSnippetDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  281. project, err := parseID(pid)
  282. if err != nil {
  283. return nil, nil, err
  284. }
  285. u := fmt.Sprintf("projects/%s/snippets/%d/discussions", url.QueryEscape(project), snippet)
  286. req, err := s.client.NewRequest("POST", u, opt, options)
  287. if err != nil {
  288. return nil, nil, err
  289. }
  290. d := new(Discussion)
  291. resp, err := s.client.Do(req, d)
  292. if err != nil {
  293. return nil, resp, err
  294. }
  295. return d, resp, err
  296. }
  297. // AddSnippetDiscussionNoteOptions represents the available
  298. // AddSnippetDiscussionNote() options.
  299. //
  300. // GitLab API docs:
  301. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-snippet-discussion
  302. type AddSnippetDiscussionNoteOptions struct {
  303. Body *string `url:"body,omitempty" json:"body,omitempty"`
  304. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  305. }
  306. // AddSnippetDiscussionNote creates a new discussion to a single project
  307. // snippet.
  308. //
  309. // GitLab API docs:
  310. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-snippet-discussion
  311. func (s *DiscussionsService) AddSnippetDiscussionNote(pid interface{}, snippet int, discussion string, opt *AddSnippetDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  312. project, err := parseID(pid)
  313. if err != nil {
  314. return nil, nil, err
  315. }
  316. u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes",
  317. url.QueryEscape(project),
  318. snippet,
  319. discussion,
  320. )
  321. req, err := s.client.NewRequest("POST", u, opt, options)
  322. if err != nil {
  323. return nil, nil, err
  324. }
  325. d := new(Discussion)
  326. resp, err := s.client.Do(req, d)
  327. if err != nil {
  328. return nil, resp, err
  329. }
  330. return d, resp, err
  331. }
  332. // UpdateSnippetDiscussionNoteOptions represents the available
  333. // UpdateSnippetDiscussion() options.
  334. //
  335. // GitLab API docs:
  336. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-snippet-discussion-note
  337. type UpdateSnippetDiscussionNoteOptions struct {
  338. Body *string `url:"body,omitempty" json:"body,omitempty"`
  339. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  340. }
  341. // UpdateSnippetDiscussionNote modifies existing discussion of a snippet.
  342. //
  343. // GitLab API docs:
  344. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-snippet-discussion-note
  345. func (s *DiscussionsService) UpdateSnippetDiscussionNote(pid interface{}, snippet int, discussion string, note int, opt *UpdateSnippetDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  346. project, err := parseID(pid)
  347. if err != nil {
  348. return nil, nil, err
  349. }
  350. u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes/%d",
  351. url.QueryEscape(project),
  352. snippet,
  353. discussion,
  354. note,
  355. )
  356. req, err := s.client.NewRequest("PUT", u, opt, options)
  357. if err != nil {
  358. return nil, nil, err
  359. }
  360. d := new(Discussion)
  361. resp, err := s.client.Do(req, d)
  362. if err != nil {
  363. return nil, resp, err
  364. }
  365. return d, resp, err
  366. }
  367. // DeleteSnippetDiscussionNote deletes an existing discussion of a snippet.
  368. //
  369. // GitLab API docs:
  370. // https://docs.gitlab.com/ce/api/discussions.html#delete-a-snippet-discussion-note
  371. func (s *DiscussionsService) DeleteSnippetDiscussionNote(pid interface{}, snippet int, discussion string, note int, options ...OptionFunc) (*Response, error) {
  372. project, err := parseID(pid)
  373. if err != nil {
  374. return nil, err
  375. }
  376. u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes/%d",
  377. url.QueryEscape(project),
  378. snippet,
  379. discussion,
  380. note,
  381. )
  382. req, err := s.client.NewRequest("DELETE", u, nil, options)
  383. if err != nil {
  384. return nil, err
  385. }
  386. return s.client.Do(req, nil)
  387. }
  388. // ListGroupEpicDiscussionsOptions represents the available
  389. // ListEpicDiscussions() options.
  390. //
  391. // GitLab API docs:
  392. // https://docs.gitlab.com/ee/api/discussions.html#list-all-epic-discussions
  393. type ListGroupEpicDiscussionsOptions ListOptions
  394. // ListGroupEpicDiscussions gets a list of all discussions for a single
  395. // epic. Epic discussions are comments users can post to a epic.
  396. //
  397. // GitLab API docs:
  398. // https://docs.gitlab.com/ee/api/discussions.html#list-all-epic-discussions
  399. func (s *DiscussionsService) ListGroupEpicDiscussions(gid interface{}, epic int, opt *ListGroupEpicDiscussionsOptions, options ...OptionFunc) ([]*Discussion, *Response, error) {
  400. group, err := parseID(gid)
  401. if err != nil {
  402. return nil, nil, err
  403. }
  404. u := fmt.Sprintf("groups/%s/epics/%d/discussions",
  405. url.QueryEscape(group),
  406. epic,
  407. )
  408. req, err := s.client.NewRequest("GET", u, opt, options)
  409. if err != nil {
  410. return nil, nil, err
  411. }
  412. var ds []*Discussion
  413. resp, err := s.client.Do(req, &ds)
  414. if err != nil {
  415. return nil, resp, err
  416. }
  417. return ds, resp, err
  418. }
  419. // GetEpicDiscussion returns a single discussion for a given epic.
  420. //
  421. // GitLab API docs:
  422. // https://docs.gitlab.com/ee/api/discussions.html#get-single-epic-discussion
  423. func (s *DiscussionsService) GetEpicDiscussion(gid interface{}, epic int, discussion string, options ...OptionFunc) (*Discussion, *Response, error) {
  424. group, err := parseID(gid)
  425. if err != nil {
  426. return nil, nil, err
  427. }
  428. u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s",
  429. url.QueryEscape(group),
  430. epic,
  431. discussion,
  432. )
  433. req, err := s.client.NewRequest("GET", u, nil, options)
  434. if err != nil {
  435. return nil, nil, err
  436. }
  437. d := new(Discussion)
  438. resp, err := s.client.Do(req, d)
  439. if err != nil {
  440. return nil, resp, err
  441. }
  442. return d, resp, err
  443. }
  444. // CreateEpicDiscussionOptions represents the available CreateEpicDiscussion()
  445. // options.
  446. //
  447. // GitLab API docs:
  448. // https://docs.gitlab.com/ee/api/discussions.html#create-new-epic-discussion
  449. type CreateEpicDiscussionOptions struct {
  450. Body *string `url:"body,omitempty" json:"body,omitempty"`
  451. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  452. }
  453. // CreateEpicDiscussion creates a new discussion for a single epic. Epic
  454. // discussions are comments users can post to a epic.
  455. //
  456. // GitLab API docs:
  457. // https://docs.gitlab.com/ee/api/discussions.html#create-new-epic-discussion
  458. func (s *DiscussionsService) CreateEpicDiscussion(gid interface{}, epic int, opt *CreateEpicDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  459. group, err := parseID(gid)
  460. if err != nil {
  461. return nil, nil, err
  462. }
  463. u := fmt.Sprintf("groups/%s/epics/%d/discussions",
  464. url.QueryEscape(group),
  465. epic,
  466. )
  467. req, err := s.client.NewRequest("POST", u, opt, options)
  468. if err != nil {
  469. return nil, nil, err
  470. }
  471. d := new(Discussion)
  472. resp, err := s.client.Do(req, d)
  473. if err != nil {
  474. return nil, resp, err
  475. }
  476. return d, resp, err
  477. }
  478. // AddEpicDiscussionNoteOptions represents the available
  479. // AddEpicDiscussionNote() options.
  480. //
  481. // GitLab API docs:
  482. // https://docs.gitlab.com/ee/api/discussions.html#add-note-to-existing-epic-discussion
  483. type AddEpicDiscussionNoteOptions struct {
  484. Body *string `url:"body,omitempty" json:"body,omitempty"`
  485. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  486. }
  487. // AddEpicDiscussionNote creates a new discussion to a single project epic.
  488. //
  489. // GitLab API docs:
  490. // https://docs.gitlab.com/ee/api/discussions.html#add-note-to-existing-epic-discussion
  491. func (s *DiscussionsService) AddEpicDiscussionNote(gid interface{}, epic int, discussion string, opt *AddEpicDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  492. group, err := parseID(gid)
  493. if err != nil {
  494. return nil, nil, err
  495. }
  496. u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes",
  497. url.QueryEscape(group),
  498. epic,
  499. discussion,
  500. )
  501. req, err := s.client.NewRequest("POST", u, opt, options)
  502. if err != nil {
  503. return nil, nil, err
  504. }
  505. d := new(Discussion)
  506. resp, err := s.client.Do(req, d)
  507. if err != nil {
  508. return nil, resp, err
  509. }
  510. return d, resp, err
  511. }
  512. // UpdateEpicDiscussionNoteOptions represents the available UpdateEpicDiscussion()
  513. // options.
  514. //
  515. // GitLab API docs:
  516. // https://docs.gitlab.com/ee/api/discussions.html#modify-existing-epic-discussion-note
  517. type UpdateEpicDiscussionNoteOptions struct {
  518. Body *string `url:"body,omitempty" json:"body,omitempty"`
  519. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  520. }
  521. // UpdateEpicDiscussionNote modifies existing discussion of a epic.
  522. //
  523. // GitLab API docs:
  524. // https://docs.gitlab.com/ee/api/discussions.html#modify-existing-epic-discussion-note
  525. func (s *DiscussionsService) UpdateEpicDiscussionNote(gid interface{}, epic int, discussion string, note int, opt *UpdateEpicDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  526. group, err := parseID(gid)
  527. if err != nil {
  528. return nil, nil, err
  529. }
  530. u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes/%d",
  531. url.QueryEscape(group),
  532. epic,
  533. discussion,
  534. note,
  535. )
  536. req, err := s.client.NewRequest("PUT", u, opt, options)
  537. if err != nil {
  538. return nil, nil, err
  539. }
  540. d := new(Discussion)
  541. resp, err := s.client.Do(req, d)
  542. if err != nil {
  543. return nil, resp, err
  544. }
  545. return d, resp, err
  546. }
  547. // DeleteEpicDiscussionNote deletes an existing discussion of a epic.
  548. //
  549. // GitLab API docs:
  550. // https://docs.gitlab.com/ee/api/discussions.html#delete-an-epic-discussion-note
  551. func (s *DiscussionsService) DeleteEpicDiscussionNote(gid interface{}, epic int, discussion string, note int, options ...OptionFunc) (*Response, error) {
  552. group, err := parseID(gid)
  553. if err != nil {
  554. return nil, err
  555. }
  556. u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes/%d",
  557. url.QueryEscape(group),
  558. epic,
  559. discussion,
  560. note,
  561. )
  562. req, err := s.client.NewRequest("DELETE", u, nil, options)
  563. if err != nil {
  564. return nil, err
  565. }
  566. return s.client.Do(req, nil)
  567. }
  568. // ListMergeRequestDiscussionsOptions represents the available
  569. // ListMergeRequestDiscussions() options.
  570. //
  571. // GitLab API docs:
  572. // https://docs.gitlab.com/ce/api/discussions.html#list-all-merge-request-discussions
  573. type ListMergeRequestDiscussionsOptions ListOptions
  574. // ListMergeRequestDiscussions gets a list of all discussions for a single
  575. // merge request.
  576. //
  577. // GitLab API docs:
  578. // https://docs.gitlab.com/ce/api/discussions.html#list-all-merge-request-discussions
  579. func (s *DiscussionsService) ListMergeRequestDiscussions(pid interface{}, mergeRequest int, opt *ListMergeRequestDiscussionsOptions, options ...OptionFunc) ([]*Discussion, *Response, error) {
  580. project, err := parseID(pid)
  581. if err != nil {
  582. return nil, nil, err
  583. }
  584. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions",
  585. url.QueryEscape(project),
  586. mergeRequest,
  587. )
  588. req, err := s.client.NewRequest("GET", u, opt, options)
  589. if err != nil {
  590. return nil, nil, err
  591. }
  592. var ds []*Discussion
  593. resp, err := s.client.Do(req, &ds)
  594. if err != nil {
  595. return nil, resp, err
  596. }
  597. return ds, resp, err
  598. }
  599. // GetMergeRequestDiscussion returns a single discussion for a given merge
  600. // request.
  601. //
  602. // GitLab API docs:
  603. // https://docs.gitlab.com/ce/api/discussions.html#get-single-merge-request-discussion
  604. func (s *DiscussionsService) GetMergeRequestDiscussion(pid interface{}, mergeRequest int, discussion string, options ...OptionFunc) (*Discussion, *Response, error) {
  605. project, err := parseID(pid)
  606. if err != nil {
  607. return nil, nil, err
  608. }
  609. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s",
  610. url.QueryEscape(project),
  611. mergeRequest,
  612. discussion,
  613. )
  614. req, err := s.client.NewRequest("GET", u, nil, options)
  615. if err != nil {
  616. return nil, nil, err
  617. }
  618. d := new(Discussion)
  619. resp, err := s.client.Do(req, d)
  620. if err != nil {
  621. return nil, resp, err
  622. }
  623. return d, resp, err
  624. }
  625. // CreateMergeRequestDiscussionOptions represents the available
  626. // CreateMergeRequestDiscussion() options.
  627. //
  628. // GitLab API docs:
  629. // https://docs.gitlab.com/ce/api/discussions.html#create-new-merge-request-discussion
  630. type CreateMergeRequestDiscussionOptions struct {
  631. Body *string `url:"body,omitempty" json:"body,omitempty"`
  632. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  633. Position *NotePosition `url:"position,omitempty" json:"position,omitempty"`
  634. }
  635. // CreateMergeRequestDiscussion creates a new discussion for a single merge
  636. // request.
  637. //
  638. // GitLab API docs:
  639. // https://docs.gitlab.com/ce/api/discussions.html#create-new-merge-request-discussion
  640. func (s *DiscussionsService) CreateMergeRequestDiscussion(pid interface{}, mergeRequest int, opt *CreateMergeRequestDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  641. project, err := parseID(pid)
  642. if err != nil {
  643. return nil, nil, err
  644. }
  645. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions",
  646. url.QueryEscape(project),
  647. mergeRequest,
  648. )
  649. req, err := s.client.NewRequest("POST", u, opt, options)
  650. if err != nil {
  651. return nil, nil, err
  652. }
  653. d := new(Discussion)
  654. resp, err := s.client.Do(req, d)
  655. if err != nil {
  656. return nil, resp, err
  657. }
  658. return d, resp, err
  659. }
  660. // ResolveMergeRequestDiscussionOptions represents the available
  661. // ResolveMergeRequestDiscussion() options.
  662. //
  663. // GitLab API docs:
  664. // https://docs.gitlab.com/ee/api/discussions.html#resolve-a-merge-request-discussion
  665. type ResolveMergeRequestDiscussionOptions struct {
  666. Resolved *bool `url:"resolved,omitempty" json:"resolved,omitempty"`
  667. }
  668. // ResolveMergeRequestDiscussion resolves/unresolves whole discussion of a merge
  669. // request.
  670. //
  671. // GitLab API docs:
  672. // https://docs.gitlab.com/ee/api/discussions.html#resolve-a-merge-request-discussion
  673. func (s *DiscussionsService) ResolveMergeRequestDiscussion(pid interface{}, mergeRequest int, discussion string, opt *ResolveMergeRequestDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  674. project, err := parseID(pid)
  675. if err != nil {
  676. return nil, nil, err
  677. }
  678. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s",
  679. url.QueryEscape(project),
  680. mergeRequest,
  681. discussion,
  682. )
  683. req, err := s.client.NewRequest("PUT", u, opt, options)
  684. if err != nil {
  685. return nil, nil, err
  686. }
  687. d := new(Discussion)
  688. resp, err := s.client.Do(req, d)
  689. if err != nil {
  690. return nil, resp, err
  691. }
  692. return d, resp, err
  693. }
  694. // AddMergeRequestDiscussionNoteOptions represents the available
  695. // AddMergeRequestDiscussionNote() options.
  696. //
  697. // GitLab API docs:
  698. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-merge-request-discussion
  699. type AddMergeRequestDiscussionNoteOptions struct {
  700. Body *string `url:"body,omitempty" json:"body,omitempty"`
  701. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  702. }
  703. // AddMergeRequestDiscussionNote creates a new discussion to a single project
  704. // merge request.
  705. //
  706. // GitLab API docs:
  707. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-merge-request-discussion
  708. func (s *DiscussionsService) AddMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, opt *AddMergeRequestDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  709. project, err := parseID(pid)
  710. if err != nil {
  711. return nil, nil, err
  712. }
  713. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes",
  714. url.QueryEscape(project),
  715. mergeRequest,
  716. discussion,
  717. )
  718. req, err := s.client.NewRequest("POST", u, opt, options)
  719. if err != nil {
  720. return nil, nil, err
  721. }
  722. d := new(Discussion)
  723. resp, err := s.client.Do(req, d)
  724. if err != nil {
  725. return nil, resp, err
  726. }
  727. return d, resp, err
  728. }
  729. // UpdateMergeRequestDiscussionNoteOptions represents the available
  730. // UpdateMergeRequestDiscussion() options.
  731. //
  732. // GitLab API docs:
  733. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-merge-request-discussion-note
  734. type UpdateMergeRequestDiscussionNoteOptions struct {
  735. Body *string `url:"body,omitempty" json:"body,omitempty"`
  736. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  737. }
  738. // UpdateMergeRequestDiscussionNote modifies existing discussion of a merge
  739. // request.
  740. //
  741. // GitLab API docs:
  742. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-merge-request-discussion-note
  743. func (s *DiscussionsService) UpdateMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, note int, opt *UpdateMergeRequestDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  744. project, err := parseID(pid)
  745. if err != nil {
  746. return nil, nil, err
  747. }
  748. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d",
  749. url.QueryEscape(project),
  750. mergeRequest,
  751. discussion,
  752. note,
  753. )
  754. req, err := s.client.NewRequest("PUT", u, opt, options)
  755. if err != nil {
  756. return nil, nil, err
  757. }
  758. d := new(Discussion)
  759. resp, err := s.client.Do(req, d)
  760. if err != nil {
  761. return nil, resp, err
  762. }
  763. return d, resp, err
  764. }
  765. // DeleteMergeRequestDiscussionNote deletes an existing discussion of a merge
  766. // request.
  767. //
  768. // GitLab API docs:
  769. // https://docs.gitlab.com/ce/api/discussions.html#delete-a-merge-request-discussion-note
  770. func (s *DiscussionsService) DeleteMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, note int, options ...OptionFunc) (*Response, error) {
  771. project, err := parseID(pid)
  772. if err != nil {
  773. return nil, err
  774. }
  775. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d",
  776. url.QueryEscape(project),
  777. mergeRequest,
  778. discussion,
  779. note,
  780. )
  781. req, err := s.client.NewRequest("DELETE", u, nil, options)
  782. if err != nil {
  783. return nil, err
  784. }
  785. return s.client.Do(req, nil)
  786. }
  787. // ListCommitDiscussionsOptions represents the available
  788. // ListCommitDiscussions() options.
  789. //
  790. // GitLab API docs:
  791. // https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussions
  792. type ListCommitDiscussionsOptions ListOptions
  793. // ListCommitDiscussions gets a list of all discussions for a single
  794. // commit.
  795. //
  796. // GitLab API docs:
  797. // https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussions
  798. func (s *DiscussionsService) ListCommitDiscussions(pid interface{}, commit string, opt *ListCommitDiscussionsOptions, options ...OptionFunc) ([]*Discussion, *Response, error) {
  799. project, err := parseID(pid)
  800. if err != nil {
  801. return nil, nil, err
  802. }
  803. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions",
  804. url.QueryEscape(project),
  805. commit,
  806. )
  807. req, err := s.client.NewRequest("GET", u, opt, options)
  808. if err != nil {
  809. return nil, nil, err
  810. }
  811. var ds []*Discussion
  812. resp, err := s.client.Do(req, &ds)
  813. if err != nil {
  814. return nil, resp, err
  815. }
  816. return ds, resp, err
  817. }
  818. // GetCommitDiscussion returns a single discussion for a specific project
  819. // commit.
  820. //
  821. // GitLab API docs:
  822. // https://docs.gitlab.com/ce/api/discussions.html#get-single-commit-discussion
  823. func (s *DiscussionsService) GetCommitDiscussion(pid interface{}, commit string, discussion string, options ...OptionFunc) (*Discussion, *Response, error) {
  824. project, err := parseID(pid)
  825. if err != nil {
  826. return nil, nil, err
  827. }
  828. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s",
  829. url.QueryEscape(project),
  830. commit,
  831. discussion,
  832. )
  833. req, err := s.client.NewRequest("GET", u, nil, options)
  834. if err != nil {
  835. return nil, nil, err
  836. }
  837. d := new(Discussion)
  838. resp, err := s.client.Do(req, d)
  839. if err != nil {
  840. return nil, resp, err
  841. }
  842. return d, resp, err
  843. }
  844. // CreateCommitDiscussionOptions represents the available
  845. // CreateCommitDiscussion() options.
  846. //
  847. // GitLab API docs:
  848. // https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-discussion
  849. type CreateCommitDiscussionOptions struct {
  850. Body *string `url:"body,omitempty" json:"body,omitempty"`
  851. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  852. Position *NotePosition `url:"position,omitempty" json:"position,omitempty"`
  853. }
  854. // CreateCommitDiscussion creates a new discussion to a single project commit.
  855. //
  856. // GitLab API docs:
  857. // https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-discussion
  858. func (s *DiscussionsService) CreateCommitDiscussion(pid interface{}, commit string, opt *CreateCommitDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  859. project, err := parseID(pid)
  860. if err != nil {
  861. return nil, nil, err
  862. }
  863. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions",
  864. url.QueryEscape(project),
  865. commit,
  866. )
  867. req, err := s.client.NewRequest("POST", u, opt, options)
  868. if err != nil {
  869. return nil, nil, err
  870. }
  871. d := new(Discussion)
  872. resp, err := s.client.Do(req, d)
  873. if err != nil {
  874. return nil, resp, err
  875. }
  876. return d, resp, err
  877. }
  878. // AddCommitDiscussionNoteOptions represents the available
  879. // AddCommitDiscussionNote() options.
  880. //
  881. // GitLab API docs:
  882. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-discussion
  883. type AddCommitDiscussionNoteOptions struct {
  884. Body *string `url:"body,omitempty" json:"body,omitempty"`
  885. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  886. }
  887. // AddCommitDiscussionNote creates a new discussion to a single project commit.
  888. //
  889. // GitLab API docs:
  890. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-discussion
  891. func (s *DiscussionsService) AddCommitDiscussionNote(pid interface{}, commit string, discussion string, opt *AddCommitDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  892. project, err := parseID(pid)
  893. if err != nil {
  894. return nil, nil, err
  895. }
  896. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes",
  897. url.QueryEscape(project),
  898. commit,
  899. discussion,
  900. )
  901. req, err := s.client.NewRequest("POST", u, opt, options)
  902. if err != nil {
  903. return nil, nil, err
  904. }
  905. d := new(Discussion)
  906. resp, err := s.client.Do(req, d)
  907. if err != nil {
  908. return nil, resp, err
  909. }
  910. return d, resp, err
  911. }
  912. // UpdateCommitDiscussionNoteOptions represents the available
  913. // UpdateCommitDiscussion() options.
  914. //
  915. // GitLab API docs:
  916. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-commit-discussion-note
  917. type UpdateCommitDiscussionNoteOptions struct {
  918. Body *string `url:"body,omitempty" json:"body,omitempty"`
  919. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  920. }
  921. // UpdateCommitDiscussionNote modifies existing discussion of an commit.
  922. //
  923. // GitLab API docs:
  924. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-commit-discussion-note
  925. func (s *DiscussionsService) UpdateCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  926. project, err := parseID(pid)
  927. if err != nil {
  928. return nil, nil, err
  929. }
  930. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d",
  931. url.QueryEscape(project),
  932. commit,
  933. discussion,
  934. note,
  935. )
  936. req, err := s.client.NewRequest("PUT", u, opt, options)
  937. if err != nil {
  938. return nil, nil, err
  939. }
  940. d := new(Discussion)
  941. resp, err := s.client.Do(req, d)
  942. if err != nil {
  943. return nil, resp, err
  944. }
  945. return d, resp, err
  946. }
  947. // DeleteCommitDiscussionNote deletes an existing discussion of an commit.
  948. //
  949. // GitLab API docs:
  950. // https://docs.gitlab.com/ce/api/discussions.html#delete-an-commit-discussion-note
  951. func (s *DiscussionsService) DeleteCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, options ...OptionFunc) (*Response, error) {
  952. project, err := parseID(pid)
  953. if err != nil {
  954. return nil, err
  955. }
  956. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d",
  957. url.QueryEscape(project),
  958. commit,
  959. discussion,
  960. note,
  961. )
  962. req, err := s.client.NewRequest("DELETE", u, nil, options)
  963. if err != nil {
  964. return nil, err
  965. }
  966. return s.client.Do(req, nil)
  967. }