execx

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2024 License: MIT Imports: 9 Imported by: 0

README

execx

Provides os/exec.Cmd wrappers.

import (
	"bytes"
	"context"
	"fmt"

	"github.com/berquerant/execx"
)

func main() {
	script := execx.NewScript(
		`echo line1
echo ${line2}
cat -
echo line3 > /dev/stderr`,
		"sh",
	)
	script.Env.Set("line2", "LINE2")

	if err := script.Runner(func(cmd *execx.Cmd) error {
		cmd.Stdin = bytes.NewBufferString("from stdin\n")
		_, err := cmd.Run(
			context.TODO(),
			execx.WithStdoutConsumer(func(x execx.Token) {
				fmt.Printf("1:%s\n", x)
			}),
			execx.WithStderrConsumer(func(x execx.Token) {
				fmt.Printf("2:%s\n", x)
			}),
		)
		return err
	}); err != nil {
		panic(err)
	}

	// Output:
	// 1:line1
	// 1:LINE2
	// 1:from stdin
	// 2:line3
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cmd

type Cmd struct {
	Args  []string
	Stdin io.Reader
	Dir   string
	Env   Env
}

Cmd is an external command.

func New

func New(name string, arg ...string) *Cmd

Create a new Cmd.

Set the current directory to [Cmd.Dir], current environment variables to [Cmd.Env].

func (Cmd) Run

func (c Cmd) Run(ctx context.Context, opt ...Option) (*Result, error)

Run executes the command.

If WithStdoutConsumer set, you can get the standard output of a command without waiting for the command to finish. If WithStderrConsumer set, you can get the standard error of a command without waiting for the command to finish. WithSplitFunc sets the split function for a scanner used in consumers, default is bufio.ScanLines. WithSplitSeparator sets the separator inserted between tokens when concatenating tokens passed to consumers, default is `[]byte("\n")`. If WithStdoutWriter set, write the standard output into it instead of [Result.Stdout]. If WithStderrWriter set, write the standard error into it instead of [Result.Stderr].

Example
package main

import (
	"context"
	"fmt"
	"io"
	"strings"

	"github.com/berquerant/execx"
)

func main() {
	cmd := execx.New("echo", "Hello, ${NAME}!")
	cmd.Env.Set("NAME", "world")
	r, err := cmd.Run(context.TODO())
	if err != nil {
		panic(err)
	}
	fmt.Println(strings.Join(r.ExpandedArgs, " "))
	b, err := io.ReadAll(r.Stdout)
	if err != nil {
		panic(err)
	}
	fmt.Print(string(b))

}
Output:

echo Hello, world!
Hello, world!

type Config

type Config struct {
	StdoutConsumer *ConfigItem[func(Token)]
	StderrConsumer *ConfigItem[func(Token)]
	SplitFunc      *ConfigItem[SplitFunc]
	SplitSeparator *ConfigItem[[]byte]
	StdoutWriter   *ConfigItem[io.Writer]
	StderrWriter   *ConfigItem[io.Writer]
}

func (*Config) Apply

func (s *Config) Apply(opt ...Option)

type ConfigBuilder

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

func NewConfigBuilder

func NewConfigBuilder() *ConfigBuilder

func (*ConfigBuilder) Build

func (s *ConfigBuilder) Build() *Config

func (*ConfigBuilder) SplitFunc added in v0.3.0

func (s *ConfigBuilder) SplitFunc(v SplitFunc) *ConfigBuilder

func (*ConfigBuilder) SplitSeparator added in v0.4.0

func (s *ConfigBuilder) SplitSeparator(v []byte) *ConfigBuilder

func (*ConfigBuilder) StderrConsumer

func (s *ConfigBuilder) StderrConsumer(v func(Token)) *ConfigBuilder

func (*ConfigBuilder) StderrWriter added in v0.4.0

func (s *ConfigBuilder) StderrWriter(v io.Writer) *ConfigBuilder

func (*ConfigBuilder) StdoutConsumer

func (s *ConfigBuilder) StdoutConsumer(v func(Token)) *ConfigBuilder

func (*ConfigBuilder) StdoutWriter added in v0.4.0

func (s *ConfigBuilder) StdoutWriter(v io.Writer) *ConfigBuilder

type ConfigItem

type ConfigItem[T any] struct {
	// contains filtered or unexported fields
}

func NewConfigItem

func NewConfigItem[T any](defaultValue T) *ConfigItem[T]

func (*ConfigItem[T]) Default

func (s *ConfigItem[T]) Default() T

func (*ConfigItem[T]) Get

func (s *ConfigItem[T]) Get() T

func (*ConfigItem[T]) IsModified

func (s *ConfigItem[T]) IsModified() bool

func (*ConfigItem[T]) Set

func (s *ConfigItem[T]) Set(value T)

type Env

type Env map[string]string

Env represents a set of environment variables.

func EnvFromEnviron

func EnvFromEnviron() Env

EnvFromEnviron creates a new Env from os.Environ.

func EnvFromSlice

func EnvFromSlice(envSlice []string) Env

EnvFromSlice creates a new Env from strings, in the form "key=value".

func NewEnv

func NewEnv() Env

NewEnv creates a new empty Env.

func (Env) Expand

func (e Env) Expand(target string) string

Expand expands environment variables in target.

func (Env) ExpandStrings

func (e Env) ExpandStrings(target []string) []string

ExpandStrings expands environment variables in multiple targets.

func (Env) Get

func (e Env) Get(key string) (string, bool)

func (Env) IntoSlice

func (e Env) IntoSlice() []string

IntoSlice converts into os.Environ format.

func (Env) Merge

func (e Env) Merge(other Env)

func (Env) Set

func (e Env) Set(key, value string)

type Option

type Option func(*Config)

func WithSplitFunc added in v0.3.0

func WithSplitFunc(v SplitFunc) Option

func WithSplitSeparator added in v0.4.0

func WithSplitSeparator(v []byte) Option

func WithStderrConsumer

func WithStderrConsumer(v func(Token)) Option

func WithStderrWriter added in v0.4.0

func WithStderrWriter(v io.Writer) Option

func WithStdoutConsumer

func WithStdoutConsumer(v func(Token)) Option

func WithStdoutWriter added in v0.4.0

func WithStdoutWriter(v io.Writer) Option

type Result

type Result struct {
	// ExpandedArgs is actual command.
	ExpandedArgs []string
	Stdout       io.Reader
	Stderr       io.Reader
}

Result is Cmd execution result.

type Script

type Script struct {
	// Shell executes Content.
	Shell []string
	// Content is a set of commands.
	Content string
	Env     Env
	// If KeepScriptFile is true, then do not regenerate script files,
	// and not reflect changes in Content and Env when calling Runner.
	KeepScriptFile bool
	// contains filtered or unexported fields
}

Script is an executable script, set of commands.

func NewScript

func NewScript(content string, shell string, arg ...string) *Script

NewScript creates a new Script.

func (*Script) Close added in v0.2.0

func (s *Script) Close() error

Close removes a temporary script file.

func (*Script) Runner

func (s *Script) Runner(f func(*Cmd) error) error

Runner creates a new Cmd and pass it to f.

Example
package main

import (
	"bytes"
	"context"
	"fmt"

	"github.com/berquerant/execx"
)

func main() {
	script := execx.NewScript(
		`echo line1
echo ${line2}
cat -
echo line3 > /dev/stderr`,
		"sh",
	)
	script.Env.Set("line2", "LINE2")

	if err := script.Runner(func(cmd *execx.Cmd) error {
		cmd.Stdin = bytes.NewBufferString("from stdin\n")
		_, err := cmd.Run(
			context.TODO(),
			execx.WithStdoutConsumer(func(x execx.Token) {
				fmt.Printf("1:%s\n", x)
			}),
			execx.WithStderrConsumer(func(x execx.Token) {
				fmt.Printf("2:%s\n", x)
			}),
		)
		return err
	}); err != nil {
		panic(err)
	}

}
Output:

1:line1
1:LINE2
1:from stdin
2:line3

type SplitFunc added in v0.3.0

type SplitFunc = bufio.SplitFunc

type Token added in v0.3.0

type Token interface {
	String() string
	Bytes() []byte
}

Jump to

Keyboard shortcuts

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