packer-cn/packer/progressbar.go

85 lines
1.6 KiB
Go
Raw Normal View History

// +build !solaris
package packer
import (
"io"
"path/filepath"
"sync"
pb "github.com/cheggaaa/pb"
)
func ProgressBarConfig(bar *pb.ProgressBar, prefix string) {
bar.SetUnits(pb.U_BYTES)
bar.Prefix(prefix)
}
var defaultUiProgressBar = &UiProgressBar{}
// UiProgressBar is a self managed progress bar singleton.
// decorate your struct with a *UiProgressBar to
// give it TrackProgress capabilities.
// In TrackProgress if UiProgressBar is nil
// defaultUiProgressBar will be used as
// the progress bar.
type UiProgressBar struct {
Noop bool
lock sync.Mutex
pool *pb.Pool
pbs int
}
2018-09-12 19:21:58 -04:00
func (p *UiProgressBar) TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) io.ReadCloser {
if p == nil {
return defaultUiProgressBar.TrackProgress(src, currentSize, totalSize, stream)
2018-10-15 10:31:59 -04:00
}
if p.Noop {
return stream
}
p.lock.Lock()
defer p.lock.Unlock()
newPb := pb.New64(totalSize)
newPb.Set64(currentSize)
ProgressBarConfig(newPb, filepath.Base(src))
if p.pool == nil {
pool := pb.NewPool()
err := pool.Start()
if err != nil {
// here, we probably cannot lock
// stdout, so let's just return
// stream to avoid any error.
return stream
}
p.pool = pool
2018-09-12 20:04:10 -04:00
}
p.pool.Add(newPb)
reader := newPb.NewProxyReader(stream)
p.pbs++
return &readCloser{
Reader: reader,
close: func() error {
p.lock.Lock()
defer p.lock.Unlock()
newPb.Finish()
p.pbs--
if p.pbs <= 0 {
p.pool.Stop()
p.pool = nil
}
return nil
},
}
}
type readCloser struct {
io.Reader
close func() error
}
func (c *readCloser) Close() error { return c.close() }