github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/cli/command/formatter/buildcache.go (about) 1 package formatter 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 "time" 8 9 "github.com/docker/docker/api/types" 10 "github.com/docker/docker/pkg/stringid" 11 "github.com/docker/go-units" 12 ) 13 14 const ( 15 defaultBuildCacheTableFormat = "table {{.ID}}\t{{.Type}}\t{{.Size}}\t{{.CreatedSince}}\t{{.LastUsedSince}}\t{{.UsageCount}}\t{{.Shared}}\t{{.Description}}" 16 17 cacheIDHeader = "CACHE ID" 18 cacheTypeHeader = "CACHE TYPE" 19 parentHeader = "PARENT" 20 lastUsedSinceHeader = "LAST USED" 21 usageCountHeader = "USAGE" 22 inUseHeader = "IN USE" 23 sharedHeader = "SHARED" 24 ) 25 26 // NewBuildCacheFormat returns a Format for rendering using a Context 27 func NewBuildCacheFormat(source string, quiet bool) Format { 28 switch source { 29 case TableFormatKey: 30 if quiet { 31 return DefaultQuietFormat 32 } 33 return Format(defaultBuildCacheTableFormat) 34 case RawFormatKey: 35 if quiet { 36 return `build_cache_id: {{.ID}}` 37 } 38 format := `build_cache_id: {{.ID}} 39 parent_id: {{.Parent}} 40 build_cache_type: {{.CacheType}} 41 description: {{.Description}} 42 created_at: {{.CreatedAt}} 43 created_since: {{.CreatedSince}} 44 last_used_at: {{.LastUsedAt}} 45 last_used_since: {{.LastUsedSince}} 46 usage_count: {{.UsageCount}} 47 in_use: {{.InUse}} 48 shared: {{.Shared}} 49 ` 50 return Format(format) 51 } 52 return Format(source) 53 } 54 55 func buildCacheSort(buildCache []*types.BuildCache) { 56 sort.Slice(buildCache, func(i, j int) bool { 57 lui, luj := buildCache[i].LastUsedAt, buildCache[j].LastUsedAt 58 switch { 59 case lui == nil && luj == nil: 60 return strings.Compare(buildCache[i].ID, buildCache[j].ID) < 0 61 case lui == nil: 62 return true 63 case luj == nil: 64 return false 65 case lui.Equal(*luj): 66 return strings.Compare(buildCache[i].ID, buildCache[j].ID) < 0 67 default: 68 return lui.Before(*luj) 69 } 70 }) 71 } 72 73 // BuildCacheWrite renders the context for a list of containers 74 func BuildCacheWrite(ctx Context, buildCaches []*types.BuildCache) error { 75 render := func(format func(subContext SubContext) error) error { 76 buildCacheSort(buildCaches) 77 for _, bc := range buildCaches { 78 err := format(&buildCacheContext{trunc: ctx.Trunc, v: bc}) 79 if err != nil { 80 return err 81 } 82 } 83 return nil 84 } 85 return ctx.Write(newBuildCacheContext(), render) 86 } 87 88 type buildCacheContext struct { 89 HeaderContext 90 trunc bool 91 v *types.BuildCache 92 } 93 94 func newBuildCacheContext() *buildCacheContext { 95 buildCacheCtx := buildCacheContext{} 96 buildCacheCtx.Header = SubHeaderContext{ 97 "ID": cacheIDHeader, 98 "Parent": parentHeader, 99 "CacheType": cacheTypeHeader, 100 "Size": SizeHeader, 101 "CreatedSince": CreatedSinceHeader, 102 "LastUsedSince": lastUsedSinceHeader, 103 "UsageCount": usageCountHeader, 104 "InUse": inUseHeader, 105 "Shared": sharedHeader, 106 "Description": DescriptionHeader, 107 } 108 return &buildCacheCtx 109 } 110 111 func (c *buildCacheContext) MarshalJSON() ([]byte, error) { 112 return MarshalJSON(c) 113 } 114 115 func (c *buildCacheContext) ID() string { 116 id := c.v.ID 117 if c.trunc { 118 id = stringid.TruncateID(c.v.ID) 119 } 120 if c.v.InUse { 121 return id + "*" 122 } 123 return id 124 } 125 126 func (c *buildCacheContext) Parent() string { 127 if c.trunc { 128 return stringid.TruncateID(c.v.Parent) 129 } 130 return c.v.Parent 131 } 132 133 func (c *buildCacheContext) CacheType() string { 134 return c.v.Type 135 } 136 137 func (c *buildCacheContext) Description() string { 138 return c.v.Description 139 } 140 141 func (c *buildCacheContext) Size() string { 142 return units.HumanSizeWithPrecision(float64(c.v.Size), 3) 143 } 144 145 func (c *buildCacheContext) CreatedAt() string { 146 return c.v.CreatedAt.String() 147 } 148 149 func (c *buildCacheContext) CreatedSince() string { 150 return units.HumanDuration(time.Now().UTC().Sub(c.v.CreatedAt)) + " ago" 151 } 152 153 func (c *buildCacheContext) LastUsedAt() string { 154 if c.v.LastUsedAt == nil { 155 return "" 156 } 157 return c.v.LastUsedAt.String() 158 } 159 160 func (c *buildCacheContext) LastUsedSince() string { 161 if c.v.LastUsedAt == nil { 162 return "" 163 } 164 return units.HumanDuration(time.Now().UTC().Sub(*c.v.LastUsedAt)) + " ago" 165 } 166 167 func (c *buildCacheContext) UsageCount() string { 168 return fmt.Sprintf("%d", c.v.UsageCount) 169 } 170 171 func (c *buildCacheContext) InUse() string { 172 return fmt.Sprintf("%t", c.v.InUse) 173 } 174 175 func (c *buildCacheContext) Shared() string { 176 return fmt.Sprintf("%t", c.v.Shared) 177 }