mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-30 23:47:12 +00:00
eea03676d3
Signed-off-by: Royce Remer <royceremer@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
55 lines
1.5 KiB
Go
55 lines
1.5 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package process
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"os/exec"
|
|
)
|
|
|
|
type Cmd struct {
|
|
*exec.Cmd
|
|
|
|
onCancelUserFunc func() error
|
|
termGraceful bool
|
|
}
|
|
|
|
func (c *Cmd) WithOnCancelGracefully(userFunc func() error) *Cmd {
|
|
c.termGraceful, c.onCancelUserFunc = true, userFunc
|
|
return c
|
|
}
|
|
|
|
func (c *Cmd) WithOnCancelForceKill(userFunc func() error) *Cmd {
|
|
c.termGraceful, c.onCancelUserFunc = false, userFunc
|
|
return c
|
|
}
|
|
|
|
func (c *Cmd) WithDir(dir string) *Cmd {
|
|
c.Cmd.Dir = dir
|
|
return c
|
|
}
|
|
|
|
func (c *Cmd) OutputString() (string, string, error) {
|
|
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
|
c.Cmd.Stdout = stdout
|
|
c.Cmd.Stderr = stderr
|
|
err := c.Cmd.Run()
|
|
return stdout.String(), stderr.String(), err
|
|
}
|
|
|
|
// CommandContext returns a wrapped exec.Cmd which kills the process group when the context is canceled.
|
|
// By default, it uses graceful termination (SIGTERM) on Unix-like systems to make the subprocesses have chances
|
|
// to clean up (e.g. remove temporary files or lock files).
|
|
func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
|
|
c := &Cmd{Cmd: exec.CommandContext(ctx, name, arg...)} //nolint:forbidigo // wrap it
|
|
setSysProcAttribute(c.Cmd)
|
|
c.Cmd.Cancel = c.onCancel
|
|
|
|
// Unlike exec.CommandContext, we use graceful termination by default to avoid corrupting data or leaving lock files behind.
|
|
// If some processes don't respond to SIGTERM, can switch to WithOnCancelForceKill (SIGKILL) to force kill them.
|
|
c.termGraceful = true
|
|
return c
|
|
}
|