@@ -138,26 +138,61 @@ func printProgressWithBar(statuschan <-chan git.RepoFileStatus, nitems int) (fil
138
138
return printProgressOutput (statuschan )
139
139
}
140
140
ndigits := len (fmt .Sprintf ("%d" , nitems ))
141
- dfmt := fmt .Sprintf ("%%%dd/%%%dd" , ndigits , ndigits )
141
+ dfmt := fmt .Sprintf ("%%%dd/%%%dd" , ndigits , ndigits ) // dynamic formatting string adapts to number of digits in item count
142
142
filesuccess = make (map [string ]bool )
143
- var barratio float64
144
- var ncomplt int
145
- linewidth := termwidth ()
146
- if linewidth > 80 {
147
- linewidth = 80
148
- }
149
- barwidth := linewidth - (5 + ndigits * 2 )
150
- barratio = float64 (barwidth ) / float64 (nitems )
143
+
144
+ // closure binds ndigits and nitems but keeps bar width dynamic so it can
145
+ // adapt to terminal resizing -- introduces a few operations per refresh,
146
+ // but makes the bar printing much nicer
147
+ printbar := func (completed int ) int {
148
+ linewidth := termwidth ()
149
+ if linewidth > 80 {
150
+ linewidth = 80
151
+ } else if linewidth < 30 {
152
+ // Skip bar printing for very small terminals
153
+ fmt .Println ()
154
+ return 0
155
+ }
156
+ fullbarwidth := linewidth - (5 + ndigits * 2 )
157
+ if fullbarwidth < 0 {
158
+ // Again, skip bar printing if ndigits is so large that a bar would
159
+ // have negative width. Since we skip printing the bar if the
160
+ // termwidth is < 30, this can only happen when processing more
161
+ // than 1e13 files, but if we ever change the min width to
162
+ // something smaller than 30 (or make it dynamic somehow), this
163
+ // guard will be useful.
164
+ fmt .Println ()
165
+ return 0
166
+ }
167
+ barratio := float64 (fullbarwidth ) / float64 (nitems )
168
+
169
+ complsigns := int (math .Floor (float64 (completed ) * barratio ))
170
+ blocks := strings .Repeat ("=" , complsigns )
171
+ blanks := strings .Repeat (" " , fullbarwidth - complsigns )
172
+ dprg := fmt .Sprintf (dfmt , completed , nitems )
173
+ fmt .Printf ("\n [%s%s] %s\r " , blocks , blanks , dprg )
174
+ return linewidth
175
+ }
176
+
151
177
outline := new (bytes.Buffer )
152
178
outappend := func (part string ) {
153
179
if len (part ) > 0 {
154
180
outline .WriteString (part )
155
181
outline .WriteString (" " )
156
182
}
157
183
}
184
+
158
185
printed := false
186
+ prevlinewidth := 0
187
+ ncompleted := 0
159
188
for stat := range statuschan {
160
- ncomplt ++
189
+ ncompleted ++
190
+ if ncompleted > nitems {
191
+ // BUG: Not sure when this occurs, but it's been happening in the
192
+ // CI environment for some remove-content calls and I haven't been
193
+ // able to reproduce - AK, 2019-07-07
194
+ nitems = ncompleted
195
+ }
161
196
outline .Reset ()
162
197
outline .WriteString (" " )
163
198
outappend (stat .State )
@@ -172,13 +207,9 @@ func printProgressWithBar(statuschan <-chan git.RepoFileStatus, nitems int) (fil
172
207
filesuccess [stat .FileName ] = false
173
208
}
174
209
newprint := outline .String ()
175
- fmt .Printf ("\r %s\r " , strings .Repeat (" " , linewidth )) // clear the line
210
+ fmt .Printf ("\r %s\r " , strings .Repeat (" " , prevlinewidth )) // clear the line
176
211
fmt .Fprint (color .Output , newprint )
177
- complsigns := int (math .Floor (float64 (ncomplt ) * barratio ))
178
- blocks := strings .Repeat ("=" , complsigns )
179
- blanks := strings .Repeat (" " , barwidth - complsigns )
180
- dprg := fmt .Sprintf (dfmt , ncomplt , nitems )
181
- fmt .Printf ("\n [%s%s] %s\r " , blocks , blanks , dprg )
212
+ prevlinewidth = printbar (ncompleted )
182
213
printed = true
183
214
}
184
215
if ! printed {
0 commit comments