This repository has been archived by the owner on Aug 17, 2022. It is now read-only.
/
util.go
executable file
·137 lines (127 loc) · 3.2 KB
/
util.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
_ "github.com/go-sql-driver/mysql"
"io"
"log"
"os/exec"
"runtime"
"strings"
)
// generateChecksum generates a checksum for the file based on the name and
// version number.
func generateChecksum(path string, num int) (string, error) {
var result string
key := fmt.Sprintf("%s -- Version %d -- ", path, num)
hash := md5.New()
_, err := io.WriteString(hash, key)
if err != nil {
return result, handle("Error in generating md5 hash.", err)
}
// Generate checksum
hashInBytes := hash.Sum(nil)[:16]
result = hex.EncodeToString(hashInBytes)
return result, nil
}
// awsOutput outputs the AWS operation response if not empty.
func awsOutput(input string) {
// Skip if empty response
snip := strings.Replace(input, " ", "", -1)
if strings.Replace(snip, "\n", "", -1) == "{}" {
return
}
log.Print("AWS response: " + input)
}
var commandWithOutput = commandWithOutputFunc
// commandWithOutputFunc executes a shell command and returns the stdout,
// stderr, and err.
func commandWithOutputFunc(input string) (string, string, error) {
cmd := exec.Command("sh", "-cx", input)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
outResp := stdout.String()
errResp := stderr.String()
return outResp, errResp, err
}
// commandVerbose outputs a system command to log with stdout, stderr, and
// err output.
func commandVerbose(input string) (string, string, error) {
log.Print("Command: " + input)
stdout, stderr, err := commandWithOutput(input)
if stdout != "" {
log.Print(stdout)
}
if stderr != "" {
log.Print(stderr)
}
if err != nil {
errOut("Error in running command.", err)
} else {
log.Print("Command ran successfully.")
}
return stdout, stderr, err
}
// commandVerboseOnErr outputs a system command to log with all output on
// error.
func commandVerboseOnErr(input string) (string, string, error) {
log.Print("Command: " + input)
stdout, stderr, err := commandWithOutput(input)
if err != nil {
if stdout != "" {
log.Print(stdout)
}
if stderr != "" {
log.Print(stderr)
}
errOut("Error in running command.", err)
} else {
log.Print("Command ran successfully.")
}
return stdout, stderr, err
}
// handle logs errors and information at runtime. Used for easier error
// tracing up the call stack.
func handle(input string, err error) error {
if err == nil {
return err
}
pc, fn, line, ok := runtime.Caller(1)
if input[len(input)-1:] != "." { // Add a period.
input += "."
}
input += " " + err.Error()
if !ok {
log.Printf("[error] %s", input)
return errors.New(input)
}
p := strings.Split(fn, "/")
fn = p[len(p)-1]
log.Printf("[error] in %s[%s:%d] %s",
runtime.FuncForPC(pc).Name(), fn, line, input)
return errors.New(input)
}
// errOut outputs error messages but doesn't create a new error.
func errOut(input string, err error) {
if err == nil {
return
}
pc, fn, line, ok := runtime.Caller(1)
if input[len(input)-1:] != "." {
input += "."
}
input += " " + err.Error()
if !ok {
log.Printf("[error] %s", input)
return
}
p := strings.Split(fn, "/")
fn = p[len(p)-1]
log.Printf("[error] in %s[%s:%d] %s", runtime.FuncForPC(pc).Name(),
fn, line, input)
}