Skip to content

Commit f2ab5e6

Browse files
committed
duplicate issue
1 parent a36bba7 commit f2ab5e6

1 file changed

Lines changed: 397 additions & 0 deletions

File tree

github/sub_issue.go

Lines changed: 397 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,397 @@
1+
// Copyright 2013 The go-github AUTHORS. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
6+
package github
7+
8+
import (
9+
"context"
10+
"fmt"
11+
"time"
12+
)
13+
14+
// IssuesService handles communication with the issue related
15+
// methods of the GitHub API.
16+
//
17+
// GitHub API docs: https://docs.github.com/rest/issues/
18+
type SubIssuesService service
19+
20+
// Issue represents a GitHub issue on a repository.
21+
//
22+
// Note: As far as the GitHub API is concerned, every pull request is an issue,
23+
// but not every issue is a pull request. Some endpoints, events, and webhooks
24+
// may also return pull requests via this struct. If PullRequestLinks is nil,
25+
// this is an issue, and if PullRequestLinks is not nil, this is a pull request.
26+
// The IsPullRequest helper method can be used to check that.
27+
type SubIssue struct {
28+
ID *int64 `json:"id,omitempty"`
29+
Number *int `json:"number,omitempty"`
30+
State *string `json:"state,omitempty"`
31+
// StateReason can be one of: "completed", "not_planned", "reopened".
32+
Issue *Issue `json:"issue,omitempty"`
33+
StateReason *string `json:"state_reason,omitempty"`
34+
Locked *bool `json:"locked,omitempty"`
35+
Title *string `json:"title,omitempty"`
36+
Body *string `json:"body,omitempty"`
37+
AuthorAssociation *string `json:"author_association,omitempty"`
38+
User *User `json:"user,omitempty"`
39+
Labels []*Label `json:"labels,omitempty"`
40+
Assignee *User `json:"assignee,omitempty"`
41+
Comments *int `json:"comments,omitempty"`
42+
ClosedAt *Timestamp `json:"closed_at,omitempty"`
43+
CreatedAt *Timestamp `json:"created_at,omitempty"`
44+
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
45+
ClosedBy *User `json:"closed_by,omitempty"`
46+
URL *string `json:"url,omitempty"`
47+
HTMLURL *string `json:"html_url,omitempty"`
48+
CommentsURL *string `json:"comments_url,omitempty"`
49+
EventsURL *string `json:"events_url,omitempty"`
50+
LabelsURL *string `json:"labels_url,omitempty"`
51+
RepositoryURL *string `json:"repository_url,omitempty"`
52+
Milestone *Milestone `json:"milestone,omitempty"`
53+
// PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"`
54+
Repository *Repository `json:"repository,omitempty"`
55+
Reactions *Reactions `json:"reactions,omitempty"`
56+
Assignees []*User `json:"assignees,omitempty"`
57+
NodeID *string `json:"node_id,omitempty"`
58+
Draft *bool `json:"draft,omitempty"`
59+
Type *IssueType `json:"type,omitempty"`
60+
61+
// TextMatches is only populated from search results that request text matches
62+
// See: search.go and https://docs.github.com/rest/search/#text-match-metadata
63+
TextMatches []*TextMatch `json:"text_matches,omitempty"`
64+
65+
// ActiveLockReason is populated only when LockReason is provided while locking the issue.
66+
// Possible values are: "off-topic", "too heated", "resolved", and "spam".
67+
ActiveLockReason *string `json:"active_lock_reason,omitempty"`
68+
}
69+
70+
func (i SubIssue) String() string {
71+
return Stringify(i)
72+
}
73+
74+
// // IsPullRequest reports whether the issue is also a pull request. It uses the
75+
// // method recommended by GitHub's API documentation, which is to check whether
76+
// // PullRequestLinks is non-nil.
77+
// func (i SubIssue) IsPullRequest() bool {
78+
// return i.PullRequestLinks != nil
79+
// }
80+
81+
// IssueRequest represents a request to create/edit an issue.
82+
// It is separate from Issue above because otherwise Labels
83+
// and Assignee fail to serialize to the correct JSON.
84+
type SubIssueRequest struct {
85+
Title *string `json:"title,omitempty"`
86+
Body *string `json:"body,omitempty"`
87+
Labels *[]string `json:"labels,omitempty"`
88+
Assignee *string `json:"assignee,omitempty"`
89+
State *string `json:"state,omitempty"`
90+
// StateReason can be 'completed' or 'not_planned'.
91+
StateReason *string `json:"state_reason,omitempty"`
92+
Milestone *int `json:"milestone,omitempty"`
93+
Assignees *[]string `json:"assignees,omitempty"`
94+
}
95+
96+
// IssueListOptions specifies the optional parameters to the IssuesService.List
97+
// and IssuesService.ListByOrg methods.
98+
type SubIssueListOptions struct {
99+
// Filter specifies which issues to list. Possible values are: assigned,
100+
// created, mentioned, subscribed, all. Default is "assigned".
101+
Filter string `url:"filter,omitempty"`
102+
103+
// State filters issues based on their state. Possible values are: open,
104+
// closed, all. Default is "open".
105+
State string `url:"state,omitempty"`
106+
107+
// Labels filters issues based on their label.
108+
Labels []string `url:"labels,comma,omitempty"`
109+
110+
// Sort specifies how to sort issues. Possible values are: created, updated,
111+
// and comments. Default value is "created".
112+
Sort string `url:"sort,omitempty"`
113+
114+
// Direction in which to sort issues. Possible values are: asc, desc.
115+
// Default is "desc".
116+
Direction string `url:"direction,omitempty"`
117+
118+
// Since filters issues by time.
119+
Since time.Time `url:"since,omitempty"`
120+
121+
ListOptions
122+
}
123+
124+
// PullRequestLinks object is added to the Issue object when it's an issue included
125+
// in the IssueCommentEvent webhook payload, if the webhook is fired by a comment on a PR.
126+
// type PullRequestLinks struct {
127+
// URL *string `json:"url,omitempty"`
128+
// HTMLURL *string `json:"html_url,omitempty"`
129+
// DiffURL *string `json:"diff_url,omitempty"`
130+
// PatchURL *string `json:"patch_url,omitempty"`
131+
// MergedAt *Timestamp `json:"merged_at,omitempty"`
132+
// }
133+
134+
// IssueType represents the type of issue.
135+
// For now it shows up when receiveing an Issue event.
136+
type SubIssueType struct {
137+
ID *int64 `json:"id,omitempty"`
138+
NodeID *string `json:"node_id,omitempty"`
139+
Name *string `json:"name,omitempty"`
140+
Description *string `json:"description,omitempty"`
141+
Color *string `json:"color,omitempty"`
142+
CreatedAt *Timestamp `json:"created_at,omitempty"`
143+
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
144+
}
145+
146+
// List the issues for the authenticated user. If all is true, list issues
147+
// across all the user's visible repositories including owned, member, and
148+
// organization repositories; if false, list only owned and member
149+
// repositories.
150+
//
151+
// GitHub API docs: https://docs.github.com/rest/issues/issues#list-issues-assigned-to-the-authenticated-user
152+
// GitHub API docs: https://docs.github.com/rest/issues/issues#list-user-account-issues-assigned-to-the-authenticated-user
153+
//
154+
//meta:operation GET /issues
155+
//meta:operation GET /user/issues
156+
func (s *SubIssuesService) List(ctx context.Context, all bool, opts *SubIssueListOptions) ([]*SubIssue, *Response, error) {
157+
var u string
158+
if all {
159+
u = "issues"
160+
} else {
161+
u = "user/issues"
162+
}
163+
return s.listSubIssues(ctx, u, opts)
164+
}
165+
166+
// ListByOrg fetches the issues in the specified organization for the
167+
// authenticated user.
168+
//
169+
// GitHub API docs: https://docs.github.com/rest/issues/issues#list-organization-issues-assigned-to-the-authenticated-user
170+
//
171+
//meta:operation GET /orgs/{org}/issues
172+
func (s *IssuesService) ListByOrg(ctx context.Context, org string, opts *IssueListOptions) ([]*Issue, *Response, error) {
173+
u := fmt.Sprintf("orgs/%v/issues", org)
174+
return s.listIssues(ctx, u, opts)
175+
}
176+
177+
func (s *IssuesService) listSubIssues(ctx context.Context, u string, opts *IssueListOptions) ([]*Issue, *Response, error) {
178+
u, err := addOptions(u, opts)
179+
if err != nil {
180+
return nil, nil, err
181+
}
182+
183+
req, err := s.client.NewRequest("GET", u, nil)
184+
if err != nil {
185+
return nil, nil, err
186+
}
187+
188+
// TODO: remove custom Accept header when this API fully launch.
189+
req.Header.Set("Accept", mediaTypeReactionsPreview)
190+
191+
var issues []*Issue
192+
resp, err := s.client.Do(ctx, req, &issues)
193+
if err != nil {
194+
return nil, resp, err
195+
}
196+
197+
return issues, resp, nil
198+
}
199+
200+
// IssueListByRepoOptions specifies the optional parameters to the
201+
// IssuesService.ListByRepo method.
202+
type IssueListByRepoOptions struct {
203+
// Milestone limits issues for the specified milestone. Possible values are
204+
// a milestone number, "none" for issues with no milestone, "*" for issues
205+
// with any milestone.
206+
Milestone string `url:"milestone,omitempty"`
207+
208+
// State filters issues based on their state. Possible values are: open,
209+
// closed, all. Default is "open".
210+
State string `url:"state,omitempty"`
211+
212+
// Assignee filters issues based on their assignee. Possible values are a
213+
// user name, "none" for issues that are not assigned, "*" for issues with
214+
// any assigned user.
215+
Assignee string `url:"assignee,omitempty"`
216+
217+
// Creator filters issues based on their creator.
218+
Creator string `url:"creator,omitempty"`
219+
220+
// Mentioned filters issues to those mentioned a specific user.
221+
Mentioned string `url:"mentioned,omitempty"`
222+
223+
// Labels filters issues based on their label.
224+
Labels []string `url:"labels,omitempty,comma"`
225+
226+
// Sort specifies how to sort issues. Possible values are: created, updated,
227+
// and comments. Default value is "created".
228+
Sort string `url:"sort,omitempty"`
229+
230+
// Direction in which to sort issues. Possible values are: asc, desc.
231+
// Default is "desc".
232+
Direction string `url:"direction,omitempty"`
233+
234+
// Since filters issues by time.
235+
Since time.Time `url:"since,omitempty"`
236+
237+
ListOptions
238+
}
239+
240+
// ListByRepo lists the issues for the specified repository.
241+
//
242+
// GitHub API docs: https://docs.github.com/rest/issues/issues#list-repository-issues
243+
//
244+
//meta:operation GET /repos/{owner}/{repo}/issues
245+
func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opts *IssueListByRepoOptions) ([]*Issue, *Response, error) {
246+
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
247+
u, err := addOptions(u, opts)
248+
if err != nil {
249+
return nil, nil, err
250+
}
251+
252+
req, err := s.client.NewRequest("GET", u, nil)
253+
if err != nil {
254+
return nil, nil, err
255+
}
256+
257+
// TODO: remove custom Accept header when this API fully launches.
258+
req.Header.Set("Accept", mediaTypeReactionsPreview)
259+
260+
var issues []*Issue
261+
resp, err := s.client.Do(ctx, req, &issues)
262+
if err != nil {
263+
return nil, resp, err
264+
}
265+
266+
return issues, resp, nil
267+
}
268+
269+
// Get a single issue.
270+
//
271+
// GitHub API docs: https://docs.github.com/rest/issues/issues#get-an-issue
272+
//
273+
//meta:operation GET /repos/{owner}/{repo}/issues/{issue_number}
274+
func (s *IssuesService) Get(ctx context.Context, owner string, repo string, number int) (*Issue, *Response, error) {
275+
u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
276+
req, err := s.client.NewRequest("GET", u, nil)
277+
if err != nil {
278+
return nil, nil, err
279+
}
280+
281+
// TODO: remove custom Accept header when this API fully launch.
282+
req.Header.Set("Accept", mediaTypeReactionsPreview)
283+
284+
issue := new(Issue)
285+
resp, err := s.client.Do(ctx, req, issue)
286+
if err != nil {
287+
return nil, resp, err
288+
}
289+
290+
return issue, resp, nil
291+
}
292+
293+
// Create a new issue on the specified repository.
294+
//
295+
// GitHub API docs: https://docs.github.com/rest/issues/issues#create-an-issue
296+
//
297+
//meta:operation POST /repos/{owner}/{repo}/issues
298+
func (s *IssuesService) Create(ctx context.Context, owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) {
299+
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
300+
req, err := s.client.NewRequest("POST", u, issue)
301+
if err != nil {
302+
return nil, nil, err
303+
}
304+
305+
i := new(Issue)
306+
resp, err := s.client.Do(ctx, req, i)
307+
if err != nil {
308+
return nil, resp, err
309+
}
310+
311+
return i, resp, nil
312+
}
313+
314+
// Edit (update) an issue.
315+
//
316+
// GitHub API docs: https://docs.github.com/rest/issues/issues#update-an-issue
317+
//
318+
//meta:operation PATCH /repos/{owner}/{repo}/issues/{issue_number}
319+
func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) {
320+
u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
321+
req, err := s.client.NewRequest("PATCH", u, issue)
322+
if err != nil {
323+
return nil, nil, err
324+
}
325+
326+
i := new(Issue)
327+
resp, err := s.client.Do(ctx, req, i)
328+
if err != nil {
329+
return nil, resp, err
330+
}
331+
332+
return i, resp, nil
333+
}
334+
335+
// RemoveMilestone removes a milestone from an issue.
336+
//
337+
// This is a helper method to explicitly update an issue with a `null` milestone, thereby removing it.
338+
//
339+
// GitHub API docs: https://docs.github.com/rest/issues/issues#update-an-issue
340+
//
341+
//meta:operation PATCH /repos/{owner}/{repo}/issues/{issue_number}
342+
func (s *IssuesService) RemoveMilestone(ctx context.Context, owner, repo string, issueNumber int) (*Issue, *Response, error) {
343+
u := fmt.Sprintf("repos/%v/%v/issues/%v", owner, repo, issueNumber)
344+
req, err := s.client.NewRequest("PATCH", u, &struct {
345+
Milestone *Milestone `json:"milestone"`
346+
}{})
347+
if err != nil {
348+
return nil, nil, err
349+
}
350+
351+
i := new(Issue)
352+
resp, err := s.client.Do(ctx, req, i)
353+
if err != nil {
354+
return nil, resp, err
355+
}
356+
357+
return i, resp, nil
358+
}
359+
360+
// LockIssueOptions specifies the optional parameters to the
361+
// IssuesService.Lock method.
362+
type LockIssueOptions struct {
363+
// LockReason specifies the reason to lock this issue.
364+
// Providing a lock reason can help make it clearer to contributors why an issue
365+
// was locked. Possible values are: "off-topic", "too heated", "resolved", and "spam".
366+
LockReason string `json:"lock_reason,omitempty"`
367+
}
368+
369+
// Lock an issue's conversation.
370+
//
371+
// GitHub API docs: https://docs.github.com/rest/issues/issues#lock-an-issue
372+
//
373+
//meta:operation PUT /repos/{owner}/{repo}/issues/{issue_number}/lock
374+
func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int, opts *LockIssueOptions) (*Response, error) {
375+
u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
376+
req, err := s.client.NewRequest("PUT", u, opts)
377+
if err != nil {
378+
return nil, err
379+
}
380+
381+
return s.client.Do(ctx, req, nil)
382+
}
383+
384+
// Unlock an issue's conversation.
385+
//
386+
// GitHub API docs: https://docs.github.com/rest/issues/issues#unlock-an-issue
387+
//
388+
//meta:operation DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock
389+
func (s *IssuesService) Unlock(ctx context.Context, owner string, repo string, number int) (*Response, error) {
390+
u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
391+
req, err := s.client.NewRequest("DELETE", u, nil)
392+
if err != nil {
393+
return nil, err
394+
}
395+
396+
return s.client.Do(ctx, req, nil)
397+
}

0 commit comments

Comments
 (0)