toolkit

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2026 License: Apache-2.0 Imports: 20 Imported by: 7

Documentation

Overview

Package toolkit provides testable abstractions and helpers for CLI programs.

The central type is Runtime, an explicit dependency container that bundles environment variables, filesystem operations, clock, logger, streams, and hasher. Production code uses NewRuntime or NewOsRuntime; test code uses NewTestRuntime which wires in-memory implementations and a jailed filesystem.

Key interfaces:

  • Env for environment variable access (implemented by OsEnv and TestEnv)
  • FileSystem for filesystem operations (implemented by OsFS)
  • Hasher for deterministic content hashing

Helper functions provide cross-platform user path resolution (UserConfigPath, UserDataPath, UserStatePath, UserCachePath) and environment variable expansion (ExpandEnv, ExpandPath).

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoEnvKey      = errors.New("env key missing")
	ErrEscapeAttempt = jailpkg.ErrEscapeAttempt
)
View Source
var DefaultEditor = "nano"

Functions

func CreateTestStdio deprecated

func CreateTestStdio(content string) (*os.File, func())

Deprecated: CreateTestStdio is unstable and may change in future releases.

CreateTestStdio creates a temporary file prefilled with the given content and seeks it to the beginning, making it suitable to pass as a stand-in for stdin, stdout, or stderr in tests.

It returns the open *os.File and a cleanup function. The cleanup function closes the file and removes it from disk. The function panics on any error while creating, writing, or seeking the temporary file; this makes test setup failures immediately visible.

Example usage in tests:

f, cleanup := CreateTestStdio("input text")
defer cleanup()
// pass f where a *os.File is needed

The returned file is created in the OS temporary directory using the pattern "test-stdio-*".

func DumpEnv

func DumpEnv(env Env) string

DumpEnv returns a sorted, newline separated representation of env.

func Edit

func Edit(ctx context.Context, rt *Runtime, path string) error

Edit launches the user's editor to edit the provided file path.

func EnsureInJail

func EnsureInJail(jail, p string) string

EnsureInJail returns a path that resides inside jail when possible.

func EnsureInJailFor

func EnsureInJailFor(jail, p string) string

EnsureInJailFor is a test-friendly helper that mirrors EnsureInJail.

func ExpandEnv

func ExpandEnv(env Env, s string) string

ExpandEnv expands $var or ${var} in s using env.

func ExpandPath

func ExpandPath(env Env, p string) (string, error)

ExpandPath expands a leading tilde in the provided path to the user's home directory obtained from env.

func GetDefault

func GetDefault(env Env, key, other string) string

GetDefault returns the value of key from env when present and non-empty.

func IsInJail

func IsInJail(jail, rel string) bool

IsInJail reports whether the provided path resides within the jail boundary.

func IsInteractiveTerminal

func IsInteractiveTerminal(f *os.File) bool

IsInteractiveTerminal reports whether the provided file is connected to an interactive terminal.

This delegates to golang.org/x/term.IsTerminal and returns true when the file descriptor refers to a terminal device (TTY). Pass os.Stdin to check the program's standard input.

Notes:

  • The check uses the file descriptor (f.Fd()) and will return false for pipes, redirected files, and other non-terminal descriptors.
  • It is a non-destructive check and does not change the file position.

func IsJailed added in v1.0.0

func IsJailed(j Jailed) bool

IsJailed reports whether j has a non-empty jail configured.

func RemoveJailPrefix

func RemoveJailPrefix(jail, path string) string

RemoveJailPrefix removes the jail prefix from a path and returns an absolute path.

func StdinHasData

func StdinHasData(f *os.File) bool

StdinHasData reports whether the provided file appears to be receiving piped or redirected input (for example: `echo hi | myprog` or `myprog < file.txt`).

The implementation performs a lightweight metadata check: it returns true when the file is not a character device (that is, not a terminal). This is a common, portable heuristic used to detect piped input.

