internal/pkg: implement caching for directories
All checks were successful
Test / Create distribution (push) Successful in 45s
Test / Sandbox (push) Successful in 2m30s
Test / Hakurei (push) Successful in 3m38s
Test / ShareFS (push) Successful in 3m40s
Test / Hpkg (push) Successful in 4m29s
Test / Sandbox (race detector) (push) Successful in 4m50s
Test / Hakurei (race detector) (push) Successful in 5m49s
Test / Flake checks (push) Successful in 1m43s

This works on any directories and should be robust against any bad state the artifact curing process might have failed at.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-01-03 22:49:01 +09:00
parent 863d3dcf9f
commit 40081e7a06
3 changed files with 342 additions and 24 deletions

View File

@@ -8,7 +8,10 @@ import (
"encoding/binary"
"errors"
"io"
"io/fs"
"os"
"path"
"path/filepath"
"slices"
"sync"
@@ -190,6 +193,100 @@ func (c *Cache) pathnameIdent(id *ID) *check.Absolute {
)
}
// Store looks up an identifier, and if it is not present, calls makeArtifact
// with a private working directory and stores its result instead. An optional
// checksum can be passed via the result buffer which is used to validate the
// produced directory.
func (c *Cache) Store(
id ID,
makeArtifact func(work *check.Absolute) error,
buf *Checksum,
validate bool,
) (
pathname *check.Absolute,
store bool,
err error,
) {
pathname = c.pathnameIdent(&id)
c.mu.Lock()
defer c.mu.Unlock()
_, err = os.Lstat(pathname.String())
if err == nil || !errors.Is(err, os.ErrNotExist) {
return
}
store = true
var (
workPathname *check.Absolute
workPathnameRaw string
)
if workPathnameRaw, err = os.MkdirTemp(
c.base.Append(dirWork).String(),
path.Base(pathname.String()+".*"),
); err != nil {
return
} else if workPathname, err = check.NewAbs(workPathnameRaw); err != nil {
return
}
defer func() {
if err != nil {
chmodErr := filepath.WalkDir(workPathname.String(), func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return os.Chmod(path, 0700)
}
return nil
})
removeErr := os.RemoveAll(workPathname.String())
if chmodErr != nil || removeErr != nil {
err = errors.Join(err, chmodErr, removeErr)
} else if errors.Is(err, os.ErrExist) {
// two artifacts may be backed by the same file
err = nil
}
}
}()
if err = os.Chmod(workPathname.String(), 0700); err != nil {
return
}
if err = makeArtifact(workPathname); err != nil {
return
}
var checksum Checksum
if checksum, err = HashDir(workPathname); err != nil {
return
}
if validate {
if checksum != *buf {
err = &ChecksumMismatchError{checksum, *buf}
return
}
} else {
*buf = checksum
}
checksumPathname := c.pathname(&checksum)
if err = os.Rename(
workPathname.String(),
checksumPathname.String(),
); err != nil {
if !errors.Is(err, os.ErrExist) {
return
}
}
if linkErr := os.Symlink(
"../"+dirChecksum+"/"+path.Base(checksumPathname.String()),
pathname.String(),
); linkErr != nil {
err = linkErr
}
return
}
// storeFile stores the contents of a [File]. An optional checksum can be
// passed via the result buffer which is used to validate the submitted data.
//