discussions.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  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) (*Note, *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. n := new(Note)
  151. resp, err := s.client.Do(req, n)
  152. if err != nil {
  153. return nil, resp, err
  154. }
  155. return n, 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) (*Note, *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. n := new(Note)
  186. resp, err := s.client.Do(req, n)
  187. if err != nil {
  188. return nil, resp, err
  189. }
  190. return n, 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) (*Note, *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. n := new(Note)
  326. resp, err := s.client.Do(req, n)
  327. if err != nil {
  328. return nil, resp, err
  329. }
  330. return n, 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) (*Note, *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. n := new(Note)
  361. resp, err := s.client.Do(req, n)
  362. if err != nil {
  363. return nil, resp, err
  364. }
  365. return n, 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) (*Note, *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. n := new(Note)
  506. resp, err := s.client.Do(req, n)
  507. if err != nil {
  508. return nil, resp, err
  509. }
  510. return n, 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) (*Note, *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. n := new(Note)
  541. resp, err := s.client.Do(req, n)
  542. if err != nil {
  543. return nil, resp, err
  544. }
  545. return n, 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) (*Note, *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. n := new(Note)
  723. resp, err := s.client.Do(req, n)
  724. if err != nil {
  725. return nil, resp, err
  726. }
  727. return n, 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. Resolved *bool `url:"resolved,omitempty" json:"resolved,omitempty"`
  738. }
  739. // UpdateMergeRequestDiscussionNote modifies existing discussion of a merge
  740. // request.
  741. //
  742. // GitLab API docs:
  743. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-merge-request-discussion-note
  744. func (s *DiscussionsService) UpdateMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, note int, opt *UpdateMergeRequestDiscussionNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
  745. project, err := parseID(pid)
  746. if err != nil {
  747. return nil, nil, err
  748. }
  749. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d",
  750. url.QueryEscape(project),
  751. mergeRequest,
  752. discussion,
  753. note,
  754. )
  755. req, err := s.client.NewRequest("PUT", u, opt, options)
  756. if err != nil {
  757. return nil, nil, err
  758. }
  759. n := new(Note)
  760. resp, err := s.client.Do(req, n)
  761. if err != nil {
  762. return nil, resp, err
  763. }
  764. return n, resp, err
  765. }
  766. // DeleteMergeRequestDiscussionNote deletes an existing discussion of a merge
  767. // request.
  768. //
  769. // GitLab API docs:
  770. // https://docs.gitlab.com/ce/api/discussions.html#delete-a-merge-request-discussion-note
  771. func (s *DiscussionsService) DeleteMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, note int, options ...OptionFunc) (*Response, error) {
  772. project, err := parseID(pid)
  773. if err != nil {
  774. return nil, err
  775. }
  776. u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d",
  777. url.QueryEscape(project),
  778. mergeRequest,
  779. discussion,
  780. note,
  781. )
  782. req, err := s.client.NewRequest("DELETE", u, nil, options)
  783. if err != nil {
  784. return nil, err
  785. }
  786. return s.client.Do(req, nil)
  787. }
  788. // ListCommitDiscussionsOptions represents the available
  789. // ListCommitDiscussions() options.
  790. //
  791. // GitLab API docs:
  792. // https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussions
  793. type ListCommitDiscussionsOptions ListOptions
  794. // ListCommitDiscussions gets a list of all discussions for a single
  795. // commit.
  796. //
  797. // GitLab API docs:
  798. // https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussions
  799. func (s *DiscussionsService) ListCommitDiscussions(pid interface{}, commit string, opt *ListCommitDiscussionsOptions, options ...OptionFunc) ([]*Discussion, *Response, error) {
  800. project, err := parseID(pid)
  801. if err != nil {
  802. return nil, nil, err
  803. }
  804. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions",
  805. url.QueryEscape(project),
  806. commit,
  807. )
  808. req, err := s.client.NewRequest("GET", u, opt, options)
  809. if err != nil {
  810. return nil, nil, err
  811. }
  812. var ds []*Discussion
  813. resp, err := s.client.Do(req, &ds)
  814. if err != nil {
  815. return nil, resp, err
  816. }
  817. return ds, resp, err
  818. }
  819. // GetCommitDiscussion returns a single discussion for a specific project
  820. // commit.
  821. //
  822. // GitLab API docs:
  823. // https://docs.gitlab.com/ce/api/discussions.html#get-single-commit-discussion
  824. func (s *DiscussionsService) GetCommitDiscussion(pid interface{}, commit string, discussion string, options ...OptionFunc) (*Discussion, *Response, error) {
  825. project, err := parseID(pid)
  826. if err != nil {
  827. return nil, nil, err
  828. }
  829. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s",
  830. url.QueryEscape(project),
  831. commit,
  832. discussion,
  833. )
  834. req, err := s.client.NewRequest("GET", u, nil, options)
  835. if err != nil {
  836. return nil, nil, err
  837. }
  838. d := new(Discussion)
  839. resp, err := s.client.Do(req, d)
  840. if err != nil {
  841. return nil, resp, err
  842. }
  843. return d, resp, err
  844. }
  845. // CreateCommitDiscussionOptions represents the available
  846. // CreateCommitDiscussion() options.
  847. //
  848. // GitLab API docs:
  849. // https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-discussion
  850. type CreateCommitDiscussionOptions struct {
  851. Body *string `url:"body,omitempty" json:"body,omitempty"`
  852. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  853. Position *NotePosition `url:"position,omitempty" json:"position,omitempty"`
  854. }
  855. // CreateCommitDiscussion creates a new discussion to a single project commit.
  856. //
  857. // GitLab API docs:
  858. // https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-discussion
  859. func (s *DiscussionsService) CreateCommitDiscussion(pid interface{}, commit string, opt *CreateCommitDiscussionOptions, options ...OptionFunc) (*Discussion, *Response, error) {
  860. project, err := parseID(pid)
  861. if err != nil {
  862. return nil, nil, err
  863. }
  864. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions",
  865. url.QueryEscape(project),
  866. commit,
  867. )
  868. req, err := s.client.NewRequest("POST", u, opt, options)
  869. if err != nil {
  870. return nil, nil, err
  871. }
  872. d := new(Discussion)
  873. resp, err := s.client.Do(req, d)
  874. if err != nil {
  875. return nil, resp, err
  876. }
  877. return d, resp, err
  878. }
  879. // AddCommitDiscussionNoteOptions represents the available
  880. // AddCommitDiscussionNote() options.
  881. //
  882. // GitLab API docs:
  883. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-discussion
  884. type AddCommitDiscussionNoteOptions struct {
  885. Body *string `url:"body,omitempty" json:"body,omitempty"`
  886. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  887. }
  888. // AddCommitDiscussionNote creates a new discussion to a single project commit.
  889. //
  890. // GitLab API docs:
  891. // https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-discussion
  892. func (s *DiscussionsService) AddCommitDiscussionNote(pid interface{}, commit string, discussion string, opt *AddCommitDiscussionNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
  893. project, err := parseID(pid)
  894. if err != nil {
  895. return nil, nil, err
  896. }
  897. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes",
  898. url.QueryEscape(project),
  899. commit,
  900. discussion,
  901. )
  902. req, err := s.client.NewRequest("POST", u, opt, options)
  903. if err != nil {
  904. return nil, nil, err
  905. }
  906. n := new(Note)
  907. resp, err := s.client.Do(req, n)
  908. if err != nil {
  909. return nil, resp, err
  910. }
  911. return n, resp, err
  912. }
  913. // UpdateCommitDiscussionNoteOptions represents the available
  914. // UpdateCommitDiscussion() options.
  915. //
  916. // GitLab API docs:
  917. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-commit-discussion-note
  918. type UpdateCommitDiscussionNoteOptions struct {
  919. Body *string `url:"body,omitempty" json:"body,omitempty"`
  920. CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"`
  921. }
  922. // UpdateCommitDiscussionNote modifies existing discussion of an commit.
  923. //
  924. // GitLab API docs:
  925. // https://docs.gitlab.com/ce/api/discussions.html#modify-existing-commit-discussion-note
  926. func (s *DiscussionsService) UpdateCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
  927. project, err := parseID(pid)
  928. if err != nil {
  929. return nil, nil, err
  930. }
  931. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d",
  932. url.QueryEscape(project),
  933. commit,
  934. discussion,
  935. note,
  936. )
  937. req, err := s.client.NewRequest("PUT", u, opt, options)
  938. if err != nil {
  939. return nil, nil, err
  940. }
  941. n := new(Note)
  942. resp, err := s.client.Do(req, n)
  943. if err != nil {
  944. return nil, resp, err
  945. }
  946. return n, resp, err
  947. }
  948. // DeleteCommitDiscussionNote deletes an existing discussion of an commit.
  949. //
  950. // GitLab API docs:
  951. // https://docs.gitlab.com/ce/api/discussions.html#delete-an-commit-discussion-note
  952. func (s *DiscussionsService) DeleteCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, options ...OptionFunc) (*Response, error) {
  953. project, err := parseID(pid)
  954. if err != nil {
  955. return nil, err
  956. }
  957. u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d",
  958. url.QueryEscape(project),
  959. commit,
  960. discussion,
  961. note,
  962. )
  963. req, err := s.client.NewRequest("DELETE", u, nil, options)
  964. if err != nil {
  965. return nil, err
  966. }
  967. return s.client.Do(req, nil)
  968. }