A command that captures pipeline output to custom io.Writer destinations instead of sending to stdout/stderr.
The capture command serves as a pipeline sink, allowing you to redirect command output to buffers, files, or any io.Writer implementation. This is particularly useful for:
- Testing pipelines and capturing their output
- Processing command output programmatically
- Storing results in memory for further manipulation
- Custom logging and output handling
import (
"bytes"
gloo "github.com/yupsh/framework"
"github.com/yupsh/capture"
"github.com/yupsh/grep"
"github.com/yupsh/pipe"
"github.com/yupsh/sort"
)
func main() {
// Create buffers to capture output
var stdout, stderr bytes.Buffer
// Build a pipeline that captures output
pipeline := pipe.Pipeline(
grep.Grep("ERROR"),
sort.Sort(),
capture.Capture(&stdout, &stderr),
)
// Run the pipeline
err := gloo.Run(pipeline)
if err != nil {
log.Fatal(err)
}
// Process the captured output
fmt.Printf("Captured %d bytes: %s\n", stdout.Len(), stdout.String())
}Creates a capture command that routes:
- stdin →
stdoutwriter - error messages →
stderrwriter
Parameters:
stdout:io.Writer- destination for captured standard outputstderr:io.Writer- destination for captured error output
Returns:
gloo.Command- a command that can be used in pipelines
var out bytes.Buffer
pipeline := pipe.Pipeline(
cat.Cat("file.txt"),
capture.Capture(&out, io.Discard),
)
gloo.MustRun(pipeline)
fmt.Println(out.String())// Equivalent to shell's 2>&1 - merge both streams to one writer
var combined bytes.Buffer
pipeline := pipe.Pipeline(
grep.Grep("pattern"),
capture.Capture(&combined, &combined),
)
gloo.MustRun(pipeline)
// combined contains both stdout and stderrvar buf bytes.Buffer
file, _ := os.Create("output.txt")
defer file.Close()
// Use io.MultiWriter to write to both
multi := io.MultiWriter(&buf, file)
pipeline := pipe.Pipeline(
grep.Grep("pattern"),
capture.Capture(multi, os.Stderr),
)
gloo.MustRun(pipeline)func TestPipeline(t *testing.T) {
var out, err bytes.Buffer
pipeline := pipe.Pipeline(
grep.Grep("test"),
capture.Capture(&out, &err),
)
if err := gloo.Run(pipeline); err != nil {
t.Fatal(err)
}
if out.String() != "expected output\n" {
t.Errorf("unexpected output: %s", out.String())
}
}- Input: Reads from stdin (the output of the previous command in the pipeline)
- Output: Writes to the provided
stdoutwriter - Errors: Writes to the provided
stderrwriter - Return: Returns any error that occurs during copying
- The capture command is always the last command in a pipeline (it's a sink)
- Both stdout and stderr writers must be non-nil
- Uses
io.Copyfor efficient streaming - Does not buffer the entire output in memory unless you use a buffer like
bytes.Buffer - Compatible with any
io.Writerimplementation
- tee - Write output to files while also passing it through
- pipe - Pipeline composition
- framework - Core command framework
GNU Affero General Public License v3.0 - see LICENSE file for details.