| 5 | 5 |
"fmt"
|
| 6 | 6 |
"io"
|
| 7 | 7 |
"log"
|
|
8 |
"runtime/debug"
|
| 8 | 9 |
"strings"
|
| 9 | 10 |
"time"
|
| 10 | 11 |
|
|
| 297 | 298 |
}
|
| 298 | 299 |
|
| 299 | 300 |
func (b *Bar) render(tw int) {
|
| 300 | |
if b.recoveredPanic != nil {
|
| 301 | |
b.toShutdown = false
|
| 302 | |
b.frameCh <- b.panicToFrame(tw)
|
| 303 | |
return
|
| 304 | |
}
|
| 305 | |
select {
|
| 306 | |
case b.operateState <- func(s *bState) {
|
|
301 |
select {
|
|
302 |
case b.operateState <- func(s *bState) {
|
|
303 |
stat := newStatistics(tw, s)
|
| 307 | 304 |
defer func() {
|
| 308 | 305 |
// recovering if user defined decorator panics for example
|
| 309 | 306 |
if p := recover(); p != nil {
|
|
307 |
var sb strings.Builder
|
|
308 |
fmt.Fprintf(&sb, "%#v\n", stat)
|
|
309 |
sb.Write(debug.Stack())
|
|
310 |
stack := sb.String()
|
|
311 |
nlc := strings.Count(stack, "\n")
|
|
312 |
s.extender = func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) {
|
|
313 |
return io.MultiReader(r, strings.NewReader(stack)), nlc
|
|
314 |
}
|
|
315 |
b.recoveredPanic = p
|
|
316 |
b.extendedLines = nlc
|
|
317 |
b.toShutdown = true
|
|
318 |
b.frameCh <- io.MultiReader(b.panicToFrame(tw), strings.NewReader(stack))
|
| 310 | 319 |
b.dlogger.Println(p)
|
| 311 | |
b.recoveredPanic = p
|
| 312 | |
b.toShutdown = !s.completeFlushed
|
| 313 | |
b.frameCh <- b.panicToFrame(tw)
|
| 314 | 320 |
}
|
| 315 | 321 |
}()
|
| 316 | 322 |
|
| 317 | |
st := newStatistics(tw, s)
|
| 318 | |
frame, lines := s.extender(s.draw(st), s.reqWidth, st)
|
|
323 |
frame, lines := s.extender(s.draw(stat), s.reqWidth, stat)
|
| 319 | 324 |
b.extendedLines = lines
|
| 320 | 325 |
|
| 321 | 326 |
b.toShutdown = s.toComplete && !s.completeFlushed
|
|
| 324 | 329 |
}:
|
| 325 | 330 |
case <-b.done:
|
| 326 | 331 |
s := b.cacheState
|
| 327 | |
st := newStatistics(tw, s)
|
| 328 | |
frame, lines := s.extender(s.draw(st), s.reqWidth, st)
|
|
332 |
stat := newStatistics(tw, s)
|
|
333 |
var r io.Reader
|
|
334 |
if b.recoveredPanic != nil {
|
|
335 |
r = b.panicToFrame(tw)
|
|
336 |
} else {
|
|
337 |
r = s.draw(stat)
|
|
338 |
}
|
|
339 |
frame, lines := s.extender(r, s.reqWidth, stat)
|
| 329 | 340 |
b.extendedLines = lines
|
| 330 | 341 |
b.frameCh <- frame
|
| 331 | 342 |
}
|
| 332 | 343 |
}
|
| 333 | 344 |
|
| 334 | |
func (b *Bar) panicToFrame(termWidth int) io.Reader {
|
| 335 | |
return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%dv\n", termWidth), b.recoveredPanic))
|
|
345 |
func (b *Bar) panicToFrame(tw int) io.Reader {
|
|
346 |
return strings.NewReader(runewidth.Truncate(fmt.Sprint(b.recoveredPanic), tw, "…") + "\n")
|
| 336 | 347 |
}
|
| 337 | 348 |
|
| 338 | 349 |
func (b *Bar) subscribeDecorators() {
|