internal/pkg: override "." for directory checksum

This makes the checksum consistent with the final resting state of artifact directories without incurring the cost of an extra pair of chown syscalls.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-01-05 04:00:13 +09:00
parent 7548a627e5
commit 834cb0d40b
4 changed files with 130 additions and 72 deletions

View File

@@ -376,6 +376,63 @@ func removeAll(pathname *check.Absolute) (chmodErr, removeErr error) {
return
}
// overrideFileInfo overrides the permission bits of [fs.FileInfo] to 0500 and
// is the concrete type returned by overrideFile.Stat.
type overrideFileInfo struct{ fs.FileInfo }
// Mode returns [fs.FileMode] with its permission bits set to 0500.
func (fi overrideFileInfo) Mode() fs.FileMode {
return fi.FileInfo.Mode()&(^fs.FileMode(0777)) | 0500
}
// Sys returns nil to avoid passing the original permission bits.
func (fi overrideFileInfo) Sys() any { return nil }
// overrideFile overrides the permission bits of [fs.File] to 0500 and is the
// concrete type returned by dotOverrideFS for calls with "." passed as name.
type overrideFile struct{ fs.File }
func (f overrideFile) Stat() (fi fs.FileInfo, err error) {
fi, err = f.File.Stat()
if err != nil {
return
}
fi = overrideFileInfo{fi}
return
}
// dirFS is implemented by the concrete type of the return value of [os.DirFS].
type dirFS interface {
fs.StatFS
fs.ReadFileFS
fs.ReadDirFS
fs.ReadLinkFS
}
// dotOverrideFS overrides the permission bits of "." to 0500 to avoid the extra
// system calls to add and remove write bit from the target directory.
type dotOverrideFS struct{ dirFS }
// Open wraps the underlying [fs.FS] with "." special case.
func (fsys dotOverrideFS) Open(name string) (f fs.File, err error) {
f, err = fsys.dirFS.Open(name)
if err != nil || name != "." {
return
}
f = overrideFile{f}
return
}
// Stat wraps the underlying [fs.FS] with "." special case.
func (fsys dotOverrideFS) Stat(name string) (fi fs.FileInfo, err error) {
fi, err = fsys.dirFS.Stat(name)
if err != nil || name != "." {
return
}
fi = overrideFileInfo{fi}
return
}
// Cure cures the [Artifact] and returns its pathname and [Checksum].
func (c *Cache) Cure(a Artifact) (
pathname *check.Absolute,
@@ -556,13 +613,11 @@ func (c *Cache) Cure(a Artifact) (
return
}
// override this before hashing since it will be made read-only after
// the rename anyway so do not let perm bits affect the checksum
if err = os.Chmod(workPathname.String(), 0700); err != nil {
return
}
var gotChecksum Checksum
if gotChecksum, err = HashDir(workPathname); err != nil {
if gotChecksum, err = HashFS(
dotOverrideFS{os.DirFS(workPathname.String()).(dirFS)},
".",
); err != nil {
return
}
@@ -583,6 +638,9 @@ func (c *Cache) Cure(a Artifact) (
}
}
if err = os.Chmod(workPathname.String(), 0700); err != nil {
return
}
c.checksumMu.Lock()
if err = os.Rename(
workPathname.String(),