-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathformatter_history.go
More file actions
120 lines (104 loc) · 2.88 KB
/
formatter_history.go
File metadata and controls
120 lines (104 loc) · 2.88 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package image
import (
"strconv"
"strings"
"time"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/go-units"
"github.com/moby/moby/api/types/image"
"github.com/moby/moby/client"
)
const (
defaultHistoryTableFormat = "table {{.ID}}\t{{.CreatedSince}}\t{{.CreatedBy}}\t{{.Size}}\t{{.Comment}}"
nonHumanHistoryTableFormat = "table {{.ID}}\t{{.CreatedAt}}\t{{.CreatedBy}}\t{{.Size}}\t{{.Comment}}"
historyIDHeader = "IMAGE"
createdByHeader = "CREATED BY"
commentHeader = "COMMENT"
)
// newHistoryFormat returns a format for rendering a historyContext.
func newHistoryFormat(source string, quiet bool, human bool) formatter.Format {
if source == formatter.TableFormatKey {
switch {
case quiet:
return formatter.DefaultQuietFormat
case !human:
return nonHumanHistoryTableFormat
default:
return defaultHistoryTableFormat
}
}
return formatter.Format(source)
}
// historyWrite writes the context
func historyWrite(fmtCtx formatter.Context, human bool, history client.ImageHistoryResult) error {
historyCtx := &historyContext{
HeaderContext: formatter.HeaderContext{
Header: formatter.SubHeaderContext{
"ID": historyIDHeader,
"CreatedSince": formatter.CreatedSinceHeader,
"CreatedAt": formatter.CreatedAtHeader,
"CreatedBy": createdByHeader,
"Size": formatter.SizeHeader,
"Comment": commentHeader,
},
},
}
return fmtCtx.Write(historyCtx, func(format func(subContext formatter.SubContext) error) error {
for _, h := range history.Items {
if err := format(&historyContext{
trunc: fmtCtx.Trunc,
h: h,
human: human,
}); err != nil {
return err
}
}
return nil
})
}
type historyContext struct {
formatter.HeaderContext
trunc bool
human bool
h image.HistoryResponseItem
}
func (c *historyContext) MarshalJSON() ([]byte, error) {
return formatter.MarshalJSON(c)
}
func (c *historyContext) ID() string {
if c.trunc {
return formatter.TruncateID(c.h.ID)
}
return c.h.ID
}
func (c *historyContext) CreatedAt() string {
return time.Unix(c.h.Created, 0).Format(time.RFC3339)
}
// epoch is the time before which created-at dates are not displayed with human units.
var epoch = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC).Unix()
func (c *historyContext) CreatedSince() string {
if !c.human {
return c.CreatedAt()
}
if c.h.Created <= epoch {
return "N/A"
}
created := units.HumanDuration(time.Now().UTC().Sub(time.Unix(c.h.Created, 0)))
return created + " ago"
}
func (c *historyContext) CreatedBy() string {
createdBy := strings.ReplaceAll(c.h.CreatedBy, "\t", " ")
if c.trunc {
return formatter.Ellipsis(createdBy, 45)
}
return createdBy
}
func (c *historyContext) Size() string {
if c.human {
return units.HumanSizeWithPrecision(float64(c.h.Size), 3)
}
return strconv.FormatInt(c.h.Size, 10)
}
func (c *historyContext) Comment() string {
return c.h.Comment
}