-
Notifications
You must be signed in to change notification settings - Fork 32
/
result.go
123 lines (104 loc) · 2.35 KB
/
result.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package wrap
import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"text/template"
"github.com/Songmu/wrapcommander"
)
type result struct {
Cmd []string
Name, Note string
Output string `json:"-"`
ExitCode int
Signaled bool
Msg string
Success bool
}
var reg = regexp.MustCompile(`[^-a-zA-Z0-9_]`)
func normalizeName(str string) string {
return reg.ReplaceAllString(strings.TrimSpace(str), "_")
}
func (re *result) checkName() string {
if re.Name != "" {
return re.Name
}
sum := md5.Sum([]byte(strings.Join(re.Cmd, " ")))
return fmt.Sprintf("mkrwrap-%s-%x",
normalizeName(filepath.Base(re.Cmd[0])),
sum[0:3])
}
func (re *result) resultFile() string {
return filepath.Join(os.TempDir(), fmt.Sprintf("mkrwrap-%s.json", re.checkName()))
}
func (re *result) loadLastResult() (*result, error) {
prevRe := &result{}
fname := re.resultFile()
f, err := os.Open(fname)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
defer f.Close()
err = json.NewDecoder(f).Decode(prevRe)
return prevRe, err
}
func (re *result) saveResult() error {
fname := re.resultFile()
tmpf, err := ioutil.TempFile(filepath.Dir(fname), "tmp-mkrwrap")
if err != nil {
return err
}
defer func(tmpfname string) {
tmpf.Close()
os.Remove(tmpfname)
}(tmpf.Name())
if err := json.NewEncoder(tmpf).Encode(re); err != nil {
return err
}
if err := tmpf.Close(); err != nil {
return err
}
return os.Rename(tmpf.Name(), fname)
}
func (re *result) errorEnd(format string, err error) *result {
re.Msg = fmt.Sprintf(format, err)
re.ExitCode = wrapcommander.ResolveExitCode(err)
return re
}
const msgTplText = `{{.Msg}}
{{- if ne .Note "" }}
Note: {{.Note}}{{end}}
% {{.Command}}
{{- if .Detail }}
{{.Output}}{{end}}`
var msgTpl *template.Template
func init() {
msgTpl = template.Must(template.New("msg").Parse(msgTplText))
}
func (re *result) buildMsg(detail bool) string {
s := struct {
Msg, Note, Command, Output string
Detail bool
}{
re.Msg, re.Note, strings.Join(re.Cmd, " "), re.Output,
detail,
}
buf := &bytes.Buffer{}
template.Must(msgTpl.Clone()).Execute(buf, s)
msg := buf.String()
const messageLengthLimit = 1024
runes := []rune(msg)
if len(runes) > messageLengthLimit {
msg = string(runes[0:messageLengthLimit])
}
return msg
}