Categorygithub.com/krystal/go-runner
modulepackage
0.2.0
Repository: https://github.com/krystal/go-runner.git
Documentation: pkg.go.dev

# README

go-runner

Go package exposing a simple interface for executing commands, enabling easy mocking and wrapping of executed commands.

Go Reference GitHub tag (latest SemVer) Actions Status Coverage GitHub last commit GitHub issues GitHub pull requests License Status

The Runner interface is basic and minimal, but it is sufficient for most use cases. This makes it easy to mock Runner for testing purposes.

It's also easy to create wrapper runners which modify commands before executing them. The Sudo struct is a simple example of this.

Import

import "github.com/krystal/go-runner"

Interface

type Runner interface {
	Run(
		stdin io.Reader,
		stdout, stderr io.Writer,
		command string,
		args ...string,
	) error
	RunContext(
		ctx context.Context,
		stdin io.Reader,
		stdout, stderr io.Writer,
		command string,
		args ...string,
	) error
	Env(env ...string)
}

Usage

Basic:

var stdout bytes.Buffer

r := runner.New()
_ = r.Run(nil, &stdout, nil, "echo", "Hello world!")

fmt.Print(stdout.String())
Hello world!

Environment:

var stdout bytes.Buffer

r := runner.New()
r.Env("USER=johndoe", "HOME=/home/johnny")
_ = r.Run(nil, &stdout, nil, "sh", "-c", `echo "Hi, ${USER} (${HOME})"`)

fmt.Print(stdout.String())
Hi, johndoe (/home/johnny)

Stdin, Stdout, and Stderr:

stdin := bytes.NewBufferString("Hello world!")
var stdout, stderr bytes.Buffer

r := runner.New()
err := r.Run(
	stdin, &stdout, &stderr,
	"sh", "-c", "cat; echo 'Oh noes! :(' >&2",
)
if err != nil {
	fmt.Println(err)
}

fmt.Print(stderr.String())
fmt.Print(stdout.String())
Oh noes! :(
Hello world!

Failure:

var stdout, stderr bytes.Buffer

r := runner.New()
err := r.Run(
	nil, &stdout, &stderr,
	"sh", "-c", "echo 'Hello world!'; echo 'Oh noes! :(' >&2; exit 3",
)
if err != nil {
	fmt.Printf("%s: %s", err.Error(), stderr.String())
}
exit status 3: Oh noes! :(

Context:

var stdout bytes.Buffer

ctx, cancel := context.WithTimeout(
	context.Background(), 1*time.Second,
)
defer cancel()

r := runner.New()
err := r.RunContext(
	ctx, nil, &stdout, nil,
	"sh", "-c", "sleep 0.5 && echo 'Hello world!'",
)
if err != nil {
	fmt.Println(err)
}

fmt.Print(stdout.String())
Hello world!

Sudo (requires NOPASS in sudoers file):

var stdout bytes.Buffer
r := runner.New()

sudo := &runner.Sudo{Runner: r}
_ = sudo.Run(nil, &stdout, nil, "whoami")

sudo.User = "web"
_ = sudo.Run(nil, &stdout, nil, "whoami")

fmt.Print(stdout.String())
root
web

Documentation

Please see the Go Reference for documentation and examples.

License

MIT

# Packages

Code generated by MockGen.
No description provided by the author

# Functions

New returns a Local instance which meets the Runner interface, and executes commands locally on the host machine.

# Variables

No description provided by the author
No description provided by the author
No description provided by the author

# Structs

Local is a Runner implementation that executes commands locally on the host machine.
SSHCLI is a Runner that wraps another Runner, essentially prefixing given commands and arguments with "ssh", relevant SSH CLI arguments, and the given destination.
Sudo is a Runner that wraps another Runner and runs commands via sudo.
Testing is a Runner that wraps another Runner, and logs all executed commands and their arguments to a *testing.T instance.

# Interfaces

Runner is the interface that all runner structs implements.
TestingT is a interface that describes the *testing.T methods needed by the Testing runner implementation.