added branch params to PR list API (#119)

This commit is contained in:
Marko Gaćeša 2022-12-09 15:45:02 +01:00 committed by GitHub
parent a0646e9935
commit 6bde210adf
7 changed files with 123 additions and 18 deletions

View File

@ -49,6 +49,10 @@ func NewController(
} }
func (c *Controller) verifyBranchExistence(ctx context.Context, repo *types.Repository, branch string) error { func (c *Controller) verifyBranchExistence(ctx context.Context, repo *types.Repository, branch string) error {
if branch == "" {
return usererror.BadRequest("branch name can't be empty")
}
_, err := c.gitRPCClient.GetRef(ctx, _, err := c.gitRPCClient.GetRef(ctx,
&gitrpc.GetRefParams{RepoUID: repo.GitUID, Name: branch, Type: gitrpc.RefTypeBranch}) &gitrpc.GetRefParams{RepoUID: repo.GitUID, Name: branch, Type: gitrpc.RefTypeBranch})
if errors.Is(err, gitrpc.ErrNotFound) { if errors.Is(err, gitrpc.ErrNotFound) {

View File

@ -6,6 +6,7 @@ package pullreq
import ( import (
"context" "context"
"fmt"
"time" "time"
"github.com/harness/gitness/internal/api/usererror" "github.com/harness/gitness/internal/api/usererror"
@ -60,6 +61,21 @@ func (c *Controller) Create(
var pr *types.PullReq var pr *types.PullReq
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) error { err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) error {
var existing int64
existing, err = c.pullreqStore.Count(ctx, targetRepo.ID, &types.PullReqFilter{
SourceRepoID: sourceRepo.ID,
SourceBranch: in.SourceBranch,
TargetBranch: in.TargetBranch,
States: []enum.PullReqState{enum.PullReqStateOpen},
})
if err != nil {
return fmt.Errorf("failed to count existing pull requests: %w", err)
}
if existing > 0 {
return usererror.BadRequest("a pull request for this target and source branch already exists")
}
var lastNumber int64 var lastNumber int64
lastNumber, err = c.pullreqStore.LastNumber(ctx, targetRepo.ID) lastNumber, err = c.pullreqStore.LastNumber(ctx, targetRepo.ID)

View File

@ -24,5 +24,16 @@ func (c *Controller) List(
return nil, err return nil, err
} }
if filter.SourceRepoRef == repoRef {
filter.SourceRepoID = repo.ID
} else if filter.SourceRepoRef != "" {
var sourceRepo *types.Repository
sourceRepo, err = c.getRepoCheckAccess(ctx, session, filter.SourceRepoRef, enum.PermissionRepoView)
if err != nil {
return nil, err
}
filter.SourceRepoID = sourceRepo.ID
}
return c.pullreqStore.List(ctx, repo.ID, filter) return c.pullreqStore.List(ctx, repo.ID, filter)
} }

View File

@ -28,7 +28,7 @@ type listPullReqRequest struct {
type pullReqRequest struct { type pullReqRequest struct {
repoRequest repoRequest
ID int64 `path:"pullreqNumber"` ID int64 `path:"pullreq_number"`
} }
type getPullReqRequest struct { type getPullReqRequest struct {
@ -49,6 +49,48 @@ var queryParameterQueryPullRequest = openapi3.ParameterOrRef{
}, },
} }
var queryParameterSourceRepoRefPullRequest = openapi3.ParameterOrRef{
Parameter: &openapi3.Parameter{
Name: "source_repo_ref",
In: openapi3.ParameterInQuery,
Description: ptr.String("Source repository ref of the pull requests."),
Required: ptr.Bool(false),
Schema: &openapi3.SchemaOrRef{
Schema: &openapi3.Schema{
Type: ptrSchemaType(openapi3.SchemaTypeString),
},
},
},
}
var queryParameterSourceBranchPullRequest = openapi3.ParameterOrRef{
Parameter: &openapi3.Parameter{
Name: "source_branch",
In: openapi3.ParameterInQuery,
Description: ptr.String("Source branch of the pull requests."),
Required: ptr.Bool(false),
Schema: &openapi3.SchemaOrRef{
Schema: &openapi3.Schema{
Type: ptrSchemaType(openapi3.SchemaTypeString),
},
},
},
}
var queryParameterTargetBranchPullRequest = openapi3.ParameterOrRef{
Parameter: &openapi3.Parameter{
Name: "target_branch",
In: openapi3.ParameterInQuery,
Description: ptr.String("Target branch of the pull requests."),
Required: ptr.Bool(false),
Schema: &openapi3.SchemaOrRef{
Schema: &openapi3.Schema{
Type: ptrSchemaType(openapi3.SchemaTypeString),
},
},
},
}
var queryParameterCreatedByPullRequest = openapi3.ParameterOrRef{ var queryParameterCreatedByPullRequest = openapi3.ParameterOrRef{
Parameter: &openapi3.Parameter{ Parameter: &openapi3.Parameter{
Name: request.QueryParamCreatedBy, Name: request.QueryParamCreatedBy,
@ -125,7 +167,8 @@ func pullReqOperations(reflector *openapi3.Reflector) {
listPullReq.WithTags("pullreq") listPullReq.WithTags("pullreq")
listPullReq.WithMapOfAnything(map[string]interface{}{"operationId": "listPullReq"}) listPullReq.WithMapOfAnything(map[string]interface{}{"operationId": "listPullReq"})
listPullReq.WithParameters( listPullReq.WithParameters(
queryParameterStatePullRequest, queryParameterStatePullRequest, queryParameterSourceRepoRefPullRequest,
queryParameterSourceBranchPullRequest, queryParameterTargetBranchPullRequest,
queryParameterQueryPullRequest, queryParameterCreatedByPullRequest, queryParameterQueryPullRequest, queryParameterCreatedByPullRequest,
queryParameterDirection, queryParameterSortPullRequest, queryParameterDirection, queryParameterSortPullRequest,
queryParameterPage, queryParameterPerPage) queryParameterPage, queryParameterPerPage)
@ -146,5 +189,5 @@ func pullReqOperations(reflector *openapi3.Reflector) {
_ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusInternalServerError) _ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusInternalServerError)
_ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusUnauthorized) _ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusUnauthorized)
_ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusForbidden) _ = reflector.SetJSONResponse(&getPullReq, new(usererror.Error), http.StatusForbidden)
_ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repoRef}/pullreq/{pullreqNumber}", getPullReq) _ = reflector.Spec.AddOperation(http.MethodGet, "/repos/{repoRef}/pullreq/{pullreq_number}", getPullReq)
} }

View File

@ -12,7 +12,7 @@ import (
) )
const ( const (
PathParamPullReqNumber = "pullreqNumber" PathParamPullReqNumber = "pullreq_number"
) )
func GetPullReqNumberFromPath(r *http.Request) (int64, error) { func GetPullReqNumberFromPath(r *http.Request) (int64, error) {
@ -58,12 +58,15 @@ func ParsePullReqFilter(r *http.Request) (*types.PullReqFilter, error) {
return nil, err return nil, err
} }
return &types.PullReqFilter{ return &types.PullReqFilter{
Page: ParsePage(r), Page: ParsePage(r),
Size: ParseSize(r), Size: ParseSize(r),
Query: ParseQuery(r), Query: ParseQuery(r),
CreatedBy: createdBy, CreatedBy: createdBy,
States: ParsePullReqStates(r), SourceRepoRef: r.FormValue("source_repo_ref"),
Sort: ParseSortPullReq(r), SourceBranch: r.FormValue("source_branch"),
Order: ParseOrder(r), TargetBranch: r.FormValue("target_branch"),
States: ParsePullReqStates(r),
Sort: ParseSortPullReq(r),
Order: ParseOrder(r),
}, nil }, nil
} }

