feat: [CODE-3450]: add pullreq count API (#3624)

* add pullreq count API
main
Marko Gaćeša 2025-04-04 10:46:19 +00:00 committed by Harness
parent 80112d19fe
commit 28f012c577
5 changed files with 151 additions and 0 deletions

View File

@ -0,0 +1,45 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package space
import (
"context"
"fmt"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
// CountPullReqs returns the number of pull requests from the provided space that matches the criteria.
func (c *Controller) CountPullReqs(
ctx context.Context,
session *auth.Session,
spaceRef string,
includeSubspaces bool,
filter *types.PullReqFilter,
) (int64, error) {
space, err := c.getSpaceCheckAuth(ctx, session, spaceRef, enum.PermissionSpaceView)
if err != nil {
return 0, fmt.Errorf("failed to acquire access to space: %w", err)
}
count, err := c.prListService.CountForSpace(ctx, space, includeSubspaces, filter)
if err != nil {
return 0, fmt.Errorf("failed to fetch pull requests from space: %w", err)
}
return count, nil
}

View File

@ -0,0 +1,55 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package space
import (
"net/http"
"github.com/harness/gitness/app/api/controller/space"
"github.com/harness/gitness/app/api/render"
"github.com/harness/gitness/app/api/request"
)
func HandleCountPullReqs(spaceCtrl *space.Controller) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session, _ := request.AuthSessionFrom(ctx)
spaceRef, err := request.GetSpaceRefFromPath(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
includeSubspaces, err := request.GetIncludeSubspacesFromQuery(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
pullReqFilter, err := request.ParsePullReqFilter(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
count, err := spaceCtrl.CountPullReqs(ctx, session, spaceRef, includeSubspaces, pullReqFilter)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
render.JSON(w, http.StatusOK, count)
}
}

View File

@ -679,6 +679,26 @@ func spaceOperations(reflector *openapi3.Reflector) {
_ = reflector.Spec.AddOperation(http.MethodPatch,
"/spaces/{space_ref}/labels/{key}/values/{value}", opUpdateLabelValue)
countPullReq := openapi3.Operation{}
countPullReq.WithTags("space")
countPullReq.WithMapOfAnything(map[string]interface{}{"operationId": "countSpacePullReq"})
countPullReq.WithParameters(
queryParameterStatePullRequest, queryParameterSourceRepoRefPullRequest,
queryParameterSourceBranchPullRequest, queryParameterTargetBranchPullRequest,
queryParameterQueryPullRequest, queryParameterCreatedByPullRequest,
queryParameterCreatedLt, queryParameterCreatedGt, queryParameterUpdatedLt,
queryParameterIncludeSubspaces,
QueryParameterLabelID, QueryParameterValueID,
queryParameterAuthorID, queryParameterCommenterID, queryParameterMentionedID,
queryParameterReviewerID, queryParameterReviewDecision)
_ = reflector.SetRequest(&countPullReq, new(spaceRequest), http.MethodGet)
_ = reflector.SetJSONResponse(&countPullReq, new([]types.PullReqRepo), http.StatusOK)
_ = reflector.SetJSONResponse(&countPullReq, new(usererror.Error), http.StatusBadRequest)
_ = reflector.SetJSONResponse(&countPullReq, new(usererror.Error), http.StatusInternalServerError)
_ = reflector.SetJSONResponse(&countPullReq, new(usererror.Error), http.StatusUnauthorized)
_ = reflector.SetJSONResponse(&countPullReq, new(usererror.Error), http.StatusForbidden)
_ = reflector.Spec.AddOperation(http.MethodGet, "/spaces/{space_ref}/pullreq/count", countPullReq)
listPullReq := openapi3.Operation{}
listPullReq.WithTags("space")
listPullReq.WithMapOfAnything(map[string]interface{}{"operationId": "listSpacePullReq"})

View File

@ -277,6 +277,7 @@ func setupSpaces(
r.Get("/export-progress", handlerspace.HandleExportProgress(spaceCtrl))
r.Post("/public-access", handlerspace.HandleUpdatePublicAccess(spaceCtrl))
r.Get("/pullreq", handlerspace.HandleListPullReqs(spaceCtrl))
r.Get("/pullreq/count", handlerspace.HandleCountPullReqs(spaceCtrl))
r.Route("/members", func(r chi.Router) {
r.Get("/", handlerspace.HandleMembershipList(spaceCtrl))

View File

@ -72,6 +72,36 @@ func NewListService(
}
}
// CountForSpace returns number of pull requests in a specific space (and optionally in subspaces).
// The API doesn't do a permission check for repositories.
func (c *ListService) CountForSpace(
ctx context.Context,
space *types.SpaceCore,
includeSubspaces bool,
filter *types.PullReqFilter,
) (int64, error) {
if includeSubspaces {
subspaces, err := c.spaceStore.GetDescendantsData(ctx, space.ID)
if err != nil {
return 0, fmt.Errorf("failed to get space descendant data: %w", err)
}
filter.SpaceIDs = make([]int64, 0, len(subspaces))
for i := range subspaces {
filter.SpaceIDs = append(filter.SpaceIDs, subspaces[i].ID)
}
} else {
filter.SpaceIDs = []int64{space.ID}
}
count, err := c.pullreqStore.Count(ctx, filter)
if err != nil {
return 0, fmt.Errorf("failed to count pull requests: %w", err)
}
return count, nil
}
// ListForSpace returns a list of pull requests and their respective repositories for a specific space.
//
//nolint:gocognit