diff --git a/.vscode/settings.json b/.vscode/settings.json index 8045a222a..ff3e9e5e3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,7 @@ "previewLimit": 50, "driver": "SQLite", "name": "gitness", - "database": "${workspaceFolder:gitness}/database.sqlite3" + "database": "${workspaceFolder:gitness}/cmd/gitness/database.sqlite3" } ] } \ No newline at end of file diff --git a/cli/server/harness.wire_gen.go b/cli/server/harness.wire_gen.go index 7c9bcbcc5..af8002d58 100644 --- a/cli/server/harness.wire_gen.go +++ b/cli/server/harness.wire_gen.go @@ -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" diff --git a/internal/api/controller/pullreq/metadata.go b/internal/api/controller/pullreq/metadata.go deleted file mode 100644 index 6326b860b..000000000 --- a/internal/api/controller/pullreq/metadata.go +++ /dev/null @@ -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 -} diff --git a/internal/api/controller/pullreq/pr_find.go b/internal/api/controller/pullreq/pr_find.go index 90547790d..b5ae9aea2 100644 --- a/internal/api/controller/pullreq/pr_find.go +++ b/internal/api/controller/pullreq/pr_find.go @@ -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 } diff --git a/internal/api/handler/pullreq/metadata.go b/internal/api/handler/pullreq/metadata.go deleted file mode 100644 index 0b1acb76e..000000000 --- a/internal/api/handler/pullreq/metadata.go +++ /dev/null @@ -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) - } -} diff --git a/internal/router/api.go b/internal/router/api.go index 3b724ae26..66eae2409 100644 --- a/internal/router/api.go +++ b/internal/router/api.go @@ -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)) }) }) } diff --git a/mocks/mock_client.go b/mocks/mock_client.go index 3216e04cb..fbd985bd4 100644 --- a/mocks/mock_client.go +++ b/mocks/mock_client.go @@ -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. diff --git a/mocks/mock_store.go b/mocks/mock_store.go index 30b7ec550..8ad9973bf 100644 --- a/mocks/mock_store.go +++ b/mocks/mock_store.go @@ -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. diff --git a/types/pullreq.go b/types/pullreq.go index 2dcb82443..6b6ea4774 100644 --- a/types/pullreq.go +++ b/types/pullreq.go @@ -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"` -}