mukan-ignite/ignite/pkg/dircache/cache.go
Mukan Erkin Törük c32551b6f7
Some checks failed
Docs Deploy / build_and_deploy (push) Has been cancelled
Generate Docs / cli (push) Has been cancelled
Generate Config Doc / cli (push) Has been cancelled
Go formatting / go-formatting (push) Has been cancelled
Check links / markdown-link-check (push) Has been cancelled
Integration / pre-test (push) Has been cancelled
Integration / test on (push) Has been cancelled
Integration / status (push) Has been cancelled
Lint / Lint Go code (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:24 +03:00

111 lines
2.7 KiB
Go

package dircache
import (
"crypto/sha256"
"fmt"
"os"
"path/filepath"
"github.com/otiai10/copy"
"git.cw.tr/mukan-network/mukan-ignite/ignite/config"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/cache"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/dirchange"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/errors"
)
var ErrCacheNotFound = errors.New("cache not found")
type Cache struct {
path string
storageCache cache.Cache[string]
}
// New creates a new Buf based on the installed binary.
func New(cacheStorage cache.Storage, dir, specNamespace string) (Cache, error) {
path, err := cachePath()
if err != nil {
return Cache{}, err
}
path = filepath.Join(path, dir)
if err := os.MkdirAll(path, 0o755); err != nil && !os.IsExist(err) {
return Cache{}, err
}
return Cache{
path: path,
storageCache: cache.New[string](cacheStorage, specNamespace),
}, nil
}
// ClearCache remove the cache path.
func ClearCache() error {
path, err := cachePath()
if err != nil {
return err
}
return os.RemoveAll(path)
}
// cachePath returns the cache path.
func cachePath() (string, error) {
globalPath, err := config.DirPath()
if err != nil {
return "", err
}
return filepath.Join(globalPath, "cache"), nil
}
// cacheKey create the cache key.
func cacheKey(src string, keys ...string) (string, error) {
checksum, err := dirchange.ChecksumFromPaths(src, "")
if err != nil {
return "", err
}
h := sha256.New()
if _, err := h.Write(checksum); err != nil {
return "", err
}
for _, key := range keys {
if _, err := h.Write([]byte(key)); err != nil {
return "", err
}
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
// CopyTo gets the cache folder based on the cache key from the storage and copies the folder to the output.
func (c Cache) CopyTo(src, output string, keys ...string) (string, error) {
key, err := cacheKey(src, keys...)
if err != nil {
return key, err
}
cachedPath, err := c.storageCache.Get(key)
if errors.Is(err, cache.ErrorNotFound) {
return key, ErrCacheNotFound
} else if err != nil {
return key, err
}
if err := copy.Copy(cachedPath, output); err != nil {
return "", errors.Wrapf(err, "get dir cache cannot copy path %s to %s", cachedPath, output)
}
return key, nil
}
// Save copies the source to the cache folder and saves the path into the storage based on the key.
func (c Cache) Save(src, key string) error {
path := filepath.Join(c.path, key)
if err := os.Mkdir(path, 0o700); os.IsExist(err) {
return nil
} else if err != nil {
return err
}
if err := copy.Copy(src, path); err != nil {
return errors.Wrapf(err, "save dir cache cannot copy path %s to %s", src, path)
}
return c.storageCache.Put(key, path)
}