Ship the Node build module's toolchain lock as an archive, not a template naming hosts (issue 1488)

This commit is contained in:
2026-10-20 21:15:56 +00:00
parent 00fa5e74d0
commit 983a6c39c8
6 changed files with 52 additions and 38 deletions
@@ -24,7 +24,7 @@ func realMachine(t *testing.T) (*Module, string) {
}
home, cache, work := t.TempDir(), t.TempDir(), t.TempDir()
for _, n := range []string{"package.json", "package-lock.json"} {
raw, err := os.ReadFile(filepath.Join(moduleDir, "files", "toolchain", n))
raw, err := os.ReadFile(filepath.Join(moduleDir, "toolchain", n))
if err != nil {
t.Fatal(err)
}
@@ -4,6 +4,7 @@ import (
"encoding/json"
"os"
"path/filepath"
"regexp"
"slices"
"strings"
"testing"
@@ -124,22 +125,13 @@ func TestTheToolsServedAreTheToolsTheManifestNames(t *testing.T) {
}
}
// 1488/AC1: the module carries the committed lock beside its package.json, and the manifest has the mesh write both
// into the home's toolchain directory, where the program reads them.
// 1488/AC1: the module carries the committed lock beside its package.json, and the manifest unpacks them into the
// home's toolchain directory, where the program reads them.
func TestTheModuleCarriesItsToolchainLockAndTheManifestPlacesIt(t *testing.T) {
m := readManifest(t)
for _, name := range []string{"package.json", "package-lock.json"} {
if _, err := os.Stat(filepath.Join(moduleDir, "files", "toolchain", name)); err != nil {
t.Errorf("the module carries no files/toolchain/%s: %v", name, err)
}
}
lock := resource(t, m, "toolchain-lock")
if lock["path"] != "${dir:toolchain-dir}/package-lock.json" || lock["owner"] != "mesh-build-node" {
t.Errorf("toolchain-lock = %v", lock)
}
for _, r := range readForgeManifest(t).Resources {
if r["id"] == "toolchain-lock" && r["template"] != "files/toolchain/package-lock.json" {
t.Errorf("toolchain-lock takes its text from %v", r["template"])
if _, err := os.Stat(filepath.Join(moduleDir, "toolchain", name)); err != nil {
t.Errorf("the module carries no toolchain/%s: %v", name, err)
}
}
if !slices.Contains(m.Requires, "npm-package-registry") {
@@ -150,7 +142,7 @@ func TestTheModuleCarriesItsToolchainLockAndTheManifestPlacesIt(t *testing.T) {
// 1488/AC1: the lock names the versions of the recipe: typescript 5.9.3, esbuild 0.25.12, @novox/mesh-sdk 0.1.14
// and nats, all by the lock's own hash (read from the file the module carries).
func TestTheLockNamesTheToolchainVersions(t *testing.T) {
raw, err := os.ReadFile(filepath.Join(moduleDir, "files", "toolchain", "package-lock.json"))
raw, err := os.ReadFile(filepath.Join(moduleDir, "toolchain", "package-lock.json"))
if err != nil {
t.Fatal(err)
}
@@ -168,3 +160,34 @@ func TestTheLockNamesTheToolchainVersions(t *testing.T) {
}
}
}
// 1488 (the catalogue's manifest check): a manifest names no host, the mesh being name-agnostic. The tree-read
// manifest carries each template's text as the resource's content, and the toolchain's lock names registries, so it is
// shipped as an archive artifact instead, never as a template. No resource of the module, read as the mesh reads it,
// carries content naming a host, and the raw module.json names none either.
func TestNoResourceCarriesContentNamingAHost(t *testing.T) {
host := regexp.MustCompile(`(?i)://[a-z0-9]|\b[a-z0-9-]+(\.[a-z0-9-]+)*\.(com|org|net|be|io|dev)\b`)
m := readManifest(t)
for i, r := range m.Resources {
if c, _ := r["content"].(string); host.MatchString(c) {
t.Errorf("resources[%d] (%v) carries content naming %q", i, r["id"], host.FindString(c))
}
}
raw, _ := os.ReadFile(filepath.Join(moduleDir, "module.json"))
if h := host.FindString(string(raw)); h != "" {
t.Errorf("module.json names %q", h)
}
}
// 1488: the toolchain's package.json and lock are shipped in the archive artifact `toolchain` and unpacked into the
// home's toolchain directory, where the program reads them.
func TestTheToolchainFilesAreAnArchiveUnpackedIntoTheHome(t *testing.T) {
m := readManifest(t)
r := resource(t, m, "toolchain-dir")
if r["type"] != "archive" || r["path"] != "${dir:state}/toolchain" || r["owner"] != "mesh-build-node" {
t.Errorf("toolchain-dir = %v, want an archive unpacked at ${dir:state}/toolchain", r)
}
if _, err := os.Stat(filepath.Join(moduleDir, "toolchain", "package-lock.json")); err != nil {
t.Errorf("the module carries no toolchain/package-lock.json: %v", err)
}
}