diff options
Diffstat (limited to 'vendor/code.gitea.io/sdk/gitea/issue.go')
-rw-r--r-- | vendor/code.gitea.io/sdk/gitea/issue.go | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/vendor/code.gitea.io/sdk/gitea/issue.go b/vendor/code.gitea.io/sdk/gitea/issue.go new file mode 100644 index 0000000000..1b09b3f796 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/issue.go @@ -0,0 +1,233 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitea + +import ( + "bytes" + "encoding/json" + "fmt" + "net/url" + "strings" + "time" +) + +// PullRequestMeta PR info if an issue is a PR +type PullRequestMeta struct { + HasMerged bool `json:"merged"` + Merged *time.Time `json:"merged_at"` +} + +// RepositoryMeta basic repository information +type RepositoryMeta struct { + ID int64 `json:"id"` + Name string `json:"name"` + Owner string `json:"owner"` + FullName string `json:"full_name"` +} + +// Issue represents an issue in a repository +type Issue struct { + ID int64 `json:"id"` + URL string `json:"url"` + Index int64 `json:"number"` + Poster *User `json:"user"` + OriginalAuthor string `json:"original_author"` + OriginalAuthorID int64 `json:"original_author_id"` + Title string `json:"title"` + Body string `json:"body"` + Labels []*Label `json:"labels"` + Milestone *Milestone `json:"milestone"` + Assignee *User `json:"assignee"` + Assignees []*User `json:"assignees"` + // Whether the issue is open or closed + State StateType `json:"state"` + IsLocked bool `json:"is_locked"` + Comments int `json:"comments"` + Created time.Time `json:"created_at"` + Updated time.Time `json:"updated_at"` + Closed *time.Time `json:"closed_at"` + Deadline *time.Time `json:"due_date"` + PullRequest *PullRequestMeta `json:"pull_request"` + Repository *RepositoryMeta `json:"repository"` +} + +// ListIssueOption list issue options +type ListIssueOption struct { + ListOptions + State StateType + Type IssueType + Labels []string + Milestones []string + KeyWord string +} + +// StateType issue state type +type StateType string + +const ( + // StateOpen pr/issue is opend + StateOpen StateType = "open" + // StateClosed pr/issue is closed + StateClosed StateType = "closed" + // StateAll is all + StateAll StateType = "all" +) + +// IssueType is issue a pull or only an issue +type IssueType string + +const ( + // IssueTypeAll pr and issue + IssueTypeAll IssueType = "" + // IssueTypeIssue only issues + IssueTypeIssue IssueType = "issues" + // IssueTypePull only pulls + IssueTypePull IssueType = "pulls" +) + +// QueryEncode turns options into querystring argument +func (opt *ListIssueOption) QueryEncode() string { + query := opt.getURLQuery() + + if len(opt.State) > 0 { + query.Add("state", string(opt.State)) + } + + if len(opt.Labels) > 0 { + query.Add("labels", strings.Join(opt.Labels, ",")) + } + + if len(opt.KeyWord) > 0 { + query.Add("q", opt.KeyWord) + } + + query.Add("type", string(opt.Type)) + + if len(opt.Milestones) > 0 { + query.Add("milestones", strings.Join(opt.Milestones, ",")) + } + + return query.Encode() +} + +// ListIssues returns all issues assigned the authenticated user +func (c *Client) ListIssues(opt ListIssueOption) ([]*Issue, *Response, error) { + opt.setDefaults() + issues := make([]*Issue, 0, opt.PageSize) + + link, _ := url.Parse("/repos/issues/search") + link.RawQuery = opt.QueryEncode() + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues) + if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { + for i := 0; i < len(issues); i++ { + if issues[i].Repository != nil { + issues[i].Repository.Owner = strings.Split(issues[i].Repository.FullName, "/")[0] + } + } + } + return issues, resp, err +} + +// ListRepoIssues returns all issues for a given repository +func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, *Response, error) { + opt.setDefaults() + issues := make([]*Issue, 0, opt.PageSize) + + link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/issues", owner, repo)) + link.RawQuery = opt.QueryEncode() + resp, err := c.getParsedResponse("GET", link.String(), jsonHeader, nil, &issues) + if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil { + for i := 0; i < len(issues); i++ { + if issues[i].Repository != nil { + issues[i].Repository.Owner = strings.Split(issues[i].Repository.FullName, "/")[0] + } + } + } + return issues, resp, err +} + +// GetIssue returns a single issue for a given repository +func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, *Response, error) { + issue := new(Issue) + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue) + if e := c.CheckServerVersionConstraint(">=1.12.0"); e != nil && issue.Repository != nil { + issue.Repository.Owner = strings.Split(issue.Repository.FullName, "/")[0] + } + return issue, resp, err +} + +// CreateIssueOption options to create one issue +type CreateIssueOption struct { + Title string `json:"title"` + Body string `json:"body"` + // username of assignee + Assignee string `json:"assignee"` + Assignees []string `json:"assignees"` + Deadline *time.Time `json:"due_date"` + // milestone id + Milestone int64 `json:"milestone"` + // list of label ids + Labels []int64 `json:"labels"` + Closed bool `json:"closed"` +} + +// Validate the CreateIssueOption struct +func (opt CreateIssueOption) Validate() error { + if len(strings.TrimSpace(opt.Title)) == 0 { + return fmt.Errorf("title is empty") + } + return nil +} + +// CreateIssue create a new issue for a given repository +func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, *Response, error) { + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + issue := new(Issue) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo), + jsonHeader, bytes.NewReader(body), issue) + return issue, resp, err +} + +// EditIssueOption options for editing an issue +type EditIssueOption struct { + Title string `json:"title"` + Body *string `json:"body"` + Assignee *string `json:"assignee"` + Assignees []string `json:"assignees"` + Milestone *int64 `json:"milestone"` + State *StateType `json:"state"` + Deadline *time.Time `json:"due_date"` +} + +// Validate the EditIssueOption struct +func (opt EditIssueOption) Validate() error { + if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 { + return fmt.Errorf("title is empty") + } + return nil +} + +// EditIssue modify an existing issue for a given repository +func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, *Response, error) { + if err := opt.Validate(); err != nil { + return nil, nil, err + } + body, err := json.Marshal(&opt) + if err != nil { + return nil, nil, err + } + issue := new(Issue) + resp, err := c.getParsedResponse("PATCH", + fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), + jsonHeader, bytes.NewReader(body), issue) + return issue, resp, err +} |