github.com/rseymour/docker@v1.5.0/utils/progressreader.go (about)

     1  package utils
     2  
     3  import (
     4  	"io"
     5  	"time"
     6  )
     7  
     8  // Reader with progress bar
     9  type progressReader struct {
    10  	reader     io.ReadCloser // Stream to read from
    11  	output     io.Writer     // Where to send progress bar to
    12  	progress   JSONProgress
    13  	lastUpdate int // How many bytes read at least update
    14  	ID         string
    15  	action     string
    16  	sf         *StreamFormatter
    17  	newLine    bool
    18  }
    19  
    20  func (r *progressReader) Read(p []byte) (n int, err error) {
    21  	read, err := r.reader.Read(p)
    22  	r.progress.Current += read
    23  	updateEvery := 1024 * 512 //512kB
    24  	if r.progress.Total > 0 {
    25  		// Update progress for every 1% read if 1% < 512kB
    26  		if increment := int(0.01 * float64(r.progress.Total)); increment < updateEvery {
    27  			updateEvery = increment
    28  		}
    29  	}
    30  	if r.progress.Current-r.lastUpdate > updateEvery || err != nil {
    31  		r.output.Write(r.sf.FormatProgress(r.ID, r.action, &r.progress))
    32  		r.lastUpdate = r.progress.Current
    33  	}
    34  	// Send newline when complete
    35  	if r.newLine && err != nil && read == 0 {
    36  		r.output.Write(r.sf.FormatStatus("", ""))
    37  	}
    38  	return read, err
    39  }
    40  func (r *progressReader) Close() error {
    41  	r.progress.Current = r.progress.Total
    42  	r.output.Write(r.sf.FormatProgress(r.ID, r.action, &r.progress))
    43  	return r.reader.Close()
    44  }
    45  func ProgressReader(r io.ReadCloser, size int, output io.Writer, sf *StreamFormatter, newline bool, ID, action string) *progressReader {
    46  	return &progressReader{
    47  		reader:   r,
    48  		output:   NewWriteFlusher(output),
    49  		ID:       ID,
    50  		action:   action,
    51  		progress: JSONProgress{Total: size, Start: time.Now().UTC().Unix()},
    52  		sf:       sf,
    53  		newLine:  newline,
    54  	}
    55  }