feat(pull_request): support review/close a pull request

This commit is contained in:
HJJ 2024-04-15 17:39:04 +08:00
parent 15a1c4d63b
commit bdb059c957
13 changed files with 92 additions and 25 deletions

16
cmd/pull_request/close.go Normal file
View File

@ -0,0 +1,16 @@
package pull_request
import (
"gitee_cli/internal/api/pull_request"
"github.com/spf13/cobra"
)
var CloseCmd = &cobra.Command{
Use: "close",
Short: "Close pull request",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
iid := args[0]
pull_request.Close(iid)
},
}

View File

@ -14,4 +14,6 @@ func init() {
Pr.AddCommand(ListCmd) Pr.AddCommand(ListCmd)
Pr.AddCommand(CreateCmd) Pr.AddCommand(CreateCmd)
Pr.AddCommand(CommentCmd) Pr.AddCommand(CommentCmd)
Pr.AddCommand(CloseCmd)
Pr.AddCommand(ReviewCmd)
} }

View File

@ -0,0 +1,16 @@
package pull_request
import (
"gitee_cli/internal/api/pull_request"
"github.com/spf13/cobra"
)
var ReviewCmd = &cobra.Command{
Use: "review",
Short: "Review a pull request",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
iid := args[0]
pull_request.Review(iid)
},
}

View File

