@@ -10,10 +10,8 @@ import (
10
10
11
11
// Progress is an interface for a simple progress meter. Call
12
12
// `Start()` to begin reporting. `format` should include some kind of
13
- // '%d' field, into which will be written the current count. The
14
- // format should be constructed so that the new output covers up the
15
- // old output (e.g., it should be fixed length or include some
16
- // trailing spaces). A CR character will be added automatically.
13
+ // '%d' field, into which will be written the current count. A spinner
14
+ // and a CR character will be added automatically.
17
15
//
18
16
// Call `Inc()` every time the quantity of interest increases. Call
19
17
// `Stop()` to stop reporting. After an instance's `Stop()` method has
@@ -26,13 +24,16 @@ type Progress interface {
26
24
Done ()
27
25
}
28
26
27
+ var Spinners = []string {"|" , "(" , "<" , "-" , "<" , "(" , "|" , ")" , ">" , "-" , ">" , ")" }
28
+
29
29
// progressMeter is a `Progress` that reports the current state every
30
30
// `period`.
31
31
type progressMeter struct {
32
32
lock sync.Mutex
33
33
format string
34
34
period time.Duration
35
35
lastShownCount int64
36
+ spinnerIndex int
36
37
// When `ticker` is changed, that tells the old goroutine that
37
38
// it's time to shut down.
38
39
ticker * time.Ticker
@@ -50,9 +51,10 @@ func NewProgressMeter(period time.Duration) Progress {
50
51
func (p * progressMeter ) Start (format string ) {
51
52
p .lock .Lock ()
52
53
defer p .lock .Unlock ()
53
- p .format = " \r " + format
54
+ p .format = format + " %s %s"
54
55
atomic .StoreInt64 (& p .count , 0 )
55
56
p .lastShownCount = - 1
57
+ p .spinnerIndex = 0
56
58
ticker := time .NewTicker (p .period )
57
59
p .ticker = ticker
58
60
go func () {
@@ -66,10 +68,14 @@ func (p *progressMeter) Start(format string) {
66
68
return
67
69
}
68
70
c := atomic .LoadInt64 (& p .count )
69
- if c != p .lastShownCount {
70
- fmt .Fprintf (os .Stderr , p .format , c )
71
- p .lastShownCount = c
71
+ var s string
72
+ if c == 0 {
73
+ p .spinnerIndex = (p .spinnerIndex + 1 ) % len (Spinners )
74
+ s = Spinners [p .spinnerIndex ]
75
+ } else {
76
+ s = ""
72
77
}
78
+ fmt .Fprintf (os .Stderr , p .format , c , s , "\r " )
73
79
p .lock .Unlock ()
74
80
}
75
81
}()
@@ -88,7 +94,7 @@ func (p *progressMeter) Done() {
88
94
defer p .lock .Unlock ()
89
95
p .ticker = nil
90
96
c := atomic .LoadInt64 (& p .count )
91
- fmt .Fprintf (os .Stderr , p .format + " \n " , c )
97
+ fmt .Fprintf (os .Stderr , p .format , c , " " , " \n " )
92
98
}
93
99
94
100
// NoProgressMeter is a `Progress` that doesn't actually report
0 commit comments