mirror of https://github.com/docker/docs.git
Make the progressbar human readable
This commit is contained in:
parent
f355d33b5f
commit
1e0738f63f
|
@ -70,7 +70,7 @@ type progressReader struct {
|
||||||
readProgress int // How much has been read so far (bytes)
|
readProgress int // How much has been read so far (bytes)
|
||||||
lastUpdate int // How many bytes read at least update
|
lastUpdate int // How many bytes read at least update
|
||||||
template string // Template to print. Default "%v/%v (%v)"
|
template string // Template to print. Default "%v/%v (%v)"
|
||||||
sf *StreamFormatter
|
sf *StreamFormatter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *progressReader) Read(p []byte) (n int, err error) {
|
func (r *progressReader) Read(p []byte) (n int, err error) {
|
||||||
|
@ -86,7 +86,7 @@ func (r *progressReader) Read(p []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
if r.readProgress-r.lastUpdate > updateEvery || err != nil {
|
if r.readProgress-r.lastUpdate > updateEvery || err != nil {
|
||||||
if r.readTotal > 0 {
|
if r.readTotal > 0 {
|
||||||
fmt.Fprintf(r.output, r.template, r.readProgress, r.readTotal, fmt.Sprintf("%.0f%%", float64(r.readProgress)/float64(r.readTotal)*100))
|
fmt.Fprintf(r.output, r.template, HumanSize(r.readProgress), HumanSize(r.readTotal), fmt.Sprintf("%.0f%%", float64(r.readProgress)/float64(r.readTotal)*100))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(r.output, r.template, r.readProgress, "?", "n/a")
|
fmt.Fprintf(r.output, r.template, r.readProgress, "?", "n/a")
|
||||||
}
|
}
|
||||||
|
@ -103,13 +103,25 @@ func (r *progressReader) Close() error {
|
||||||
return io.ReadCloser(r.reader).Close()
|
return io.ReadCloser(r.reader).Close()
|
||||||
}
|
}
|
||||||
func ProgressReader(r io.ReadCloser, size int, output io.Writer, template []byte, sf *StreamFormatter) *progressReader {
|
func ProgressReader(r io.ReadCloser, size int, output io.Writer, template []byte, sf *StreamFormatter) *progressReader {
|
||||||
tpl := string(template)
|
tpl := string(template)
|
||||||
if tpl == "" {
|
if tpl == "" {
|
||||||
tpl = string(sf.FormatProgress("", "%v/%v (%v)"))
|
tpl = string(sf.FormatProgress("", "%v/%v (%v)"))
|
||||||
}
|
}
|
||||||
return &progressReader{r, NewWriteFlusher(output), size, 0, 0, tpl, sf}
|
return &progressReader{r, NewWriteFlusher(output), size, 0, 0, tpl, sf}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HumanSize(origSize int) string {
|
||||||
|
size := float64(origSize)
|
||||||
|
for _, unit := range []string{"b", "Kb", "Mb", "Gb", "Tb"} {
|
||||||
|
if int(size)/1024 == 0 {
|
||||||
|
return fmt.Sprintf("%.03f%s", size, unit)
|
||||||
|
} else {
|
||||||
|
size = size / 1024
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strconv.Itoa(origSize)
|
||||||
|
}
|
||||||
|
|
||||||
// HumanDuration returns a human-readable approximation of a duration
|
// HumanDuration returns a human-readable approximation of a duration
|
||||||
// (eg. "About a minute", "4 hours ago", etc.)
|
// (eg. "About a minute", "4 hours ago", etc.)
|
||||||
func HumanDuration(d time.Duration) string {
|
func HumanDuration(d time.Duration) string {
|
||||||
|
@ -585,7 +597,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte
|
||||||
sf.used = true
|
sf.used = true
|
||||||
str := fmt.Sprintf(format, a...)
|
str := fmt.Sprintf(format, a...)
|
||||||
if sf.json {
|
if sf.json {
|
||||||
b, err := json.Marshal(&JSONMessage{Status:str});
|
b, err := json.Marshal(&JSONMessage{Status: str})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return sf.FormatError(err)
|
return sf.FormatError(err)
|
||||||
}
|
}
|
||||||
|
@ -597,7 +609,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte
|
||||||
func (sf *StreamFormatter) FormatError(err error) []byte {
|
func (sf *StreamFormatter) FormatError(err error) []byte {
|
||||||
sf.used = true
|
sf.used = true
|
||||||
if sf.json {
|
if sf.json {
|
||||||
if b, err := json.Marshal(&JSONMessage{Error:err.Error()}); err == nil {
|
if b, err := json.Marshal(&JSONMessage{Error: err.Error()}); err == nil {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
return []byte("{\"error\":\"format error\"}")
|
return []byte("{\"error\":\"format error\"}")
|
||||||
|
@ -608,10 +620,10 @@ func (sf *StreamFormatter) FormatError(err error) []byte {
|
||||||
func (sf *StreamFormatter) FormatProgress(action, str string) []byte {
|
func (sf *StreamFormatter) FormatProgress(action, str string) []byte {
|
||||||
sf.used = true
|
sf.used = true
|
||||||
if sf.json {
|
if sf.json {
|
||||||
b, err := json.Marshal(&JSONMessage{Status: action, Progress:str})
|
b, err := json.Marshal(&JSONMessage{Status: action, Progress: str})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
return []byte(action + " " + str + "\r")
|
return []byte(action + " " + str + "\r")
|
||||||
|
|
Loading…
Reference in New Issue