Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"strings"
"sync"
"syscall"

"github.com/alecthomas/kingpin/v2"
"github.com/fatih/color"
"github.com/felixge/fgprof"
Expand Down Expand Up @@ -347,6 +346,19 @@ func init() {
}
}

// syncLogs flushes logs when the program exits.
func syncLogs(syncFn func() error) {
if syncFn == nil {
return
}
done := make(chan struct{})
go func() {
_ = syncFn()
close(done)
}()
<-done
}

func main() {
// setup logger
logFormat := log.WithConsoleSink
Expand All @@ -358,15 +370,16 @@ func main() {
context.SetDefaultLogger(logger)

if *localDev {
run(overseer.State{})
run(overseer.State{}, sync)
os.Exit(0)
}

defer func() { _ = sync() }()
logFatal := logFatalFunc(logger)

updateCfg := overseer.Config{
Program: run,
Program: func(s overseer.State) {
run(s, sync)
},
Debug: *debug,
RestartSignal: syscall.SIGTERM,
// TODO: Eventually add a PreUpgrade func for signature check w/ x509 PKCS1v15
Expand All @@ -387,10 +400,12 @@ func main() {
}
}

func run(state overseer.State) {

func run(state overseer.State, logSync func() error) {
ctx, cancel := context.WithCancelCause(context.Background())
defer cancel(nil)
defer func() {
syncLogs(logSync)
}()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary anonymous function wrapper in defer

Low Severity

The anonymous function wrapper around syncLogs(logSync) is unnecessary. Since syncLogs doesn't return any values and logSync is a parameter that doesn't change during execution, this can be simplified to defer syncLogs(logSync).

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this


go func() {
if err := cleantemp.CleanTempArtifacts(ctx); err != nil {
Expand All @@ -413,6 +428,8 @@ func run(state overseer.State) {
} else {
logger.Info("cleaned temporary artifacts")
}

syncLogs(logSync)
os.Exit(0)
}()

Expand Down Expand Up @@ -606,6 +623,7 @@ func run(state overseer.State) {

if metrics.hasFoundResults && *fail {
logger.V(2).Info("exiting with code 183 because results were found")
syncLogs(logSync)
os.Exit(183)
}
}
Expand Down
27 changes: 22 additions & 5 deletions pkg/gitparse/gitparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const (

// defaultMaxCommitSize is the maximum size for a commit. Larger commits will be cut off.
defaultMaxCommitSize int64 = 2 * 1024 * 1024 * 1024 // 2GB

// defaultWaitDelay is the default time to wait after context cancellation before forcefully killing git processes.
defaultWaitDelay = 5 * time.Second
)

// contentWriter defines a common interface for writing, reading, and managing diff content.
Expand Down Expand Up @@ -124,6 +127,7 @@ type Parser struct {
maxDiffSize int64
maxCommitSize int64
dateFormat string
waitDelay time.Duration

useCustomContentWriter bool
}
Expand Down Expand Up @@ -204,6 +208,14 @@ func WithMaxCommitSize(maxCommitSize int64) Option {
}
}

// WithWaitDelay sets the waitDelay option. This specifies how long to wait after
// context cancellation before forcefully killing git processes.
func WithWaitDelay(waitDelay time.Duration) Option {
return func(parser *Parser) {
parser.waitDelay = waitDelay
}
}

// Option is used for adding options to Config.
type Option func(*Parser)

Expand All @@ -213,6 +225,7 @@ func NewParser(options ...Option) *Parser {
dateFormat: defaultDateFormat,
maxDiffSize: defaultMaxDiffSize,
maxCommitSize: defaultMaxCommitSize,
waitDelay: defaultWaitDelay,
}
for _, option := range options {
option(parser)
Expand Down Expand Up @@ -253,7 +266,7 @@ func (c *Parser) RepoPath(
args = append(args, "--", ".", ":(exclude)"+glob)
}

cmd := exec.Command("git", args...)
cmd := exec.CommandContext(ctx, "git", args...)
absPath, err := filepath.Abs(source)
if err == nil {
if !isBare {
Expand All @@ -273,26 +286,27 @@ func (c *Parser) RepoPath(
}
}

return c.executeCommand(ctx, cmd, false)
return c.executeCommand(ctx, cmd, false, c.waitDelay)
}

// Staged parses the output of the `git diff` command for the `source` path.
func (c *Parser) Staged(ctx context.Context, source string) (chan *Diff, error) {
// Provide the --cached flag to diff to get the diff of the staged changes.
args := []string{"-C", source, "diff", "-p", "--cached", "--full-history", "--diff-filter=AM", "--date=iso-strict"}

cmd := exec.Command("git", args...)
cmd := exec.CommandContext(ctx, "git", args...)

absPath, err := filepath.Abs(source)
if err == nil {
cmd.Env = append(cmd.Env, "GIT_DIR="+filepath.Join(absPath, ".git"))
}

return c.executeCommand(ctx, cmd, true)
return c.executeCommand(ctx, cmd, true, c.waitDelay)
}

// executeCommand runs an exec.Cmd, reads stdout and stderr, and waits for the Cmd to complete.
func (c *Parser) executeCommand(ctx context.Context, cmd *exec.Cmd, isStaged bool) (chan *Diff, error) {
// waitDelay specifies how long to wait after context cancellation before forcefully killing the process.
func (c *Parser) executeCommand(ctx context.Context, cmd *exec.Cmd, isStaged bool, waitDelay time.Duration) (chan *Diff, error) {
diffChan := make(chan *Diff, 64)

stdOut, err := cmd.StdoutPipe()
Expand All @@ -304,6 +318,9 @@ func (c *Parser) executeCommand(ctx context.Context, cmd *exec.Cmd, isStaged boo
return diffChan, err
}

// Set WaitDelay to allow the command additional time to exit after context cancellation
cmd.WaitDelay = waitDelay

err = cmd.Start()
if err != nil {
return diffChan, err
Expand Down
20 changes: 20 additions & 0 deletions pkg/gitparse/gitparse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,26 @@ func TestMaxCommitSize(t *testing.T) {
}

}
func TestWaitDelay(t *testing.T) {
// Test that WithWaitDelay sets the waitDelay correctly
customDelay := 10 * time.Second
parser := NewParser(WithWaitDelay(customDelay))
if parser.waitDelay != customDelay {
t.Errorf("waitDelay not set correctly. Got: %v, expected: %v", parser.waitDelay, customDelay)
}

// Test that default waitDelay is used when not specified
defaultParser := NewParser()
if defaultParser.waitDelay != defaultWaitDelay {
t.Errorf("default waitDelay not set correctly. Got: %v, expected: %v", defaultParser.waitDelay, defaultWaitDelay)
}

// Test that zero value is allowed (caller can set to 0 if they want no delay)
zeroDelayParser := NewParser(WithWaitDelay(0))
if zeroDelayParser.waitDelay != 0 {
t.Errorf("zero waitDelay not set correctly. Got: %v, expected: 0", zeroDelayParser.waitDelay)
}
}

const commitLog = `commit e50b135fd29e91b2fbb25923797f5ecffe59f359
Author: lionzxy <nikita@kulikof.ru>
Expand Down
Loading