github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/pkg/store/filestore/filestore.go (about)

     1  package filestore
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/benchkram/bob/pkg/file"
    11  	"github.com/benchkram/bob/pkg/store"
    12  	"github.com/benchkram/errz"
    13  )
    14  
    15  type s struct {
    16  	dir string
    17  }
    18  
    19  // New creates a filestore. The caller is responsible to pass a
    20  // existing directory.
    21  func New(dir string, opts ...Option) store.Store {
    22  	s := &s{
    23  		dir: dir,
    24  	}
    25  
    26  	for _, opt := range opts {
    27  		if opt == nil {
    28  			continue
    29  		}
    30  		opt(s)
    31  	}
    32  
    33  	return s
    34  }
    35  
    36  // NewArtifact creates a new file. The caller is responsible to call Close().
    37  // Existing artifacts are overwritten.
    38  func (s *s) NewArtifact(_ context.Context, artifactID string, _ int64) (io.WriteCloser, error) {
    39  	return os.Create(filepath.Join(s.dir, artifactID))
    40  }
    41  
    42  // GetArtifact opens a file
    43  func (s *s) GetArtifact(_ context.Context, id string) (empty io.ReadCloser, size int64, _ error) {
    44  	f, err := os.Open(filepath.Join(s.dir, id))
    45  	if err != nil {
    46  		return nil, 0, err
    47  	}
    48  	stat, err := f.Stat()
    49  	if err != nil {
    50  		return nil, 0, err
    51  	}
    52  	return f, stat.Size(), nil
    53  }
    54  
    55  func (s *s) Clean(_ context.Context) (err error) {
    56  	defer errz.Recover(&err)
    57  
    58  	homeDir, err := os.UserHomeDir()
    59  	errz.Fatal(err)
    60  	if s.dir == "/" || s.dir == homeDir {
    61  		return fmt.Errorf("Cleanup of %s is not allowed", s.dir)
    62  	}
    63  
    64  	entrys, err := os.ReadDir(s.dir)
    65  	errz.Fatal(err)
    66  
    67  	for _, entry := range entrys {
    68  		if entry.IsDir() {
    69  			continue
    70  		}
    71  		_ = os.Remove(filepath.Join(s.dir, entry.Name()))
    72  	}
    73  
    74  	return nil
    75  }
    76  
    77  // List the items id's in the store
    78  func (s *s) List(_ context.Context) (items []string, err error) {
    79  	defer errz.Recover(&err)
    80  	entrys, err := os.ReadDir(s.dir)
    81  	errz.Fatal(err)
    82  
    83  	items = []string{}
    84  	for _, e := range entrys {
    85  		items = append(items, e.Name())
    86  	}
    87  
    88  	return items, nil
    89  }
    90  
    91  // Done does nothing
    92  func (s *s) Done() error {
    93  	return nil
    94  }
    95  
    96  func (s *s) ArtifactExists(ctx context.Context, id string) bool {
    97  	return file.Exists(filepath.Join(s.dir, id))
    98  }
    99  
   100  func (s *s) ArtifactRemove(ctx context.Context, id string) error {
   101  	if !s.ArtifactExists(ctx, id) {
   102  		return nil
   103  	}
   104  	return os.Remove(filepath.Join(s.dir, id))
   105  }