aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-07-08 15:26:42 +0900
committerOphestra <cat@gensokyo.uk>2026-07-08 15:26:42 +0900
commit472849cfd618e6607de6bace8965c8b6e275f245 (patch)
tree60a2ececb770e9682a4ce897c773240147102c5e
parent3c6e9b3d0526a9338dc897a8e288647b2ec12b10 (diff)
internal/pkg: optionally force implementation entry
For validation of build determinism. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/mbf/main.go11
-rw-r--r--internal/pkg/pkg.go49
2 files changed, 50 insertions, 10 deletions
diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go
index a6c74a0f..37f799c8 100644
--- a/cmd/mbf/main.go
+++ b/cmd/mbf/main.go
@@ -696,6 +696,7 @@ func main() {
flagNoReply bool
flagFaults bool
flagPop bool
+ flagRebuild bool
flagBoot bool
flagStd bool
@@ -724,7 +725,11 @@ func main() {
default:
var pathname *check.Absolute
err := cm.Do(func(cache *pkg.Cache) (err error) {
- pathname, _, err = cache.Cure(a)
+ if flagRebuild {
+ pathname, _, err = cache.CureNew(a)
+ } else {
+ pathname, _, err = cache.Cure(a)
+ }
return
})
if err != nil {
@@ -885,6 +890,10 @@ func main() {
&flagPop,
"pop", command.BoolFlag(false),
"Display and destroy the most recent fault entry",
+ ).Flag(
+ &flagRebuild,
+ "rebuild", command.BoolFlag(false),
+ "Always enter the artifact implementation",
)
}
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 9d32231d..4d1d3f72 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -6,6 +6,7 @@ import (
"bytes"
"cmp"
"context"
+ "crypto/rand"
"crypto/sha512"
"encoding/base64"
"encoding/binary"
@@ -303,7 +304,7 @@ func (c *common) Open(a Artifact) (r io.ReadCloser, err error) {
}
var pathname *check.Absolute
- if pathname, _, _, err = c.cache.cure(a, true); err != nil {
+ if pathname, _, _, err = c.cache.cure(a, true, false); err != nil {
return
}
@@ -1633,7 +1634,7 @@ func (c *Cache) Cure(a Artifact) (
return
}
- pathname, checksum, _, err = c.cure(a, true)
+ pathname, checksum, _, err = c.cure(a, true, false)
return
}
@@ -1651,7 +1652,29 @@ func (c *Cache) CureWhence(a Artifact) (
return
}
- return c.cure(a, true)
+ return c.cure(a, true, false)
+}
+
+// CureNew is like Cure, but always enters the implementation.
+func (c *Cache) CureNew(a Artifact) (
+ pathname *check.Absolute,
+ checksum unique.Handle[Checksum],
+ err error,
+) {
+ c.abortMu.RLock()
+ defer c.abortMu.RUnlock()
+
+ if err = c.toplevel.Load().ctx.Err(); err != nil {
+ return
+ }
+
+ var whence int
+retry:
+ pathname, checksum, whence, err = c.cure(a, true, true)
+ if err != nil || whence == WNew {
+ return
+ }
+ goto retry
}
// CureError wraps a non-nil error returned attempting to cure an [Artifact].
@@ -2020,13 +2043,19 @@ func WhenceString(whence int) string {
// cure implements Cure without acquiring a read lock on abortMu. cure must not
// be entered during Abort.
-func (c *Cache) cure(a Artifact, curesExempt bool) (
+func (c *Cache) cure(a Artifact, curesExempt, rebuild bool) (
pathname *check.Absolute,
checksum unique.Handle[Checksum],
whence int,
err error,
) {
id := c.Ident(a)
+ if rebuild {
+ var v ID
+ _, _ = rand.Read(v[:])
+ id = unique.Make(v)
+ }
+
ids := Encode(id.Value())
pathname = c.base.Append(
dirIdentifier,
@@ -2354,7 +2383,7 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
substitutes,
)
- if c.flags&CIgnoreSubstitutes == 0 {
+ if !rebuild && c.flags&CIgnoreSubstitutes == 0 {
var substituteChecksum unique.Handle[Checksum]
substituteChecksum, err = c.loadSubstitute(substitute)
if err != nil {
@@ -2419,8 +2448,10 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
return
} else if err = externStatus.Close(); err != nil {
return
- } else if err = f.linkSubstitute(ids, substitutes); err != nil {
- return
+ } else if !rebuild {
+ if err = f.linkSubstitute(ids, substitutes); err != nil {
+ return
+ }
}
}
return
@@ -2432,7 +2463,7 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
err = ca.Cure(&f)
c.exitCure(a, curesExempt)
- if err == nil {
+ if !rebuild && err == nil {
err = f.linkSubstitute(ids, substitutes)
}
if err != nil {
@@ -2526,7 +2557,7 @@ func (pending *pendingArtifactDep) cure(c *Cache) {
defer pending.Done()
var err error
- pending.resP.pathname, pending.resP.checksum, _, err = c.cure(pending.a, false)
+ pending.resP.pathname, pending.resP.checksum, _, err = c.cure(pending.a, false, false)
if err == nil {
return
}