package storage import ( "context" "errors" "io" ) type EntryType string const ( EntryTypeFile EntryType = "file" EntryTypeDirectory EntryType = "directory" EntryTypeSymlink EntryType = "symlink" EntryTypeOther EntryType = "other" ) type Entry struct { Path string Type EntryType Size int64 } type Backend interface { ReadFile(ctx context.Context, path string) ([]byte, error) OpenReader(ctx context.Context, path string) (io.ReadCloser, error) WriteFile(ctx context.Context, path string, data []byte, opts WriteOptions) (Entry, error) WriteFrom(ctx context.Context, path string, r io.Reader, opts WriteOptions) (Entry, error) Stat(ctx context.Context, path string) (Entry, error) Walk(ctx context.Context, prefix string, opts WalkOptions, fn WalkFunc) error HasAny(ctx context.Context, prefix string) (bool, error) DeleteManagedOutputs(ctx context.Context, bundlePath string, managedOutputPaths []string, opts DeleteOptions) error DeleteManagedBundle(ctx context.Context, bundlePath string, managedOutputPaths []string, opts DeleteOptions) error DeletePrefix(ctx context.Context, prefix string, opts DeleteOptions) error } type WalkOptions struct { Recursive bool Limit int } type WalkFunc func(Entry) error var ErrStopWalk = errors.New("stop walk") type WriteOptions struct { ContentType string Overwrite bool PreferAtomic bool Size int64 SizeKnown bool } type DeleteOptions struct { IgnoreMissing bool PruneEmptyDirs bool } func List(ctx context.Context, backend Backend, prefix string, opts WalkOptions) ([]Entry, error) { var entries []Entry err := backend.Walk(ctx, prefix, opts, func(entry Entry) error { entries = append(entries, entry) return nil }) if err != nil { return nil, err } SortEntries(entries) return entries, nil }