script

package module
v2.1.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2019 License: MIT Imports: 18 Imported by: 0

README

go-script

Go library facilitating the creation of programs that resemble bash scripts.

Rationale

Go's advantages like static binding and a huge modern standard library do suggest its usage for little tools that used to be implemented as shell scripts.

This library is intended as a wrapper for typical tasks shell scripts include and aimed at bringing the LOC size closer to unparalleled bash shortness.

go-script uses several other libraries that enable you to create scripts with a good user feedback and user interface on the command line.

This library strives for a good test coverage even though it is not always easy for user facing code like this.

Methods

GoDoc CircleCI Coverage Status Go Report Card

The methods include helpers for executing external commands (including environment variables), maintaining a working directory, handling files and directories (cp/mv), and evaluating command output (exit code, stdout/stderr). You can use methods for requesting input from users, print progress bars and activity indicators, and use helpers for printing colorful or bold text.

Usage

package main

import (
	"fmt"
	"github.com/jojomi/go-script"
)

func main() {
	sc := script.NewContext()
	sc.MustCommandExist("date")
	sc.SetWorkingDir("/tmp")
	pr := sc.MustExecuteSilent("date", "-R")
	fmt.Print("The current date: ", pr.Output())
	fmt.Println(pr.StateString())
}

More example can be found in the examples directory, execute them like this:

go run examples/command-checking/command-checking.go

Warning

This library's API is not yet stable. Use at your own discretion.

You should be prepared for future API changes of any kind.

In doubt, fork away to keep a certain API status or use vendoring (dep) to keep your desired state.

On The Shoulders or Giants

Libraries Used in go-script
  • go-isatty to detect terminal capabilities

  • survey for user interactions

  • wow for activity indicators

  • pb for progress bars

  • color for printing colorful and bold output

  • go-shutil (forked) for copying data

  • afero for abstracting filesystem for easier testing

Other Libraries

Some libraries have proven highly useful in conjunction with go-script:

More inspiration can be found at awesome-go.

Development

Comments, issues, and of course pull requests are highly welcome.

If you create a Merge Request, be sure to execute ./precommit.sh beforehand.

License

see LICENSE

Documentation

Overview

Package script is a library facilitating the creation of programs that resemble bash scripts.

forked from https://github.com/termie/go-shutil

Index

Constants

This section is empty.

Variables

View Source
var RecoverFunc = func() {
	if r := recover(); r != nil {
		os.Stderr.WriteString(fmt.Sprintf("%v\n", r))
	}
}

RecoverFunc prints any panic message to Stderr

Functions

func Copy

func Copy(fs afero.Fs, src, dst string, followSymlinks bool) (string, error)

Copy data and mode bits ("cp src dst"). Return the file's destination.

The destination may be a directory.

If followSymlinks is false, symlinks won't be followed. This resembles GNU's "cp -P src dst".

If source and destination are the same file, a SameFileError will be rased.

func CopyFile

func CopyFile(fs afero.Fs, src, dst string, followSymlinks bool) error

CopyFile copies data from src to dst

func CopyMode

func CopyMode(fs afero.Fs, src, dst string, followSymlinks bool) error

CopyMode copies mode bits from src to dst.

func CopyTree

func CopyTree(fs afero.Fs, src, dst string, options *CopyTreeOptions) error

Recursively copy a directory tree.

The destination directory must not already exist.

If the optional Symlinks flag is true, symbolic links in the source tree result in symbolic links in the destination tree; if it is false, the contents of the files pointed to by symbolic links are copied. If the file pointed by the symlink doesn't exist, an error will be returned.

You can set the optional IgnoreDanglingSymlinks flag to true if you want to silence this error. Notice that this has no effect on platforms that don't support os.Symlink.

The optional ignore argument is a callable. If given, it is called with the `src` parameter, which is the directory being visited by CopyTree(), and `names` which is the list of `src` contents, as returned by ioutil.ReadDir():

callable(src, entries) -> ignoredNames

