/
progress.go
127 lines (111 loc) · 2.98 KB
/
progress.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
package shared
import (
"fmt"
"os"
"strings"
"time"
"github.com/cheggaaa/pb/v3"
"github.com/mitchellh/go-homedir"
)
var (
bar *pb.ProgressBar
)
var barIntFormat string
var cwd string
var userdir string
// ProgressCount displays a counter while calculating the real total progress
var (
fileCount int
)
// ProgressCount called when loading the list (before end is known)
func ProgressCount() {
if progress {
// display count of scanned file names
fileCount++
saveCursorPosition()
fmt.Fprintf(os.Stderr, "Scanning (%d)...", fileCount)
restoreCursorPosition()
}
}
// ProgressStart start the progress bar
func ProgressStart(fcs []FileContext) {
if progress {
var max int64
if true {
for _, fc := range fcs {
max += fc.Size()
}
} else {
max = int64(len(fcs))
}
pb.RegisterElement("mypercent", myPercentElement, false)
numWidth := len(fmt.Sprintf("%d", len(fcs)))
barIntFormat = fmt.Sprintf("%%%dd", numWidth)
path, err := os.Getwd()
if err != nil {
if Debug {
fmt.Fprintf(os.Stderr, "ERROR: unable to retrieve current working directory (%s)\n", err.Error())
}
} else {
cwd = path
}
userdir, _ = homedir.Dir()
pb.RegisterElement("fixedbar", pb.ElementBar, false)
tmpl := `PASS {{string . "good"}} / FAIL {{string . "bad"}} {{ fixedbar . "[" "=" ">" "·" "]"}} {{mypercent . }} {{string . "filename"}}`
bar = pb.Start64(max)
bar.SetTemplateString(tmpl)
}
}
// ProgressUpdate update the progress bar
func ProgressUpdate(good int, bad int, fc FileContext) {
if bar != nil {
bar.Set("good", fmt.Sprintf(barIntFormat, good))
bar.Set("bad", fmt.Sprintf(barIntFormat, bad))
if fc.FilePath == "" {
elapsed := time.Now().Truncate(time.Second).Sub(bar.StartTime().Truncate(time.Second))
if elapsed < 10*time.Second {
elapsed = time.Now().Truncate(time.Millisecond).Sub(bar.StartTime().Truncate(time.Millisecond))
}
bar.Set("filename", fmt.Sprintf("Done in %s", elapsed))
} else {
if true {
bar.Add64(fc.Size())
} else {
bar.Add64(1)
}
if strings.HasPrefix(fc.FilePath, cwd) {
bar.Set("filename", fmt.Sprintf(".%s", fc.FilePath[len(cwd):]))
} else if strings.HasPrefix(fc.FilePath, userdir) {
bar.Set("filename", fmt.Sprintf("~%s", fc.FilePath[len(userdir):]))
} else {
bar.Set("filename", fc.FilePath)
}
}
}
}
// ProgressEnd call when completely done
func ProgressEnd() {
if bar != nil {
bar.Finish()
if Debug {
fmt.Fprintf(os.Stderr, "DEBUG: Bytes processed: %d\n", bar.Total())
}
}
}
// variation of pb.ElementPercent that is fixed width and rounds down
var myPercentElement pb.ElementFunc = func(state *pb.State, args ...string) string {
if state.Total() == 0 {
return " "
}
percent1000 := state.Value() * 1000 / state.Total()
return fmt.Sprintf("%3d.%01d%%", percent1000/10, percent1000%10)
}
func clearLine() {
fmt.Fprintf(os.Stderr, "\033[2K")
}
func saveCursorPosition() {
fmt.Fprintf(os.Stderr, "\033[s")
}
func restoreCursorPosition() {
fmt.Fprintf(os.Stderr, "\033[u")
}