feat: [code-2984]: fix datarace on branch and tag counts, improved cmd package with mutex (#3202)

* requested changes
* fix datarace on beanch and tag counts, improved cmd package with mux
BT-10437
Enver Biševac 2024-12-25 13:22:48 +00:00 committed by Harness
parent 2b959817d5
commit 0a042b66e5
3 changed files with 36 additions and 20 deletions

View File

@ -131,25 +131,29 @@ func (g *Git) GetBranchCount(
command.WithFlag("--format=%(refname:short)"),
)
var err error
go func() {
defer pipeIn.Close()
err = cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(pipeIn))
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(pipeIn))
if err != nil {
_ = pipeIn.CloseWithError(
processGitErrorf(err, "failed to trigger branch command"),
)
return
}
_ = pipeIn.Close()
}()
if err != nil {
return 0, processGitErrorf(err, "failed to trigger branch command")
}
return countLines(pipeOut), nil
return countLines(pipeOut)
}
func countLines(pipe io.Reader) int {
func countLines(pipe io.Reader) (int, error) {
scanner := bufio.NewScanner(pipe)
count := 0
for scanner.Scan() {
count++
}
return count
if err := scanner.Err(); err != nil {
return 0, err
}
return count, nil
}

View File

@ -412,14 +412,16 @@ func (g *Git) GetTagCount(
cmd := command.New("tag")
var err error
go func() {
defer pipeIn.Close()
err = cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(pipeIn))
err := cmd.Run(ctx, command.WithDir(repoPath), command.WithStdout(pipeIn))
if err != nil {
_ = pipeIn.CloseWithError(
processGitErrorf(err, "failed to trigger tag command"),
)
return
}
_ = pipeIn.Close()
}()
if err != nil {
return 0, processGitErrorf(err, "failed to trigger branch command")
}
return countLines(pipeOut), nil
return countLines(pipeOut)
}

View File

@ -22,6 +22,7 @@ import (
"io"
"os/exec"
"regexp"
"sync"
)
var (
@ -65,6 +66,8 @@ type Command struct {
// internal counter for GIT_CONFIG_COUNT environment variable.
// more info: [link](https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT)
configEnvCounter int
mux sync.RWMutex
}
// New creates new command for interacting with the git process.
@ -74,15 +77,16 @@ func New(name string, options ...CmdOptionFunc) *Command {
Envs: make(Envs),
}
for _, opt := range options {
opt(c)
}
c.Add(options...)
return c
}
// Clone clones the command object.
func (c *Command) Clone() *Command {
c.mux.RLock()
defer c.mux.RUnlock()
globals := make([]string, len(c.Globals))
copy(globals, c.Globals)
@ -113,6 +117,9 @@ func (c *Command) Clone() *Command {
// Add appends given options to the command.
func (c *Command) Add(options ...CmdOptionFunc) *Command {
c.mux.Lock()
defer c.mux.Unlock()
for _, opt := range options {
opt(c)
}
@ -181,6 +188,9 @@ func (c *Command) Run(ctx context.Context, opts ...RunOptionFunc) (err error) {
}
func (c *Command) makeArgs() ([]string, error) {
c.mux.RLock()
defer c.mux.RUnlock()
var safeArgs []string
// add globals