From aa0eaa6c523ae9981ab6dbc27ff048836449874f Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 21 Oct 2026 21:24:24 +0200 Subject: [PATCH] Build the merge preview's module trees with mesh-sdk's ModuleTrees and re-pin mesh-sdk to 78364e31, so the two fetch steps share it (issues 1675, 1676) --- .../mesh-build-go/cmd/mesh-build-go/fetch.go | 10 ++-- .../cmd/mesh-build-go/preview.go | 56 +------------------ .../cmd/mesh-build-go/preview_test.go | 4 ++ modules/mesh-build-go/go.mod | 2 +- modules/mesh-build-go/go.sum | 2 + .../cmd/mesh-build-node/fetch.go | 10 ++-- .../cmd/mesh-build-node/preview.go | 56 +------------------ modules/mesh-build-node/go.mod | 2 +- modules/mesh-build-node/go.sum | 2 + 9 files changed, 22 insertions(+), 122 deletions(-) diff --git a/modules/mesh-build-go/cmd/mesh-build-go/fetch.go b/modules/mesh-build-go/cmd/mesh-build-go/fetch.go index dd4fd719..98462762 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/fetch.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/fetch.go @@ -43,11 +43,11 @@ type FetchResult struct { // head onto it, the paths the merge changes, and the tree of each module directory (a directory holding a // module.json) in the merge. A head that does not merge cleanly is an answer: Merge is empty, Conflicts names the // files, and the workspace is left at the trunk commit. - Base string `json:"base,omitempty"` - Merge string `json:"merge,omitempty"` - Conflicts []string `json:"conflicts,omitempty"` - Changed []string `json:"changed,omitempty"` - Trees map[string]ModuleTree `json:"trees,omitempty"` + Base string `json:"base,omitempty"` + Merge string `json:"merge,omitempty"` + Conflicts []string `json:"conflicts,omitempty"` + Changed []string `json:"changed,omitempty"` + Trees map[string]buildstep.ModuleTree `json:"trees,omitempty"` // Beside are the sibling repositories placed as plain directories under the workspace's beside directory, which // build_go_test hands to the tests as MESH_CHECK_BESIDE (ADR 0484 clause 4). Beside []Sibling `json:"beside,omitempty"` diff --git a/modules/mesh-build-go/cmd/mesh-build-go/preview.go b/modules/mesh-build-go/cmd/mesh-build-go/preview.go index da279e44..14ab2b81 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/preview.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/preview.go @@ -6,8 +6,6 @@ package main import ( "context" - "crypto/sha256" - "encoding/hex" "fmt" "io/fs" "os" @@ -45,62 +43,10 @@ func (m *Module) merge(ctx context.Context, res *FetchResult, tree, remote, base if res.Merge == "" { return nil } - res.Trees, err = m.moduleTrees(ctx, tree, res.Merge) + res.Trees, err = buildstep.ModuleTrees(ctx, m.Run, nil, tree, res.Merge) return err } -// ModuleTree is what the merge holds of one module directory: its tree id, the sha256 of its module.json and the sha256 -// of each lock file it has (go.sum, package-lock.json), from which the checker and the indexer take the module's inputs. -type ModuleTree struct { - Tree string `json:"tree"` - Manifest string `json:"manifest"` - Locks map[string]string `json:"locks,omitempty"` -} - -var lockFiles = []string{"go.sum", "package-lock.json"} - -// moduleTrees are the trees, in the merge commit, of every directory of the tree that holds a module.json; the workspace -// is at the merge, so the manifest and the locks are read from it. -func (m *Module) moduleTrees(ctx context.Context, tree, merge string) (map[string]ModuleTree, error) { - r := m.Run(ctx, nil, "git", "-C", tree, "ls-files", "--", "module.json", "*/module.json") - if r.Status != 0 || r.Err != "" { - return nil, fmt.Errorf("git ls-files: %s", firstLine(r.Err+" "+r.Stderr)) - } - trees := map[string]ModuleTree{} - for _, l := range strings.Split(r.Stdout, "\n") { - if l = strings.TrimSpace(l); l == "" { - continue - } - dir := filepath.ToSlash(filepath.Dir(l)) - spec := merge + ":" + dir - if dir == "." { - spec = merge + "^{tree}" - } - t := m.Run(ctx, nil, "git", "-C", tree, "rev-parse", spec) - if t.Status != 0 || t.Err != "" { - return nil, fmt.Errorf("git rev-parse %s: %s", spec, firstLine(t.Err+" "+t.Stderr)) - } - mt := ModuleTree{Tree: strings.TrimSpace(t.Stdout)} - raw, err := os.ReadFile(filepath.Join(tree, filepath.FromSlash(l))) - if err != nil { - return nil, err - } - mt.Manifest = sha256Hex(raw) - for _, lock := range lockFiles { - if raw, err := os.ReadFile(filepath.Join(tree, filepath.FromSlash(dir), lock)); err == nil { - if mt.Locks == nil { - mt.Locks = map[string]string{} - } - mt.Locks[lock] = sha256Hex(raw) - } - } - trees[dir] = mt - } - return trees, nil -} - -func sha256Hex(b []byte) string { h := sha256.Sum256(b); return hex.EncodeToString(h[:]) } - type siblingArg struct{ repository, commit string } func siblingsArg(v any) ([]siblingArg, error) { diff --git a/modules/mesh-build-go/cmd/mesh-build-go/preview_test.go b/modules/mesh-build-go/cmd/mesh-build-go/preview_test.go index 4a1e7614..78b19943 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/preview_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/preview_test.go @@ -2,6 +2,8 @@ package main import ( "context" + "crypto/sha256" + "encoding/hex" "encoding/json" "os" "path/filepath" @@ -268,3 +270,5 @@ func TestPackagesRunOnlyInTheModuleThatHoldsThem(t *testing.T) { t.Errorf("a package no module holds: %v", err) } } + +func sha256Hex(b []byte) string { h := sha256.Sum256(b); return hex.EncodeToString(h[:]) } diff --git a/modules/mesh-build-go/go.mod b/modules/mesh-build-go/go.mod index 842e5952..15a8c845 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.20261021185947-afbe371003a5 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc github.com/nats-io/nats-server/v2 v2.11.17 ) diff --git a/modules/mesh-build-go/go.sum b/modules/mesh-build-go/go.sum index 58480c49..e35e25ab 100644 --- a/modules/mesh-build-go/go.sum +++ b/modules/mesh-build-go/go.sum @@ -2,6 +2,8 @@ git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021093645-465beb4ea5e3 h1:OKxU64kH git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021093645-465beb4ea5e3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5 h1:1BiPKRPTYpgex8rSHWT9az0BteOafGWRDzd/Ba6GAcA= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc h1:ZJScJSnF6LgFl55/VJ9RT/lNroVWun469sXtx0nlVYw= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/mesh-build-node/cmd/mesh-build-node/fetch.go b/modules/mesh-build-node/cmd/mesh-build-node/fetch.go index fb8ccc79..058a80d8 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/fetch.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/fetch.go @@ -54,11 +54,11 @@ type FetchResult struct { // commit, the merge commit of the head onto it, the paths the merge changes and the tree of each module directory. // A head that does not merge cleanly is an answer: Merge is empty, Conflicts names the files, and the workspace is // left at the trunk commit with nothing installed. - Base string `json:"base,omitempty"` - Merge string `json:"merge,omitempty"` - Conflicts []string `json:"conflicts,omitempty"` - Changed []string `json:"changed,omitempty"` - Trees map[string]ModuleTree `json:"trees,omitempty"` + Base string `json:"base,omitempty"` + Merge string `json:"merge,omitempty"` + Conflicts []string `json:"conflicts,omitempty"` + Changed []string `json:"changed,omitempty"` + Trees map[string]buildstep.ModuleTree `json:"trees,omitempty"` } // Refusal is a module a fetch did not install the packages of. diff --git a/modules/mesh-build-node/cmd/mesh-build-node/preview.go b/modules/mesh-build-node/cmd/mesh-build-node/preview.go index f5090e63..f9be0b64 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/preview.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/preview.go @@ -5,8 +5,6 @@ package main import ( "context" - "crypto/sha256" - "encoding/hex" "fmt" "os" "path/filepath" @@ -36,58 +34,6 @@ func (m *Module) merge(ctx context.Context, run forgekey.Runner, res *FetchResul if res.Merge == "" { return nil } - res.Trees, err = m.moduleTrees(ctx, tree, res.Merge) + res.Trees, err = buildstep.ModuleTrees(ctx, m.Run, m.baseEnv(), tree, res.Merge) return err } - -// ModuleTree is what the merge holds of one module directory: its tree id, the sha256 of its module.json and the sha256 -// of each lock file it has (go.sum, package-lock.json), from which the checker and the indexer take the module's inputs. -type ModuleTree struct { - Tree string `json:"tree"` - Manifest string `json:"manifest"` - Locks map[string]string `json:"locks,omitempty"` -} - -var lockFiles = []string{"go.sum", "package-lock.json"} - -// moduleTrees are the trees, in the merge commit, of every directory of the tree that holds a module.json; the workspace -// is at the merge, so the manifest and the locks are read from it. -func (m *Module) moduleTrees(ctx context.Context, tree, merge string) (map[string]ModuleTree, error) { - r := m.Run(ctx, m.baseEnv(), "git", "-C", tree, "ls-files", "--", "module.json", "*/module.json") - if r.Status != 0 || r.Err != "" { - return nil, fmt.Errorf("git ls-files: %s", firstLine(r.Err+" "+r.Stderr)) - } - trees := map[string]ModuleTree{} - for _, l := range strings.Split(r.Stdout, "\n") { - if l = strings.TrimSpace(l); l == "" { - continue - } - dir := filepath.ToSlash(filepath.Dir(l)) - spec := merge + ":" + dir - if dir == "." { - spec = merge + "^{tree}" - } - t := m.Run(ctx, m.baseEnv(), "git", "-C", tree, "rev-parse", spec) - if t.Status != 0 || t.Err != "" { - return nil, fmt.Errorf("git rev-parse %s: %s", spec, firstLine(t.Err+" "+t.Stderr)) - } - mt := ModuleTree{Tree: strings.TrimSpace(t.Stdout)} - raw, err := os.ReadFile(filepath.Join(tree, filepath.FromSlash(l))) - if err != nil { - return nil, err - } - mt.Manifest = sha256Hex(raw) - for _, lock := range lockFiles { - if raw, err := os.ReadFile(filepath.Join(tree, filepath.FromSlash(dir), lock)); err == nil { - if mt.Locks == nil { - mt.Locks = map[string]string{} - } - mt.Locks[lock] = sha256Hex(raw) - } - } - trees[dir] = mt - } - return trees, nil -} - -func sha256Hex(b []byte) string { h := sha256.Sum256(b); return hex.EncodeToString(h[:]) } diff --git a/modules/mesh-build-node/go.mod b/modules/mesh-build-node/go.mod index 9c0040be..4b453f9b 100644 --- a/modules/mesh-build-node/go.mod +++ b/modules/mesh-build-node/go.mod @@ -2,4 +2,4 @@ module meshbuildnode go 1.26.0 -require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5 +require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc diff --git a/modules/mesh-build-node/go.sum b/modules/mesh-build-node/go.sum index 13d2b728..8097dd56 100644 --- a/modules/mesh-build-node/go.sum +++ b/modules/mesh-build-node/go.sum @@ -2,3 +2,5 @@ git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021093645-465beb4ea5e3 h1:OKxU64kH git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021093645-465beb4ea5e3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5 h1:1BiPKRPTYpgex8rSHWT9az0BteOafGWRDzd/Ba6GAcA= git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc h1:ZJScJSnF6LgFl55/VJ9RT/lNroVWun469sXtx0nlVYw= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=