Since CopyTree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the `src` directory that should not be copied.

The optional copyFunction argument is a callable that will be used to copy each file. It will be called with the source path and the destination path as arguments. By default, Copy() is used, but any function that supports the same signature (like Copy2() when it exists) can be used.

func SplitCommand

func SplitCommand(input string) (command string, args []string)

SplitCommand helper splits a string to command and arbitrarily many args. Does handle bash-like escaping (\) and string delimiters " and '.

Types

type AlreadyExistsError

type AlreadyExistsError struct {
	Dst string
}

func (AlreadyExistsError) Error

func (e AlreadyExistsError) Error() string

type Command

type Command interface {
	Binary() string
	Args() []string
	Add(input string)
	AddAll(input ...string)
	String() string
}

type CommandConfig

type CommandConfig struct {
	RawStdout    bool
	RawStderr    bool
	OutputStdout bool
	OutputStderr bool
	ConnectStdin bool
	Detach       bool
}

CommandConfig defines details of command execution.

type Context

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

Context for script operations. A Context includes the working directory and provides access the buffers and results of commands run in the Context. Using different Contexts it is possible to handle multiple separate environments.

func NewContext

func NewContext() (context *Context)

NewContext returns a pointer to a new Context.

func (*Context) AbsPath

func (c *Context) AbsPath(filename string) string

AbsPath returns the absolute path of the path given. If the input path is absolute, it is returned untouched except for removing trailing path separators. Otherwise the absolute path is built relative to the current working directory of the Context. This function always returns a path *without* path separator at the end. See AbsPathSep for one that adds it.

func (*Context) AbsPathSep

func (c *Context) AbsPathSep(filename string) string

AbsPathSep is a variant of AbsPath that always adds a trailing path separator

func (Context) ActivityIndicator

func (c Context) ActivityIndicator(text string) *wow.Wow

ActivityIndicator returns an activity indicator with specified text and default animation.

func (Context) ActivityIndicatorCustom

func (c Context) ActivityIndicatorCustom(text string, typ spin.Name) *wow.Wow

ActivityIndicatorCustom returns an activity indicator as specified. Use Start() to start and Stop() to stop it. See: https://godoc.org/github.com/gernest/wow

func (*Context) CommandExists

func (c *Context) CommandExists(name string) bool

CommandExists checks if a given binary exists in PATH.

func (*Context) CommandPath

func (c *Context) CommandPath(name string) (path string)

CommandPath finds the full path of a binary given its name. also see https://golang.org/pkg/os/exec/#LookPath

func (*Context) CopyDir

func (c *Context) CopyDir(src, dst string) error

CopyDir copies a directory. Cross-device copying is supported, so directories can be copied from and to tmpfs mounts.

func (*Context) CopyFile

func (c *Context) CopyFile(from, to string) error

CopyFile copies a file. Cross-device copying is supported, so files can be copied from and to tmpfs mounts.

func (*Context) DirExists

func (c *Context) DirExists(path string) bool

DirExists checks if a given filename exists (being a directory).

func (*Context) EnsureDirExists

func (c *Context) EnsureDirExists(dirname string, perm os.FileMode) error

EnsureDirExists ensures a directory with the given name exists. This function panics if it is unable to find or create a directory as requested. TODO also check if permissions are less than requested and update if possible

func (*Context) EnsurePathForFile

func (c *Context) EnsurePathForFile(filename string, perm os.FileMode) error

EnsurePathForFile guarantees the path for a given filename to exist. If the directory is not yet existing, it will be created using the permission mask given. TODO also check if permissions are less than requested and update if possible

func (*Context) Execute

func (c *Context) Execute(cc CommandConfig, command Command) (pr *ProcessResult, err error)

Execute executes a system command according to given CommandConfig.

func (*Context) ExecuteDebug

func (c *Context) ExecuteDebug(command Command) (pr *ProcessResult, err error)

ExecuteDebug executes a system command, stdout and stderr are piped

func (*Context) ExecuteDetachedDebug

