diff options
Diffstat (limited to 'modules/git')
-rw-r--r-- | modules/git/blame.go | 14 | ||||
-rw-r--r-- | modules/git/command.go | 37 | ||||
-rw-r--r-- | modules/git/git.go | 4 |
3 files changed, 44 insertions, 11 deletions
diff --git a/modules/git/blame.go b/modules/git/blame.go index 4f4343fe96..5a9ae9a74f 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -6,6 +6,7 @@ package git import ( "bufio" + "context" "fmt" "io" "os" @@ -28,6 +29,7 @@ type BlameReader struct { output io.ReadCloser scanner *bufio.Scanner lastSha *string + cancel context.CancelFunc } var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") @@ -76,7 +78,8 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { // Close BlameReader - don't run NextPart after invoking that func (r *BlameReader) Close() error { - process.GetManager().Remove(r.pid) + defer process.GetManager().Remove(r.pid) + defer r.cancel() if err := r.cmd.Wait(); err != nil { return fmt.Errorf("Wait: %v", err) @@ -97,20 +100,24 @@ func CreateBlameReader(repoPath, commitID, file string) (*BlameReader, error) { } func createBlameReader(dir string, command ...string) (*BlameReader, error) { - cmd := exec.Command(command[0], command[1:]...) + // FIXME: graceful: This should have a timeout + ctx, cancel := context.WithCancel(DefaultContext) + cmd := exec.CommandContext(ctx, command[0], command[1:]...) cmd.Dir = dir cmd.Stderr = os.Stderr stdout, err := cmd.StdoutPipe() if err != nil { + defer cancel() return nil, fmt.Errorf("StdoutPipe: %v", err) } if err = cmd.Start(); err != nil { + defer cancel() return nil, fmt.Errorf("Start: %v", err) } - pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cmd) + pid := process.GetManager().Add(fmt.Sprintf("GetBlame [repo_path: %s]", dir), cancel) scanner := bufio.NewScanner(stdout) @@ -120,5 +127,6 @@ func createBlameReader(dir string, command ...string) (*BlameReader, error) { stdout, scanner, nil, + cancel, }, nil } diff --git a/modules/git/command.go b/modules/git/command.go index 65878edb7d..f01db2e1d8 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -30,8 +30,10 @@ const DefaultLocale = "C" // Command represents a command with its subcommands or arguments. type Command struct { - name string - args []string + name string + args []string + parentContext context.Context + desc string } func (c *Command) String() string { @@ -47,19 +49,34 @@ func NewCommand(args ...string) *Command { cargs := make([]string, len(GlobalCommandArgs)) copy(cargs, GlobalCommandArgs) return &Command{ - name: GitExecutable, - args: append(cargs, args...), + name: GitExecutable, + args: append(cargs, args...), + parentContext: DefaultContext, } } // NewCommandNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args func NewCommandNoGlobals(args ...string) *Command { return &Command{ - name: GitExecutable, - args: args, + name: GitExecutable, + args: args, + parentContext: DefaultContext, } } +// SetParentContext sets the parent context for this command +func (c *Command) SetParentContext(ctx context.Context) *Command { + c.parentContext = ctx + return c +} + +// SetDescription sets the description for this command which be returned on +// c.String() +func (c *Command) SetDescription(desc string) *Command { + c.desc = desc + return c +} + // AddArguments adds new argument(s) to the command. func (c *Command) AddArguments(args ...string) *Command { c.args = append(c.args, args...) @@ -92,7 +109,7 @@ func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time. log("%s: %v", dir, c) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(c.parentContext, timeout) defer cancel() cmd := exec.CommandContext(ctx, c.name, c.args...) @@ -110,7 +127,11 @@ func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time. return err } - pid := process.GetManager().Add(fmt.Sprintf("%s %s %s [repo_path: %s]", GitExecutable, c.name, strings.Join(c.args, " "), dir), cmd) + desc := c.desc + if desc == "" { + desc = fmt.Sprintf("%s %s %s [repo_path: %s]", GitExecutable, c.name, strings.Join(c.args, " "), dir) + } + pid := process.GetManager().Add(desc, cancel) defer process.GetManager().Remove(pid) if fn != nil { diff --git a/modules/git/git.go b/modules/git/git.go index df50eac72a..286e1ad8b4 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -6,6 +6,7 @@ package git import ( + "context" "fmt" "os/exec" "runtime" @@ -35,6 +36,9 @@ var ( // Could be updated to an absolute path while initialization GitExecutable = "git" + // DefaultContext is the default context to run git commands in + DefaultContext = context.Background() + gitVersion string ) |