unix

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 18, 2026 License: MIT Imports: 7 Imported by: 7

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

func NewCmd(cmd *exec.Cmd) Cmd

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

type GetDirFunc func(context.Context) (string, bool)

GetDirFunc is function which reads the working directory from shell context

type GetEnvFunc

type GetEnvFunc func(context.Context) iter.Seq2[string, string]

GetEnvFunc is functions which gets a copy of the environment from shell context

type LookupEnvFunc

type LookupEnvFunc func(context.Context, string) (string, bool)

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

type StandardIO interface {
	Stdin() io.Reader
	Stdout() io.Writer
	Stderr() io.Writer
}

StandardIO defines a unix compatible standard input output interface. All compatible filters uses this to get an access to stdio resources.

type Stdio

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

func NewStdio

func NewStdio(stdin io.Reader, stdout io.Writer, stderr io.Writer) Stdio

func (Stdio) Stderr

func (s Stdio) Stderr() io.Writer

func (Stdio) Stdin

func (s Stdio) Stdin() io.Reader

func (Stdio) Stdout

func (s Stdio) Stdout() io.Writer

Jump to

Keyboard shortcuts

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