-
Notifications
You must be signed in to change notification settings - Fork 0
/
output.go
executable file
·132 lines (108 loc) · 2.81 KB
/
output.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
package output
import (
"bufio"
"fmt"
"os"
"strings"
"github.com/logrusorgru/aurora"
)
const (
checkMark = "\xE2\x9C\x94"
heavyBallotX = "\xE2\x9C\x98"
)
var (
// Verbose can be set to show debug lines
Verbose bool
currentOp *Operation
)
// Operation represents something currently happening that can
// be completed, failed or abandoned.
type Operation struct{}
func newOp() *Operation {
// If an operation has been abandoned, we need a new line
if currentOp != nil {
fmt.Printf("\n")
}
currentOp = &Operation{}
return currentOp
}
// Complete prints the result of running fmt.Sprintf on args and
// a new line. If args is empty then a default check mark is used.
func (o *Operation) Complete(args ...interface{}) {
end := fmt.Sprintf(" %s", aurora.Green(checkMark))
switch len(args) {
case 0:
case 1:
end = fmt.Sprintf("%s", args[0])
default:
end = fmt.Sprintf(fmt.Sprintf("%s", args[0]), args[1:]...)
}
fmt.Printf("%s\n", end)
currentOp = nil
}
// Failed prints a heavy ballot X and a new line
func (o *Operation) Failed() {
fmt.Printf(" %s\n", aurora.Red(heavyBallotX))
currentOp = nil
}
// Abandon just prints a new line without a symbol
func (o *Operation) Abandon() {
fmt.Printf("\n")
currentOp = nil
}
// Info prints the string and returns an Operation that can
// be used to control whether a check mark or ballot x is placed
// at the end of the line.
func Info(format string, a ...interface{}) *Operation {
op := newOp()
fmt.Printf(format, a...)
return op
}
// InfoLn prints the string on its own line without
// returning an Operation.
func InfoLn(format string, a ...interface{}) {
Info(format, a...).Abandon()
}
// Debug will output only if the Verbose flag is set.
func Debug(format string, a ...interface{}) {
if Verbose {
f := fmt.Sprintf(format, a...)
fmt.Printf("%s\n", aurora.Gray(12, f))
}
}
// Fatal exists with status code 1 after printing the line in red
func Fatal(format string, a ...interface{}) {
if currentOp != nil {
newOp().Abandon() // Print a blank line
}
fmt.Printf(aurora.Sprintf(aurora.Red(format), a...))
fmt.Printf("\n")
os.Exit(1)
}
// Confirm will prompt the user to enter yes or no, returning the result.
func Confirm(def bool, format string, a ...interface{}) bool {
newOp().Abandon() // Print blank line
defer fmt.Printf("\n") // Print another blank line at the end
reader := bufio.NewReader(os.Stdin)
msg := fmt.Sprintf(format, a...)
yes, no := "y", "n"
if def {
yes = strings.ToUpper(yes)
} else {
no = strings.ToUpper(no)
}
opts := aurora.Sprintf(aurora.Gray(16, "(%s/%s)"), yes, no)
for {
fmt.Printf("%s %s ", msg, opts)
input, _ := reader.ReadString('\n')
input = strings.ToLower(strings.TrimSpace(input))
switch input {
case "y", "yes":
return true
case "n", "no":
return false
case "":
return def
}
}
}