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  }