github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/cli/command/builder/prune.go (about)

     1  package builder
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/docker/cli/cli"
     9  	"github.com/docker/cli/cli/command"
    10  	"github.com/docker/cli/opts"
    11  	"github.com/docker/docker/api/types"
    12  	units "github.com/docker/go-units"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  type pruneOptions struct {
    17  	force       bool
    18  	all         bool
    19  	filter      opts.FilterOpt
    20  	keepStorage opts.MemBytes
    21  }
    22  
    23  // NewPruneCommand returns a new cobra prune command for images
    24  func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
    25  	options := pruneOptions{filter: opts.NewFilterOpt()}
    26  
    27  	cmd := &cobra.Command{
    28  		Use:   "prune",
    29  		Short: "Remove build cache",
    30  		Args:  cli.NoArgs,
    31  		RunE: func(cmd *cobra.Command, args []string) error {
    32  			spaceReclaimed, output, err := runPrune(dockerCli, options)
    33  			if err != nil {
    34  				return err
    35  			}
    36  			if output != "" {
    37  				fmt.Fprintln(dockerCli.Out(), output)
    38  			}
    39  			fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))
    40  			return nil
    41  		},
    42  		Annotations: map[string]string{"version": "1.39"},
    43  	}
    44  
    45  	flags := cmd.Flags()
    46  	flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
    47  	flags.BoolVarP(&options.all, "all", "a", false, "Remove all unused build cache, not just dangling ones")
    48  	flags.Var(&options.filter, "filter", "Provide filter values (e.g. 'until=24h')")
    49  	flags.Var(&options.keepStorage, "keep-storage", "Amount of disk space to keep for cache")
    50  
    51  	return cmd
    52  }
    53  
    54  const (
    55  	normalWarning   = `WARNING! This will remove all dangling build cache. Are you sure you want to continue?`
    56  	allCacheWarning = `WARNING! This will remove all build cache. Are you sure you want to continue?`
    57  )
    58  
    59  func runPrune(dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) {
    60  	pruneFilters := options.filter.Value()
    61  	pruneFilters = command.PruneFilters(dockerCli, pruneFilters)
    62  
    63  	warning := normalWarning
    64  	if options.all {
    65  		warning = allCacheWarning
    66  	}
    67  	if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) {
    68  		return 0, "", nil
    69  	}
    70  
    71  	report, err := dockerCli.Client().BuildCachePrune(context.Background(), types.BuildCachePruneOptions{
    72  		All:         options.all,
    73  		KeepStorage: options.keepStorage.Value(),
    74  		Filters:     pruneFilters,
    75  	})
    76  	if err != nil {
    77  		return 0, "", err
    78  	}
    79  
    80  	if len(report.CachesDeleted) > 0 {
    81  		var sb strings.Builder
    82  		sb.WriteString("Deleted build cache objects:\n")
    83  		for _, id := range report.CachesDeleted {
    84  			sb.WriteString(id)
    85  			sb.WriteByte('\n')
    86  		}
    87  		output = sb.String()
    88  	}
    89  
    90  	return report.SpaceReclaimed, output, nil
    91  }
    92  
    93  // CachePrune executes a prune command for build cache
    94  func CachePrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
    95  	return runPrune(dockerCli, pruneOptions{force: true, all: all, filter: filter})
    96  }