diff --git a/commands.go b/commands.go index 2a672d49e3..99d91ac771 100644 --- a/commands.go +++ b/commands.go @@ -1536,19 +1536,7 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer) e } if resp.Header.Get("Content-Type") == "application/json" { - dec := json.NewDecoder(resp.Body) - jm := utils.JSONMessage{} - for { - if err := dec.Decode(&jm); err == io.EOF { - break - } else if err != nil { - return err - } - jm.Display(out) - } - if jm.Progress != "" { - fmt.Fprintf(out, "\n") - } + utils.DisplayJSONMessagesStream(resp.Body, out) } else { if _, err := io.Copy(out, resp.Body); err != nil { return err diff --git a/utils/utils.go b/utils/utils.go index 6361945eef..6081935b41 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -617,6 +617,7 @@ func (jm *JSONMessage) Display(out io.Writer) (error) { if jm.Error != "" { return fmt.Errorf(jm.Error) } + fmt.Fprintf(out, "%c[2K", 27) if jm.Time != 0 { fmt.Fprintf(out, "[%s] ", time.Unix(jm.Time, 0)) } @@ -626,8 +627,43 @@ func (jm *JSONMessage) Display(out io.Writer) (error) { if jm.Progress != "" { fmt.Fprintf(out, "%s %s\r", jm.Status, jm.Progress) } else { - fmt.Fprintf(out, "%s\n", jm.Status) + fmt.Fprintf(out, "%s\r", jm.Status) } + if jm.ID == "" { + fmt.Fprintf(out, "\n") + } + return nil +} + +func DisplayJSONMessagesStream(in io.Reader, out io.Writer) error { + dec := json.NewDecoder(in) + jm := JSONMessage{} + ids := make(map[string]int) + diff := 0 + for { + if err := dec.Decode(&jm); err == io.EOF { + break + } else if err != nil { + return err + } + if jm.ID != "" { + line, ok := ids[jm.ID] + if !ok { + line = len(ids) + ids[jm.ID] = line + fmt.Fprintf(out, "\n") + diff = 0 + } else { + diff = len(ids) - line + } + fmt.Fprintf(out, "%c[%dA", 27, diff) + } + jm.Display(out) + if jm.ID != "" { + fmt.Fprintf(out, "%c[%dB", 27, diff) + } + } +// fmt.Fprintf(out, "\n") return nil }