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 }