1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- // Package progressreader provides a Reader with a progress bar that can be
- // printed out using the streamformatter package.
- package progressreader
- import (
- "io"
- "github.com/docker/docker/pkg/jsonmessage"
- "github.com/docker/docker/pkg/streamformatter"
- )
- // Config contains the configuration for a Reader with progress bar.
- type Config struct {
- In io.ReadCloser // Stream to read from
- Out io.Writer // Where to send progress bar to
- Formatter *streamformatter.StreamFormatter
- Size int
- Current int
- LastUpdate int
- NewLines bool
- ID string
- Action string
- }
- // New creates a new Config.
- func New(newReader Config) *Config {
- return &newReader
- }
- func (config *Config) Read(p []byte) (n int, err error) {
- read, err := config.In.Read(p)
- config.Current += read
- updateEvery := 1024 * 512 //512kB
- if config.Size > 0 {
- // Update progress for every 1% read if 1% < 512kB
- if increment := int(0.01 * float64(config.Size)); increment < updateEvery {
- updateEvery = increment
- }
- }
- if config.Current-config.LastUpdate > updateEvery || err != nil {
- updateProgress(config)
- config.LastUpdate = config.Current
- }
- if err != nil && read == 0 {
- updateProgress(config)
- if config.NewLines {
- config.Out.Write(config.Formatter.FormatStatus("", ""))
- }
- }
- return read, err
- }
- // Close closes the reader (Config).
- func (config *Config) Close() error {
- if config.Current < config.Size {
- //print a full progress bar when closing prematurely
- config.Current = config.Size
- updateProgress(config)
- }
- return config.In.Close()
- }
- func updateProgress(config *Config) {
- progress := jsonmessage.JSONProgress{Current: config.Current, Total: config.Size}
- fmtMessage := config.Formatter.FormatProgress(config.ID, config.Action, &progress)
- config.Out.Write(fmtMessage)
- }
|