Codebase list golang-github-vbauerster-mpb / 24cf663
WithDebugOutput Vladimir Bauer 8 years ago
8 changed file(s) with 46 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
295295 }
296296 }
297297
298 func (b *Bar) render(tw int, pSyncer, aSyncer *widthSyncer) <-chan *renderedState {
298 func (b *Bar) render(debugOut io.Writer, tw int, pSyncer, aSyncer *widthSyncer) <-chan *renderedState {
299299 ch := make(chan *renderedState, 1)
300300
301301 go func() {
305305 defer func() {
306306 // recovering if external decorators panic
307307 if p := recover(); p != nil {
308 s.panicMsg = fmt.Sprintf("b#%02d panic: %v\n", s.id, p)
308 s.panicMsg = fmt.Sprintf("panic: %v", p)
309309 s.pDecorators = nil
310310 s.aDecorators = nil
311311 s.toComplete = true
312 r = strings.NewReader(s.panicMsg)
312 // truncate panic msg to one tw line, if necessary
313 r = strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw-1), s.panicMsg))
314 fmt.Fprintf(debugOut, "%s %s bar id %02d %v\n", "[mpb]", time.Now(), s.id, s.panicMsg)
313315 }
314316 ch <- &renderedState{b, r, s.toComplete}
315317 }()
319321 s := b.cacheState
320322 var r io.Reader
321323 if s.panicMsg != "" {
322 r = strings.NewReader(s.panicMsg)
324 r = strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw-1), s.panicMsg))
323325 } else {
324326 r = s.draw(tw, pSyncer, aSyncer)
325327 }
9090 p := New(WithOutput(&buf), WithWaitGroup(&wg))
9191
9292 wantPanic := "Upps!!!"
93 numBars := 3
93 numBars := 1
9494 wg.Add(numBars)
9595
9696 for i := 0; i < numBars; i++ {
9797 name := fmt.Sprintf("b#%02d:", i)
98 bar := p.AddBar(100, BarID(i), PrependDecorators(
98 bar := p.AddBar(100, PrependDecorators(
9999 func(s *decor.Statistics, _ chan<- int, _ <-chan int) string {
100 if s.ID == 2 && s.Current >= 42 {
100 if s.Current >= 42 {
101101 panic(wantPanic)
102102 }
103103 return name
115115
116116 p.Wait()
117117
118 wantPanic = fmt.Sprintf("b#%02d panic: %v", 2, wantPanic)
118 wantPanic = fmt.Sprintf("panic: %s", wantPanic)
119 lastLine := getLastLine(buf.Bytes())
119120
120 if !strings.Contains(buf.String(), wantPanic) {
121 if string(lastLine) != wantPanic {
121122 t.Errorf("Want: %q, got: %q\n", wantPanic, buf.String())
122123 }
123124 }
11
22 import (
33 "fmt"
4 "os"
45 "sync"
56 "time"
67
1011
1112 func main() {
1213 var wg sync.WaitGroup
13 p := mpb.New(mpb.WithWaitGroup(&wg))
14 p := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithDebugOutput(os.Stderr))
1415
15 wantPanic := "Upps!!!"
16 wantPanic := "Some realy long panic panic panic panic panic panic panic, really it is very long"
1617 numBars := 3
1718 wg.Add(numBars)
1819
7878 }
7979 }
8080
81 // WithDebugOutput sets debug output.
82 func WithDebugOutput(w io.Writer) ProgressOption {
83 return func(s *pState) {
84 if w == nil {
85 w = ioutil.Discard
86 }
87 s.debugOut = w
88 }
89 }
90
8191 // WithInterceptors provides a way to write to the underlying progress pool's
8292 // writer. Could be useful if you want to output something below the bars, while
8393 // they're rendering.
22 import (
33 "container/heap"
44 "io"
5 "io/ioutil"
56 "os"
67 "sync"
78 "time"
4647 shutdownNotifier chan struct{}
4748 interceptors []func(io.Writer)
4849 waitBars map[*Bar]*Bar
50 debugOut io.Writer
4951 }
5052 widthSyncer struct {
5153 // Public for easy testing
6769 rr: prr,
6870 ticker: time.NewTicker(prr),
6971 waitBars: make(map[*Bar]*Bar),
72 debugOut: ioutil.Discard,
7073 }
7174
7275 for _, opt := range options {
244247 for s.bHeap.Len() > 0 {
245248 b := heap.Pop(s.bHeap).(*Bar)
246249 defer heap.Push(s.bHeap, b)
247 pp = append(pp, b.render(tw, pSyncer, aSyncer))
250 pp = append(pp, b.render(s.debugOut, tw, pSyncer, aSyncer))
248251 }
249252 return pp
250253 }
4242 tw, _, _ := cwriter.TermSize()
4343 err := s.writeAndFlush(tw, numP, numA)
4444 if err != nil {
45 fmt.Fprintln(os.Stderr, err)
45 fmt.Fprintf(s.debugOut, "%s %s %v\n", "[mpb]", time.Now(), err)
4646 }
4747 case <-winch:
4848 if s.heapUpdated {
5353 tw, _, _ := cwriter.TermSize()
5454 err := s.writeAndFlush(tw-tw/8, numP, numA)
5555 if err != nil {
56 fmt.Fprintln(os.Stderr, err)
56 fmt.Fprintf(s.debugOut, "%s %s %v\n", "[mpb]", time.Now(), err)
5757 }
5858 if timer != nil && timer.Reset(resumeDelay) {
5959 break
1010
1111 . "github.com/vbauerster/mpb"
1212 "github.com/vbauerster/mpb/cwriter"
13 )
14
15 var (
16 cursorUp = fmt.Sprintf("%c[%dA", cwriter.ESC, 1)
17 clearLine = fmt.Sprintf("%c[2K\r", cwriter.ESC)
18 clearCursorAndLine = cursorUp + clearLine
1319 )
1420
1521 func init() {
105111 }
106112 }
107113
108 var (
109 cursorUp = fmt.Sprintf("%c[%dA", cwriter.ESC, 1)
110 clearLine = fmt.Sprintf("%c[2K\r", cwriter.ESC)
111 clearCursorAndLine = cursorUp + clearLine
112 )
113
114114 func TestWithFormat(t *testing.T) {
115115 var buf bytes.Buffer
116116 customFormat := "╢▌▌░╟"
128128
129129 p.Wait()
130130
131 bb := bytes.Split(buf.Bytes(), []byte("\n"))
132 lastLine := bb[len(bb)-2]
133 lastLine = lastLine[len(clearCursorAndLine):]
131 lastLine := getLastLine(buf.Bytes())
134132
135133 for _, r := range customFormat {
136134 if !bytes.ContainsRune(lastLine, r) {
139137 }
140138 }
141139
140 func getLastLine(bb []byte) []byte {
141 split := bytes.Split(bb, []byte("\n"))
142 lastLine := split[len(split)-2]
143 return lastLine[len(clearCursorAndLine):]
144 }
145
142146 func randomDuration(max time.Duration) time.Duration {
143147 return time.Duration(rand.Intn(10)+1) * max / 10
144148 }
33
44 import (
55 "fmt"
6 "os"
6 "time"
77
88 "github.com/vbauerster/mpb/cwriter"
99 )
3131 tw, _, _ := cwriter.TermSize()
3232 err := s.writeAndFlush(tw, numP, numA)
3333 if err != nil {
34 fmt.Fprintln(os.Stderr, err)
34 fmt.Fprintf(s.debugOut, "%s %s %v\n", "[mpb]", time.Now(), err)
3535 }
3636 }
3737 }