Notes and caveats:

  • The check does not attempt to read from the file. It only inspects the file mode returned by Stat().
  • For pipes this indicates stdin is coming from a pipe or redirect, but it does not strictly guarantee that bytes are immediately available to read. An open pipe may be empty until the writer writes to it.
  • If f.Stat() returns an error the function conservatively returns false.
  • Callers should pass os.Stdin to check the program's standard input, or a *os.File pointing to another stream for testing.

Example:

if StdinHasData(os.Stdin) {
    // read from stdin
}

func UserCachePath

func UserCachePath(env Env) (string, error)

UserCachePath returns the directory that should be used to store per-user cache files.

func UserConfigPath

func UserConfigPath(env Env) (string, error)

UserConfigPath returns the directory that should be used to store per-user configuration files.

func UserDataPath

func UserDataPath(env Env) (string, error)

UserDataPath returns the directory that should be used to store per-user application data.

func UserStatePath

func UserStatePath(env Env) (string, error)

UserStatePath returns the directory that should be used to store per-user state files for an application.

Types

type Env

type Env = envpkg.Env

Env is retained for backward compatibility. New code can import toolkit/env directly.

type EnvCloner added in v1.0.0

type EnvCloner = envpkg.EnvCloner

EnvCloner is retained for backward compatibility.

type FileSystem

type FileSystem = filesystempkg.FileSystem

FileSystem is retained for backward compatibility. New code can import toolkit/filesystem directly.

type Hasher

type Hasher interface {
	Hash(data []byte) string
}

Hasher computes a deterministic short hash for a byte slice. Implementations should return a textual representation suitable for inclusion in meta fields.

var DefaultHasher Hasher = &MD5Hasher{}

DefaultHasher is the fallback hasher used when none is provided.

func OrDefaultHasher added in v1.0.0

func OrDefaultHasher(h Hasher) Hasher

OrDefaultHasher returns h unless it is nil, in which case DefaultHasher is returned.

type Jailed added in v1.0.0

type Jailed = jailpkg.Jailed

Jailed is retained for backward compatibility. New code can import toolkit/jail directly.

type MD5Hasher

type MD5Hasher struct{}

MD5Hasher is a simple Hasher implementation that returns an MD5 hex digest.

Note: MD5 is used here for deterministic, compact hashes only and is not intended for cryptographic integrity protection.

func (*MD5Hasher) Hash

func (m *MD5Hasher) Hash(data []byte) string

Hash implements Hasher by returning the lowercase hex MD5 of the trimmed input bytes.

type OsEnv

type OsEnv = envpkg.OsEnv

OsEnv is retained for backward compatibility.

type OsFS added in v1.0.0

type OsFS = filesystempkg.OsFS

OsFS is retained for backward compatibility.

func NewOsFS added in v1.0.0

func NewOsFS(jail, wd string) (*OsFS, error)

NewOsFS is retained for backward compatibility.

type ProcessInfo added in v1.1.0

type ProcessInfo struct {
	PID       int       // os.Getpid()
	Hostname  string    // os.Hostname()
	StartedAt time.Time // process start time
	UID       string    // unique instance ID (UUID)
}

ProcessInfo identifies the current process for lock ownership and stale lock detection.

func NewProcessInfo added in v1.1.0

func NewProcessInfo(c clock.Clock) ProcessInfo

NewProcessInfo creates ProcessInfo for the current OS process.

type Runtime added in v1.0.0

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime is the explicit dependency container for commands and helpers.

Context values are not used for mutable runtime dependencies; callers pass a Runtime directly.

func NewOsRuntime added in v1.0.0

func NewOsRuntime() (*Runtime, error)

func NewRuntime added in v1.0.0

func NewRuntime(opts ...RuntimeOption) (*Runtime, error)

NewRuntime constructs a Runtime with defaults and applies options.

func NewTestRuntime added in v1.0.0

func NewTestRuntime(jail, home, user string, opts ...RuntimeOption) (*Runtime, error)

NewTestRuntime constructs a runtime configured for tests with in-memory env and a jailed filesystem. Callers may override defaults via runtime options.

func (*Runtime) AbsPath added in v1.0.0

func (rt *Runtime) AbsPath(rel string) (string, error)

