1
0
Fork 0
mirror of https://github.com/Luzifer/s3sync.git synced 2024-10-18 06:24:20 +00:00
s3sync/pkg/fsprovider/local.go

93 lines
2.2 KiB
Go
Raw Normal View History

package fsprovider
import (
"io"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors"
)
const directoryCreatePerms = 0o750
type (
// Local implements the Provider for filesystem access
Local struct{}
)
// NewLocal creates a new Local file provider
func NewLocal() *Local {
return &Local{}
}
// DeleteFile deletes a local file
func (*Local) DeleteFile(path string) error {
return errors.Wrap(os.Remove(path), "removing file")
}
// GetAbsolutePath converts the given path into an absolute path
func (*Local) GetAbsolutePath(path string) (string, error) {
fp, err := filepath.Abs(path)
return fp, errors.Wrap(err, "getting absolute filepath")
}
// ListFiles retrieves the metadata of all files with given prefix
func (*Local) ListFiles(prefix string) ([]File, error) {
out := []File{}
err := filepath.Walk(prefix, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if f.IsDir() {
return nil
}
linkTarget, err := filepath.EvalSymlinks(path)
if err != nil {
return errors.Wrap(err, "evaluating symlinks")
}
if path != linkTarget {
if f, err = os.Stat(linkTarget); err != nil {
return errors.Wrap(err, "getting file-stat of link target")
}
}
out = append(out, File{
Filename: strings.TrimLeft(strings.Replace(path, prefix, "", 1), string(os.PathSeparator)),
LastModified: f.ModTime(),
Size: f.Size(),
})
return nil
})
return out, errors.Wrap(err, "walking prefix")
}
// ReadFile opens the local file for reading
func (*Local) ReadFile(path string) (io.ReadCloser, error) {
f, err := os.Open(path) //#nosec:G304 // The purpose is to read a dynamic file
return f, errors.Wrap(err, "opening file")
}
// WriteFile takes the content of the file and writes it to the local
// filesystem
func (*Local) WriteFile(path string, content io.Reader, _ bool) error {
if err := os.MkdirAll(filepath.Dir(path), directoryCreatePerms); err != nil {
return errors.Wrap(err, "creating file path")
}
f, err := os.Create(path) //#nosec:G304 // The purpose is to create a dynamic file
if err != nil {
return errors.Wrap(err, "creating file")
}
if _, err := io.Copy(f, content); err != nil {
return errors.Wrap(err, "copying content")
}
return errors.Wrap(f.Close(), "closing file")
}