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