Documentation ¶
Overview ¶
Package exec provides an easy way to execute commands, improving the ease-of-use and error handling of the standard library os/exec package. For example:
err := exec.Run("git", "commit", "-am") // or err := exec.RunSh("git commit -am") // or err := exec.Verbose().Run("git", "commit", "-am")
Index ¶
- func CloseReader(r io.Reader)
- func CloseWriter(w io.Writer)
- func CmdRan(err error) bool
- func ExitStatus(err error) int
- func IsPipe(rw any) bool
- func LookPath(file string) (string, error)
- func MkdirAll(path string, perm os.FileMode) error
- func Output(cmd string, args ...string) (string, error)
- func PrintCmd(cmd string, err error)
- func RemoveAll(path string) error
- func Run(cmd string, args ...string) error
- func SetMajor(c *Config)
- func SetMinor(c *Config)
- func SetSilent(c *Config)
- func SetVerbose(c *Config)
- func Start(cmd string, args ...string) (*exec.Cmd, error)
- type Cmd
- type CmdIO
- type Config
- func (c *Config) GetWriter(w io.Writer, err error) io.Writer
- func (c *Config) MkdirAll(path string, perm os.FileMode) error
- func (c *Config) Output(cmd string, args ...string) (string, error)
- func (c *Config) OutputIO(cio *CmdIO, cmd string, args ...string) (string, error)
- func (c *Config) PrintCmd(cmd string, err error)
- func (c *Config) RemoveAll(path string) error
- func (c *Config) Run(cmd string, args ...string) error
- func (c *Config) RunIO(cio *CmdIO, cmd string, args ...string) error
- func (t *Config) SetBuffer(v bool) *Config
- func (t *Config) SetDir(v string) *Config
- func (t *Config) SetEcho(v io.Writer) *Config
- func (c *Config) SetEnv(key, val string) *Config
- func (t *Config) SetPrintOnly(v bool) *Config
- func (t *Config) SetStdIO(v StdIO) *Config
- func (c *Config) SetStderr(w io.Writer) *Config
- func (c *Config) SetStdin(r io.Reader) *Config
- func (c *Config) SetStdout(w io.Writer) *Config
- func (c *Config) Start(cmd string, args ...string) (*exec.Cmd, error)
- func (c *Config) StartIO(cio *CmdIO, cmd string, args ...string) error
- type ReadWrapper
- type StdIO
- func (st *StdIO) ErrPrint(v ...any)
- func (st *StdIO) ErrPrintf(f string, v ...any)
- func (st *StdIO) ErrPrintln(v ...any)
- func (st *StdIO) GetWrapped() *StdIO
- func (st *StdIO) NewWrappers(o *StdIO)
- func (st *StdIO) OutIsPipe() bool
- func (st *StdIO) Print(v ...any)
- func (st *StdIO) Printf(f string, v ...any)
- func (st *StdIO) Println(v ...any)
- func (st *StdIO) Set(o *StdIO) *StdIO
- func (st *StdIO) SetAll(out, err io.Writer, in io.Reader)
- func (st *StdIO) SetFromOS()
- func (st *StdIO) SetToOS() *StdIO
- func (st *StdIO) SetWrappedErr(w io.Writer)
- func (st *StdIO) SetWrappedIn(r io.Reader)
- func (st *StdIO) SetWrappedOut(w io.Writer)
- func (st *StdIO) SetWrappers(o *StdIO) *StdIO
- type StdIOState
- func (st *StdIOState) ErrIsInOut(er io.Writer) bool
- func (st *StdIOState) PopErr() io.Writer
- func (st *StdIOState) PopIn() io.Reader
- func (st *StdIOState) PopOut() io.Writer
- func (st *StdIOState) PopToStart()
- func (st *StdIOState) PushErr(err io.Writer)
- func (st *StdIOState) PushIn(in io.Reader)
- func (st *StdIOState) PushOut(out io.Writer)
- func (st *StdIOState) PushOutPipe()
- func (st *StdIOState) StackStart()
- type WriteWrapper
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CloseReader ¶ added in v0.1.4
CloseReader closes given Reader, if it has a Close() method
func CloseWriter ¶ added in v0.1.4
CloseWriter closes given Writer, if it has a Close() method
func CmdRan ¶
CmdRan examines the error to determine if it was generated as a result of a command running via os/exec.Command. If the error is nil, or the command ran (even if it exited with a non-zero exit code), CmdRan reports true. If the error is an unrecognized type, or it is an error from exec.Command that says the command failed to run (usually due to the command not existing or not being executable), it reports false.
func ExitStatus ¶
ExitStatus returns the exit status of the error if it is an exec.ExitError or if it implements ExitStatus() int. 0 if it is nil or 1 if it is a different error.
func IsPipe ¶ added in v0.1.4
IsPipe returns true if the given object is an os.File corresponding to a Pipe, which is also not the same as the current os.Stdout, in case that is a Pipe.
func LookPath ¶
LookPath searches for an executable named file in the directories named by the PATH environment variable. If file contains a slash, it is tried directly and the PATH is not consulted. Otherwise, on success, the result is an absolute path.
In older versions of Go, LookPath could return a path relative to the current directory. As of Go 1.19, LookPath will instead return that path along with an error satisfying errors.Is(err, ErrDot). See the package documentation for more details.
func MkdirAll ¶
MkdirAll calls Config.MkdirAll on Major
func Output ¶
Output calls Config.Output on Major
func SetMajor ¶
func SetMajor(c *Config)
SetMajor sets the config object that Major returns. It should be used sparingly, and only in cases where there is a clear property that should be set for all commands. If the given config object is nil, Major will go back to returning its default value.
func SetMinor ¶
func SetMinor(c *Config)
SetMinor sets the config object that Minor returns. It should be used sparingly, and only in cases where there is a clear property that should be set for all commands. If the given config object is nil, Minor will go back to returning its default value.
func SetSilent ¶
func SetSilent(c *Config)
SetSilent sets the config object that Silent returns. It should be used sparingly, and only in cases where there is a clear property that should be set for all commands. If the given config object is nil, Silent will go back to returning its default value.
func SetVerbose ¶
func SetVerbose(c *Config)
SetVerbose sets the config object that Verbose returns. It should be used sparingly, and only in cases where there is a clear property that should be set for all commands. If the given config object is nil, Verbose will go back to returning its default value.
Types ¶
type CmdIO ¶ added in v0.1.4
type CmdIO struct { StdIOState // Cmd is the [exec.Cmd] Cmd *exec.Cmd }
CmdIO maintains an exec.Cmd pointer and IO state saved for the command
type Config ¶
type Config struct { // Buffer is whether to buffer the output of Stdout and Stderr, // which is necessary for the correct printing of commands and output // when there is an error with a command, and for correct coloring // on Windows. Therefore, it should be kept at the default value of // true in most cases, except for when a command will run for a log // time and print output throughout (eg: a log command). Buffer bool // PrintOnly is whether to only print commands that would be run and // not actually run them. It can be used, for example, for safely testing // an app. PrintOnly bool // The directory to execute commands in. If it is unset, // commands are run in the current directory. Dir string // Env contains any additional environment variables specified. // The current environment variables will also be passed to the // command, but they will be overridden by any variables here // if there are conflicts. Env map[string]string `set:"-"` // Echo is the writer for echoing the command string to. // It can be set to nil to disable echoing. Echo io.Writer // Standard Input / Output management StdIO StdIO }
Config contains the configuration information that controls the behavior of exec. It is passed to most high-level functions, and a default version of it can be easily constructed using [DefaultConfig].
func Major ¶
func Major() *Config
Major returns the default Config object for a major command, based on logx.UserLevel. It should be used for commands that are central to an app's logic and are more important for the user to know about and be able to see the output of. It results in commands and output being printed with a logx.UserLevel of slog.LevelInfo or below, whereas Minor results in that when it is slog.LevelDebug or below. Most commands in a typical use case should be Major, which is why the global helper functions operate on it. The object returned by Major is guaranteed to be unique, so it can be modified directly.
func Minor ¶
func Minor() *Config
Minor returns the default Config object for a minor command, based on logx.UserLevel. It should be used for commands that support an app behind the scenes and are less important for the user to know about and be able to see the output of. It results in commands and output being printed with a logx.UserLevel of slog.LevelDebug or below, whereas Major results in that when it is slog.LevelInfo or below. The object returned by Minor is guaranteed to be unique, so it can be modified directly.
func Silent ¶
func Silent() *Config
Silent returns the default Config object for a silent command, based on logx.UserLevel. It should be used for commands that whose output/input is private and needs to be always hidden from the user; for example, for a command that involves passwords. It results in commands and output never being printed. The object returned by Silent is guaranteed to be unique, so it can be modified directly.
func Verbose ¶
func Verbose() *Config
Verbose returns the default Config object for a verbose command, based on logx.UserLevel. It should be used for commands whose output are central to an application; for example, for a logger or app runner. It results in commands and output being printed with a logx.UserLevel of slog.LevelWarn or below, whereas Major and Minor result in that when it is slog.LevelInfo and [slog.levelDebug] or below, respectively. The object returned by Verbose is guaranteed to be unique, so it can be modified directly.
func (*Config) GetWriter ¶
GetWriter returns the appropriate writer to use based on the given writer and error. If the given error is non-nil, the returned writer is guaranteed to be non-nil, with [Config.Stderr] used as a backup. Otherwise, the returned writer will only be non-nil if the passed one is.
func (*Config) MkdirAll ¶
MkdirAll is a helper function that calls os.MkdirAll and Config.PrintCmd.
func (*Config) OutputIO ¶ added in v0.1.4
OutputIO runs the command and returns the text from stdout.
func (*Config) PrintCmd ¶
PrintCmd uses [GetWriter] to print the given command to [Config.Echo] or [Config.Stderr], based on the given error and the config settings. A newline is automatically inserted.
func (*Config) RemoveAll ¶
RemoveAll is a helper function that calls os.RemoveAll and Config.PrintCmd.
func (*Config) Run ¶
Run runs the given command using the given configuration information and arguments, waiting for it to complete before returning.
func (*Config) RunIO ¶ added in v0.1.4
RunIO runs the given command using the given configuration information and arguments, waiting for it to complete before returning. This IO version of Run uses specified stdio and sets the command in it as well, for easier management of dynamically updated IO routing.
func (*Config) SetBuffer ¶
SetBuffer sets the [Config.Buffer]: Buffer is whether to buffer the output of Stdout and Stderr, which is necessary for the correct printing of commands and output when there is an error with a command, and for correct coloring on Windows. Therefore, it should be kept at the default value of true in most cases, except for when a command will run for a log time and print output throughout (eg: a log command).
func (*Config) SetDir ¶
SetDir sets the [Config.Dir]: The directory to execute commands in. If it is unset, commands are run in the current directory.
func (*Config) SetEcho ¶ added in v0.1.4
SetEcho sets the [Config.Echo]: Echo is the writer for echoing the command string to. It can be set to nil to disable echoing.
func (*Config) SetPrintOnly ¶
SetPrintOnly sets the [Config.PrintOnly]: PrintOnly is whether to only print commands that would be run and not actually run them. It can be used, for example, for safely testing an app.
func (*Config) SetStdIO ¶ added in v0.1.4
SetStdIO sets the [Config.StdIO]: Standard Input / Output management
func (*Config) Start ¶ added in v0.1.4
Start starts the given command using the given configuration information and arguments, just starting the command but not waiting for it to finish. Returns the exec.Cmd command on which you can Wait for the command to finish (in a separate goroutine). See [StartIO] for a version that manages dynamic IO routing for you.
func (*Config) StartIO ¶ added in v0.1.4
StartIO starts the given command using the given configuration information and arguments, just starting the command but not waiting for it to finish. This IO version of Start uses specified stdio and sets the command in it as well, which should be used to Wait for the command to finish (in a separate goroutine). For dynamic IO routing uses, call [CmdIO.StackStart] prior to setting the IO values using Push commands, and then call [PopToStart] after Wait finishes, to close any open IO and reset.
type ReadWrapper ¶ added in v0.1.4
ReadWrapper is an io.Reader that wraps another io.Reader
type StdIO ¶ added in v0.1.4
type StdIO struct { // Out is the writer to write the standard output of called commands to. // It can be set to nil to disable the writing of the standard output. Out io.Writer // Err is the writer to write the standard error of called commands to. // It can be set to nil to disable the writing of the standard error. Err io.Writer // In is the reader to use as the standard input. In io.Reader }
StdIO contains one set of standard input / output Reader / Writers.
func (*StdIO) ErrPrintln ¶ added in v0.2.0
ErrPrintln prints to the [StdIO.Err]
func (*StdIO) GetWrapped ¶ added in v0.1.4
GetWrapped returns the current wrapped values as a StdIO. The wrappers must have been created using NewWrappers initially.
func (*StdIO) NewWrappers ¶ added in v0.1.4
NewWrappers initializes this StdIO with wrappers around given StdIO
func (*StdIO) Set ¶ added in v0.1.4
Set sets our values from other StdIO, returning the current values at time of call, to restore later.
func (*StdIO) SetFromOS ¶ added in v0.1.4
func (st *StdIO) SetFromOS()
SetFromOS sets all our IO to current os.Std*
func (*StdIO) SetToOS ¶ added in v0.1.4
SetToOS sets the current IO to os.Std*, returning a StdIO with the current IO settings prior to this call, which can be used to restore. Note: os.Std* are *os.File types, and this function will panic if the current IO are not actually *os.Files. The results of a prior SetToOS call will do the right thing for saving and restoring the os state.
func (*StdIO) SetWrappedErr ¶ added in v0.2.0
SetWrappedErr sets the wrapped Err to given writer. The wrappers must have been created using NewWrappers initially.
func (*StdIO) SetWrappedIn ¶ added in v0.2.0
SetWrappedIn sets the wrapped In to given reader. The wrappers must have been created using NewWrappers initially.
func (*StdIO) SetWrappedOut ¶ added in v0.2.0
SetWrappedOut sets the wrapped Out to given writer. The wrappers must have been created using NewWrappers initially.
func (*StdIO) SetWrappers ¶ added in v0.1.4
SetWrappers sets the wrappers to current values from given StdIO, returning a copy of the wrapped values previously in place at start of call, which can be used in restoring state later. The wrappers must have been created using NewWrappers initially.
type StdIOState ¶ added in v0.1.4
type StdIOState struct { StdIO // OutStack is stack of out OutStack stack.Stack[io.Writer] // ErrStack is stack of err ErrStack stack.Stack[io.Writer] // InStack is stack of in InStack stack.Stack[io.Reader] // PipeIn is a stack of the os.File to use for reading from the Out, // when Out is a Pipe, created by [PushOutPipe]. // Use [OutIsPipe] function to determine if the current output is a Pipe // in order to determine whether to use the current [PipeIn.Peek()]. // These will be automatically closed during [PopToStart] whenever the // corresponding Out is a Pipe. PipeIn stack.Stack[*os.File] // Starting depths of the respective stacks, for unwinding the stack // to a defined starting point. OutStart, ErrStart, InStart int }
StdIOState maintains a stack of StdIO settings for easier management of dynamic IO routing. Call [StackStart] prior to setting the IO values using Push commands, and then call [PopToStart] when done to close any open IO and reset.
func (*StdIOState) ErrIsInOut ¶ added in v0.1.4
func (st *StdIOState) ErrIsInOut(er io.Writer) bool
ErrIsInOut returns true if the given Err writer is also present within the active (> [OutStart]) stack of Outs. If this is true, then Err should not be closed, as it will be closed when the Out is closed.
func (*StdIOState) PopErr ¶ added in v0.1.4
func (st *StdIOState) PopErr() io.Writer
PopErr restores previous io.Writer as [Err] from the stack, saved during [PushErr], returning the current Err at time of call. This does NOT close the current one, in case you need to use it before closing, so that is your responsibility (see [PopToStart] that does this for you). Note that Err is often the same as Out, in which case only Out should be closed.
func (*StdIOState) PopIn ¶ added in v0.1.4
func (st *StdIOState) PopIn() io.Reader
PopIn restores previous io.Reader as [In] from the stack, saved during [PushIn], returning the current In at time of call. This does NOT close the current one, in case you need to use it before closing, so that is your responsibility (see [PopToStart] that does this for you).
func (*StdIOState) PopOut ¶ added in v0.1.4
func (st *StdIOState) PopOut() io.Writer
PopOut restores previous io.Writer as [Out] from the stack, saved during [PushOut], returning the current Out at time of call. Pops and closes corresponding PipeIn if current Out is a Pipe. This does NOT close the current one, in case you need to use it before closing, so that is your responsibility (see [PopToStart] that does this for you).
func (*StdIOState) PopToStart ¶ added in v0.1.4
func (st *StdIOState) PopToStart()
PopToStart unwinds the IO stacks to the depths recorded at [StackStart], automatically closing the ones that are popped. It automatically checks if any of the Err items are the same as Out and does not redundantly close those.
func (*StdIOState) PushErr ¶ added in v0.1.4
func (st *StdIOState) PushErr(err io.Writer)
PushErr pushes a new io.Writer as the current [Err], saving the current one on a stack, which can be restored using [PopErr].
func (*StdIOState) PushIn ¶ added in v0.1.4
func (st *StdIOState) PushIn(in io.Reader)
PushIn pushes a new io.Reader as the current [In], saving the current one on a stack, which can be restored using [PopIn].
func (*StdIOState) PushOut ¶ added in v0.1.4
func (st *StdIOState) PushOut(out io.Writer)
PushOut pushes a new io.Writer as the current [Out], saving the current one on a stack, which can be restored using [PopOut].
func (*StdIOState) PushOutPipe ¶ added in v0.1.4
func (st *StdIOState) PushOutPipe()
PushOutPipe calls os.Pipe() and pushes the writer side as the new [Out], and pushes the Reader side to [PipeIn] which should then be used as the [In] for any other relevant process. Call [OutIsPipe] to determine if the current Out is a Pipe, to know whether to use the PipeIn.Peek() value.
func (*StdIOState) StackStart ¶ added in v0.1.4
func (st *StdIOState) StackStart()
StackStart records the starting depths of the IO stacks
type WriteWrapper ¶ added in v0.1.4
WriteWrapper is an io.Writer that wraps another io.Writer