github.com/a4a881d4/docker@v1.9.0-rc2/pkg/progressreader/progressreader.go (about) 1 // Package progressreader provides a Reader with a progress bar that can be 2 // printed out using the streamformatter package. 3 package progressreader 4 5 import ( 6 "io" 7 8 "github.com/docker/docker/pkg/jsonmessage" 9 "github.com/docker/docker/pkg/streamformatter" 10 ) 11 12 // Config contains the configuration for a Reader with progress bar. 13 type Config struct { 14 In io.ReadCloser // Stream to read from 15 Out io.Writer // Where to send progress bar to 16 Formatter *streamformatter.StreamFormatter 17 Size int64 18 Current int64 19 LastUpdate int64 20 NewLines bool 21 ID string 22 Action string 23 } 24 25 // New creates a new Config. 26 func New(newReader Config) *Config { 27 return &newReader 28 } 29 30 func (config *Config) Read(p []byte) (n int, err error) { 31 read, err := config.In.Read(p) 32 config.Current += int64(read) 33 updateEvery := int64(1024 * 512) //512kB 34 if config.Size > 0 { 35 // Update progress for every 1% read if 1% < 512kB 36 if increment := int64(0.01 * float64(config.Size)); increment < updateEvery { 37 updateEvery = increment 38 } 39 } 40 if config.Current-config.LastUpdate > updateEvery || err != nil { 41 updateProgress(config) 42 config.LastUpdate = config.Current 43 } 44 45 if err != nil && read == 0 { 46 updateProgress(config) 47 if config.NewLines { 48 config.Out.Write(config.Formatter.FormatStatus("", "")) 49 } 50 } 51 return read, err 52 } 53 54 // Close closes the reader (Config). 55 func (config *Config) Close() error { 56 if config.Current < config.Size { 57 //print a full progress bar when closing prematurely 58 config.Current = config.Size 59 updateProgress(config) 60 } 61 return config.In.Close() 62 } 63 64 func updateProgress(config *Config) { 65 progress := jsonmessage.JSONProgress{Current: config.Current, Total: config.Size} 66 fmtMessage := config.Formatter.FormatProgress(config.ID, config.Action, &progress) 67 config.Out.Write(fmtMessage) 68 }