Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
Go
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788package storage
import ( "context" "fmt" "io" "os" "path/filepath")
type Disk struct { root string}
func NewDisk(root string) (*Disk, error) { if root == "" { return nil, fmt.Errorf("storage: disk backend requires a directory") } if err := os.MkdirAll(root, 0o755); err != nil { return nil, fmt.Errorf("storage: create disk root: %w", err) } return &Disk{root: filepath.Clean(root)}, nil}
func (d *Disk) path(key string) (string, error) { if err := ValidateKey(key); err != nil { return "", err } return filepath.Join(d.root, filepath.FromSlash(key)), nil}
func (d *Disk) Get(_ context.Context, key string) (io.ReadCloser, error) { p, err := d.path(key) if err != nil { return nil, err } f, err := os.Open(p) if err != nil { if os.IsNotExist(err) { return nil, ErrNotExist } return nil, fmt.Errorf("storage: get %q: %w", key, err) } return f, nil}
func (d *Disk) Put(_ context.Context, key string, r io.Reader) error { p, err := d.path(key) if err != nil { return err } if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { return fmt.Errorf("storage: put %q: %w", key, err) } // dont let readers see a partial object tmp, err := os.CreateTemp(filepath.Dir(p), ".tmp-*") if err != nil { return fmt.Errorf("storage: put %q: %w", key, err) } tmpName := tmp.Name() defer os.Remove(tmpName) if _, err := io.Copy(tmp, r); err != nil { _ = tmp.Close() return fmt.Errorf("storage: put %q: %w", key, err) } if err := tmp.Close(); err != nil { return fmt.Errorf("storage: put %q: %w", key, err) } if err := os.Rename(tmpName, p); err != nil { return fmt.Errorf("storage: put %q: %w", key, err) } return nil}
func (d *Disk) Delete(_ context.Context, key string) error { p, err := d.path(key) if err != nil { return err } if err := os.Remove(p); err != nil { if os.IsNotExist(err) { return nil } return fmt.Errorf("storage: delete %q: %w", key, err) } return nil}