From 5c65b1f3dc630441cca86dfd1ec2b102c1b6bdce Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 25 Oct 2026 01:00:32 +0200 Subject: [PATCH] mesh-build-go: give each ask a cache layer in its workspace, so what its vet compiles its unit tests and integration level find compiled (issue 1921, try speed S2) --- modules/mesh-build-go/cmd/mesh-build-go/isolate.go | 13 +++++++++++-- .../mesh-build-go/cmd/mesh-build-go/isolate_test.go | 11 ++++++++++- modules/mesh-build-go/go.mod | 2 +- modules/mesh-build-go/go.sum | 2 ++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/modules/mesh-build-go/cmd/mesh-build-go/isolate.go b/modules/mesh-build-go/cmd/mesh-build-go/isolate.go index a50bea28..a5a170b6 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/isolate.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/isolate.go @@ -29,21 +29,30 @@ func (m *Module) caches() []string { } // isolation is how a run step of the workspace is shut off: the workspace (its tree, its siblings, its run directories, -// its packed artifacts) read-write, the caches beneath a throwaway layer unless write, and an environment of a PATH and +// its packed artifacts) read-write, the caches beneath the ask's own layer unless write, and an environment of a PATH and // a locale alone (the step's HOME is its own, inside its /tmp). func (m *Module) isolation(workspace string, write bool) buildstep.Isolation { path := os.Getenv("PATH") if path == "" { path = defaultPath } - return buildstep.Isolation{ + iso := buildstep.Isolation{ Workspace: filepath.Join(m.Work, workspace), Caches: m.caches(), WriteCaches: write, Env: []string{"PATH=" + path, "LC_ALL=C"}, } + if !write { + // What one command of the ask compiles is kept for its later commands (the vet, the unit tests, the integration + // level's compile), in the workspace and gone with it (issue 1921, try speed S2). + iso.CacheLayer = filepath.Join(iso.Workspace, cacheLayerDir) + } + return iso } +// cacheLayerDir is the directory in a workspace's root where an ask keeps what its commands wrote into the caches. +const cacheLayerDir = "cachelayer" + // stepRunner is the runner of a run step of the workspace: buildstep.Isolated over m.Run, so every command it runs is // shut off; write is true for a trunk build alone (the shared caches are written by trunk builds only). Inside is the // integration level's own process, already running shut off (level.go): it runs its commands as they are. diff --git a/modules/mesh-build-go/cmd/mesh-build-go/isolate_test.go b/modules/mesh-build-go/cmd/mesh-build-go/isolate_test.go index 9d6615c5..efb19e5d 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/isolate_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/isolate_test.go @@ -20,6 +20,7 @@ import ( type shutOff struct { flags []string binds, roBinds, overlays []string + uppers map[string]string // the writable layer each --overlay gives a cache: cache -> upper env []string command string chdir string @@ -27,7 +28,7 @@ type shutOff struct { // bwrapArity is how many words each bubblewrap option the SDK writes takes. var bwrapArity = map[string]int{"--unshare-all": 0, "--die-with-parent": 0, "--new-session": 0, "--clearenv": 0, - "--proc": 1, "--dev": 1, "--tmpfs": 1, "--dir": 1, "--chdir": 1, "--overlay-src": 1, "--tmp-overlay": 1, + "--proc": 1, "--dev": 1, "--tmpfs": 1, "--dir": 1, "--chdir": 1, "--overlay-src": 1, "--tmp-overlay": 1, "--overlay": 3, "--ro-bind": 2, "--ro-bind-try": 2, "--bind": 2, "--symlink": 2, "--setenv": 2} // throughBubblewrap is the fake runner of a step's tests: a bubblewrap command is read back (recorded in seen) and its @@ -56,6 +57,11 @@ func throughBubblewrap(t *testing.T, run forgekey.Runner, seen *[]shutOff) forge s.roBinds = append(s.roBinds, args[i+1]) case "--overlay-src": s.overlays = append(s.overlays, args[i+1]) + case "--overlay": + if s.uppers == nil { + s.uppers = map[string]string{} + } + s.uppers[args[i+3]] = args[i+1] case "--setenv": s.env = append(s.env, args[i+1]+"="+args[i+2]) case "--chdir": @@ -105,6 +111,9 @@ func checkShutOff(t *testing.T, m *Module, s shutOff, write bool) { t.Errorf("a trunk build's %s does not write the shared cache %s (bound %v, layered %v)", s.command, c, bound, layered) case !write && (bound || !layered): t.Errorf("%s may write the shared cache %s (bound %v, layered %v): only a trunk build does", s.command, c, bound, layered) + case !write && !strings.HasPrefix(s.uppers[c], filepath.Join(m.Work, "ws1", "cachelayer")+"/"): + // 1921/S2: what one command of the ask compiles is kept for its later commands, in the workspace + t.Errorf("%s writes the cache %s into %q, not the ask's cache layer in its workspace", s.command, c, s.uppers[c]) } } if want := filepath.Join(m.Work, "ws1"); !slices.Contains(s.binds, want) { diff --git a/modules/mesh-build-go/go.mod b/modules/mesh-build-go/go.mod index 46e9e151..ebde537b 100644 --- a/modules/mesh-build-go/go.mod +++ b/modules/mesh-build-go/go.mod @@ -3,7 +3,7 @@ module meshbuildgo go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024214154-bc16740feb0d + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024225846-cb548a6a588c github.com/distribution/distribution/v3 v3.1.2 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 diff --git a/modules/mesh-build-go/go.sum b/modules/mesh-build-go/go.sum index 0f0bc5de..6df07410 100644 --- a/modules/mesh-build-go/go.sum +++ b/modules/mesh-build-go/go.sum @@ -1,5 +1,7 @@ git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024214154-bc16740feb0d h1:oJREw0ggKqJWJ5DEISSL0i2ZC5XqdXAidxo9NJ74TCc= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024214154-bc16740feb0d/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024225846-cb548a6a588c h1:GWHP9ozfkFXHVEL2gE4Xa5kc5e8uPO+UL9+mau6iaIs= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261024225846-cb548a6a588c/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=