Documentation ¶
Overview ¶
Package exec is a wrapper around the os/exec package that supports timeouts and testing.
Example usage:
Simple command with argument:
err := exec.Run(ctx, &exec.Command{ Name: "touch", Args: []string{file}, })
More complicated example:
output := bytes.Buffer{} err := exec.Run(ctx, &exec.Command{ Name: "make", Args: []string{"all"}, // Set environment: Env: []string{fmt.Sprintf("GOPATH=%s", projectGoPath)}, // Set working directory: Dir: projectDir, // Capture output: CombinedOutput: &output, // Set a timeout: Timeout: 10*time.Minute, }) For testing, see exec_testutil.go and exec.CommandCollector.
Index ¶
- Constants
- Variables
- func DebugString(command *Command) string
- func DefaultRun(ctx context.Context, command *Command) error
- func GetRunFn(ctx context.Context) func(context.Context, *Command) error
- func IsTimeout(err error) bool
- func LookPath(file, path string) (string, error)
- func NewContext(ctx context.Context, runFn func(context.Context, *Command) error) context.Context
- func NoInterruptContext(ctx context.Context) context.Context
- func Run(ctx context.Context, command *Command) error
- func RunCommand(ctx context.Context, command *Command) (string, error)
- func RunCwd(ctx context.Context, cwd string, args ...string) (string, error)
- func RunSimple(ctx context.Context, commandLine string) (string, error)
- func WithRetryContext(ctx context.Context, settings backoff.BackOff) context.Context
- type Command
- type CommandCollector
- type Process
- type Verbosity
- type WriteLog
Constants ¶
const (
TIMEOUT_ERROR_PREFIX = "Command killed since it took longer than"
)
Variables ¶
Functions ¶
func DebugString ¶
DebugString returns the Env, Name, and Args of command joined with spaces. Does not perform any quoting.
func DefaultRun ¶
DefaultRun can be passed to SetRunForTesting to go back to running commands as normal.
func IsTimeout ¶
IsTimeout returns true if the specified error was raised due to a command timing out.
func LookPath ¶
LookPath searches for an executable named file in the directories named by the path argument. Implementation is taken directly from the os/exec package but modified to search given path argument instead of os.Getenv("PATH").
func NewContext ¶
NewContext returns a context.Context instance which uses the given function to run Commands.
func NoInterruptContext ¶
NoInterruptContext returns a context.Context instance which launches subprocesses in a difference process group so that they are not killed when this process is killed.
On Windows, this function just returns withoutCancel(ctx).
func Run ¶
Run runs command and waits for it to finish. If any failure, returns non-nil. If a timeout was specified, returns an error once the command has exceeded that timeout.
func RunCommand ¶
RunCommand executes the given command and returns the combined stdout and stderr. May also return an error if the command exited with a non-zero status or there is any other error.
func RunCwd ¶
RunCwd executes the given command in the given directory. Returns the combined stdout and stderr. May also return an error if the command exited with a non-zero status or there is any other error.
Types ¶
type Command ¶
type Command struct { // Name of the command, as passed to osexec.Command. Can be the path to a binary or the // name of a command that osexec.Lookpath can find. Name string // Arguments of the command, not including Name. Args []string // The environment of the process. If nil, the current process's environment is used. Env []string // If Env is non-nil, adds the current process's entire environment to Env, excluding // variables that are set in Env. InheritEnv bool // If Env is non-nil, adds the current process's PATH to Env. Do not include PATH in Env. InheritPath bool // The working directory of the command. If nil, runs in the current process's current // directory. Dir string // See docs for osexec.Cmd.Stdin. Stdin io.Reader // If true, duplicates stdout of the command to WriteInfoLog. LogStdout bool // Sends the stdout of the command to this Writer, e.g. os.File or bytes.Buffer. Stdout io.Writer // If true, duplicates stderr of the command to WriteWarningLog. LogStderr bool // Sends the stderr of the command to this Writer, e.g. os.File or bytes.Buffer. Stderr io.Writer // Sends the combined stdout and stderr of the command to this Writer, in addition to // Stdout and Stderr. Only one goroutine will write at a time. Note: the Go runtime seems to // combine stdout and stderr into one stream as long as LogStdout and LogStderr are false // and Stdout and Stderr are nil. Otherwise, the stdout and stderr of the command could be // arbitrarily reordered when written to CombinedOutput. CombinedOutput io.Writer // Time limit to wait for the command to finish. No limit if not specified. Timeout time.Duration // Whether to log when the command starts. Verbose Verbosity // SysProcAttr holds optional, operating system-specific attributes. // Run passes it to os.StartProcess as the os.ProcAttr's Sys field. SysProcAttr *syscall.SysProcAttr }
func ParseCommand ¶
ParseCommand divides commandLine at spaces; treats the first token as the program name and the other tokens as arguments. Note: don't expect this function to do anything smart with quotes or escaped spaces.
type CommandCollector ¶
type CommandCollector struct {
// contains filtered or unexported fields
}
CommandCollector collects arguments to the Run method for later inspection. Safe for use in multiple goroutines as long as the function passed to SetDelegateRun is.
Example usage:
mock := exec.CommandCollector{} ctx := exec.NewContext(context.Background(), mock.Run) err := exec.Run(ctx, &exec.Command{ Name: "touch", Args: []string{"/tmp/file"}, }) assert.Equal(t, "touch /tmp/file"", exec.DebugString(mock.Commands()[0]))
func (*CommandCollector) ClearCommands ¶
func (c *CommandCollector) ClearCommands()
ClearCommands resets the commands seen thus far.
func (*CommandCollector) Commands ¶
func (c *CommandCollector) Commands() []*Command
Commands returns a copy of the commands that have been run up to this point.
func (*CommandCollector) Run ¶
func (c *CommandCollector) Run(ctx context.Context, command *Command) error
Run collects command into c and delegates to the function specified by SetDelegateRun. Returns nil if SetDelegateRun has not been called. The command will be visible in Commands() before the SetDelegateRun function is called.
func (*CommandCollector) SetDelegateRun ¶
func (c *CommandCollector) SetDelegateRun(delegateRun func(context.Context, *Command) error)
SetDelegateRun allows some custom function to be executed when Run is called on this object. By default, nothing will happen apart from storing the command.
type Process ¶
type Process interface {
Kill() error
}
func RunIndefinitely ¶
RunIndefinitely starts the command and then returns. Clients can listen for the command to end on the returned channel or kill the process manually using the Process handle. The timeout param is ignored if it is set. If starting the command returns an error, that error is returned.