Victor Vieux пре 11 година
родитељ
комит
f50fe14e13
3 измењених фајлова са 48 додато и 15 уклоњено
  1. 1 1
      commands.go
  2. 38 10
      utils/jsonmessage.go
  3. 9 4
      utils/jsonmessage_test.go

+ 1 - 1
commands.go

@@ -2294,7 +2294,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

+ 38 - 10
utils/jsonmessage.go

@@ -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"`
-	Total   int   `json:"total,omitempty"`
-	Start   int64 `json:"start,omitempty"`
+	terminalFd uintptr
+	Current    int   `json:"current,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))
-	perEntry := fromStart / time.Duration(p.Current)
-	left := time.Duration(p.Total-p.Current) * perEntry
-	left = (left / time.Second) * time.Second
-	return fmt.Sprintf("[%s>%s] %8v/%v %s", strings.Repeat("=", percentage), strings.Repeat(" ", 50-percentage), current, total, left.String())
+	if p.Start > 0 {
+		fromStart := time.Now().UTC().Sub(time.Unix(int64(p.Start), 0))
+		perEntry := fromStart / time.Duration(p.Current)
+		left := time.Duration(p.Total-p.Current) * perEntry
+		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 {

+ 9 - 4
utils/jsonmessage_test.go

@@ -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}
-	if jp2.String() != "     1 B/?" {
-		t.Fatalf("Expected '     1/?', got '%s'", jp2.String())
+	jp2 := JSONProgress{Current: 1}
+	if jp2.String() != "     1 B" {
+		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())
 	}
 	}
 }
 }