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  }