AbsPath returns a cleaned absolute runtime path based on runtime env/cwd.

func (*Runtime) AppendFile added in v1.2.0

func (rt *Runtime) AppendFile(rel string, data []byte, perm os.FileMode) error

func (*Runtime) AtomicWriteFile added in v1.0.0

func (rt *Runtime) AtomicWriteFile(rel string, data []byte, perm os.FileMode) error

func (*Runtime) Clock added in v1.0.0

func (rt *Runtime) Clock() clock.Clock

Clock returns the runtime clock dependency.

func (*Runtime) Clone added in v1.0.0

func (rt *Runtime) Clone() *Runtime

Clone returns a shallow clone of runtime dependencies and deep-copies Env and Stream when supported.

func (*Runtime) Env added in v1.0.0

func (rt *Runtime) Env() Env

Env returns the runtime Env dependency.

func (*Runtime) Environ added in v1.0.0

func (rt *Runtime) Environ() []string

func (*Runtime) FS added in v1.0.0

func (rt *Runtime) FS() FileSystem

FS returns the runtime FileSystem dependency.

func (*Runtime) Get added in v1.0.0

func (rt *Runtime) Get(key string) string

func (*Runtime) GetHome added in v1.0.0

func (rt *Runtime) GetHome() (string, error)

func (*Runtime) GetJail added in v1.0.0

func (rt *Runtime) GetJail() string

GetJail returns the canonical runtime jail.

func (*Runtime) GetTempDir added in v1.0.0

func (rt *Runtime) GetTempDir() string

func (*Runtime) GetUser added in v1.0.0

func (rt *Runtime) GetUser() (string, error)

func (*Runtime) Getwd added in v1.0.0

func (rt *Runtime) Getwd() (string, error)

Getwd returns the canonical runtime working directory.

func (*Runtime) Glob added in v1.0.0

func (rt *Runtime) Glob(pattern string) ([]string, error)

func (*Runtime) Has added in v1.0.0

func (rt *Runtime) Has(key string) bool

func (*Runtime) Hasher added in v1.0.0

func (rt *Runtime) Hasher() Hasher

Hasher returns the runtime hasher dependency.

func (*Runtime) Logger added in v1.0.0

func (rt *Runtime) Logger() *slog.Logger

Logger returns the runtime logger dependency.

func (*Runtime) Mkdir added in v1.0.0

func (rt *Runtime) Mkdir(rel string, perm os.FileMode, all bool) error

func (*Runtime) Name added in v1.0.0

func (rt *Runtime) Name() string

func (*Runtime) Process added in v1.1.0

func (rt *Runtime) Process() *ProcessInfo

Process returns the optional process identity for lock ownership. Returns nil when no process info was configured.

func (*Runtime) ReadDir added in v1.0.0

func (rt *Runtime) ReadDir(rel string) ([]os.DirEntry, error)

func (*Runtime) ReadFile added in v1.0.0

func (rt *Runtime) ReadFile(rel string) ([]byte, error)

func (*Runtime) Rel added in v1.0.0

func (rt *Runtime) Rel(basePath, targetPath string) (string, error)

func (*Runtime) RelativePath added in v1.0.0

func (rt *Runtime) RelativePath(basepath, path string) string

RelativePath returns path relative to basepath. If computation fails, target absolute path is returned.

func (*Runtime) Remove added in v1.0.0

func (rt *Runtime) Remove(rel string, all bool) error

func (*Runtime) Rename added in v1.0.0

func (rt *Runtime) Rename(src, dst string) error

func (*Runtime) ResolvePath added in v1.0.0

func (rt *Runtime) ResolvePath(rel string, follow bool) (string, error)

ResolvePath resolves rel to an absolute path and optionally follows symlinks.

func (*Runtime) Set added in v1.0.0

func (rt *Runtime) Set(key, value string) error

func (*Runtime) SetClock added in v1.0.0

func (rt *Runtime) SetClock(c clock.Clock) error

SetClock updates the runtime clock dependency.

func (*Runtime) SetHasher added in v1.0.0

