1
0
mirror of https://github.com/harness/drone.git synced 2025-04-27 21:23:39 +00:00

[maint] pr statistic is in pr response now ()

This commit is contained in:
Enver Bisevac 2023-01-31 15:21:05 +01:00 committed by GitHub
parent ce322ec596
commit e2b350e704
9 changed files with 117 additions and 170 deletions
.vscode
cli/server
internal
api
controller/pullreq
handler/pullreq
router
mocks
types

@ -6,7 +6,7 @@
"previewLimit": 50,
"driver": "SQLite",
"name": "gitness",
"database": "${workspaceFolder:gitness}/database.sqlite3"
"database": "${workspaceFolder:gitness}/cmd/gitness/database.sqlite3"
}
]
}

@ -7,6 +7,7 @@ package server
import (
"context"
"github.com/harness/gitness/events"
"github.com/harness/gitness/gitrpc"
server2 "github.com/harness/gitness/gitrpc/server"

@ -1,116 +0,0 @@
// Copyright 2022 Harness Inc. All rights reserved.
// Use of this source code is governed by the Polyform Free Trial License
// that can be found in the LICENSE.md file for this repository.
package pullreq
import (
"context"
"fmt"
"github.com/harness/gitness/gitrpc"
"github.com/harness/gitness/internal/auth"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"golang.org/x/sync/errgroup"
)
func (c *Controller) GetMetaData(
ctx context.Context,
session *auth.Session,
repoRef string,
pullreqNum int64,
) (types.PullReqMetaData, error) {
// declare variables which will be used in go routines,
// no need for atomic operations because writing and reading variable
// doesn't happen at the same time
var (
totalConvs int64
totalCommits int
totalFiles int
)
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView)
if err != nil {
return types.PullReqMetaData{}, fmt.Errorf("failed to acquire access to target repo: %w", err)
}
pr, err := c.pullreqStore.FindByNumber(ctx, repo.ID, pullreqNum)
if err != nil {
return types.PullReqMetaData{}, fmt.Errorf("failed to get pull request by number: %w", err)
}
gitRef := pr.SourceBranch
afterRef := pr.TargetBranch
if pr.State == enum.PullReqStateMerged {
gitRef = *pr.MergeHeadSHA
afterRef = *pr.MergeBaseSHA
}
errGroup, groupCtx := errgroup.WithContext(ctx)
errGroup.Go(func() error {
// return conversations
var errStore error
filter := &types.PullReqActivityFilter{
Types: []enum.PullReqActivityType{
enum.PullReqActivityTypeComment,
enum.PullReqActivityTypeCodeComment,
},
}
totalConvs, errStore = c.activityStore.Count(groupCtx, pr.ID, filter)
if errStore != nil {
return fmt.Errorf("failed to count pull request comments: %w", errStore)
}
return nil
})
errGroup.Go(func() error {
// read total commits
options := &gitrpc.GetCommitDivergencesParams{
ReadParams: gitrpc.CreateRPCReadParams(repo),
Requests: []gitrpc.CommitDivergenceRequest{
{
From: gitRef,
To: afterRef,
},
},
}
rpcOutput, errGit := c.gitRPCClient.GetCommitDivergences(groupCtx, options)
if errGit != nil {
return fmt.Errorf("failed to count pull request commits: %w", errGit)
}
if len(rpcOutput.Divergences) > 0 {
totalCommits = int(rpcOutput.Divergences[0].Ahead)
}
return nil
})
errGroup.Go(func() error {
// read short stat
stat, errGit := c.gitRPCClient.DiffShortStat(groupCtx, &gitrpc.DiffParams{
ReadParams: gitrpc.CreateRPCReadParams(repo),
BaseRef: afterRef,
HeadRef: gitRef,
MergeBase: true,
})
if errGit != nil {
return fmt.Errorf("failed to count pull request file changes: %w", errGit)
}
totalFiles = stat.Files
return nil
})
err = errGroup.Wait()
if err != nil {
return types.PullReqMetaData{}, err
}
return types.PullReqMetaData{
Conversations: totalConvs,
Commits: totalCommits,
FilesChanged: totalFiles,
}, nil
}

