-
Notifications
You must be signed in to change notification settings - Fork 3
/
progressreader.go
68 lines (60 loc) · 1.8 KB
/
progressreader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 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 int64
Current int64
LastUpdate int64
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 += int64(read)
updateEvery := int64(1024 * 512) //512kB
if config.Size > 0 {
// Update progress for every 1% read if 1% < 512kB
if increment := int64(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)
}