package cli import ( "context" "strings" "github.com/kopia/kopia/internal/epoch" "github.com/kopia/kopia/repo" "github.com/kopia/kopia/repo/blob" "github.com/kopia/kopia/repo/content" ) type commandBlobList struct { blobListPrefix string blobListPrefixExclude []string blobListMinSize int64 blobListMaxSize int64 dataOnly bool jo jsonOutput out textOutput } func (c *commandBlobList) setup(svc appServices, parent commandParent) { cmd := parent.Command("list", "List BLOBs").Alias("ls") cmd.Flag("prefix", "Blob ID prefix").StringVar(&c.blobListPrefix) cmd.Flag("exclude-prefix", "Blob ID prefixes to exclude").StringsVar(&c.blobListPrefixExclude) cmd.Flag("min-size", "Minimum size").Int64Var(&c.blobListMinSize) cmd.Flag("max-size", "Maximum size").Int64Var(&c.blobListMaxSize) cmd.Flag("data-only", "Only list data blobs").BoolVar(&c.dataOnly) c.jo.setup(svc, cmd) c.out.setup(svc) cmd.Action(svc.directRepositoryReadAction(c.run)) } func (c *commandBlobList) run(ctx context.Context, rep repo.DirectRepository) error { var jl jsonList jl.begin(&c.jo) defer jl.end() // nolint:wrapcheck return rep.BlobReader().ListBlobs(ctx, blob.ID(c.blobListPrefix), func(b blob.Metadata) error { if !c.shouldInclude(b) { return nil } if c.jo.jsonOutput { jl.emit(b) } else { c.out.printStdout("%-70v %10v %v\n", b.BlobID, b.Length, formatTimestamp(b.Timestamp)) } return nil }) } func (c *commandBlobList) shouldInclude(b blob.Metadata) bool { if c.dataOnly { if strings.HasPrefix(string(b.BlobID), content.IndexBlobPrefix) { return false } if strings.HasPrefix(string(b.BlobID), epoch.EpochManagerIndexUberPrefix) { return false } if strings.HasPrefix(string(b.BlobID), content.TextLogBlobPrefix) { return false } if strings.HasPrefix(string(b.BlobID), "kopia.") { return false } } if c.blobListMaxSize != 0 && b.Length > c.blobListMaxSize { return false } if c.blobListMinSize != 0 && b.Length < c.blobListMinSize { return false } for _, ex := range c.blobListPrefixExclude { if strings.HasPrefix(string(b.BlobID), ex) { return false } } return true }