1package script
2
3import (
4	"bytes"
5	"io"
6	"io/ioutil"
7	"os"
8	"path/filepath"
9
10	"github.com/hashicorp/go-multierror"
11)
12
13// To writes the output of the stream to an io.Writer and closes it.
14func (s Stream) To(w io.Writer) error {
15	var errors *multierror.Error
16	if _, err := io.Copy(w, s); err != nil {
17		errors = multierror.Append(errors, err)
18	}
19	if err := s.Close(); err != nil {
20		errors = multierror.Append(errors, err)
21	}
22	return errors.ErrorOrNil()
23}
24
25func (s Stream) Iterate(iterator func(line []byte) error) error {
26	return s.Modify(ModifyFn(func(line []byte) (modifed []byte, err error) {
27		err = iterator(line)
28		return nil, err
29	})).To(ioutil.Discard)
30}
31
32type iterator struct{}
33
34// ToStdout pipes the stdout of the stream to screen.
35func (s Stream) ToStdout() error {
36	return s.To(os.Stdout)
37}
38
39// ToString reads stdout of the stream and returns it as a string.
40func (s Stream) ToString() (string, error) {
41	var out bytes.Buffer
42	err := s.To(&out)
43	return out.String(), err
44
45}
46
47// ToFile dumps the output of the stream to a file.
48func (s Stream) ToFile(path string) error {
49	f, err := File(path)
50	if err != nil {
51		return err
52	}
53	defer f.Close()
54	return s.To(f)
55}
56
57// AppendFile appends the output of the stream to a file.
58func (s Stream) AppendFile(path string) error {
59	f, err := AppendFile(path)
60	if err != nil {
61		return err
62	}
63	defer f.Close()
64	return s.To(f)
65}
66
67// ToTempFile dumps the output of the stream to a temporary file and returns the temporary files'
68// path.
69func (s Stream) ToTempFile() (path string, err error) {
70	f, err := ioutil.TempFile("", "script-")
71	if err != nil {
72		return "", err
73	}
74	defer f.Close()
75	return f.Name(), s.To(f)
76}
77
78// Discard executes the stream pipeline but discards the output.
79func (s Stream) Discard() error {
80	return s.To(ioutil.Discard)
81}
82
83func File(path string) (io.WriteCloser, error) {
84	err := makeDir(path)
85	if err != nil {
86		return nil, err
87	}
88	return os.Create(path)
89}
90
91func AppendFile(path string) (io.WriteCloser, error) {
92	err := makeDir(path)
93	if err != nil {
94		return nil, err
95	}
96	if _, err := os.Stat(path); err != nil {
97		return File(path)
98	}
99	return os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0666)
100}
101
102func makeDir(path string) error {
103	return os.MkdirAll(filepath.Dir(path), 0775)
104}
105