checkLibraries
uses node:fs
Each of tcm's libraries (TCM_LIBRARIES), added to a fresh codebase as another codebase would add it, by its
namespace as the branch this runs on has it (released or not: a library's releases are made on main once it's
landed): every definition it brings must be named there (nothing it uses arrives as an unnamed version). pnpm verify runs it; pnpm tcm run tcmts.dev.checkLibraries does too.
import { Codebase } from "#codebase/tcmts/cli/codebase"; import { addLibrary, libraryName, releaseNamespace, within } from "#codebase/tcmts/cli/libraries"; import { packagesIn } from "#codebase/tcmts/cli/manifests"; import { codebaseDir, TCM_LIBRARIES } from "#codebase/tcmts/dev"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; export async function checkLibraries(): Promise<void> { const session = process.env.TCM_BRANCH; // (each library's namespace here, on this branch) const here = Codebase.open(codebaseDir()); const head = here.store.head(); const packages = await Promise.all( packagesIn(here, here.store.names()).map(async (p) => ({ name: p.name, namespace: await releaseNamespace(here.store, { package: p.name, version: "", namespace: p.namespace, causal: head, }), })), ); here.store.close(); delete process.env.TCM_BRANCH; try { for (const name of TCM_LIBRARIES) { const dir = fs.mkdtempSync(path.join(os.tmpdir(), `tcm library ${name} `)); try { const cb = Codebase.init(dir); const pkg = packages.find((p) => p.name === name); if (!pkg) throw new Error(`${name}: no package of that name on ${session ?? "main"}`); // (by hash, which names no package: called after it, as `tcm lib add` calls a release) const lib = await addLibrary(cb, { name: libraryName(name), source: codebaseDir(), what: `#${pkg.namespace}`, }); const rows = cb.store.names(); const named = new Set(rows.map((r) => r.hash)); const unnamed = new Set<string>(); for (const r of rows.filter((x) => within(x.path, lib.path))) { const rec = cb.store.getDef(r.hash); if (!rec) continue; for (const m of cb.store.componentMembers(rec.componentHash)) for (const d of m.deps) if (d.ref.startsWith("#") && !named.has(d.ref.slice(1))) unnamed.add(`${r.path} uses #${d.ref.slice(1, 9)}`); } if (unnamed.size) throw new Error( `${name}, added to a fresh codebase, uses what it doesn't name:\n ${[...unnamed].join("\n ")}`, ); console.log( `${name}: added as ${lib.path} (as ${session ?? "main"} has it, #${pkg.namespace.slice(0, 8)}), every definition named`, ); } finally { fs.rmSync(dir, { recursive: true, force: true }); } } } finally { if (session !== undefined) process.env.TCM_BRANCH = session; } }