Documentation
¶
Overview ¶
Package unix implements unix like resources like standard io and provides an universal interface to execute the filters.
The main interface is Filter, which allows one to implement a Unix filter—a program consuming standard input and producing results on standard output. Below is the simplest filter in Go. Context-aware IO types like codeberg.org/gonix/gio.ContextReader typically handle context cancellation, simplifying this use case.
type cat struct{}
func (cat) Run(_ context.Context, stdio.StandardIO) error {
_, err := io.Copy(stdio.Stdout(), stdio.Stdin())
return err
}
Cmd wraps *os/exec.Cmd and provides a way for OS executables to be compatible with gonix.
The package defines multiple integration points for a shell, as Unix tools require context such as working directory, environment variables, and command-line arguments.
Functions GetDirFunc, GetEnvFunc, and LookupEnvFunc provide prototypes for accessing data from a shell context, while ShellContextConfig enables code to pass the proper functions to the filter. The implementation must be provided by a given shell like codeberg.org/gonix/sh.
FilterBuilderFunc implements a builder pattern that passes the command name, arguments, and shell context to the filter. FilterLookupFunc allows resolving the appropriate FilterBuilderFunc for a given command name, providing a lookup helper built on top of a map.
var bin = unix.FilterLookupFunc{
"gonix/cat": cat.FromArgs(),
"rust/wc": coreutils.Wc(),
}
Example ¶
package main
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"strings"
"codeberg.org/gonix/gio/pipe"
. "codeberg.org/gonix/gio/unix"
)
// Cat
// aka cat
type Cat struct {
cat []byte
}
func (c Cat) Run(ctx context.Context, stdio StandardIO) error {
buf := bytes.NewBuffer(c.cat)
_, err := io.Copy(stdio.Stdout(), buf)
return err
}
// CountLines counts a number of read lines
// aka wc -l
type CountLines struct{}
func (c CountLines) Run(ctx context.Context, stdio StandardIO) error {
counter := 0
r := bufio.NewScanner(stdio.Stdin())
for r.Scan() {
counter++
}
if r.Err() != nil {
return r.Err()
}
fmt.Fprintf(stdio.Stdout(), "%d\n", counter)
return nil
}
// Pipe runs commands via pipe
// err := NewPipe().Run(ctx, stdio, cat, wc)
// is cat | wc -l
type Pipe struct {
pipe.Line[byte]
}
func NewPipe() Pipe {
return Pipe{Line: pipe.NewLine[byte]()}
}
func (p Pipe) Pipefail(b bool) Pipe {
return Pipe{Line: p.Line.Pipefail(b)}
}
func (p Pipe) Run(ctx context.Context, stdio StandardIO, filters ...Filter) error {
pipeio := pipe.NewStdio[byte](stdio.Stdin(), stdio.Stdout(), stdio.Stderr())
pipefilters := make([]pipe.Filter[byte], len(filters))
for idx, f := range filters {
pipefilters[idx] = pipeFilter{filter: f}
}
return p.Line.Run(ctx, pipeio, pipefilters...)
}
type pipeFilter struct {
filter Filter
}
func (f pipeFilter) Run(ctx context.Context, stdio pipe.StandardIO[byte]) error {
unixio := NewStdio(stdio.Stdin(), stdio.Stdout(), stdio.Stderr())
return f.filter.Run(ctx, unixio)
}
func main() {
ctx := context.Background()
cat := Cat{
cat: []byte("three\nsmall\npigs\n"),
}
wc := CountLines{}
var out strings.Builder
stdio := NewStdio(
nil,
&out,
os.Stderr,
)
// an equivalent of cat | wc -l
err := NewPipe().Run(ctx, stdio, cat, wc)
if err != nil {
log.Fatal(err)
}
fmt.Println(out.String())
}
Output: 3
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cmd ¶
type Cmd struct {
// contains filtered or unexported fields
}
Exec is a wrapper of os/exec.Cmd providing a Filter compatible interface
func NewCmd ¶
NewCmd wraps exec.Cmd. The intended usage is
cmd := NewCmd(exec.Command("go", "version"))
func (Cmd) Run ¶
func (c Cmd) Run(ctx context.Context, stdio StandardIO) error
Run implements Filter interface for Cmd wrapper. It creates a _new_ instance of exec.Command under a hood, so any previous state is ignored here.
Returns a pipe.Error if Run results in *exec.ExitError. Code is ExitCode and Err is the *exec.ExitError
type Filter ¶
type Filter interface {
Run(context.Context, StandardIO) error
}
Filter is a basic abstraction of a unix command - it consumes stdin and provides output to stdout and errors to stderr. The standard io is an argument allowing programs to be connected via pipes or to consume any arbitrary sources or output anywhere.
type FilterBuilderFunc ¶
type FilterBuilderFunc func(command string, args []string, opts ...ShellContextOption) (Filter, error)
FilterBuilderFunc returns the function building the unix.Filter given the arguments and a configuration like where to obtain environment variables and so
type FilterLookupFunc ¶
type FilterLookupFunc func(command string) (FilterBuilderFunc, bool)
FilterLookupFunc returns a proper filter builder based on a command name
type FilterLookupMap ¶
type FilterLookupMap map[string]FilterBuilderFunc
FilterLookupMap provides a lookup on top of map[string]FilterBuilderFunc
func (FilterLookupMap) Lookup ¶
func (l FilterLookupMap) Lookup(command string) (FilterBuilderFunc, bool)
type GetDirFunc ¶
GetDirFunc is function which reads the working directory from shell context
type GetEnvFunc ¶
GetEnvFunc is functions which gets a copy of the environment from shell context
type LookupEnvFunc ¶
LookupEnvFunc is functions which lookups the environment value from a shell context
type ShellContextConfig ¶
type ShellContextConfig struct {
// contains filtered or unexported fields
}
func (ShellContextConfig) GetDirFunc ¶
func (c ShellContextConfig) GetDirFunc() GetDirFunc
GetDirFunc returns configured GetDirFunc - defaults to one returning "", false if nothing configured
func (ShellContextConfig) GetEnvFunc ¶
func (c ShellContextConfig) GetEnvFunc() GetEnvFunc
GetEnvFunc returns configured GetEnvFunc - defaults to empty iterator if nothing is configured
func (ShellContextConfig) LookupEnvFunc ¶
func (c ShellContextConfig) LookupEnvFunc() LookupEnvFunc
LookupEnvFunc returns configured LookupEnvFunc - defaults to empty iterator if nothing is configured
type ShellContextOption ¶
type ShellContextOption func(c ShellContextConfig) ShellContextConfig
ShellContextOption allows configure various options for passing extra shell context like a working dir or env variables
func WithGetDirFunc ¶
func WithGetDirFunc(f GetDirFunc) ShellContextOption
WithGetDirFunc passes the GetDirFunc into the builder
func WithGetEnvFunc ¶
func WithGetEnvFunc(f GetEnvFunc) ShellContextOption
WithGetDirFunc passes the GetEnvFunc into the builder
func WithLookupEnvFunc ¶
func WithLookupEnvFunc(f LookupEnvFunc) ShellContextOption
WithLookupEnvFunc passes the LokupEnvFunc into the builder
func WithShellContextConfig ¶
func WithShellContextConfig(cfg ShellContextConfig) ShellContextOption
WithShellContextConfig passes the existing shell config below
type StandardIO ¶
StandardIO defines a unix compatible standard input output interface. All compatible filters uses this to get an access to stdio resources.