Add additions and deletions stats to commit file response (#1015)

eb/code-1016-2
Darko Draskovic 2024-02-07 16:07:53 +00:00 committed by Harness
parent e3bf017f78
commit d96afd89bd
6 changed files with 116 additions and 4 deletions

View File

@ -160,5 +160,6 @@ func (c *Controller) CommitFiles(ctx context.Context,
return types.CommitFilesResponse{
CommitID: commit.CommitID,
RuleViolations: violations,
Stats: commit.Stats,
}, nil, nil
}

View File

@ -60,7 +60,8 @@ func (c *Controller) Export(ctx context.Context, session *auth.Session, spaceRef
var repos []*types.Repository
page := 1
for {
reposInPage, err := c.repoStore.List(ctx, space.ID, &types.RepoFilter{Size: 200, Page: page, Order: enum.OrderDesc})
reposInPage, err := c.repoStore.List(
ctx, space.ID, &types.RepoFilter{Size: 200, Page: page, Order: enum.OrderDesc})
if err != nil {
return err
}

View File

@ -20,9 +20,12 @@ import (
"context"
"fmt"
"io"
"regexp"
"strconv"
"sync"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git/command"
"github.com/harness/gitness/git/diff"
"github.com/harness/gitness/git/enum"
"github.com/harness/gitness/git/types"
@ -30,6 +33,26 @@ import (
"golang.org/x/sync/errgroup"
)
// Parse "1 file changed, 3 insertions(+), 3 deletions(-)" for nums.
var shortStatsRegexp = regexp.MustCompile(
`files? changed(?:, (\d+) insertions?\(\+\))?(?:, (\d+) deletions?\(-\))?`)
type CommitShortStatParams struct {
Path string
Ref string
}
func (p CommitShortStatParams) Validate() error {
if p.Path == "" {
return errors.InvalidArgument("path cannot be empty")
}
if p.Ref == "" {
return errors.InvalidArgument("ref cannot be empty")
}
return nil
}
type DiffParams struct {
ReadParams
BaseRef string
@ -177,6 +200,69 @@ func (s *Service) DiffStats(ctx context.Context, params *DiffParams) (DiffStatsO
}, nil
}
func parseCommitShortStat(statBuffer *bytes.Buffer) (CommitShortStatOutput, error) {
matches := shortStatsRegexp.FindStringSubmatch(statBuffer.String())
if len(matches) != 3 {
return CommitShortStatOutput{}, errors.Internal(errors.New("failed to match stats line"), "")
}
var stat CommitShortStatOutput
// if there are insertions; no insertions case: "1 file changed, 3 deletions(-)"
if len(matches[1]) > 0 {
if value, err := strconv.Atoi(matches[1]); err == nil {
stat.Additions = value
} else {
return CommitShortStatOutput{}, fmt.Errorf("failed to parse additions stats: %w", err)
}
}
// if there are deletions; no deletions case: "1 file changed, 3 insertions(+)"
if len(matches[2]) > 0 {
if value, err := strconv.Atoi(matches[2]); err == nil {
stat.Deletions = value
} else {
return CommitShortStatOutput{}, fmt.Errorf("failed to parse deletions stats: %w", err)
}
}
return stat, nil
}
type CommitShortStatOutput struct {
Additions int
Deletions int
}
func (s *Service) CommitShortStat(
ctx context.Context,
params *CommitShortStatParams,
) (CommitShortStatOutput, error) {
if err := params.Validate(); err != nil {
return CommitShortStatOutput{}, err
}
// git log -1 --shortstat --pretty=format:""
cmd := command.New(
"log",
command.WithFlag("-1"),
command.WithFlag("--shortstat"),
command.WithFlag(`--pretty=format:""`),
command.WithArg(params.Ref),
)
stdout := bytes.NewBuffer(nil)
if err := cmd.Run(ctx, command.WithDir(params.Path), command.WithStdout(stdout)); err != nil {
return CommitShortStatOutput{}, errors.Internal(err, "failed to show stats")
}
stat, err := parseCommitShortStat(stdout)
if err != nil {
return CommitShortStatOutput{}, errors.Internal(err, "failed to parse stats line")
}
return stat, nil
}
type GetDiffHunkHeadersParams struct {
ReadParams
SourceCommitSHA string

View File

@ -74,6 +74,7 @@ type Interface interface {
CommitDiff(ctx context.Context, params *GetCommitParams, w io.Writer) error
DiffShortStat(ctx context.Context, params *DiffParams) (DiffShortStatOutput, error)
DiffStats(ctx context.Context, params *DiffParams) (DiffStatsOutput, error)
CommitShortStat(ctx context.Context, params *CommitShortStatParams) (CommitShortStatOutput, error)
GetDiffHunkHeaders(ctx context.Context, params GetDiffHunkHeadersParams) (GetDiffHunkHeadersOutput, error)
DiffCut(ctx context.Context, params *DiffCutParams) (DiffCutOutput, error)

View File

@ -87,7 +87,14 @@ func (p *CommitFilesParams) Validate() error {
return p.WriteParams.Validate()
}
type CommitFileStat struct {
Total int
Additions int
Deletions int
}
type CommitFilesResponse struct {
Stats CommitFileStat
CommitID string
}
@ -235,6 +242,14 @@ func (s *Service) CommitFiles(ctx context.Context, params *CommitFilesParams) (C
log.Debug().Msg("update ref")
stats, err := s.CommitShortStat(ctx, &CommitShortStatParams{
Path: repo.Path,
Ref: newCommitSHA,
})
if err != nil {
return CommitFilesResponse{}, fmt.Errorf("failed to get diff stats: %w", err)
}
branchRef := adapter.GetReferenceFromBranchName(params.Branch)
if params.Branch != params.NewBranch {
// we are creating a new branch, rather than updating the existing one
@ -264,6 +279,11 @@ func (s *Service) CommitFiles(ctx context.Context, params *CommitFilesParams) (C
return CommitFilesResponse{
CommitID: commit.ID.String(),
Stats: CommitFileStat{
Total: stats.Additions + stats.Deletions,
Additions: stats.Additions,
Deletions: stats.Deletions,
},
}, nil
}

View File

@ -14,9 +14,12 @@
package types
import "github.com/harness/gitness/git"
// CommitFilesResponse holds commit id.
type CommitFilesResponse struct {
DryRunRules bool `json:"dry_run_rules,omitempty"`
CommitID string `json:"commit_id"`
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
DryRunRules bool `json:"dry_run_rules,omitempty"`
CommitID string `json:"commit_id"`
RuleViolations []RuleViolations `json:"rule_violations,omitempty"`
Stats git.CommitFileStat `json:"stats,omitempty"`
}