@ -17,7 +17,7 @@ var RootCmd = &cobra.Command{
Use: "gitee", Use: "gitee",
Short: "Gitee In terminal", Short: "Gitee In terminal",
Long: "Gitee CLI is a tool which interact with gitee server seamlessly via terminal", Long: "Gitee CLI is a tool which interact with gitee server seamlessly via terminal",
Version: "0.0.3", Version: "0.0.4",
} }
func init() { func init() {

2
go.mod
View File

@ -10,7 +10,6 @@ require (
github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/glamour v0.7.0
github.com/charmbracelet/lipgloss v0.10.0 github.com/charmbracelet/lipgloss v0.10.0
github.com/fatih/color v1.16.0 github.com/fatih/color v1.16.0
github.com/olekukonko/tablewriter v0.0.5
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0
github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1
@ -38,6 +37,7 @@ require (
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect github.com/muesli/termenv v0.15.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/yuin/goldmark v1.7.0 // indirect github.com/yuin/goldmark v1.7.0 // indirect

View File

@ -17,7 +17,7 @@ func List() ([]Enterprise, error) {
url := "https://api.gitee.com/enterprises/list" url := "https://api.gitee.com/enterprises/list"
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
_, err := giteeClient.Do() err := giteeClient.Do()
if err != nil || giteeClient.IsFail() { if err != nil || giteeClient.IsFail() {
return nil, err return nil, err
} }
@ -38,7 +38,7 @@ func List() ([]Enterprise, error) {
func Find(path string) (Enterprise, error) { func Find(path string) (Enterprise, error) {
url := fmt.Sprintf("https://gitee.com/api/v5/enterprises/%s", path) url := fmt.Sprintf("https://gitee.com/api/v5/enterprises/%s", path)
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
if _, err := giteeClient.Do(); err != nil { if err := giteeClient.Do(); err != nil {
return Enterprise{}, errors.New("查询企业失败!") return Enterprise{}, errors.New("查询企业失败!")
} }
data, _ := giteeClient.GetRespBody() data, _ := giteeClient.GetRespBody()

View File

@ -4,18 +4,18 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"gitee_cli/utils/http_utils"
"gitee_cli/internal/api/issue_state" "gitee_cli/internal/api/issue_state"
"gitee_cli/utils/http_utils"
) )
const Endpoint = "https://api.gitee.com/enterprises/%d/issues" const Endpoint = "https://api.gitee.com/enterprises/%d/issues"
type Issue struct { type Issue struct {
Id int `json:"id"` Id int `json:"id"`
Ident string `json:"ident"` Ident string `json:"ident"`
Title string `json:"title"` Title string `json:"title"`
Url string `json:"issue_url"` Url string `json:"issue_url"`
Description string `json:"description"` Description string `json:"description"`
IssueState issue_state.IssueState `json:"issue_state"` IssueState issue_state.IssueState `json:"issue_state"`
} }
@ -24,7 +24,7 @@ func Find(enterpriseId int, params map[string]string) ([]Issue, error) {
giteeClient := http_utils.NewGiteeClient("GET", url, params, nil) giteeClient := http_utils.NewGiteeClient("GET", url, params, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
_, err := giteeClient.Do() err := giteeClient.Do()
if err != nil || giteeClient.IsFail() { if err != nil || giteeClient.IsFail() {
return []Issue{}, err return []Issue{}, err
} }

View File

@ -16,7 +16,7 @@ func ListWithIssue(entId int, issueId int) ([]IssueState, error) {
url := fmt.Sprintf("https://api.gitee.com/enterprises/%d/issues/%d/issue_states", entId, issueId) url := fmt.Sprintf("https://api.gitee.com/enterprises/%d/issues/%d/issue_states", entId, issueId)
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
if _, err := giteeClient.Do(); err != nil { if err := giteeClient.Do(); err != nil {
return nil, err return nil, err
} }

View File

@ -40,7 +40,7 @@ func List(issueType int, entPath string) ([]IssueType, error) {
url := fmt.Sprintf("https://api.gitee.com/enterprises/%d/issue_types/enterprise_issue_types?category=%s&page=1&per_page=1000&state=1", ent.Id, category) url := fmt.Sprintf("https://api.gitee.com/enterprises/%d/issue_types/enterprise_issue_types?category=%s&page=1&per_page=1000&state=1", ent.Id, category)
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
if _, err := giteeClient.Do(); err != nil { if err := giteeClient.Do(); err != nil {
return nil, err return nil, err
} }
@ -72,7 +72,7 @@ func FetchTemplate(issueTypeId, entId int) (string, error) {
url := fmt.Sprintf("https://api.gitee.com/enterprises/%d/issue_types/%d", entId, issueTypeId) url := fmt.Sprintf("https://api.gitee.com/enterprises/%d/issue_types/%d", entId, issueTypeId)
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
if _, err := giteeClient.Do(); err != nil { if err := giteeClient.Do(); err != nil {
return "", errors.New("获取模板失败!") return "", errors.New("获取模板失败!")
} }
issueType := IssueType{} issueType := IssueType{}

View File

@ -18,7 +18,7 @@ func Find(enterpriseId int, params map[string]string) ([]Member, error) {
giteeClient := http_utils.NewGiteeClient("GET", url, params, nil) giteeClient := http_utils.NewGiteeClient("GET", url, params, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
_, err := giteeClient.Do() err := giteeClient.Do()
if err != nil || giteeClient.IsFail() { if err != nil || giteeClient.IsFail() {
return []Member{}, err return []Member{}, err
} }

View File

@ -7,6 +7,8 @@ import (
"gitee_cli/config" "gitee_cli/config"
"gitee_cli/utils/git_utils" "gitee_cli/utils/git_utils"
"gitee_cli/utils/http_utils" "gitee_cli/utils/http_utils"
"github.com/fatih/color"
"os"
"os/exec" "os/exec"
"strconv" "strconv"
"strings" "strings"
@ -50,7 +52,7 @@ func Note(iid int, note string) error {
payload := map[string]string{"body": note} payload := map[string]string{"body": note}
giteeClient := http_utils.NewGiteeClient("POST", url, nil, payload) giteeClient := http_utils.NewGiteeClient("POST", url, nil, payload)
giteeClient, _ = giteeClient.Do() giteeClient.Do()
if giteeClient.IsFail() { if giteeClient.IsFail() {
return errors.New(fmt.Sprintf("评论 pr %d 失败!", iid)) return errors.New(fmt.Sprintf("评论 pr %d 失败!", iid))
} }
@ -199,10 +201,12 @@ func CreatePr(baseRepo, baseRef, headRef, title, body, assignees, testers string
"testers": testers, "testers": testers,
"draft": draft, "draft": draft,
"prune_source_branch": prune, "prune_source_branch": prune,
"assignees_number": len(strings.Split(assignees, ",")),
"testers_number": len(strings.Split(testers, ",")),
} }
giteeClient := http_utils.NewGiteeClient("POST", url, nil, payload) giteeClient := http_utils.NewGiteeClient("POST", url, nil, payload)
giteeClient, err := giteeClient.Do() err := giteeClient.Do()
if err != nil { if err != nil {
return PullRequest{}, errors.New("GiteeCilent 异常!") return PullRequest{}, errors.New("GiteeCilent 异常!")
@ -273,7 +277,7 @@ func CreateLightPr(baseRepo, baseRef, prTitle string) (PullRequest, error) {
func Detail(iid, repoPath string) (PullRequest, error) { func Detail(iid, repoPath string) (PullRequest, error) {
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/pulls/%s", repoPath, iid) url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/pulls/%s", repoPath, iid)
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
if _, err := giteeClient.Do(); err != nil || giteeClient.IsFail() { if err := giteeClient.Do(); err != nil || giteeClient.IsFail() {
return PullRequest{}, errors.New("获取 Pull Request 详情失败") return PullRequest{}, errors.New("获取 Pull Request 详情失败")
} }
@ -289,10 +293,40 @@ func FetchPatchContent(iid, repoPath string) (string, error) {
url := fmt.Sprintf("https://gitee.com/%s/pulls/%s.diff", repoPath, iid) url := fmt.Sprintf("https://gitee.com/%s/pulls/%s.diff", repoPath, iid)
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
if _, err := giteeClient.Do(); err != nil || giteeClient.IsFail() { if err := giteeClient.Do(); err != nil || giteeClient.IsFail() {
return "", errors.New("获取 Pull Request 补丁内容失败") return "", errors.New("获取 Pull Request 补丁内容失败")
} }
data, _ := giteeClient.GetRespBody() data, _ := giteeClient.GetRespBody()
return string(data), nil return string(data), nil
} }
func Close(iid string) {
pathWithNamespace, err := git_utils.ParseCurrentRepo()
if err != nil {
pathWithNamespace = config.Conf.DefaultPathWithNamespace
}
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/pulls/%s", pathWithNamespace, iid)
payload := map[string]string{"state": "closed"}
giteeClient := http_utils.NewGiteeClient("PATCH", url, nil, payload)
if giteeClient.Do(); giteeClient.IsFail() {
color.Red("关闭 PR 失败!")
os.Exit(1)
}
color.Green("关闭 PR 成功🏅")
}
func Review(iid string) {
pathWithNamespace, err := git_utils.ParseCurrentRepo()
if err != nil {
pathWithNamespace = config.Conf.DefaultPathWithNamespace
}
url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/pulls/%s/review", pathWithNamespace, iid)
giteeClient := http_utils.NewGiteeClient("POST", url, nil, nil)
giteeClient.Do()
if giteeClient.IsFail() {
color.Red("审查通过失败!")
os.Exit(1)
}
color.Green("审查通过成功🏅")
}

View File

@ -74,7 +74,7 @@ func BasicUser() (User, error) {
url := "https://api.gitee.com/enterprises/users" url := "https://api.gitee.com/enterprises/users"
giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil) giteeClient := http_utils.NewGiteeClient("GET", url, nil, nil)
giteeClient.SetCookieAuth() giteeClient.SetCookieAuth()
_, err := giteeClient.Do() err := giteeClient.Do()
if err != nil || giteeClient.IsFail() { if err != nil || giteeClient.IsFail() {
return User{}, errors.New("查询用户失败!") return User{}, errors.New("查询用户失败!")
} }

View File

@ -45,12 +45,11 @@ func NewGiteeClient(method, urlString string, query map[string]string, payload i
} }
} }
func (g *GiteeClient) SetHeaders(headers map[string]string) *GiteeClient { func (g *GiteeClient) SetHeaders(headers map[string]string) {
g.Headers = headers g.Headers = headers
return g
} }
func (g *GiteeClient) Do() (*GiteeClient, error) { func (g *GiteeClient) Do() error {
// 多次调用首先置空 // 多次调用首先置空
g.Response = nil g.Response = nil
_payload, _ := json.Marshal(g.Payload) _payload, _ := json.Marshal(g.Payload)
@ -75,10 +74,10 @@ func (g *GiteeClient) Do() (*GiteeClient, error) {
var err error var err error
if resp, err = client.Do(req); err != nil { if resp, err = client.Do(req); err != nil {
return g, err return err
} }
g.Response = resp g.Response = resp
return g, nil return nil
} }
func (g *GiteeClient) IsSuccess() bool { func (g *GiteeClient) IsSuccess() bool {