From a0fdcf0cc6f25a0adbd40137d4753dc2c51aebb8 Mon Sep 17 00:00:00 2001 From: Leslie Leung Date: Wed, 8 Nov 2023 02:36:50 +0800 Subject: [PATCH] refactor: modify storage interface --- internal/rip/rip.go | 24 ++++++------------------ internal/storage/file.go | 36 +++++++++++++++--------------------- internal/storage/storage.go | 16 ++++++++++++++-- 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/internal/rip/rip.go b/internal/rip/rip.go index e5dd5a9..dec5a52 100644 --- a/internal/rip/rip.go +++ b/internal/rip/rip.go @@ -1,6 +1,7 @@ package rip import ( + "bytes" "context" "github.com/go-git/go-git/v5" "github.com/google/uuid" @@ -44,7 +45,6 @@ func Rip(repo config.Repository, storages []config.Storage) error { ui.Printf("Repository %s cloned", repo.Name) files, err := archiver.FilesFromDisk(nil, map[string]string{ path.Join(currentDir, ".reaper", id): repo.Name, - // TODO add file hash }) if err != nil { ui.Errorf("Error reading files, %s", err) @@ -53,32 +53,25 @@ func Rip(repo config.Repository, storages []config.Storage) error { now := time.Now().Format("20060102150405") base := repo.Name + "-" + now + ".tar.gz" - p := path.Join(currentDir, ".reaper", base) - out, err := os.Create(p) - if err != nil { - ui.Errorf("Error creating archive, %s", err) - return err - } + // TODO store to a temporary file first if greater than certain size + archive := &bytes.Buffer{} + format := archiver.CompressedArchive{ Compression: archiver.Gz{}, Archival: archiver.Tar{}, } - err = format.Archive(context.Background(), out, files) + err = format.Archive(context.Background(), archive, files) if err != nil { ui.Errorf("Error creating archive, %s", err) return err } - if err := out.Close(); err != nil { - ui.Errorf("Error closing archive, %s", err) - return err - } // handle storages for _, s := range storages { switch s.Type { case "file": fileBackend := storage.File{} - err := fileBackend.PutObjectFromPath(p, path.Join(s.Path, base)) + err := fileBackend.PutObject(path.Join(s.Path, base), archive.Bytes()) if err != nil { ui.Errorf("Error storing file, %s", err) return err @@ -93,10 +86,5 @@ func Rip(repo config.Repository, storages []config.Storage) error { ui.Errorf("Error cleaning up working directory, %s", err) return err } - err = os.Remove(p) - if err != nil { - ui.Errorf("Error cleaning up archive, %s", err) - return err - } return nil } diff --git a/internal/storage/file.go b/internal/storage/file.go index e08ecc6..da480f1 100644 --- a/internal/storage/file.go +++ b/internal/storage/file.go @@ -1,7 +1,6 @@ package storage import ( - "io" "os" "path" ) @@ -11,6 +10,21 @@ var _ Storage = (*File)(nil) type File struct { } +func (f File) ListObject(prefix string) ([]Object, error) { + // TODO implement me + panic("implement me") +} + +func (f File) GetObject(identifier string) (Object, error) { + // TODO implement me + panic("implement me") +} + +func (f File) DeleteObject(identifier string) error { + // TODO implement me + panic("implement me") +} + // createPathIfNotExist creates the directory for the given file path if it does not exist. func createPathIfNotExist(filePath string) error { dir := path.Dir(filePath) @@ -39,23 +53,3 @@ func (f File) PutObject(identifier string, data []byte) error { } return os.WriteFile(identifier, data, 0664) } - -func (f File) PutObjectFromPath(path string, identifier string) error { - source, err := os.Open(path) - if err != nil { - return err - } - defer source.Close() - - if err := createPathIfNotExist(identifier); err != nil { - return err - } - destination, err := os.Create(identifier) - if err != nil { - return err - } - defer destination.Close() - - _, err = io.Copy(destination, source) - return err -} diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 96c5af8..1e4d44f 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -1,8 +1,20 @@ package storage +import "time" + +type Object struct { + Path string + Content []byte + LastModified time.Time +} + type Storage interface { + // ListObject returns a list of all objects in the storage backend. + ListObject(prefix string) ([]Object, error) + // GetObject returns the object identified by the given identifier. + GetObject(identifier string) (Object, error) // PutObject stores the data in the storage backend identified by the given identifier. PutObject(identifier string, data []byte) error - // PutObjectFromPath reads the file at the given path and stores the data in the storage backend identified by the given identifier. - PutObjectFromPath(path string, identifier string) error + // DeleteObject deletes the object identified by the given identifier. + DeleteObject(identifier string) error }