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