Codebase list golang-github-vbauerster-mpb / 93889df
don't auto refresh if output is not terminal Vladimir Bauer 3 years ago
3 changed file(s) with 28 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
7171 // will effectively disable auto refresh rate and discard any output,
7272 // useful if you want to disable progress bars with little overhead.
7373 func WithOutput(w io.Writer) ContainerOption {
74 var discarded bool
7574 if w == nil {
7675 w = io.Discard
77 discarded = true
7876 }
7977 return func(s *pState) {
8078 s.output = w
81 s.outputDiscarded = discarded
8279 }
8380 }
8481
3939 return w
4040 }
4141
42 // IsTerminal tells whether underlying io.Writer is terminal.
43 func (w *Writer) IsTerminal() bool {
44 return w.terminal
45 }
46
4247 // GetTermSize returns WxH of underlying terminal.
4348 func (w *Writer) GetTermSize() (width, height int, err error) {
4449 return w.termSize(w.fd)
4242 reqWidth int
4343 popPriority int
4444 popCompleted bool
45 outputDiscarded bool
4645 disableAutoRefresh bool
47 ignoreNotTTY bool
4846 manualRefresh chan interface{}
4947 renderDelay <-chan struct{}
50 shutdownNotifier chan struct{}
48 shutdownNotifier chan<- interface{}
5149 queueBars map[*Bar]*Bar
5250 output io.Writer
5351 debugOut io.Writer
8987 operateState: make(chan func(*pState)),
9088 interceptIo: make(chan func(io.Writer)),
9189 done: make(chan struct{}),
90 shutdown: make(chan struct{}),
9291 cancel: cancel,
93 }
94
95 if s.shutdownNotifier != nil {
96 p.shutdown = s.shutdownNotifier
97 s.shutdownNotifier = nil
98 } else {
99 p.shutdown = make(chan struct{})
10092 }
10193
10294 go p.serve(s, cwriter.New(s.output))
232224 <-p.shutdown
233225 }
234226
235 func (p *Progress) newTicker(s *pState) chan time.Time {
227 func (p *Progress) newTicker(s *pState, isTerminal bool) chan time.Time {
236228 ch := make(chan time.Time)
237229 go func() {
238230 var autoRefresh <-chan time.Time
239 if !s.disableAutoRefresh && !s.outputDiscarded {
231 if isTerminal && !s.disableAutoRefresh {
240232 if s.renderDelay != nil {
241233 <-s.renderDelay
242234 }
264256 }
265257
266258 func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
259 render := func() error {
260 return s.render(cw)
261 }
267262
268263 go s.hm.run()
269264
270 refreshCh := p.newTicker(s)
265 refreshCh := p.newTicker(s, cw.IsTerminal())
271266
272267 for {
273268 select {
276271 case fn := <-p.interceptIo:
277272 fn(cw)
278273 case <-refreshCh:
279 err := s.render(cw)
274 err := render()
280275 if err != nil {
281 refreshCh = nil
282276 _, _ = fmt.Fprintln(s.debugOut, err.Error())
277 render = func() error { return nil }
283278 p.cancel() // cancel all bars
284279 }
285280 case <-p.done:
286 close(s.hm)
281 if s.shutdownNotifier != nil {
282 go func() {
283 s.shutdownNotifier <- s.hm.end()
284 }()
285 } else {
286 close(s.hm)
287 }
287288 close(p.shutdown)
288289 return
289290 }
290291 }
291292 }
292293
293 func (s *pState) render(cw *cwriter.Writer) error {
294 width, height, err := cw.GetTermSize()
295 if err != nil {
296 if !s.ignoreNotTTY {
294 func (s *pState) render(cw *cwriter.Writer) (err error) {
295 var width, height int
296 if cw.IsTerminal() {
297 width, height, err = cw.GetTermSize()
298 if err != nil {
297299 return err
298300 }
301 } else {
299302 width = s.reqWidth
300303 height = 100
301304 }