func (c *Context) ExecuteDetachedDebug(command Command) (pr *ProcessResult, err error)

ExecuteDetachedDebug executes a system command, stdout and stderr are piped. The command is executed in the background (detached).

func (*Context) ExecuteDetachedFullySilent

func (c *Context) ExecuteDetachedFullySilent(command Command) (pr *ProcessResult, err error)

ExecuteDetachedFullySilent executes a system command without outputting stdout or stderr (both are still captured and can be retrieved using the returned ProcessResult). The command is executed in the background (detached).

func (*Context) ExecuteDetachedSilent

func (c *Context) ExecuteDetachedSilent(command Command) (pr *ProcessResult, err error)

ExecuteDetachedSilent executes a system command without outputting stdout (it is still captured and can be retrieved using the returned ProcessResult). The command is executed in the background (detached).

func (*Context) ExecuteFullySilent

func (c *Context) ExecuteFullySilent(command Command) (pr *ProcessResult, err error)

ExecuteFullySilent executes a system command without outputting stdout or stderr (both are still captured and can be retrieved using the returned ProcessResult)

func (*Context) ExecuteRaw

func (c *Context) ExecuteRaw(command Command) (pr *ProcessResult, err error)

ExecuteRaw executes a system command without touching stdout and stderr.

func (*Context) ExecuteSilent

func (c *Context) ExecuteSilent(command Command) (pr *ProcessResult, err error)

ExecuteSilent executes a system command without outputting stdout (it is still captured and can be retrieved using the returned ProcessResult)

func (*Context) FileExists

func (c *Context) FileExists(filename string) bool

FileExists checks if a given filename exists (being a file).

func (Context) FileHasContent

func (c Context) FileHasContent(filename, search string) (bool, error)

FileHasContent func

func (Context) FileHasContentRegexp

func (c Context) FileHasContentRegexp(filename, searchRegexp string) (bool, error)

FileHasContentRegexp func

func (Context) IsTerminal

func (c Context) IsTerminal() bool

IsTerminal returns if this program is run inside an interactive terminal

func (*Context) IsUserRoot

func (c *Context) IsUserRoot() bool

IsUserRoot checks if a user is root priviledged (Linux and Mac only? Windows?)

func (*Context) MoveDir

func (c *Context) MoveDir(from, to string) error

MoveDir moves a directory. Cross-device moving is supported, so directories can be moved from and to tmpfs mounts.

func (*Context) MoveFile

func (c *Context) MoveFile(from, to string) error

MoveFile moves a file. Cross-device moving is supported, so files can be moved from and to tmpfs mounts.

func (*Context) MustCommandExist

func (c *Context) MustCommandExist(name string)

MustCommandExist ensures a given binary exists in PATH, otherwise panics.

func (*Context) MustExecuteDebug

func (c *Context) MustExecuteDebug(command Command) (pr *ProcessResult)

MustExecuteDebug ensures a system command to be executed, otherwise panics

func (*Context) MustExecuteFullySilent

func (c *Context) MustExecuteFullySilent(command Command) (pr *ProcessResult)

MustExecuteFullySilent ensures a system command to be executed without outputting stdout and stderr, otherwise panics

func (*Context) MustExecuteSilent

func (c *Context) MustExecuteSilent(command Command) (pr *ProcessResult)

MustExecuteSilent ensures a system command to be executed without outputting stdout, otherwise panics

func (Context) ProgressFileReader

func (c Context) ProgressFileReader(f *os.File) (io.Reader, *pb.ProgressBar, error)

ProgressFileReader returns a reader that is able to visualize read progress for a file.

func (Context) ProgressReader

func (c Context) ProgressReader(reader io.Reader, size int) (io.Reader, *pb.ProgressBar)

ProgressReader returns a reader that is able to visualize read progress.

func (Context) ReplaceInFile

func (c Context) ReplaceInFile(filename, searchRegexp, replacement string) error
func (c *Context) ResolveSymlinks(dir string) error

