Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 82b375cd86ab9d3ec55a43771c34d7b62625e0c9
parent 0278e0af2c2dfefde5332afce1cd9ec53772875b
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Tue,  6 Oct 2026 08:24:00 -0400

publish: source publish reads ARCHILYZER_SOURCE_REPO before looking for a checkout

The runtime image has no .git; docker-compose.source.yml mounts the host's git
common dir read-only and names it here. A value that names nothing refuses the
publish by name instead of falling through to "no repository".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mcommon/publish/source.test.ts | 29+++++++++++++++++++++++++++++
Mcommon/publish/source.ts | 26+++++++++++++++++++++++---
2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/common/publish/source.test.ts b/common/publish/source.test.ts @@ -375,6 +375,35 @@ test("no git repository here (a docker runtime, a tarball install): the build ge assert.ok(!existsSync(path.join(pub, "source"))); }); +test("ARCHILYZER_SOURCE_REPO names the repository where the checkout has none (the container's mount); one that names nothing refuses by name (release 18)", async () => { + const bare = dir("no-git-env"); + const pub = path.join(dir("site"), "public"); + const logs: string[] = []; + const base: SourcePublishOpts = { + paths: { monorepoRoot: bare } as Paths, + publicDir: pub, + onLog: (l) => logs.push(l), + scrubFile: path.join(bare, "none.txt"), + denylistFile: path.join(bare, "none.txt"), + check: true, + }; + // A mounted repository: found, so the publish goes on to the next step — + // here, the operator's files, which this scenario leaves out on purpose. + // It is a git DIR — what the overlay mounts (the host's common dir), and what + // the checkout lookup answers. + const repo = path.join(sourceRepo(), ".git"); + assert.equal(await publishSource({ ...base, env: { ...process.env, ARCHILYZER_SOURCE_REPO: repo } }), 1); + assert.ok(!logs.includes(`[source] ${NO_REPOSITORY}`), logs.join("\n")); + assert.match(logs.join("\n"), /none\.txt/, "it reached the operator's files"); + // A variable naming a path that is not there: a refusal that names it, never + // the "no repository" sentence. + logs.length = 0; + const gone = path.join(bare, "not-mounted.git"); + assert.equal(await publishSource({ ...base, env: { ...process.env, ARCHILYZER_SOURCE_REPO: gone } }), 1); + assert.match(logs.join("\n"), /REFUSED: ARCHILYZER_SOURCE_REPO names .*not-mounted\.git, which is not there/); + assert.ok(!logs.includes(`[source] ${NO_REPOSITORY}`)); +}); + test("round trip: --check writes nothing; publish; a dumb clone of the mirror is main, scrubbed, from static files", async (t) => { if (filterRepoProblem) return t.skip(`git-filter-repo unavailable: ${filterRepoProblem}`); const repo = sourceRepo(); diff --git a/common/publish/source.ts b/common/publish/source.ts @@ -133,7 +133,8 @@ export type SourcePublishOpts = PublishOpts & { check?: boolean; // Leave the scratch dir (the rewritten bare clone, the stage) for a look. keepScratch?: boolean; - // The repository to mirror. Default: this checkout's git COMMON dir, so a + // The repository to mirror. Default: ARCHILYZER_SOURCE_REPO (a container's + // mount of the host's repository), else this checkout's git COMMON dir, so a // worktree build mirrors the primary's main. sourceRepo?: string; // Default: HOMEPAGE_PUBLIC_DIR, else <repo>/homepage/public. @@ -611,6 +612,25 @@ async function commonDir(ctx: Ctx, cwd: string): Promise<string | null> { throw new SourceRefusal(`git rev-parse exited ${r.code}${tail ? `: ${tail}` : ""}`); } +// The repository to mirror when the caller names none: ARCHILYZER_SOURCE_REPO +// when it is set — in a container, the host's git common dir mounted read-only +// by docker-compose.source.yml, since the image has no .git — else this +// checkout's common dir. A variable that names nothing is a refusal, not a +// silent fall-through to "no repository" (which would withdraw the publish +// with a sentence about tarball installs). +async function sourceRepoFor(ctx: Ctx, cwd: string): Promise<string | null> { + const named = ctx.env.ARCHILYZER_SOURCE_REPO?.trim(); + if (named) { + if (!existsSync(named)) { + throw new SourceRefusal( + `ARCHILYZER_SOURCE_REPO names ${named}, which is not there — mount the host's git common dir there (docker-compose.source.yml), or unset it`, + ); + } + return named; + } + return commonDir(ctx, cwd); +} + // The real path of `p`, or of its deepest existing ancestor with the rest // appended: a scratch root may not exist yet, and a symlink must not hide // where it lands. @@ -764,7 +784,7 @@ async function publish( // 1. The private main — or no repository at all (L8: the docker runtime, // a tarball install), where nothing can be mirrored and nothing can leak. - const sourceRepo = opts.sourceRepo ?? (await commonDir(ctx, paths.monorepoRoot)); + const sourceRepo = opts.sourceRepo ?? (await sourceRepoFor(ctx, paths.monorepoRoot)); if (sourceRepo === null) { onLog(`[source] ${NO_REPOSITORY}`); if (opts.check) return 1; @@ -1328,7 +1348,7 @@ export async function publishedSourceProblem( }; let main: string | null = null; try { - const repo = opts.sourceRepo ?? (await commonDir(ctx, paths.monorepoRoot)); + const repo = opts.sourceRepo ?? (await sourceRepoFor(ctx, paths.monorepoRoot)); main = repo ? await revParse(ctx, repo, `refs/heads/${SOURCE_BRANCH}^{commit}`) : null; } catch (err) { if (!(err instanceof SourceRefusal)) throw err;