From 1cdffd26f7250ebb347f1b6bab734395cdf6edd8 Mon Sep 17 00:00:00 2001 From: huntedbytheirs Date: Sat, 8 Aug 2026 19:22:22 -0400 Subject: [PATCH] fix(build): point generated package.lua urls at local build cache via file:// repo --- .omo/evidence/task-14-tofu-core.log | 43 ++++++++++++++++++++++++++++ .omo/notepads/tofu-core/learnings.md | 18 ++++++++++++ src/tofu/build.d | 41 +++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/.omo/evidence/task-14-tofu-core.log b/.omo/evidence/task-14-tofu-core.log index 580b2f2..6c3e8c9 100644 --- a/.omo/evidence/task-14-tofu-core.log +++ b/.omo/evidence/task-14-tofu-core.log @@ -13,3 +13,46 @@ installing package...error: build failedreason: missing dependencytestpkg-2.1 is === file listing === 429 src/tofu/build.d + +=== task-14 fix: --repo points at local build cache (file://) === + +ROOT CAUSE: +- src/tofu/build.d runMakepkg passed a HARDCODED + "--repo https://files.spectoria.dev/zuur/binary" to zeta-makepkg. +- zeta-makepkg baked that URL into every generated package.lua as + url = "https://files.spectoria.dev/zuur/binary/-.tar.gz". +- zeta -LocalProvide then fetched the tarball from the REMOTE fileserver + (404 — doesn't exist) instead of the local build cache where the + tarball actually lives at /built/packages//. + +FIX (verified live): +- runMakepkg now passes "--repo", "file://" ~ outputDir, so generated + manifests carry url = "file:///packages//-.tar.gz". +- Zeta's fetch.get handles file:// via plain file copy + (references/ZETA/lib/fetch.lua:108-110). LocalProvide installs work offline. +- Manually confirmed end-to-end: GNU Make 4.4.1 built + installed + runs. + +FILES CHANGED: +- src/tofu/build.d only (runMakepkg doc + --repo arg + new unittest 14) +- install.d ZETA_REPO untouched (remote binary pool for BINARY deps — correct) +- fetch.d, config.d untouched + +VERIFICATION: +- dub build (warningsAsErrors): PASS (Finished, Linking tofu) +- dub test: 23 modules passed unittests +- bash tests/e2e/smoketest.sh: 16/16 PASS (fake zeta-makepkg ignores --repo, + parses only --output — unaffected) +- New unittest (14) asserts fake zeta-makepkg receives "--repo file://" + and that the hardcoded https URL is NOT passed. + +EVIDENCE OUTPUT (trimmed): +dub build 2>&1 | tail -2: + Linking tofu + Finished To force a rebuild of up-to-date targets, run again with --force + +dub test 2>&1 | grep "modules passed": + 23 modules passed unittests + +bash tests/e2e/smoketest.sh 2>&1 | tail -2: + PASS: 16 checks passed + All checks passed. diff --git a/.omo/notepads/tofu-core/learnings.md b/.omo/notepads/tofu-core/learnings.md index 3a4ee4c..ed6188f 100644 --- a/.omo/notepads/tofu-core/learnings.md +++ b/.omo/notepads/tofu-core/learnings.md @@ -1437,3 +1437,21 @@ The sandbox test (test 2) creates a sentinel file, serves an index containing `o (1..1024 for jobs), warn to stderr, and fall back to the default. This mirrors the existing `parseIntOr` warning pattern already used for env vars. + +## task-14 — --repo must point at local build cache, not remote ZUUR + +- zeta-makepkg's `--repo ` is baked VERBATIM into every generated + package.lua as `url = /-.tar.gz`. A hardcoded remote + URL therefore makes `zeta -LocalProvide` fetch from the remote + fileserver (404) instead of the local build cache. +- Fix: pass `--repo file://` (the build cache dir). Generated + manifests then carry `url = "file:///packages//-.tar.gz"` + — exactly where the tarball lives. Zeta's fetch.get handles `file://` + via plain file copy (references/ZETA/lib/fetch.lua:108-110). +- The manifest should only carry a real remote repo URL when the user + deliberately publishes to ZUUR — at which point the manifest is + regenerated with the real URL. Local builds always point at the cache. +- install.d's ZETA_REPO is DIFFERENT: that's the remote binary pool used + to resolve BINARY deps, and it is correct as-is. Do not confuse the two. +- Smoketest fake zeta-makepkg parses only `--output`, so the repo URL + value is irrelevant to it — changing --repo doesn't break the e2e. diff --git a/src/tofu/build.d b/src/tofu/build.d index 5610a8e..066f95f 100644 --- a/src/tofu/build.d +++ b/src/tofu/build.d @@ -116,6 +116,16 @@ private @safe string pkgNameFromPath(string recipePath) { /// Invoke zeta-makepkg to build a recipe into `outputDir`. /// +/// The `--repo` flag is passed as `file://` (NOT a hardcoded +/// remote URL): zeta-makepkg bakes this into every generated package.lua +/// as `url = "file:///packages//-.tar.gz"`. +/// Because the tarball is produced into that very directory, Zeta's +/// fetch.get can install straight from the local build cache via plain +/// file copy — installing with `zeta -LocalProvide` works offline and +/// never 404s against a remote fileserver. If a user later publishes a +/// package to ZUUR, the manifest is regenerated with the real repo URL +/// at publish time; tofu's local builds always point at the cache. +/// /// Parameters: /// recipePath = path to the .recipe file /// outputDir = directory where packages//package.lua is produced @@ -160,7 +170,7 @@ string runMakepkg(string recipePath, string outputDir, int jobs, bool force, "--output", outputDir, "-j" ~ to!string(jobs), "--no-index", - "--repo", "https://files.spectoria.dev/zuur/binary", + "--repo", "file://" ~ outputDir, ]; if (force) cmd ~= "--force"; @@ -692,4 +702,33 @@ exit ` ~ exitCode ~ "\n"; "Expected 'recipe not found' in reason, got: " ~ result.failed[0].reason); } + + // ── Test (14): fake zeta-makepkg receives --repo file:// ───── + @safe unittest { + auto tmp = testTempDir("repo-flag"); + scope (exit) sRmdirRecurse(tmp); + + sWrite(buildPath(tmp, "hello.recipe"), + "return { name = 'hello', version = '1.0.0' }"); + + auto argsFile = buildPath(tmp, "args.txt"); + auto fakeBin = makeFakeMakepkg(tmp, "fake-makepkg-repo", "0", argsFile); + auto outDir = buildPath(tmp, "output"); + + Config cfg; + cfg.zetaToolchainPath = fakeBin; + + runMakepkg(buildPath(tmp, "hello.recipe"), outDir, 4, false, cfg); + + auto rawArgs = () @trusted { + try { return readText(argsFile); } catch (Exception) { return ""; } + }(); + auto expectedRepo = "file://" ~ outDir; + assert(rawArgs.indexOf("--repo") >= 0, + "Expected --repo flag in args, got: " ~ rawArgs); + assert(rawArgs.indexOf(expectedRepo) >= 0, + "Expected --repo " ~ expectedRepo ~ " in args, got: " ~ rawArgs); + assert(rawArgs.indexOf("https://files.spectoria.dev/zuur/binary") < 0, + "Hardcoded remote repo URL must not be passed, got: " ~ rawArgs); + } }