View File

@ -245,6 +245,18 @@ func (s *PullReqStore) Count(ctx context.Context, repoID int64, opts *types.Pull
stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States}) stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States})
} }
if opts.SourceRepoID != 0 {
stmt = stmt.Where("pullreq_source_repo_id = ?", opts.SourceRepoID)
}
if opts.SourceBranch != "" {
stmt = stmt.Where("pullreq_source_branch = ?", opts.SourceBranch)
}
if opts.TargetBranch != "" {
stmt = stmt.Where("pullreq_target_branch = ?", opts.TargetBranch)
}
if opts.CreatedBy != 0 { if opts.CreatedBy != 0 {
stmt = stmt.Where("pullreq_created_by = ?", opts.CreatedBy) stmt = stmt.Where("pullreq_created_by = ?", opts.CreatedBy)
} }
@ -280,6 +292,18 @@ func (s *PullReqStore) List(ctx context.Context, repoID int64, opts *types.PullR
stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States}) stmt = stmt.Where(squirrel.Eq{"pullreq_state": opts.States})
} }
if opts.SourceRepoID != 0 {
stmt = stmt.Where("pullreq_source_repo_id = ?", opts.SourceRepoID)
}
if opts.SourceBranch != "" {
stmt = stmt.Where("pullreq_source_branch = ?", opts.SourceBranch)
}
if opts.TargetBranch != "" {
stmt = stmt.Where("pullreq_target_branch = ?", opts.TargetBranch)
}
if opts.Query != "" { if opts.Query != "" {
stmt = stmt.Where("pullreq_title LIKE ?", "%"+opts.Query+"%") stmt = stmt.Where("pullreq_title LIKE ?", "%"+opts.Query+"%")
} }

View File

@ -36,11 +36,15 @@ type PullReq struct {
// PullReqFilter stores pull request query parameters. // PullReqFilter stores pull request query parameters.
type PullReqFilter struct { type PullReqFilter struct {
Page int `json:"page"` Page int `json:"page"`
Size int `json:"size"` Size int `json:"size"`
Query string `json:"query"` Query string `json:"query"`
CreatedBy int64 `json:"created_by"` CreatedBy int64 `json:"created_by"`
States []enum.PullReqState `json:"state"` SourceRepoID int64 `json:"-"` // caller should use source_repo_ref
Sort enum.PullReqSort `json:"sort"` SourceRepoRef string `json:"source_repo_ref"`
Order enum.Order `json:"direction"` SourceBranch string `json:"source_branch"`
TargetBranch string `json:"target_branch"`
States []enum.PullReqState `json:"state"`
Sort enum.PullReqSort `json:"sort"`
Order enum.Order `json:"direction"`
} }