package gitea import ( "context" "net/url" "strconv" ) // Pull request states. const ( PRStateOpen = "open" PRStateClosed = "closed" PRStateAll = "all" ) // Merge styles (Gitea's closed set; empty means "merge"). const ( MergeMerge = "merge" MergeRebase = "rebase" MergeRebaseMerge = "rebase-merge" MergeSquash = "squash" MergeFastForward = "fast-forward" ) // PRBranch is one end of a pull request. type PRBranch struct { Ref string `json:"ref"` SHA string `json:"sha"` Repo *Repo `json:"repo"` } // PullRequest is the PR projection (read shape). type PullRequest struct { Number int64 `json:"number"` Title string `json:"title"` Body string `json:"body"` State string `json:"state"` // open|closed User *User `json:"user"` Base *PRBranch `json:"base"` Head *PRBranch `json:"head"` Mergeable bool `json:"mergeable"` Merged bool `json:"merged"` MergedAt string `json:"merged_at"` HTMLURL string `json:"html_url"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } // PRParams is the PR-create write shape. Head may be "branch" (same // repo) or "owner:branch" (fork syntax); the server resolves both. type PRParams struct { Title string `json:"title"` Body string `json:"body"` Base string `json:"base"` Head string `json:"head"` } // MergeParams is the merge write shape. Do is one of the Merge* // constants (empty means "merge"); Title and Message are optional merge // commit fields. type MergeParams struct { Do string Title string Message string } type mergeWrite struct { Do string `json:"Do"` MergeTitle string `json:"MergeTitleField,omitempty"` MergeMessage string `json:"MergeMessageField,omitempty"` } // CreatePullRequest opens a PR and returns it. func (c *Client) CreatePullRequest(ctx context.Context, owner, repo string, p PRParams) (*PullRequest, error) { var out PullRequest path := "/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(repo) + "/pulls" if err := c.do(ctx, "POST", path, nil, p, &out); err != nil { return nil, err } return &out, nil } // ListPullRequests lists PRs filtered by state (PRStateOpen is the // server default; PRStateAll lifts it). func (c *Client) ListPullRequests(ctx context.Context, owner, repo, state string) ([]PullRequest, error) { var out []PullRequest var query url.Values if state != "" { query = url.Values{"state": []string{state}} } path := "/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(repo) + "/pulls" if err := c.do(ctx, "GET", path, query, nil, &out); err != nil { return nil, err } return out, nil } // GetPullRequest fetches one PR by number. func (c *Client) GetPullRequest(ctx context.Context, owner, repo string, number int64) (*PullRequest, error) { var out PullRequest path := "/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(repo) + "/pulls/" + strconv.FormatInt(number, 10) if err := c.do(ctx, "GET", path, nil, nil, &out); err != nil { return nil, err } return &out, nil } // MergePullRequest merges an open PR. Re-merging or merging a closed PR // maps to ErrValidation (http 409). func (c *Client) MergePullRequest(ctx context.Context, owner, repo string, number int64, p MergeParams) error { if p.Do == "" { p.Do = MergeMerge } path := "/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(repo) + "/pulls/" + strconv.FormatInt(number, 10) + "/merge" return c.do(ctx, "POST", path, nil, mergeWrite{Do: p.Do, MergeTitle: p.Title, MergeMessage: p.Message}, nil) }