mirror of
https://gitea.com/gitea/gitea-mcp.git
synced 2026-03-15 17:35:13 +00:00
feat: slim tool responses (#141)
Reduce token usage by slimming tool responses. Instead of returning full Gitea SDK objects (with nested user/repo objects, avatars, permissions, etc.), each operation now has a colocated `slim.go` that extracts only the fields an LLM needs. List endpoints return even fewer fields than single-item endpoints.
Other changes:
- Add `params` helpers to DRY parameter extraction across 40+ handlers
- Remove `{"Result": ...}` wrapper for flatter responses
- Reduce default pageSize from 100 to 30
Fixes: https://gitea.com/gitea/gitea-mcp/issues/128
*Created by Claude on behalf of @silverwind*
Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/141
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-committed-by: silverwind <me@silverwind.io>
This commit is contained in:
@@ -2,7 +2,6 @@ package pull
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/gitea"
|
||||
@@ -63,7 +62,7 @@ var (
|
||||
mcp.WithString("sort", mcp.Description("sort"), mcp.Enum("oldest", "recentupdate", "leastupdate", "mostcomment", "leastcomment", "priority"), mcp.DefaultString("recentupdate")),
|
||||
mcp.WithNumber("milestone", mcp.Description("milestone")),
|
||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||
)
|
||||
|
||||
CreatePullRequestTool = mcp.NewTool(
|
||||
@@ -104,7 +103,7 @@ var (
|
||||
mcp.WithString("repo", mcp.Required(), mcp.Description("repository name")),
|
||||
mcp.WithNumber("index", mcp.Required(), mcp.Description("pull request index")),
|
||||
mcp.WithNumber("page", mcp.Description("page number"), mcp.DefaultNumber(1)),
|
||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(100)),
|
||||
mcp.WithNumber("pageSize", mcp.Description("page size"), mcp.DefaultNumber(30)),
|
||||
)
|
||||
|
||||
GetPullRequestReviewTool = mcp.NewTool(
|
||||
@@ -269,15 +268,16 @@ func init() {
|
||||
|
||||
func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called GetPullRequestByIndexFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
@@ -290,24 +290,25 @@ func GetPullRequestByIndexFn(ctx context.Context, req mcp.CallToolRequest) (*mcp
|
||||
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(pr)
|
||||
return to.TextResult(slimPullRequest(pr))
|
||||
}
|
||||
|
||||
func GetPullRequestDiffFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called GetPullRequestDiffFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
binary, _ := req.GetArguments()["binary"].(bool)
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
binary, _ := args["binary"].(bool)
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -320,41 +321,31 @@ func GetPullRequestDiffFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Ca
|
||||
return to.ErrorResult(fmt.Errorf("get %v/%v/pr/%v diff err: %v", owner, repo, index, err))
|
||||
}
|
||||
|
||||
result := map[string]any{
|
||||
"diff": string(diffBytes),
|
||||
"binary": binary,
|
||||
"index": index,
|
||||
"repo": repo,
|
||||
"owner": owner,
|
||||
}
|
||||
return to.TextResult(result)
|
||||
return to.TextResult(string(diffBytes))
|
||||
}
|
||||
|
||||
func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called ListRepoPullRequests")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
state, _ := req.GetArguments()["state"].(string)
|
||||
sort, ok := req.GetArguments()["sort"].(string)
|
||||
if !ok {
|
||||
sort = "recentupdate"
|
||||
}
|
||||
milestone := params.GetOptionalInt(req.GetArguments(), "milestone", 0)
|
||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
||||
state, _ := args["state"].(string)
|
||||
sort := params.GetOptionalString(args, "sort", "recentupdate")
|
||||
milestone := params.GetOptionalInt(args, "milestone", 0)
|
||||
page, pageSize := params.GetPagination(args, 30)
|
||||
opt := gitea_sdk.ListPullRequestsOptions{
|
||||
State: gitea_sdk.StateType(state),
|
||||
Sort: sort,
|
||||
Milestone: milestone,
|
||||
ListOptions: gitea_sdk.ListOptions{
|
||||
Page: int(page),
|
||||
PageSize: int(pageSize),
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
},
|
||||
}
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
@@ -366,34 +357,35 @@ func ListRepoPullRequestsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
||||
return to.ErrorResult(fmt.Errorf("list %v/%v/pull_requests err: %v", owner, repo, err))
|
||||
}
|
||||
|
||||
return to.TextResult(pullRequests)
|
||||
return to.TextResult(slimPullRequests(pullRequests))
|
||||
}
|
||||
|
||||
func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called CreatePullRequestFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
title, ok := req.GetArguments()["title"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("title is required"))
|
||||
title, err := params.GetString(args, "title")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
body, ok := req.GetArguments()["body"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("body is required"))
|
||||
body, err := params.GetString(args, "body")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
head, ok := req.GetArguments()["head"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("head is required"))
|
||||
head, err := params.GetString(args, "head")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
base, ok := req.GetArguments()["base"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("base is required"))
|
||||
base, err := params.GetString(args, "base")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -409,45 +401,27 @@ func CreatePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Cal
|
||||
return to.ErrorResult(fmt.Errorf("create %v/%v/pull_request err: %v", owner, repo, err))
|
||||
}
|
||||
|
||||
return to.TextResult(pr)
|
||||
return to.TextResult(slimPullRequest(pr))
|
||||
}
|
||||
|
||||
func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called CreatePullRequestReviewerFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
var reviewers []string
|
||||
if reviewersArg, exists := req.GetArguments()["reviewers"]; exists {
|
||||
if reviewersSlice, ok := reviewersArg.([]any); ok {
|
||||
for _, reviewer := range reviewersSlice {
|
||||
if reviewerStr, ok := reviewer.(string); ok {
|
||||
reviewers = append(reviewers, reviewerStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var teamReviewers []string
|
||||
if teamReviewersArg, exists := req.GetArguments()["team_reviewers"]; exists {
|
||||
if teamReviewersSlice, ok := teamReviewersArg.([]any); ok {
|
||||
for _, teamReviewer := range teamReviewersSlice {
|
||||
if teamReviewerStr, ok := teamReviewer.(string); ok {
|
||||
teamReviewers = append(teamReviewers, teamReviewerStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reviewers := params.GetStringSlice(args, "reviewers")
|
||||
teamReviewers := params.GetStringSlice(args, "team_reviewers")
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -476,40 +450,22 @@ func CreatePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
||||
|
||||
func DeletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called DeletePullRequestReviewerFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
var reviewers []string
|
||||
if reviewersArg, exists := req.GetArguments()["reviewers"]; exists {
|
||||
if reviewersSlice, ok := reviewersArg.([]any); ok {
|
||||
for _, reviewer := range reviewersSlice {
|
||||
if reviewerStr, ok := reviewer.(string); ok {
|
||||
reviewers = append(reviewers, reviewerStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var teamReviewers []string
|
||||
if teamReviewersArg, exists := req.GetArguments()["team_reviewers"]; exists {
|
||||
if teamReviewersSlice, ok := teamReviewersArg.([]any); ok {
|
||||
for _, teamReviewer := range teamReviewersSlice {
|
||||
if teamReviewerStr, ok := teamReviewer.(string); ok {
|
||||
teamReviewers = append(teamReviewers, teamReviewerStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reviewers := params.GetStringSlice(args, "reviewers")
|
||||
teamReviewers := params.GetStringSlice(args, "team_reviewers")
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -537,20 +493,20 @@ func DeletePullRequestReviewerFn(ctx context.Context, req mcp.CallToolRequest) (
|
||||
|
||||
func ListPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called ListPullRequestReviewsFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
page := params.GetOptionalInt(req.GetArguments(), "page", 1)
|
||||
pageSize := params.GetOptionalInt(req.GetArguments(), "pageSize", 100)
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
page, pageSize := params.GetPagination(args, 30)
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -559,32 +515,33 @@ func ListPullRequestReviewsFn(ctx context.Context, req mcp.CallToolRequest) (*mc
|
||||
|
||||
reviews, _, err := client.ListPullReviews(owner, repo, index, gitea_sdk.ListPullReviewsOptions{
|
||||
ListOptions: gitea_sdk.ListOptions{
|
||||
Page: int(page),
|
||||
PageSize: int(pageSize),
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return to.ErrorResult(fmt.Errorf("list reviews for %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(reviews)
|
||||
return to.TextResult(slimReviews(reviews))
|
||||
}
|
||||
|
||||
func GetPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called GetPullRequestReviewFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(args, "review_id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
@@ -599,24 +556,25 @@ func GetPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.
|
||||
return to.ErrorResult(fmt.Errorf("get review %v for %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(review)
|
||||
return to.TextResult(slimReview(review))
|
||||
}
|
||||
|
||||
func ListPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called ListPullRequestReviewCommentsFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(args, "review_id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
@@ -631,38 +589,39 @@ func ListPullRequestReviewCommentsFn(ctx context.Context, req mcp.CallToolReques
|
||||
return to.ErrorResult(fmt.Errorf("list review comments for review %v on %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(comments)
|
||||
return to.TextResult(slimReviewComments(comments))
|
||||
}
|
||||
|
||||
func CreatePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called CreatePullRequestReviewFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
opt := gitea_sdk.CreatePullReviewOptions{}
|
||||
|
||||
if state, ok := req.GetArguments()["state"].(string); ok {
|
||||
if state, ok := args["state"].(string); ok {
|
||||
opt.State = gitea_sdk.ReviewStateType(state)
|
||||
}
|
||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
||||
if body, ok := args["body"].(string); ok {
|
||||
opt.Body = body
|
||||
}
|
||||
if commitID, ok := req.GetArguments()["commit_id"].(string); ok {
|
||||
if commitID, ok := args["commit_id"].(string); ok {
|
||||
opt.CommitID = commitID
|
||||
}
|
||||
|
||||
// Parse inline comments
|
||||
if commentsArg, exists := req.GetArguments()["comments"]; exists {
|
||||
if commentsArg, exists := args["comments"]; exists {
|
||||
if commentsSlice, ok := commentsArg.([]any); ok {
|
||||
for _, comment := range commentsSlice {
|
||||
if commentMap, ok := comment.(map[string]any); ok {
|
||||
@@ -695,36 +654,37 @@ func CreatePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
||||
return to.ErrorResult(fmt.Errorf("create review for %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(review)
|
||||
return to.TextResult(slimReview(review))
|
||||
}
|
||||
|
||||
func SubmitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called SubmitPullRequestReviewFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
state, ok := req.GetArguments()["state"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("state is required"))
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(args, "review_id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
state, err := params.GetString(args, "state")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
opt := gitea_sdk.SubmitPullReviewOptions{
|
||||
State: gitea_sdk.ReviewStateType(state),
|
||||
}
|
||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
||||
if body, ok := args["body"].(string); ok {
|
||||
opt.Body = body
|
||||
}
|
||||
|
||||
@@ -738,24 +698,25 @@ func SubmitPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
||||
return to.ErrorResult(fmt.Errorf("submit review %v for %v/%v/pr/%v err: %v", reviewID, owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(review)
|
||||
return to.TextResult(slimReview(review))
|
||||
}
|
||||
|
||||
func DeletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called DeletePullRequestReviewFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(args, "review_id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
@@ -782,25 +743,26 @@ func DeletePullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*m
|
||||
|
||||
func DismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called DismissPullRequestReviewFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(req.GetArguments(), "review_id")
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
reviewID, err := params.GetIndex(args, "review_id")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
opt := gitea_sdk.DismissPullReviewOptions{}
|
||||
if message, ok := req.GetArguments()["message"].(string); ok {
|
||||
if message, ok := args["message"].(string); ok {
|
||||
opt.Message = message
|
||||
}
|
||||
|
||||
@@ -826,38 +788,24 @@ func DismissPullRequestReviewFn(ctx context.Context, req mcp.CallToolRequest) (*
|
||||
|
||||
func MergePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called MergePullRequestFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
mergeStyle := "merge"
|
||||
if style, exists := req.GetArguments()["merge_style"].(string); exists && style != "" {
|
||||
mergeStyle = style
|
||||
}
|
||||
|
||||
title := ""
|
||||
if t, exists := req.GetArguments()["title"].(string); exists {
|
||||
title = t
|
||||
}
|
||||
|
||||
message := ""
|
||||
if msg, exists := req.GetArguments()["message"].(string); exists {
|
||||
message = msg
|
||||
}
|
||||
|
||||
deleteBranch := false
|
||||
if del, exists := req.GetArguments()["delete_branch"].(bool); exists {
|
||||
deleteBranch = del
|
||||
}
|
||||
mergeStyle := params.GetOptionalString(args, "merge_style", "merge")
|
||||
title, _ := args["title"].(string)
|
||||
message, _ := args["message"].(string)
|
||||
deleteBranch, _ := args["delete_branch"].(bool)
|
||||
|
||||
client, err := gitea.ClientFromContext(ctx)
|
||||
if err != nil {
|
||||
@@ -897,53 +845,46 @@ func MergePullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.Call
|
||||
|
||||
func EditPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
log.Debugf("Called EditPullRequestFn")
|
||||
owner, ok := req.GetArguments()["owner"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("owner is required"))
|
||||
args := req.GetArguments()
|
||||
owner, err := params.GetString(args, "owner")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
repo, ok := req.GetArguments()["repo"].(string)
|
||||
if !ok {
|
||||
return to.ErrorResult(errors.New("repo is required"))
|
||||
repo, err := params.GetString(args, "repo")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
index, err := params.GetIndex(req.GetArguments(), "index")
|
||||
index, err := params.GetIndex(args, "index")
|
||||
if err != nil {
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
|
||||
opt := gitea_sdk.EditPullRequestOption{}
|
||||
|
||||
if title, ok := req.GetArguments()["title"].(string); ok {
|
||||
if title, ok := args["title"].(string); ok {
|
||||
opt.Title = title
|
||||
}
|
||||
if body, ok := req.GetArguments()["body"].(string); ok {
|
||||
if body, ok := args["body"].(string); ok {
|
||||
opt.Body = new(body)
|
||||
}
|
||||
if base, ok := req.GetArguments()["base"].(string); ok {
|
||||
if base, ok := args["base"].(string); ok {
|
||||
opt.Base = base
|
||||
}
|
||||
if assignee, ok := req.GetArguments()["assignee"].(string); ok {
|
||||
if assignee, ok := args["assignee"].(string); ok {
|
||||
opt.Assignee = assignee
|
||||
}
|
||||
if assigneesArg, exists := req.GetArguments()["assignees"]; exists {
|
||||
if assigneesSlice, ok := assigneesArg.([]any); ok {
|
||||
var assignees []string
|
||||
for _, a := range assigneesSlice {
|
||||
if s, ok := a.(string); ok {
|
||||
assignees = append(assignees, s)
|
||||
}
|
||||
}
|
||||
opt.Assignees = assignees
|
||||
}
|
||||
if assignees := params.GetStringSlice(args, "assignees"); assignees != nil {
|
||||
opt.Assignees = assignees
|
||||
}
|
||||
if val, exists := req.GetArguments()["milestone"]; exists {
|
||||
if val, exists := args["milestone"]; exists {
|
||||
if milestone, ok := params.ToInt64(val); ok {
|
||||
opt.Milestone = milestone
|
||||
}
|
||||
}
|
||||
if state, ok := req.GetArguments()["state"].(string); ok {
|
||||
if state, ok := args["state"].(string); ok {
|
||||
opt.State = new(gitea_sdk.StateType(state))
|
||||
}
|
||||
if allowMaintainerEdit, ok := req.GetArguments()["allow_maintainer_edit"].(bool); ok {
|
||||
if allowMaintainerEdit, ok := args["allow_maintainer_edit"].(bool); ok {
|
||||
opt.AllowMaintainerEdit = new(allowMaintainerEdit)
|
||||
}
|
||||
|
||||
@@ -957,5 +898,5 @@ func EditPullRequestFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallT
|
||||
return to.ErrorResult(fmt.Errorf("edit %v/%v/pr/%v err: %v", owner, repo, index, err))
|
||||
}
|
||||
|
||||
return to.TextResult(pr)
|
||||
return to.TextResult(slimPullRequest(pr))
|
||||
}
|
||||
|
||||
@@ -116,13 +116,11 @@ func TestEditPullRequestFn(t *testing.T) {
|
||||
t.Fatalf("expected text content, got %T", result.Content[0])
|
||||
}
|
||||
|
||||
var parsed struct {
|
||||
Result map[string]any `json:"Result"`
|
||||
}
|
||||
var parsed map[string]any
|
||||
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
||||
t.Fatalf("unmarshal result text: %v", err)
|
||||
}
|
||||
if got := parsed.Result["title"].(string); got != "WIP: my feature" {
|
||||
if got := parsed["title"].(string); got != "WIP: my feature" {
|
||||
t.Fatalf("result title = %q, want %q", got, "WIP: my feature")
|
||||
}
|
||||
})
|
||||
@@ -239,20 +237,18 @@ func TestMergePullRequestFn(t *testing.T) {
|
||||
t.Fatalf("expected text content, got %T", result.Content[0])
|
||||
}
|
||||
|
||||
var parsed struct {
|
||||
Result map[string]any `json:"Result"`
|
||||
}
|
||||
var parsed map[string]any
|
||||
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
||||
t.Fatalf("unmarshal result text: %v", err)
|
||||
}
|
||||
if parsed.Result["merged"] != true {
|
||||
t.Fatalf("expected merged=true, got %v", parsed.Result["merged"])
|
||||
if parsed["merged"] != true {
|
||||
t.Fatalf("expected merged=true, got %v", parsed["merged"])
|
||||
}
|
||||
if parsed.Result["merge_style"] != "squash" {
|
||||
t.Fatalf("expected merge_style 'squash', got %v", parsed.Result["merge_style"])
|
||||
if parsed["merge_style"] != "squash" {
|
||||
t.Fatalf("expected merge_style 'squash', got %v", parsed["merge_style"])
|
||||
}
|
||||
if parsed.Result["branch_deleted"] != true {
|
||||
t.Fatalf("expected branch_deleted=true, got %v", parsed.Result["branch_deleted"])
|
||||
if parsed["branch_deleted"] != true {
|
||||
t.Fatalf("expected branch_deleted=true, got %v", parsed["branch_deleted"])
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -370,27 +366,13 @@ func TestGetPullRequestDiffFn(t *testing.T) {
|
||||
t.Fatalf("expected text content, got %T", result.Content[0])
|
||||
}
|
||||
|
||||
var parsed struct {
|
||||
Result map[string]any `json:"Result"`
|
||||
}
|
||||
// The diff response is now a plain string
|
||||
var parsed string
|
||||
if err := json.Unmarshal([]byte(textContent.Text), &parsed); err != nil {
|
||||
t.Fatalf("unmarshal result text: %v", err)
|
||||
}
|
||||
|
||||
if got, ok := parsed.Result["diff"].(string); !ok || got != diffRaw {
|
||||
t.Fatalf("diff = %q, want %q", got, diffRaw)
|
||||
}
|
||||
if got, ok := parsed.Result["binary"].(bool); !ok || got != true {
|
||||
t.Fatalf("binary = %v, want true", got)
|
||||
}
|
||||
if got, ok := parsed.Result["index"].(float64); !ok || int64(got) != int64(index) {
|
||||
t.Fatalf("index = %v, want %d", got, index)
|
||||
}
|
||||
if got, ok := parsed.Result["owner"].(string); !ok || got != owner {
|
||||
t.Fatalf("owner = %q, want %q", got, owner)
|
||||
}
|
||||
if got, ok := parsed.Result["repo"].(string); !ok || got != repo {
|
||||
t.Fatalf("repo = %q, want %q", got, repo)
|
||||
if parsed != diffRaw {
|
||||
t.Fatalf("diff = %q, want %q", parsed, diffRaw)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
191
operation/pull/slim.go
Normal file
191
operation/pull/slim.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package pull
|
||||
|
||||
import (
|
||||
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
func userLogin(u *gitea_sdk.User) string {
|
||||
if u == nil {
|
||||
return ""
|
||||
}
|
||||
return u.UserName
|
||||
}
|
||||
|
||||
func userLogins(users []*gitea_sdk.User) []string {
|
||||
if len(users) == 0 {
|
||||
return nil
|
||||
}
|
||||
out := make([]string, 0, len(users))
|
||||
for _, u := range users {
|
||||
if u != nil {
|
||||
out = append(out, u.UserName)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func labelNames(labels []*gitea_sdk.Label) []string {
|
||||
if len(labels) == 0 {
|
||||
return nil
|
||||
}
|
||||
out := make([]string, 0, len(labels))
|
||||
for _, l := range labels {
|
||||
if l != nil {
|
||||
out = append(out, l.Name)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func repoRef(r *gitea_sdk.Repository) map[string]any {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]any{
|
||||
"full_name": r.FullName,
|
||||
"description": r.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func slimPullRequest(pr *gitea_sdk.PullRequest) map[string]any {
|
||||
if pr == nil {
|
||||
return nil
|
||||
}
|
||||
m := map[string]any{
|
||||
"number": pr.Index,
|
||||
"title": pr.Title,
|
||||
"body": pr.Body,
|
||||
"state": pr.State,
|
||||
"draft": pr.Draft,
|
||||
"merged": pr.HasMerged,
|
||||
"mergeable": pr.Mergeable,
|
||||
"html_url": pr.HTMLURL,
|
||||
"user": userLogin(pr.Poster),
|
||||
"labels": labelNames(pr.Labels),
|
||||
"comments": pr.Comments,
|
||||
"created_at": pr.Created,
|
||||
"updated_at": pr.Updated,
|
||||
"closed_at": pr.Closed,
|
||||
}
|
||||
if pr.HasMerged {
|
||||
m["merged_at"] = pr.Merged
|
||||
m["merge_commit_sha"] = pr.MergedCommitID
|
||||
m["merged_by"] = userLogin(pr.MergedBy)
|
||||
}
|
||||
if pr.Head != nil {
|
||||
head := map[string]any{"ref": pr.Head.Ref, "sha": pr.Head.Sha}
|
||||
if pr.Head.Repository != nil {
|
||||
head["repo"] = repoRef(pr.Head.Repository)
|
||||
}
|
||||
m["head"] = head
|
||||
}
|
||||
if pr.Base != nil {
|
||||
base := map[string]any{"ref": pr.Base.Ref, "sha": pr.Base.Sha}
|
||||
if pr.Base.Repository != nil {
|
||||
base["repo"] = repoRef(pr.Base.Repository)
|
||||
}
|
||||
m["base"] = base
|
||||
}
|
||||
if pr.Additions != nil {
|
||||
m["additions"] = *pr.Additions
|
||||
}
|
||||
if pr.Deletions != nil {
|
||||
m["deletions"] = *pr.Deletions
|
||||
}
|
||||
if pr.ChangedFiles != nil {
|
||||
m["changed_files"] = *pr.ChangedFiles
|
||||
}
|
||||
if len(pr.Assignees) > 0 {
|
||||
m["assignees"] = userLogins(pr.Assignees)
|
||||
}
|
||||
if pr.Milestone != nil {
|
||||
m["milestone"] = pr.Milestone.Title
|
||||
}
|
||||
if pr.ReviewComments > 0 {
|
||||
m["review_comments"] = pr.ReviewComments
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func slimPullRequests(prs []*gitea_sdk.PullRequest) []map[string]any {
|
||||
out := make([]map[string]any, 0, len(prs))
|
||||
for _, pr := range prs {
|
||||
if pr == nil {
|
||||
continue
|
||||
}
|
||||
m := map[string]any{
|
||||
"number": pr.Index,
|
||||
"title": pr.Title,
|
||||
"state": pr.State,
|
||||
"draft": pr.Draft,
|
||||
"merged": pr.HasMerged,
|
||||
"html_url": pr.HTMLURL,
|
||||
"user": userLogin(pr.Poster),
|
||||
"created_at": pr.Created,
|
||||
"updated_at": pr.Updated,
|
||||
}
|
||||
if pr.Head != nil {
|
||||
m["head"] = pr.Head.Ref
|
||||
}
|
||||
if pr.Base != nil {
|
||||
m["base"] = pr.Base.Ref
|
||||
}
|
||||
if len(pr.Labels) > 0 {
|
||||
m["labels"] = labelNames(pr.Labels)
|
||||
}
|
||||
out = append(out, m)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func slimReview(r *gitea_sdk.PullReview) map[string]any {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]any{
|
||||
"id": r.ID,
|
||||
"state": r.State,
|
||||
"body": r.Body,
|
||||
"user": userLogin(r.Reviewer),
|
||||
"comments_count": r.CodeCommentsCount,
|
||||
"submitted_at": r.Submitted,
|
||||
"html_url": r.HTMLURL,
|
||||
"stale": r.Stale,
|
||||
"official": r.Official,
|
||||
"dismissed": r.Dismissed,
|
||||
}
|
||||
}
|
||||
|
||||
func slimReviews(reviews []*gitea_sdk.PullReview) []map[string]any {
|
||||
out := make([]map[string]any, 0, len(reviews))
|
||||
for _, r := range reviews {
|
||||
out = append(out, slimReview(r))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func slimReviewComment(c *gitea_sdk.PullReviewComment) map[string]any {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]any{
|
||||
"id": c.ID,
|
||||
"body": c.Body,
|
||||
"path": c.Path,
|
||||
"position": c.LineNum,
|
||||
"old_position": c.OldLineNum,
|
||||
"diff_hunk": c.DiffHunk,
|
||||
"user": userLogin(c.Reviewer),
|
||||
"html_url": c.HTMLURL,
|
||||
"created_at": c.Created,
|
||||
"updated_at": c.Updated,
|
||||
}
|
||||
}
|
||||
|
||||
func slimReviewComments(comments []*gitea_sdk.PullReviewComment) []map[string]any {
|
||||
out := make([]map[string]any, 0, len(comments))
|
||||
for _, c := range comments {
|
||||
out = append(out, slimReviewComment(c))
|
||||
}
|
||||
return out
|
||||
}
|
||||
124
operation/pull/slim_test.go
Normal file
124
operation/pull/slim_test.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package pull
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
gitea_sdk "code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
func TestSlimPullRequest(t *testing.T) {
|
||||
now := time.Now()
|
||||
additions := 10
|
||||
deletions := 5
|
||||
changedFiles := 3
|
||||
pr := &gitea_sdk.PullRequest{
|
||||
Index: 1,
|
||||
Title: "Fix bug",
|
||||
Body: "Fixes #123",
|
||||
State: "open",
|
||||
Draft: false,
|
||||
HasMerged: false,
|
||||
Mergeable: true,
|
||||
HTMLURL: "https://gitea.com/org/repo/pulls/1",
|
||||
Poster: &gitea_sdk.User{UserName: "bob"},
|
||||
Labels: []*gitea_sdk.Label{
|
||||
{Name: "bug"},
|
||||
{Name: "priority"},
|
||||
},
|
||||
Comments: 2,
|
||||
Created: &now,
|
||||
Updated: &now,
|
||||
Additions: &additions,
|
||||
Deletions: &deletions,
|
||||
ChangedFiles: &changedFiles,
|
||||
Head: &gitea_sdk.PRBranchInfo{
|
||||
Ref: "fix-branch",
|
||||
Sha: "abc123",
|
||||
},
|
||||
Base: &gitea_sdk.PRBranchInfo{
|
||||
Ref: "main",
|
||||
Sha: "def456",
|
||||
},
|
||||
Assignees: []*gitea_sdk.User{
|
||||
{UserName: "alice"},
|
||||
},
|
||||
Milestone: &gitea_sdk.Milestone{Title: "v1.0"},
|
||||
}
|
||||
|
||||
m := slimPullRequest(pr)
|
||||
|
||||
if m["number"] != int64(1) {
|
||||
t.Errorf("expected number 1, got %v", m["number"])
|
||||
}
|
||||
if m["title"] != "Fix bug" {
|
||||
t.Errorf("expected title Fix bug, got %v", m["title"])
|
||||
}
|
||||
if m["user"] != "bob" {
|
||||
t.Errorf("expected user bob, got %v", m["user"])
|
||||
}
|
||||
if m["additions"] != 10 {
|
||||
t.Errorf("expected additions 10, got %v", m["additions"])
|
||||
}
|
||||
if m["milestone"] != "v1.0" {
|
||||
t.Errorf("expected milestone v1.0, got %v", m["milestone"])
|
||||
}
|
||||
|
||||
labels := m["labels"].([]string)
|
||||
if len(labels) != 2 || labels[0] != "bug" {
|
||||
t.Errorf("expected labels [bug priority], got %v", labels)
|
||||
}
|
||||
|
||||
head := m["head"].(map[string]any)
|
||||
if head["ref"] != "fix-branch" {
|
||||
t.Errorf("expected head ref fix-branch, got %v", head["ref"])
|
||||
}
|
||||
|
||||
assignees := m["assignees"].([]string)
|
||||
if len(assignees) != 1 || assignees[0] != "alice" {
|
||||
t.Errorf("expected assignees [alice], got %v", assignees)
|
||||
}
|
||||
|
||||
// merged fields should not be present for unmerged PR
|
||||
if _, ok := m["merged_at"]; ok {
|
||||
t.Error("merged_at should not be present for unmerged PR")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlimPullRequests_ListIsSlimmer(t *testing.T) {
|
||||
pr := &gitea_sdk.PullRequest{
|
||||
Index: 1,
|
||||
Title: "PR title",
|
||||
State: "open",
|
||||
HTMLURL: "https://gitea.com/org/repo/pulls/1",
|
||||
Poster: &gitea_sdk.User{UserName: "bob"},
|
||||
Body: "Full body text here",
|
||||
Head: &gitea_sdk.PRBranchInfo{Ref: "feature"},
|
||||
Base: &gitea_sdk.PRBranchInfo{Ref: "main"},
|
||||
}
|
||||
|
||||
single := slimPullRequest(pr)
|
||||
list := slimPullRequests([]*gitea_sdk.PullRequest{pr})
|
||||
|
||||
// Single has body, list does not
|
||||
if _, ok := single["body"]; !ok {
|
||||
t.Error("single PR should have body")
|
||||
}
|
||||
if _, ok := list[0]["body"]; ok {
|
||||
t.Error("list PR should not have body")
|
||||
}
|
||||
|
||||
// List has head as string ref, single has head as map
|
||||
if _, ok := single["head"].(map[string]any); !ok {
|
||||
t.Error("single PR head should be a map")
|
||||
}
|
||||
if list[0]["head"] != "feature" {
|
||||
t.Errorf("list PR head should be string ref, got %v", list[0]["head"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlimPullRequests_Nil(t *testing.T) {
|
||||
if r := slimPullRequests(nil); len(r) != 0 {
|
||||
t.Errorf("expected empty slice, got %v", r)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user