-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcapture.go
105 lines (94 loc) · 1.83 KB
/
capture.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package trial
import (
"bufio"
"log"
"os"
"strings"
)
type capture struct {
stdout *os.File
stderr *os.File
reader *os.File
writer *os.File
done chan struct{}
lines []string
logFlags int
}
// CaptureLog overrides the log output for reading
func CaptureLog() *capture {
reader, writer, _ := os.Pipe()
c := &capture{
logFlags: log.Flags(),
reader: reader,
writer: writer,
done: make(chan struct{}),
}
log.SetOutput(writer)
log.SetFlags(0)
go c.read()
return c
}
// CaptureStdErr redirects stderr for reading
// note this does not redirect log output
func CaptureStdErr() *capture {
reader, writer, _ := os.Pipe()
c := &capture{
stderr: os.Stderr,
reader: reader,
writer: writer,
done: make(chan struct{}),
}
os.Stderr = writer
go c.read()
return c
}
// CaptureStdOut redirects stdout for reading
func CaptureStdOut() *capture {
reader, writer, _ := os.Pipe()
c := &capture{
stdout: os.Stdout,
reader: reader,
writer: writer,
done: make(chan struct{}),
}
os.Stdout = writer
go c.read()
return c
}
func (c *capture) read() {
scanner := bufio.NewScanner(bufio.NewReader(c.reader))
for scanner.Scan() {
c.lines = append(c.lines, scanner.Text())
}
close(c.done)
}
// ReadAll stops the capturing of data and returns the collected data
func (c *capture) ReadAll() string {
c.reset()
<-c.done
return strings.Join(c.lines, "\n")
}
// ReadLines stops the capturing of data and returns the collected lines
func (c *capture) ReadLines() []string {
c.reset()
<-c.done
return c.lines
}
func (c *capture) reset() {
if c.writer != nil {
c.writer.Close()
c.writer = nil
}
if c.stderr != nil {
os.Stderr = c.stderr
c.stderr = nil
}
if c.logFlags != 0 {
log.SetFlags(c.logFlags)
log.SetOutput(os.Stderr)
}
if c.stdout != nil {
os.Stdout = c.stdout
c.stdout = nil
}
}