1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #2999 from dotcloud/improve_progress_bars

Handle small screens
This commit is contained in:
Victor Vieux 2013-12-03 14:24:40 -08:00
commit f8176de191
3 changed files with 48 additions and 15 deletions

View file

@ -2303,7 +2303,7 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer, h
} }
if matchesContentType(resp.Header.Get("Content-Type"), "application/json") { if matchesContentType(resp.Header.Get("Content-Type"), "application/json") {
return utils.DisplayJSONMessagesStream(resp.Body, out, cli.isTerminal) return utils.DisplayJSONMessagesStream(resp.Body, out, cli.terminalFd, cli.isTerminal)
} }
if _, err := io.Copy(out, resp.Body); err != nil { if _, err := io.Copy(out, resp.Body); err != nil {
return err return err

View file

@ -3,6 +3,7 @@ package utils
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/dotcloud/docker/term"
"io" "io"
"strings" "strings"
"time" "time"
@ -18,27 +19,50 @@ func (e *JSONError) Error() string {
} }
type JSONProgress struct { type JSONProgress struct {
Current int `json:"current,omitempty"` terminalFd uintptr
Total int `json:"total,omitempty"` Current int `json:"current,omitempty"`
Start int64 `json:"start,omitempty"` Total int `json:"total,omitempty"`
Start int64 `json:"start,omitempty"`
} }
func (p *JSONProgress) String() string { func (p *JSONProgress) String() string {
var (
width = 200
pbBox string
numbersBox string
timeLeftBox string
)
ws, err := term.GetWinsize(p.terminalFd)
if err == nil {
width = int(ws.Width)
}
if p.Current == 0 && p.Total == 0 { if p.Current == 0 && p.Total == 0 {
return "" return ""
} }
current := HumanSize(int64(p.Current)) current := HumanSize(int64(p.Current))
if p.Total == 0 { if p.Total == 0 {
return fmt.Sprintf("%8v/?", current) return fmt.Sprintf("%8v", current)
} }
total := HumanSize(int64(p.Total)) total := HumanSize(int64(p.Total))
percentage := int(float64(p.Current)/float64(p.Total)*100) / 2 percentage := int(float64(p.Current)/float64(p.Total)*100) / 2
if width > 110 {
pbBox = fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", 50-percentage))
}
numbersBox = fmt.Sprintf("%8v/%v", current, total)
fromStart := time.Now().UTC().Sub(time.Unix(int64(p.Start), 0)) if p.Start > 0 {
perEntry := fromStart / time.Duration(p.Current) fromStart := time.Now().UTC().Sub(time.Unix(int64(p.Start), 0))
left := time.Duration(p.Total-p.Current) * perEntry perEntry := fromStart / time.Duration(p.Current)
left = (left / time.Second) * time.Second left := time.Duration(p.Total-p.Current) * perEntry
return fmt.Sprintf("[%s>%s] %8v/%v %s", strings.Repeat("=", percentage), strings.Repeat(" ", 50-percentage), current, total, left.String()) left = (left / time.Second) * time.Second
if width > 50 {
timeLeftBox = " " + left.String()
}
}
return pbBox + numbersBox + timeLeftBox
} }
type JSONMessage struct { type JSONMessage struct {
@ -84,7 +108,7 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
return nil return nil
} }
func DisplayJSONMessagesStream(in io.Reader, out io.Writer, isTerminal bool) error { func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool) error {
var ( var (
dec = json.NewDecoder(in) dec = json.NewDecoder(in)
ids = make(map[string]int) ids = make(map[string]int)
@ -98,6 +122,10 @@ func DisplayJSONMessagesStream(in io.Reader, out io.Writer, isTerminal bool) err
} }
return err return err
} }
if jm.Progress != nil {
jm.Progress.terminalFd = terminalFd
}
if (jm.Progress != nil || jm.ProgressMessage != "") && jm.ID != "" { if (jm.Progress != nil || jm.ProgressMessage != "") && jm.ID != "" {
line, ok := ids[jm.ID] line, ok := ids[jm.ID]
if !ok { if !ok {

View file

@ -12,13 +12,18 @@ func TestError(t *testing.T) {
} }
func TestProgress(t *testing.T) { func TestProgress(t *testing.T) {
jp := JSONProgress{0, 0, 0} jp := JSONProgress{}
if jp.String() != "" { if jp.String() != "" {
t.Fatalf("Expected empty string, got '%s'", jp.String()) t.Fatalf("Expected empty string, got '%s'", jp.String())
} }
jp2 := JSONProgress{1, 0, 0} jp2 := JSONProgress{Current: 1}
if jp2.String() != " 1 B/?" { if jp2.String() != " 1 B" {
t.Fatalf("Expected ' 1/?', got '%s'", jp2.String()) t.Fatalf("Expected ' 1 B', got '%s'", jp2.String())
}
jp3 := JSONProgress{Current: 50, Total: 100}
if jp3.String() != "[=========================> ] 50 B/100 B" {
t.Fatalf("Expected '[=========================> ] 50 B/100 B', got '%s'", jp3.String())
} }
} }