func (rt *Runtime) SetHasher(h Hasher) error

SetHasher updates the runtime hasher dependency.

func (*Runtime) SetHome added in v1.0.0

func (rt *Runtime) SetHome(home string) error

func (*Runtime) SetJail added in v1.0.0

func (rt *Runtime) SetJail(jailPath string) error

SetJail sets the canonical runtime jail and propagates it to both Env and FS.

func (*Runtime) SetLogger added in v1.0.0

func (rt *Runtime) SetLogger(lg *slog.Logger) error

SetLogger updates the runtime logger dependency.

func (*Runtime) SetStream added in v1.0.0

func (rt *Runtime) SetStream(s *Stream) error

SetStream updates the runtime stream dependency.

func (*Runtime) SetUser added in v1.0.0

func (rt *Runtime) SetUser(user string) error

func (*Runtime) Setwd added in v1.0.0

func (rt *Runtime) Setwd(dir string) error

Setwd sets the canonical runtime working directory and propagates it to both Env and FileSystem.

func (*Runtime) Stat added in v1.0.0

func (rt *Runtime) Stat(rel string, follow bool) (os.FileInfo, error)

func (*Runtime) Stream added in v1.0.0

func (rt *Runtime) Stream() *Stream

Stream returns the runtime stream dependency.

func (rt *Runtime) Symlink(oldName, newName string) error

func (*Runtime) Unset added in v1.0.0

func (rt *Runtime) Unset(key string)

func (*Runtime) Validate added in v1.0.0

func (rt *Runtime) Validate() error

Validate ensures required runtime dependencies are present.

func (*Runtime) WriteFile added in v1.0.0

func (rt *Runtime) WriteFile(rel string, data []byte, perm os.FileMode) error

type RuntimeOption added in v1.0.0

type RuntimeOption func(*Runtime) error

RuntimeOption mutates Runtime construction.

func WithProcessInfo added in v1.1.0

func WithProcessInfo(p ProcessInfo) RuntimeOption

func WithRuntimeClock added in v1.0.0

func WithRuntimeClock(c clock.Clock) RuntimeOption

func WithRuntimeEnv added in v1.0.0

func WithRuntimeEnv(env Env) RuntimeOption

func WithRuntimeFileSystem added in v1.0.0

func WithRuntimeFileSystem(fs FileSystem) RuntimeOption

func WithRuntimeHasher added in v1.0.0

func WithRuntimeHasher(h Hasher) RuntimeOption

func WithRuntimeJail added in v1.0.0

func WithRuntimeJail(jailPath string) RuntimeOption

func WithRuntimeLogger added in v1.0.0

func WithRuntimeLogger(lg *slog.Logger) RuntimeOption

func WithRuntimeStream added in v1.0.0

func WithRuntimeStream(s *Stream) RuntimeOption

type Stream

type Stream struct {
	// In is the input stream, typically os.Stdin.
	In io.Reader
	// Out is the output stream, typically os.Stdout.
	Out io.Writer
	// Err is the error stream, typically os.Stderr.
	Err io.Writer

	// IsPiped indicates whether stdin appears to be piped or redirected.
	IsPiped bool
	// IsTTY indicates whether stdout refers to a terminal.
	IsTTY bool
}

Stream models the standard IO streams and common stream properties.

Struct field tags are included for clarity to external consumers that may wish to encode some stream metadata. The actual reader and writer fields are not suitable for encoding and therefore are tagged to be ignored.

func DefaultStream

func DefaultStream() *Stream

DefaultStream returns a Stream configured with the real process standard input, output, and error streams. It detects whether stdin is piped and whether stdout is a terminal.

func OrDefaultStream added in v1.0.0

func OrDefaultStream(s *Stream) *Stream

OrDefaultStream returns s unless it is nil, in which case DefaultStream() is returned.

type TestEnv

type TestEnv = envpkg.TestEnv

TestEnv is retained for backward compatibility.

func NewTestEnv

func NewTestEnv(jail, home, username string) *TestEnv

NewTestEnv is retained for backward compatibility.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL