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)"), command.WithFlag("--format=%(refname:short)"),
) )
var err error
go func() { 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) scanner := bufio.NewScanner(pipe)
count := 0 count := 0
for scanner.Scan() { for scanner.Scan() {
count++ count++
} }
if err := scanner.Err(); err != nil {
return count return 0, err
}
return count, nil
} }

View File

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