You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-scm/scm/driver/gitee/pr.go

414 lines
13 KiB
Go

// Copyright 2017 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gitee
import (
"context"
"fmt"
"time"
"git.awesome-for.me/liuzhiguo/go-scm/scm"
)
type pullService struct {
client *wrapper
}
func (s *pullService) Find(ctx context.Context, repo string, number int) (*scm.PullRequest, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/%d", repo, number)
out := new(pr)
res, err := s.client.do(ctx, "GET", path, nil, out)
return convertPullRequest(out), res, err
}
func (s *pullService) FindComment(ctx context.Context, repo string, _ int, id int) (*scm.Comment, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/comments/%d", repo, id)
out := new(prComment)
res, err := s.client.do(ctx, "GET", path, nil, out)
return convertPullRequestComment(out), res, err
}
func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls?%s", repo, encodePullRequestListOptions(opts))
out := []*pr{}
res, err := s.client.do(ctx, "GET", path, nil, &out)
return convertPullRequestList(out), res, err
}
func (s *pullService) ListChanges(ctx context.Context, repo string, number int, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/%d/files", repo, number)
out := []*prFile{}
res, err := s.client.do(ctx, "GET", path, nil, &out)
return convertPrChangeList(out), res, err
}
func (s *pullService) ListComments(ctx context.Context, repo string, number int, opts scm.ListOptions) ([]*scm.Comment, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/%d/comments/?%s", repo, number, encodeListOptions(opts))
out := []*prComment{}
res, err := s.client.do(ctx, "GET", path, nil, &out)
return convertPullRequestComments(out), res, err
}
func (s *pullService) ListCommits(ctx context.Context, repo string, number int, _ scm.ListOptions) ([]*scm.Commit, *scm.Response, error) {
path := fmt.Sprintf("/repos/%s/pulls/%d/commits", repo, number)
out := []*prCommit{}
res, err := s.client.do(ctx, "GET", path, nil, &out)
return convertPrCommitList(out), res, err
}
func (s *pullService) Merge(ctx context.Context, repo string, number int) (*scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/%d/merge", repo, number)
res, err := s.client.do(ctx, "PUT", path, nil, nil)
return res, err
}
func (s *pullService) Close(ctx context.Context, repo string, number int) (*scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/%d", repo, number)
data := map[string]string{"state": "closed"}
res, err := s.client.do(ctx, "PATCH", path, &data, nil)
return res, err
}
func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls", repo)
in := &prInput{
Title: input.Title,
Body: input.Body,
Head: input.Source,
Base: input.Target,
}
out := new(pr)
res, err := s.client.do(ctx, "POST", path, in, out)
return convertPullRequest(out), res, err
}
func (s *pullService) CreateComment(ctx context.Context, repo string, number int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/%d/comments", repo, number)
in := &prCommentInput{
Body: input.Body,
}
out := new(prComment)
res, err := s.client.do(ctx, "POST", path, in, out)
return convertPullRequestComment(out), res, err
}
func (s *pullService) DeleteComment(ctx context.Context, repo string, _ int, id int) (*scm.Response, error) {
path := fmt.Sprintf("repos/%s/pulls/comments/%d", repo, id)
res, err := s.client.do(ctx, "DELETE", path, nil, nil)
return res, err
}
type (
pr struct {
ID int `json:"id"`
URL string `json:"url"`
HtmlURL string `json:"html_url"`
DiffURL string `json:"diff_url"`
PatchURL string `json:"patch_url"`
IssueURL string `json:"issue_url"`
CommitsURL string `json:"commits_url"`
ReviewCommentsURL string `json:"review_comments_url"`
ReviewCommentURL string `json:"review_comment_url"`
CommentsURL string `json:"comments_url"`
Number int `json:"number"`
State string `json:"state"`
Title string `json:"title"`
Body string `json:"body"`
AssigneesNumber int `json:"assignees_number"`
TestersNumber int `json:"testers_number"`
Assignees []assignee `json:"assignees"`
Testers []tester `json:"testers"`
Milestone milestone `json:"milestone"`
Labels []label `json:"labels"`
Locked bool `json:"locked"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ClosedAt time.Time `json:"closed_at"`
MergedAt time.Time `json:"merged_at"`
Mergeable bool `json:"mergeable"`
CanMergeCheck bool `json:"can_merge_check"`
Head headOrBase `json:"head"`
Base headOrBase `json:"base"`
User user `json:"user"`
}
assignee struct {
ID int `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
URL string `json:"url"`
HtmlURL string `json:"html_url"`
Remark string `json:"remark"`
FollowersURL string `json:"followers_url"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
StarredURL string `json:"starred_url"`
SubscriptionsURL string `json:"subscriptions_url"`
OrganizationsURL string `json:"organizations_url"`
ReposURL string `json:"repos_url"`
EventsURL string `json:"events_url"`
ReceivedEventsURL string `json:"received_events_url"`
Type string `json:"type"`
}
tester struct {
ID int `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
URL string `json:"url"`
HtmlURL string `json:"html_url"`
Remark string `json:"remark"`
FollowersURL string `json:"followers_url"`
FollowingURL string `json:"following_url"`
GistsURL string `json:"gists_url"`
StarredURL string `json:"starred_url"`
SubscriptionsURL string `json:"subscriptions_url"`
OrganizationsURL string `json:"organizations_url"`
ReposURL string `json:"repos_url"`
EventsURL string `json:"events_url"`
ReceivedEventsURL string `json:"received_events_url"`
Type string `json:"type"`
}
milestone struct {
URL string `json:"url"`
HtmlURL string `json:"html_url"`
ID int `json:"id"`
Number int `json:"number"`
RepositoryID interface{} `json:"repository_id"`
State string `json:"state"`
Title string `json:"title"`
Description string `json:"description"`
UpdatedAt time.Time `json:"updated_at"`
CreatedAt time.Time `json:"created_at"`
OpenIssues int `json:"open_issues"`
ClosedIssues int `json:"closed_issues"`
DueOn string `json:"due_on"`
}
label struct {
ID int `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
RepositoryID int `json:"repository_id"`
URL string `json:"url"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
prRepo struct {
ID int `json:"id"`
FullName string `json:"full_name"`
HumanName string `json:"human_name"`
URL string `json:"url"`
//Namespace namespace `json:"namespace"`
Path string `json:"path"`
Name string `json:"name"`
Owner user `json:"owner"`
Assigner assignee `json:"assigner"`
Description string `json:"description"`
Private bool `json:"private"`
Public bool `json:"public"`
Internal bool `json:"internal"`
Fork bool `json:"fork"`
HtmlURL string `json:"html_url"`
SshURL string `json:"ssh_url"`
}
headOrBase struct {
Label string `json:"label"`
Ref string `json:"ref"`
Sha string `json:"sha"`
User user `json:"user"`
Repo prRepo `json:"repo"`
}
prComment struct {
URL string `json:"url"`
ID int `json:"id"`
User user `json:"user"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Body string `json:"body"`
HtmlURL string `json:"html_url"`
PullRequestURL string `json:"pull_request_url"`
}
prFile struct {
Sha string `json:"sha"`
Filename string `json:"filename"`
Status string `json:"status"`
Additions string `json:"additions"`
Deletions string `json:"deletions"`
BlobURL string `json:"blob_url"`
RawURL string `json:"raw_url"`
Patch struct {
Diff string `json:"diff"`
NewPath string `json:"new_path"`
OldPath string `json:"old_path"`
AMode string `json:"a_mode"`
BMode string `json:"b_mode"`
NewFile bool `json:"new_file"`
RenamedFile bool `json:"renamed_file"`
DeletedFile bool `json:"deleted_file"`
TooLarge bool `json:"too_large"`
} `json:"patch"`
}
prCommit struct {
URL string `json:"url"`
Sha string `json:"sha"`
HtmlURL string `json:"html_url"`
CommentsURL string `json:"comments_url"`
Commit struct {
URL string `json:"url"`
Author struct {
Name string `json:"name"`
Date time.Time `json:"date"`
Email string `json:"email"`
} `json:"author"`
Committer struct {
Name string `json:"name"`
Date time.Time `json:"date"`
Email string `json:"email"`
} `json:"committer"`
Message string `json:"message"`
CommentCount int `json:"comment_count"`
} `json:"commit"`
Author author `json:"author"`
Committer author `json:"committer"`
Parents struct {
URL string `json:"url"`
Sha string `json:"sha"`
} `json:"parents"`
}
)
type prInput struct {
Title string `json:"title"`
Body string `json:"body"`
Head string `json:"head"`
Base string `json:"base"`
}
type prCommentInput struct {
Body string `json:"body"`
}
func convertPullRequestList(from []*pr) []*scm.PullRequest {
to := []*scm.PullRequest{}
for _, v := range from {
to = append(to, convertPullRequest(v))
}
return to
}
func convertPullRequest(from *pr) *scm.PullRequest {
var labels []scm.Label
for _, label := range from.Labels {
labels = append(labels, scm.Label{
Name: label.Name,
Color: label.Color,
})
}
merged := from.State == "merged"
closed := from.State == "closed"
if merged {
closed = true
}
return &scm.PullRequest{
Number: from.Number,
Title: from.Title,
Body: from.Body,
Sha: from.Head.Sha,
Ref: fmt.Sprintf("refs/pull/%d/head", from.Number),
Source: from.Head.Ref,
Target: from.Base.Ref,
Fork: from.Head.Repo.FullName,
Link: from.HtmlURL,
Diff: from.DiffURL,
Closed: closed,
Merged: merged,
Head: scm.Reference{
Name: from.Head.Ref,
Path: scm.ExpandRef(from.Head.Ref, "refs/heads"),
Sha: from.Head.Sha,
},
Base: scm.Reference{
Name: from.Base.Ref,
Path: scm.ExpandRef(from.Base.Ref, "refs/heads"),
Sha: from.Base.Sha,
},
Author: scm.User{
Login: from.User.Login,
Avatar: from.User.AvatarURL,
},
Created: from.CreatedAt,
Updated: from.UpdatedAt,
Labels: labels,
}
}
func convertPullRequestComments(from []*prComment) []*scm.Comment {
to := []*scm.Comment{}
for _, v := range from {
to = append(to, convertPullRequestComment(v))
}
return to
}
func convertPullRequestComment(from *prComment) *scm.Comment {
return &scm.Comment{
ID: from.ID,
Body: from.Body,
Author: scm.User{
Login: from.User.Login,
Name: from.User.Name,
Avatar: from.User.AvatarURL,
},
Created: from.CreatedAt,
Updated: from.UpdatedAt,
}
}
func convertPrChangeList(from []*prFile) []*scm.Change {
to := []*scm.Change{}
for _, v := range from {
to = append(to, convertPrChange(v))
}
return to
}
func convertPrChange(from *prFile) *scm.Change {
return &scm.Change{
Path: from.Filename,
Added: from.Status == "added",
Deleted: from.Status == "deleted",
Renamed: from.Status == "renamed",
BlobID: from.Sha,
}
}
func convertPrCommitList(from []*prCommit) []*scm.Commit {
to := []*scm.Commit{}
for _, v := range from {
to = append(to, convertPrCommit(v))
}
return to
}
func convertPrCommit(from *prCommit) *scm.Commit {
return &scm.Commit{
Message: from.Commit.Message,
Sha: from.Sha,
Link: from.HtmlURL,
Author: scm.Signature{
Name: from.Commit.Author.Name,
Email: from.Commit.Author.Email,
Date: from.Commit.Author.Date,
Login: from.Author.Login,
Avatar: from.Author.AvatarURL,
},
Committer: scm.Signature{
Name: from.Commit.Committer.Name,
Email: from.Commit.Committer.Email,
Date: from.Commit.Committer.Date,
Login: from.Committer.Login,
Avatar: from.Committer.AvatarURL,
},
}
}