@ -8,10 +8,13 @@ import (
"context"
"fmt"
"github.com/harness/gitness/gitrpc"
"github.com/harness/gitness/internal/api/usererror"
"github.com/harness/gitness/internal/auth"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"golang.org/x/sync/errgroup"
)
// Find returns a pull request from the provided repository.
@ -30,5 +33,103 @@ func (c *Controller) Find(
return nil, fmt.Errorf("failed to acquire access to the repo: %w", err)
}
return c.pullreqStore.FindByNumber(ctx, repo.ID, pullreqNum)
pr, err := c.pullreqStore.FindByNumber(ctx, repo.ID, pullreqNum)
if err != nil {
return nil, err
}
pr.Stats, err = c.getStats(ctx, repo, pr)
if err != nil {
return nil, err
}
return pr, nil
}
func (c *Controller) getStats(
ctx context.Context,
repo *types.Repository,
pr *types.PullReq,
) (types.PullReqStats, error) {
// declare variables which will be used in go routines,
// no need for atomic operations because writing and reading variable
// doesn't happen at the same time
var (
totalConvs int64
totalCommits int
totalFiles int
)
gitRef := pr.SourceBranch
afterRef := pr.TargetBranch
if pr.State == enum.PullReqStateMerged {
gitRef = *pr.MergeHeadSHA
afterRef = *pr.MergeBaseSHA
}
errGroup, groupCtx := errgroup.WithContext(ctx)
errGroup.Go(func() error {
// return conversations
var err error
filter := &types.PullReqActivityFilter{
Types: []enum.PullReqActivityType{
enum.PullReqActivityTypeComment,
enum.PullReqActivityTypeCodeComment,
},
}
totalConvs, err = c.activityStore.Count(groupCtx, pr.ID, filter)
if err != nil {
return fmt.Errorf("failed to count pull request comments: %w", err)
}
return nil
})
errGroup.Go(func() error {
// read total commits
options := &gitrpc.GetCommitDivergencesParams{
ReadParams: gitrpc.CreateRPCReadParams(repo),
Requests: []gitrpc.CommitDivergenceRequest{
{
From: gitRef,
To: afterRef,
},
},
}
rpcOutput, err := c.gitRPCClient.GetCommitDivergences(groupCtx, options)
if err != nil {
return fmt.Errorf("failed to count pull request commits: %w", err)
}
if len(rpcOutput.Divergences) > 0 {
totalCommits = int(rpcOutput.Divergences[0].Ahead)
}
return nil
})
errGroup.Go(func() error {
// read short stat
stat, err := c.gitRPCClient.DiffShortStat(groupCtx, &gitrpc.DiffParams{
ReadParams: gitrpc.CreateRPCReadParams(repo),
BaseRef: afterRef,
HeadRef: gitRef,
MergeBase: true,
})
if err != nil {
return fmt.Errorf("failed to count pull request file changes: %w", err)
}
totalFiles = stat.Files
return nil
})
err := errGroup.Wait()
if err != nil {
return types.PullReqStats{}, err
}
return types.PullReqStats{
Conversations: totalConvs,
Commits: totalCommits,
FilesChanged: totalFiles,
}, nil
}

@ -1,41 +0,0 @@
// Copyright 2022 Harness Inc. All rights reserved.
// Use of this source code is governed by the Polyform Free Trial License
// that can be found in the LICENSE.md file for this repository.
package pullreq
import (
"net/http"
"github.com/harness/gitness/internal/api/controller/pullreq"
"github.com/harness/gitness/internal/api/render"
"github.com/harness/gitness/internal/api/request"
)
// HandleMetaData returns a http.HandlerFunc that fethch pr meta information.
func HandleMetaData(pullreqCtrl *pullreq.Controller) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session, _ := request.AuthSessionFrom(ctx)
repoRef, err := request.GetRepoRefFromPath(r)
if err != nil {
render.TranslatedUserError(w, err)
return
}
pullreqNumber, err := request.GetPullReqNumberFromPath(r)
if err != nil {
render.TranslatedUserError(w, err)
return
}
metadata, err := pullreqCtrl.GetMetaData(ctx, session, repoRef, pullreqNumber)
if err != nil {
render.TranslatedUserError(w, err)
return
}
render.JSON(w, http.StatusOK, metadata)
}
}

@ -251,7 +251,6 @@ func SetupPullReq(r chi.Router, pullreqCtrl *pullreq.Controller) {
r.Post("/merge", handlerpullreq.HandleMerge(pullreqCtrl))
r.Get("/diff", handlerpullreq.HandleRawDiff(pullreqCtrl))
r.Get("/commits", handlerpullreq.HandleCommits(pullreqCtrl))
r.Get("/metadata", handlerpullreq.HandleMetaData(pullreqCtrl))
})
})
}

@ -8,9 +8,10 @@ import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
user "github.com/harness/gitness/internal/api/controller/user"
types "github.com/harness/gitness/types"
gomock "github.com/golang/mock/gomock"
)
// MockClient is a mock of Client interface.

@ -8,9 +8,10 @@ import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
types "github.com/harness/gitness/types"
enum "github.com/harness/gitness/types/enum"
gomock "github.com/golang/mock/gomock"
)
// MockPrincipalStore is a mock of PrincipalStore interface.

@ -40,6 +40,15 @@ type PullReq struct {
Author PrincipalInfo `json:"author"`
Merger *PrincipalInfo `json:"merger"`
Stats PullReqStats `json:"stats"`
}
// PullReqStats shows total number of conversations,
// commits and how many files modified.
type PullReqStats struct {
Conversations int64 `json:"conversations"`
Commits int `json:"commits"`
FilesChanged int `json:"files_changed"`
}
// PullReqFilter stores pull request query parameters.
@ -95,11 +104,3 @@ type PullReqReviewer struct {
type MergeResponse struct {
SHA string
}
// PullReqMetaData shows total number of conversations,
// commits and how many files modified.
type PullReqMetaData struct {
Conversations int64 `json:"conversations"`
Commits int `json:"commits"`
FilesChanged int `json:"files_changed"`
}