Documentation
¶
Overview ¶
Package script provides helper functions to write scripts.
Inspired by https://github.com/bitfield/script, with some improvements:
* Output between streamed commands is a stream and not loaded to memory.
* Better representation and handling of errors.
* Proper incocation, usage and handling of stderr of custom commands.
The script chain is represented by a (`Stream`) https://godoc.org/github.com/posener/script#Stream object. While each command in the stream is abstracted by the (`Command`) https://godoc.org/github.com/posener/script#Command struct. This library provides basic functionality, but can be extended freely.
Example (HelloWorld) ¶
A simple "hello world" example that creats a stream and pipe it to the stdout.
// Create an "hello world" stream and use the ToStdout method to write it to stdout. Echo("hello world").ToStdout()
Output: hello world
Example (Iterate) ¶
An example that shows how to iterate scanned lines.
// Stream can be any stream, in this case we have echoed 3 lines. stream := Echo("first\nsecond\nthird") // To iterate over the stream lines, it is better not to read it into memory and split over the // lines, but use the `bufio.Scanner`: defer stream.Close() scanner := bufio.NewScanner(stream) for scanner.Scan() { fmt.Println(scanner.Text()) }
Output: first second third
Example (PipeTo) ¶
An example that shows how to create custom commands using the `PipeTo` method with a `PipeFn` function.
Echo("1\n2\n3").PipeTo(func(r io.Reader) Command { // Create a command that sums up all numbers in input. // // In this example we create a reader function such that the whole code will fit into the // example function body. A more proper and readable way to do it was to create a new // type with a state that implements the `io.Reader` interface. // Use buffered reader to read lines from input. buf := bufio.NewReader(r) // Store the sum of all numbers. sum := 0 // Read function reads the next line and adds it to the sum. If it gets and EOF error, it // writes the sum to the output and returns an EOF. read := func(b []byte) (int, error) { // Read next line from input. line, _, err := buf.ReadLine() // if EOF write sum to output. if err == io.EOF { return copy(b, append([]byte(strconv.Itoa(sum)), '\n')), io.EOF } if err != nil { return 0, err } // Convert the line to a number and add it to the sum. if i, err := strconv.Atoi(string(line)); err == nil { sum += i } // We don't write anything to output, so we return 0 bytes with no error. return 0, nil } return Command{Name: "sum", Reader: readerFn(read)} }).ToStdout()
Output: 6
Index ¶
- type Command
- type Count
- type Cut
- type File
- type Files
- type Grep
- type Modifer
- type ModifierFn
- type PipeFn
- type Stream
- func (s Stream) AppendFile(path string) error
- func (s Stream) Close() error
- func (s Stream) Cut(fields ...int) Stream
- func (s Stream) Discard() error
- func (s Stream) Exec(cmd string, args ...string) Stream
- func (s Stream) ExecHandleStderr(errWriter io.Writer, cmd string, args ...string) Stream
- func (s Stream) Grep(re *regexp.Regexp) Stream
- func (s Stream) Head(n int) Stream
- func (s Stream) Modify(modifier Modifer) Stream
- func (s Stream) PipeTo(pipeFn PipeFn) Stream
- func (s Stream) Read(b []byte) (int, error)
- func (s Stream) Sort(reverse bool) Stream
- func (s Stream) ToFile(path string) error
- func (c Stream) ToStdout() error
- func (s Stream) ToString() (string, error)
- func (s Stream) ToTempFile() (path string, err error)
- func (s Stream) Uniq() Stream
- func (s Stream) Wc() Count
- type Uniq
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Command ¶
type Command struct { // Reader reads the output of the command. io.Reader // Closer closes the reader of the command. io.Closer // Name is the name of the command. Name string // contains filtered or unexported fields }
Command represents a single command in a stream. A valid command must have at least a non-nil `Reader` and not empty `Name`.
func (*Command) AppendError ¶
Append an error to the command.
type Count ¶
type Count struct { // Stream can be used to pipe the output of wc. Stream // Count the number of lines, words and chars in the input. Lines, Words, Chars int }
Count represents the output of `wc` shell command.
type Cut ¶
type Cut struct { // Fileds defines which fields will be collected to the output of the command. The fields are 1 // based (first field is 1). Fields []int // Delim is the delimited by which the fields of each line are sparated. Delim []byte }
Cut is a `Modifier` that takes selected fields from each line according to a given delimiter. The default delimiter is tab.
Shell command: `cut -d<Delim> -f<Fields>`.
type File ¶
type File struct { // FileInfo contains information about the file. os.FileInfo // Path is the path of the file. It may be relative or absolute, depending on how the `Ls` // command was invoked. Path string }
File contains information about a file.
type Files ¶
Files is a stream of a list of files. A user can eigher use the file list directly or the the created stream. In the stream, each line contains a path to a file.
func Ls ¶
Ls returns a stream of a list files. In the returned stream, each line will contain a path to a single file.
If the provided paths list is empty, the local directory will be listed.
The provided paths may be relative to the local directory or absolute - this will influence the format of the returned paths in the output.
If some provided paths correlate to the arguments correlate to the same file, it will also appear multiple times in the output.
If any of the paths fails to be listed, it will result in an error in the output, but the stream will still conain all paths that were successfully listed.
Shell command: `ls`.
type Grep ¶
Grep is a modifier that filters only line that match `Re`. If Invert was set only line that did not match the regex will be returned.
Usage:
(<Stream object>).Modify(script.Grep{Re: <re>})
Shell command: `grep [-v <Invert>] <Re>`.
type Modifer ¶
type Modifer interface { // Modify a line. The input of this function will always be a single line from the input of the // stream, without the trailing '\n'. It should return the output of the stream and should // append a trailing '\n' if it want it to be a line in the output. // // When EOF of input stream is met, the function will be called once more with a nil line value // to enable output any buffered data. // // When the return modified value is nil, the line will be dicarded. // // When the returned eof value is true, the Read will return that error. Modify(line []byte) (modifed []byte, err error) // Name returns the name of the command that will represent this modifier. Name() string }
Modifer modifies input lines to output. On each line of the input the Modify method is called, and the modifier can change it, omit it, or break the iteration.
type ModifierFn ¶
ModifierFn is a function for modifying input lines.
func (ModifierFn) Name ¶
func (m ModifierFn) Name() string
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream is a chain of commands: the stdout of each command in the stream feeds the following one. The stream object have different method that allow manipulating it, most of them resemble well known linux commands.
If a command which does not exist in this library is required, the `PipeTo` function should be used, which allows constructing a command object from a given input `io.Reader`.
The Stream object output can be used to be written to the stdout, to a file or to a string using the `.To*` methods. It also exposes an `io.ReadCloser` interface which allows the user using the stream output for any other usecase.
func ExecHandleStderr ¶
Exec executes a command, returns a stream of the stdout of the command and enable collecting the stderr of the command.
If the errWriter is nil, it will be ignored.
For example, collecting the stderr to memory can be done by providing a `&bytes.Buffer` as `errWriter`. Writing it to stderr can be done by providing `os.Stderr` as `errWriter`. Logging it to a file can be done by providing an `os.File` as the `errWriter`.
func FromReader ¶ added in v1.0.1
FromReader returns a new stream from a reader.
func (Stream) AppendFile ¶ added in v1.0.1
AppendFile appends the output of the stream to a file.
func (Stream) Close ¶
Close closes all the commands in the current stream and return the errors that occured in all of the commands by invoking the Error() function on each one of them.
func (Stream) Cut ¶
Cut takes selected fields from each line. The fields are 1 based (first field is 1).
Shell command: `cut -f<Fields>`.
func (Stream) ExecHandleStderr ¶
Exec executes a command, returns a stream of the stdout of the command and enable collecting the stderr of the command.
If the errWriter is nil, it will be ignored.
func (Stream) Grep ¶
Grep filters only line that match the given regexp.
Shell command: `grep <re>`.
func (Stream) Head ¶
Head reads only the n first lines of the given reader. If n is a negative number, the last (-n) lines will be returned.
Shell command: `head -n <n>` / `tail -n <-n>`.
func (Stream) PipeTo ¶
PipeTo pipes the current stream to a new command and return the new stream. This function should be used to add custom commands that are not available in this library.
func (Stream) ToTempFile ¶ added in v1.0.1
ToTempFile dumps the output of the stream to a temporary file and returns the temporary files' path.