- moby:a60b458179...d2590dc3cd- swarmkit:6068d1894d...48dd89375dThe .Parent field for buildcache entries was deprecated, and replaced with a .Parents (plural) field. This patch updates the code accordingly. Unlike the change in buildx9c3be32bc9we continue to fall back to the old field (which will be set on older API versions). Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
184 lines
4.3 KiB
Go
184 lines
4.3 KiB
Go
package formatter
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/pkg/stringid"
|
|
"github.com/docker/go-units"
|
|
)
|
|
|
|
const (
|
|
defaultBuildCacheTableFormat = "table {{.ID}}\t{{.Type}}\t{{.Size}}\t{{.CreatedSince}}\t{{.LastUsedSince}}\t{{.UsageCount}}\t{{.Shared}}\t{{.Description}}"
|
|
|
|
cacheIDHeader = "CACHE ID"
|
|
cacheTypeHeader = "CACHE TYPE"
|
|
parentHeader = "PARENT"
|
|
lastUsedSinceHeader = "LAST USED"
|
|
usageCountHeader = "USAGE"
|
|
inUseHeader = "IN USE"
|
|
sharedHeader = "SHARED"
|
|
)
|
|
|
|
// NewBuildCacheFormat returns a Format for rendering using a Context
|
|
func NewBuildCacheFormat(source string, quiet bool) Format {
|
|
switch source {
|
|
case TableFormatKey:
|
|
if quiet {
|
|
return DefaultQuietFormat
|
|
}
|
|
return Format(defaultBuildCacheTableFormat)
|
|
case RawFormatKey:
|
|
if quiet {
|
|
return `build_cache_id: {{.ID}}`
|
|
}
|
|
format := `build_cache_id: {{.ID}}
|
|
parent_id: {{.Parent}}
|
|
build_cache_type: {{.CacheType}}
|
|
description: {{.Description}}
|
|
created_at: {{.CreatedAt}}
|
|
created_since: {{.CreatedSince}}
|
|
last_used_at: {{.LastUsedAt}}
|
|
last_used_since: {{.LastUsedSince}}
|
|
usage_count: {{.UsageCount}}
|
|
in_use: {{.InUse}}
|
|
shared: {{.Shared}}
|
|
`
|
|
return Format(format)
|
|
}
|
|
return Format(source)
|
|
}
|
|
|
|
func buildCacheSort(buildCache []*types.BuildCache) {
|
|
sort.Slice(buildCache, func(i, j int) bool {
|
|
lui, luj := buildCache[i].LastUsedAt, buildCache[j].LastUsedAt
|
|
switch {
|
|
case lui == nil && luj == nil:
|
|
return strings.Compare(buildCache[i].ID, buildCache[j].ID) < 0
|
|
case lui == nil:
|
|
return true
|
|
case luj == nil:
|
|
return false
|
|
case lui.Equal(*luj):
|
|
return strings.Compare(buildCache[i].ID, buildCache[j].ID) < 0
|
|
default:
|
|
return lui.Before(*luj)
|
|
}
|
|
})
|
|
}
|
|
|
|
// BuildCacheWrite renders the context for a list of containers
|
|
func BuildCacheWrite(ctx Context, buildCaches []*types.BuildCache) error {
|
|
render := func(format func(subContext SubContext) error) error {
|
|
buildCacheSort(buildCaches)
|
|
for _, bc := range buildCaches {
|
|
err := format(&buildCacheContext{trunc: ctx.Trunc, v: bc})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
return ctx.Write(newBuildCacheContext(), render)
|
|
}
|
|
|
|
type buildCacheContext struct {
|
|
HeaderContext
|
|
trunc bool
|
|
v *types.BuildCache
|
|
}
|
|
|
|
func newBuildCacheContext() *buildCacheContext {
|
|
buildCacheCtx := buildCacheContext{}
|
|
buildCacheCtx.Header = SubHeaderContext{
|
|
"ID": cacheIDHeader,
|
|
"Parent": parentHeader,
|
|
"CacheType": cacheTypeHeader,
|
|
"Size": SizeHeader,
|
|
"CreatedSince": CreatedSinceHeader,
|
|
"LastUsedSince": lastUsedSinceHeader,
|
|
"UsageCount": usageCountHeader,
|
|
"InUse": inUseHeader,
|
|
"Shared": sharedHeader,
|
|
"Description": DescriptionHeader,
|
|
}
|
|
return &buildCacheCtx
|
|
}
|
|
|
|
func (c *buildCacheContext) MarshalJSON() ([]byte, error) {
|
|
return MarshalJSON(c)
|
|
}
|
|
|
|
func (c *buildCacheContext) ID() string {
|
|
id := c.v.ID
|
|
if c.trunc {
|
|
id = stringid.TruncateID(c.v.ID)
|
|
}
|
|
if c.v.InUse {
|
|
return id + "*"
|
|
}
|
|
return id
|
|
}
|
|
|
|
func (c *buildCacheContext) Parent() string {
|
|
var parent string
|
|
if len(c.v.Parents) > 0 {
|
|
parent = strings.Join(c.v.Parents, ", ")
|
|
} else {
|
|
parent = c.v.Parent //nolint:staticcheck // Ignore SA1019: Field was deprecated in API v1.42, but kept for backward compatibility
|
|
}
|
|
if c.trunc {
|
|
return stringid.TruncateID(parent)
|
|
}
|
|
return parent
|
|
}
|
|
|
|
func (c *buildCacheContext) CacheType() string {
|
|
return c.v.Type
|
|
}
|
|
|
|
func (c *buildCacheContext) Description() string {
|
|
return c.v.Description
|
|
}
|
|
|
|
func (c *buildCacheContext) Size() string {
|
|
return units.HumanSizeWithPrecision(float64(c.v.Size), 3)
|
|
}
|
|
|
|
func (c *buildCacheContext) CreatedAt() string {
|
|
return c.v.CreatedAt.String()
|
|
}
|
|
|
|
func (c *buildCacheContext) CreatedSince() string {
|
|
return units.HumanDuration(time.Now().UTC().Sub(c.v.CreatedAt)) + " ago"
|
|
}
|
|
|
|
func (c *buildCacheContext) LastUsedAt() string {
|
|
if c.v.LastUsedAt == nil {
|
|
return ""
|
|
}
|
|
return c.v.LastUsedAt.String()
|
|
}
|
|
|
|
func (c *buildCacheContext) LastUsedSince() string {
|
|
if c.v.LastUsedAt == nil {
|
|
return ""
|
|
}
|
|
return units.HumanDuration(time.Now().UTC().Sub(*c.v.LastUsedAt)) + " ago"
|
|
}
|
|
|
|
func (c *buildCacheContext) UsageCount() string {
|
|
return fmt.Sprintf("%d", c.v.UsageCount)
|
|
}
|
|
|
|
func (c *buildCacheContext) InUse() string {
|
|
return fmt.Sprintf("%t", c.v.InUse)
|
|
}
|
|
|
|
func (c *buildCacheContext) Shared() string {
|
|
return fmt.Sprintf("%t", c.v.Shared)
|
|
}
|