-
Notifications
You must be signed in to change notification settings - Fork 683
/
writer.go
75 lines (66 loc) · 1.32 KB
/
writer.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
package dexec
import (
"bytes"
"fmt"
"io"
"os"
"unicode/utf8"
)
func fixupWriter(o io.Writer, log func(string)) io.Writer {
if o == nil {
o = nilWriter{}
}
if _, isFile := o.(*os.File); isFile {
return o
}
o = &loggingWriter{
log: log,
writer: o,
}
return o
}
type nilWriter struct{}
func (nilWriter) Write(p []byte) (int, error) { return len(p), nil }
type loggingWriter struct {
log func(string)
writer io.Writer
}
func (l *loggingWriter) Write(p []byte) (n int, err error) {
n, err = l.writer.Write(p)
toLog := p[:n]
for len(toLog) > 0 {
nl := bytes.IndexByte(toLog, '\n')
var line []byte
if nl < 0 {
line = toLog
toLog = nil
} else {
line = toLog[:nl+1]
toLog = toLog[nl+1:]
}
if utf8.Valid(line) {
if utf8.RuneCount(line) > 80 {
truncated := line
for utf8.RuneCount(truncated) > 80 {
_, size := utf8.DecodeLastRune(truncated)
truncated = truncated[:len(truncated)-size]
}
l.log(fmt.Sprintf("%q… (%d runes truncated)",
truncated,
utf8.RuneCount(line)-utf8.RuneCount(truncated)))
} else {
l.log(fmt.Sprintf("%q", line))
}
} else {
l.log(fmt.Sprintf("[...%d bytes of binary data...]", len(line)))
}
}
if err != nil {
if err == io.EOF {
l.log("EOF")
} else {
l.log(fmt.Sprintf("error = %v", err))
}
}
return n, err
}