ResolveSymlinks resolve symlinks in a directory. All symlinked files are replaced with copies of the files they point to. Only one level symlinks are currently supported.

func (*Context) SetEnv

func (c *Context) SetEnv(key, value string)

SetEnv sets a certain environment variable for this context

func (*Context) SetWorkingDir

func (c *Context) SetWorkingDir(workingDir string)

SetWorkingDir changes the current working dir

func (*Context) SetWorkingDirTemp

func (c *Context) SetWorkingDirTemp() error

SetWorkingDirTemp changes the current working dir to a temporary directory, returning an error in case something went wrong

func (*Context) TempDir

func (c *Context) TempDir() (string, error)

TempDir returns a temporary directory and an error if one occurred

func (*Context) TempFile

func (c *Context) TempFile() (*os.File, error)

TempFile returns a temporary file and an error if one occurred

func (Context) WaitCmd

func (c Context) WaitCmd(pr *ProcessResult)

WaitCmd waits for a command to be finished (useful on detached processes).

func (*Context) WithTrailingPathSep

func (c *Context) WithTrailingPathSep(input string) string

WithTrailingPathSep adds a trailing os.PathSeparator to a string if it is missing

func (*Context) WithoutTrailingPathSep

func (c *Context) WithoutTrailingPathSep(input string) string

WithoutTrailingPathSep trims trailing os.PathSeparator from a string

func (*Context) WorkingDir

func (c *Context) WorkingDir() string

WorkingDir retrieves the current working dir

type CopyTreeOptions

type CopyTreeOptions struct {
	CopyFunction func(afero.Fs, string, string, bool) (string, error)
	Ignore       func(string, []os.FileInfo) []string
}

type LocalCommand

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

func LocalCommandFrom

func LocalCommandFrom(command string) *LocalCommand

func NewLocalCommand

func NewLocalCommand() *LocalCommand

func (*LocalCommand) Add

func (l *LocalCommand) Add(input string)

func (*LocalCommand) AddAll

func (l *LocalCommand) AddAll(input ...string)

func (*LocalCommand) Args

func (l *LocalCommand) Args() []string

func (*LocalCommand) Binary

func (l *LocalCommand) Binary() string

func (*LocalCommand) String

func (l *LocalCommand) String() string

type NotADirectoryError

type NotADirectoryError struct {
	Src string
}

func (NotADirectoryError) Error

func (e NotADirectoryError) Error() string

type ProcessResult

type ProcessResult struct {
	Cmd          *exec.Cmd
	Process      *os.Process
	ProcessState *os.ProcessState
	ProcessError error
	// contains filtered or unexported fields
}

ProcessResult contains the results of a process execution be it successful or not.

func NewProcessResult

func NewProcessResult() *ProcessResult

NewProcessResult creates a new empty ProcessResult

func (*ProcessResult) Error

func (pr *ProcessResult) Error() string

Error returns a string representation of the stderr output of the process denoted by this struct.

func (*ProcessResult) ExitCode

func (pr *ProcessResult) ExitCode() (int, error)

ExitCode returns the exit code of the command denoted by this struct

func (*ProcessResult) Output

func (pr *ProcessResult) Output() string

Output returns a string representation of the output of the process denoted by this struct.

func (*ProcessResult) StateString

func (pr *ProcessResult) StateString() string

StateString returns a string representation of the process denoted by this struct

func (*ProcessResult) Successful

func (pr *ProcessResult) Successful() bool

Successful returns true iff the process denoted by this struct was run successfully. Success is defined as the exit code being set to 0.

type SameFileError

type SameFileError struct {
	Src string
	Dst string
}

func (SameFileError) Error

func (e SameFileError) Error() string

type SpecialFileError

type SpecialFileError struct {
	File     string
	FileInfo os.FileInfo
}

func (SpecialFileError) Error

func (e SpecialFileError) Error() string

Directories

Path Synopsis
examples
test
bin

Jump to

Keyboard shortcuts

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