diff --git a/internal/dl/dl.go b/internal/dl/dl.go index a2a6781..6a82bca 100644 --- a/internal/dl/dl.go +++ b/internal/dl/dl.go @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . -*/ + */ // Пакет dl содержит абстракции для загрузки файлов и каталогов // из различных источников. @@ -39,6 +39,7 @@ import ( "golang.org/x/crypto/blake2b" "golang.org/x/crypto/blake2s" "golang.org/x/exp/slices" + "plemya-x.ru/alr/internal/config" "plemya-x.ru/alr/internal/dlcache" "plemya-x.ru/alr/pkg/loggerctx" ) @@ -142,6 +143,9 @@ type UpdatingDownloader interface { // Функция Download загружает файл или каталог с использованием указанных параметров func Download(ctx context.Context, opts Options) (err error) { log := loggerctx.From(ctx) + cfg := config.GetInstance(ctx) + dc := dlcache.New(cfg) + normalized, err := normalizeURL(opts.URL) if err != nil { return err @@ -156,7 +160,7 @@ func Download(ctx context.Context, opts Options) (err error) { } var t Type - cacheDir, ok := dlcache.Get(ctx, opts.URL) + cacheDir, ok := dc.Get(ctx, opts.URL) if ok { var updated bool if d, ok := d.(UpdatingDownloader); ok { @@ -203,7 +207,7 @@ func Download(ctx context.Context, opts Options) (err error) { log.Info("Downloading source").Str("source", opts.Name).Str("downloader", d.Name()).Send() - cacheDir, err = dlcache.New(ctx, opts.URL) + cacheDir, err = dc.New(ctx, opts.URL) if err != nil { return err } @@ -299,8 +303,6 @@ func linkDir(src, dest string) error { return nil } - - rel, err := filepath.Rel(src, path) if err != nil { return err diff --git a/internal/dlcache/dlcache.go b/internal/dlcache/dlcache.go index ccbf57b..77eb5f4 100644 --- a/internal/dlcache/dlcache.go +++ b/internal/dlcache/dlcache.go @@ -20,29 +20,41 @@ package dlcache import ( "context" - "crypto/sha1" - "encoding/hex" - "io" "os" "path/filepath" "plemya-x.ru/alr/internal/config" ) -// BasePath returns the base path of the download cache -func BasePath(ctx context.Context) string { - return filepath.Join(config.GetPaths(ctx).CacheDir, "dl") +type Config interface { + GetPaths(ctx context.Context) *config.Paths +} + +type DownloadCache struct { + cfg Config +} + +func New(cfg Config) *DownloadCache { + return &DownloadCache{ + cfg, + } +} + +func (dc *DownloadCache) BasePath(ctx context.Context) string { + return filepath.Join( + dc.cfg.GetPaths(ctx).CacheDir, "dl", + ) } // New creates a new directory with the given ID in the cache. // If a directory with the same ID already exists, // it will be deleted before creating a new one. -func New(ctx context.Context, id string) (string, error) { +func (dc *DownloadCache) New(ctx context.Context, id string) (string, error) { h, err := hashID(id) if err != nil { return "", err } - itemPath := filepath.Join(BasePath(ctx), h) + itemPath := filepath.Join(dc.BasePath(ctx), h) fi, err := os.Stat(itemPath) if err == nil || (fi != nil && !fi.IsDir()) { @@ -65,12 +77,12 @@ func New(ctx context.Context, id string) (string, error) { // returns the directory and true. If it // does not exist, it returns an empty string // and false. -func Get(ctx context.Context, id string) (string, bool) { +func (dc *DownloadCache) Get(ctx context.Context, id string) (string, bool) { h, err := hashID(id) if err != nil { return "", false } - itemPath := filepath.Join(BasePath(ctx), h) + itemPath := filepath.Join(dc.BasePath(ctx), h) _, err = os.Stat(itemPath) if err != nil { @@ -79,15 +91,3 @@ func Get(ctx context.Context, id string) (string, bool) { return itemPath, true } - -// hashID hashes the input ID with SHA1 -// and returns the hex string of the hashed -// ID. -func hashID(id string) (string, error) { - h := sha1.New() - _, err := io.WriteString(h, id) - if err != nil { - return "", err - } - return hex.EncodeToString(h.Sum(nil)), nil -} diff --git a/internal/dlcache/dlcache_test.go b/internal/dlcache/dlcache_test.go index d347a83..7cd78cc 100644 --- a/internal/dlcache/dlcache_test.go +++ b/internal/dlcache/dlcache_test.go @@ -39,14 +39,49 @@ func init() { config.GetPaths(context.Background()).RepoDir = dir } +type TestALRConfig struct { + CacheDir string +} + +func (c *TestALRConfig) GetPaths(ctx context.Context) *config.Paths { + return &config.Paths{ + CacheDir: c.CacheDir, + } +} + +func prepare(t *testing.T) *TestALRConfig { + t.Helper() + + dir, err := os.MkdirTemp("/tmp", "alr-dlcache-test.*") + if err != nil { + panic(err) + } + + return &TestALRConfig{ + CacheDir: dir, + } +} + +func cleanup(t *testing.T, cfg *TestALRConfig) { + t.Helper() + os.Remove(cfg.CacheDir) +} + func TestNew(t *testing.T) { + cfg := prepare(t) + defer cleanup(t, cfg) + + dc := dlcache.New(cfg) + + ctx := context.Background() + const id = "https://example.com" - dir, err := dlcache.New(id) + dir, err := dc.New(ctx, id) if err != nil { t.Errorf("Expected no error, got %s", err) } - exp := filepath.Join(dlcache.BasePath(), sha1sum(id)) + exp := filepath.Join(dc.BasePath(ctx), sha1sum(id)) if dir != exp { t.Errorf("Expected %s, got %s", exp, dir) } @@ -60,7 +95,7 @@ func TestNew(t *testing.T) { t.Errorf("Expected cache item to be a directory") } - dir2, ok := dlcache.Get(id) + dir2, ok := dc.Get(ctx, id) if !ok { t.Errorf("Expected Get() to return valid value") } diff --git a/internal/dlcache/utils.go b/internal/dlcache/utils.go new file mode 100644 index 0000000..4b7a913 --- /dev/null +++ b/internal/dlcache/utils.go @@ -0,0 +1,16 @@ +package dlcache + +import ( + "crypto/sha1" + "encoding/hex" + "io" +) + +func hashID(id string) (string, error) { + h := sha1.New() + _, err := io.WriteString(h, id) + if err != nil { + return "", err + } + return hex.EncodeToString(h.Sum(nil)), nil +}