Documentation
¶
Overview ¶
Package proc runs external programs.
It is the only place in this module that spawns a subprocess. Concentrating that here means the gosec exception for a program name held in a variable is written once, with its reason, instead of being repeated at every call site where it would gradually stop being read.
Index ¶
- Constants
- Variables
- func Available(name string) bool
- func Capture(ctx context.Context, program Command, input []byte) ([]byte, error)
- func CaptureWithin(ctx context.Context, timeout time.Duration, program Command, input []byte) ([]byte, error)
- func Failure(err error) (int, string, bool)
- func Interactive(program Command) (*exec.Cmd, error)
- func LookPath(name string) (string, error)
- func Run(ctx context.Context, name string, args ...string) ([]byte, error)
- func RunCommand(ctx context.Context, program Command) ([]byte, error)
- func RunWithin(ctx context.Context, timeout time.Duration, name string, args ...string) ([]byte, error)
- type Command
- type ExitError
- type Output
Constants ¶
const DefaultRunTimeout = 30 * time.Second
DefaultRunTimeout bounds a Run so a hung quick read — a git status on a dead network mount, a gh call to a host that never answers — recovers on its own, with an error answering to ErrTimedOut, rather than leaving a pane on "loading…" forever. It is generous because a Run is a quick read; streamed work (Start) and piped work (Capture) can legitimately run long and are not bounded here.
Variables ¶
var ErrExitStatus = errors.New("ended with a failure status")
ErrExitStatus reports a program that ran and ended with a failure status of its own — a refused commit, a rejected push — rather than one that could not start, was killed, or could not be read. The error keeps the program's own words, "git: exit status 1", so it reads as it always has.
var ErrNotFound = errors.New("program not found on PATH")
ErrNotFound reports a program that is not on PATH.
var ErrTimedOut = errors.New("gave up waiting")
ErrTimedOut reports a Run stopped because it outlasted its own bound; the error names the bound. A run the caller's context ended first — its own deadline, a Ctrl-C — does not answer to it.
Functions ¶
func Capture ¶ added in v0.0.5
Capture runs a program with input on its standard input and returns what it wrote to standard output.
Unlike Run it feeds a body in, and it returns the output even on a non-zero exit: a tool that answers with data on standard output and signals an HTTP error only through its exit status — gh api, glab api — is read either way, with its standard error folded into the returned error.
func CaptureWithin ¶ added in v0.4.1
func CaptureWithin(ctx context.Context, timeout time.Duration, program Command, input []byte) ([]byte, error)
CaptureWithin is Capture bounded by timeout, as RunWithin bounds Run; a timeout that is not positive leaves it unbounded, as Capture is, and only timeout's own expiry answers to ErrTimedOut.
func Failure ¶ added in v0.4.1
Failure reads a program's non-zero exit out of an error Run, RunCommand or Capture returned: its exit code and what it wrote to standard error, and whether the error was an exit at all — a program not found, one stopped at its bound, or one killed by a signal is not.
func Interactive ¶
Interactive builds a program that takes over the terminal — an editor — for the interface to hand the screen to. It is not started here: Bubble Tea starts it once it has released the terminal.
func LookPath ¶
LookPath reports where a program is, or an error if it is not on PATH. It is exec.LookPath, re-exported so callers wiring a seam do not reach past this package for one of its two halves.
func Run ¶
Run executes name with args and returns what it wrote to standard output, within DefaultRunTimeout.
A non-zero exit becomes an error carrying the program's standard error. That matters more than it looks: "git failed" without the reason sends the reader back to a terminal to run the command again by hand.
func RunCommand ¶ added in v0.0.7
RunCommand is Run for a caller that must set the working directory or the environment: a git command that touches the network with GIT_TERMINAL_PROMPT off, so it fails at once rather than block on a credential prompt nobody inside the interface can answer. It is bounded by DefaultRunTimeout like Run.
func RunWithin ¶ added in v0.0.6
func RunWithin(ctx context.Context, timeout time.Duration, name string, args ...string) ([]byte, error)
RunWithin is Run bounded by an explicit timeout, for a read whose own limit differs from the default. The tighter of timeout and ctx's own deadline wins; only timeout's own expiry answers to ErrTimedOut.
Types ¶
type Command ¶
type Command struct {
// Dir is the working directory.
Dir string
// Name is the program, found on this process's PATH unless Path is set,
// and the name a failure gives it.
Name string
// Path is the program's executable when the caller found it already, on
// a PATH of its own; empty finds Name on this process's.
Path string
Args []string
// Env is added to this process's own environment rather than replacing it:
// a git hook needs PATH, HOME and the rest to work at all.
Env []string
}
Command is a program to run, and where and how to run it.
type ExitError ¶ added in v0.9.0
ExitError is a program that ran and ended with a failure status of its own: which program, the status, and what it wrote to standard error, sanitized.
type Output ¶
type Output struct {
// Lines delivers each line of standard output and standard error in the
// order the program wrote them, and closes when the program has exited.
// Once the run gives up on an output a process the program left behind
// holds past outputGrace, nothing more is delivered: not even a line the
// program began and never ended.
Lines <-chan string
// Wait reports how the program exited. It blocks until then, and until its
// output has ended: read to the end, cut at a line too long to deliver, or
// given up on once a process the program left behind has held it
// outputGrace past the exit. So call it once Lines has closed. Calling it
// again returns the same result rather than blocking.
Wait func() error
// Stop kills this run — the whole process group — without disturbing the
// context the caller passed, so one hung or unwanted run can be ended on its
// own. Wait then reports the program as killed. Calling it more than once, or
// after the program has already exited, does nothing.
Stop func()
}
Output is a program's combined output as it arrives, and how it ended.
func Start ¶
Start runs a program and streams its output, for work long enough that someone should see it as it happens: a hook, a push.
Standard output and standard error share one pipe, so a failure appears between the lines it followed rather than all at the end. While ctx runs, each line waits for its reader, so a reader that goes away and leaves ctx running reads Lines to the end, or the program blocks once the lines waiting fill the pipe. Canceling ctx kills the program and drains the rest of its output unread, so a reader that goes away with ctx never leaves it blocked.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package pgroup runs a streamed child in its own process group, so canceling its context kills the whole tree rather than the child alone.
|
Package pgroup runs a streamed child in its own process group, so canceling its context kills the whole tree rather than the child alone. |