From 238cf5466ce8ecefbe4a2ca369b3dce9ac885f3c Mon Sep 17 00:00:00 2001
From: c00416947 <caihaomin@huawei.com>
Date: Tue, 14 Jul 2020 20:12:50 +0800
Subject: [PATCH] Add author/signer/reviewer in Merge description

Signed-off-by: Haomin <caihaomin@huawei.com>
---
 pkg/cibot/oauth.go            |  2 +-
 pkg/cibot/pullrequest.go      | 77 +++++++++++++++++++++++++++++++++++
 pkg/cibot/pullrequest_test.go | 35 ++++++++++++++++
 3 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 pkg/cibot/pullrequest_test.go

diff --git a/pkg/cibot/oauth.go b/pkg/cibot/oauth.go
index 79fac4b..d6e9983 100644
--- a/pkg/cibot/oauth.go
+++ b/pkg/cibot/oauth.go
@@ -30,7 +30,7 @@ func GetToken(code string) (*oauth2.Token, error) {
 	ctx := context.Background()
 	config := Setup(client, redirect, secret)
 
-	glog.Infof("Token request config : %v, code:", config, code)
+	glog.Infof("Token request config : %v, code: %s", config, code)
 
 	return config.Exchange(ctx, code)
 
diff --git a/pkg/cibot/pullrequest.go b/pkg/cibot/pullrequest.go
index bf3c738..0cea8e2 100644
--- a/pkg/cibot/pullrequest.go
+++ b/pkg/cibot/pullrequest.go
@@ -408,6 +408,15 @@ func (s *Server) MergePullRequest(event *gitee.NoteEvent) error {
 			// merge pr
 			body := gitee.PullRequestMergePutParam{}
 			body.AccessToken = s.Config.GiteeToken
+
+			// generate merge body
+			description, err := s.generateMergeDescription(event)
+			if err != nil {
+				glog.Errorf("unable to get merge description. err: %v", err)
+				return err
+			}
+
+			body.Description = description
 			_, err = s.GiteeClient.PullRequestsApi.PutV5ReposOwnerRepoPullsNumberMerge(s.Context, owner, repo, prNumber, body)
 			if err != nil {
 				glog.Errorf("unable to merge pull request. err: %v", err)
@@ -418,3 +427,71 @@ func (s *Server) MergePullRequest(event *gitee.NoteEvent) error {
 
 	return nil
 }
+
+func (s *Server) generateMergeDescription(event *gitee.NoteEvent) (string, error) {
+	// get basic params
+	owner := event.Repository.Namespace
+	repo := event.Repository.Name
+	prNumber := event.PullRequest.Number
+	commentCount := event.PullRequest.Comments
+	var perPage int32 = 20
+	pageCount := commentCount / perPage
+	if commentCount%perPage > 0 {
+		pageCount++
+	}
+
+	result := ""
+	localVarOptionals := &gitee.GetV5ReposOwnerRepoPullsNumberCommentsOpts{}
+	localVarOptionals.AccessToken = optional.NewString(s.Config.GiteeToken)
+	localVarOptionals.PerPage = optional.NewInt32(perPage)
+
+	var signers = make([]string,0)
+	var reviewers = make([]string,0)
+	// range page and get comments
+	for page := pageCount; page > 0; page-- {
+		localVarOptionals.Page = optional.NewInt32(page)
+		comments,_, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumberComments(s.Context,owner,repo,prNumber,localVarOptionals)
+		if err != nil {
+			glog.Errorf("unable to get pull request comments. err: %v", err)
+			return result, err
+		}
+
+		signers, reviewers, err = getSignersAndReviewers(comments)
+		if err != nil {
+			glog.Errorf("failed to get signers or reviewers. err: %v", err)
+		}
+	}
+
+	result = formatDescription(event.PullRequest.User.Login, reviewers, signers)
+	return result, nil
+}
+
+func formatDescription(user string, reviewers,signers []string) string {
+	return  fmt.Sprintf("From: @%s\nReviewed-by: %s\nSigned-off-by: %s\n",
+		user, strings.Join(reviewers,","), strings.Join(signers,","))
+}
+
+func getSignersAndReviewers(comments []gitee.PullRequestComments)([]string, []string ,error) {
+	var signers = make([]string,0)
+	var reviewers = make([]string,0)
+
+	if len(comments)== 0 {
+		return signers,reviewers, fmt.Errorf("comment list is empty")
+	}
+
+	for _, comment := range comments {
+		m := RegAddLgtm.FindStringSubmatch(comment.Body)
+		if m != nil && comment.UpdatedAt == comment.CreatedAt {
+			reviewer := fmt.Sprintf("@%s", comment.User.Login)
+			reviewers = append(reviewers,reviewer)
+		}
+
+		m =  RegAddApprove.FindStringSubmatch(comment.Body)
+		if m != nil && comment.UpdatedAt == comment.CreatedAt {
+			signer := fmt.Sprintf("@%s", comment.User.Login)
+			signers = append(signers,signer)
+		}
+	}
+
+	return signers,reviewers,nil
+}
diff --git a/pkg/cibot/pullrequest_test.go b/pkg/cibot/pullrequest_test.go
new file mode 100644
index 0000000..aa4ea28
--- /dev/null
+++ b/pkg/cibot/pullrequest_test.go
@@ -0,0 +1,35 @@
+package cibot
+
+import (
+	"testing"
+)
+
+func Test_formatDescription(t *testing.T) {
+	type args struct {
+		user      string
+		reviewers []string
+		signers   []string
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "test description format",
+			args: args{
+				user:      "fakeuser",
+				reviewers: []string{"@aaa", "@bbb"},
+				signers:   []string{"@ccc", "@ddd"},
+			},
+			want: "From: @fakeuser\nReviewed-by: @aaa,@bbb\nSigned-off-by: @ccc,@ddd\n",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := formatDescription(tt.args.user, tt.args.reviewers, tt.args.signers); got != tt.want {
+				t.Errorf("formatDescription() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
-- 
2.19.1

