mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-05 08:13:06 +08:00
Keep installed libnode packs out of the executable cache key
An installed @scriptc/libnode-<platform> pack versions in lockstep with the compiler, whose version every executable cache key already holds; keying on it as well made the full compiler's key differ from the bootstrap's routed key wherever a pack directory was present, so routed cache hits stopped. Only directories with a manifest.json count as installed packs, so an unbuilt workspace package is not one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
27b27fd5a8
commit
79931be198
@@ -1376,7 +1376,7 @@ async function compileTracked(
|
||||
const helperObjectRoute =
|
||||
opts.nativeProgramObject === true || usesPrecompiledRuntimePack(opts, "llvm");
|
||||
// Calls into Node record the libnode pack, keyed by its manifest (node-islands/libnode.ts).
|
||||
const libnodeKey = libnodeCacheKey(opts.libnode, process.env, dirname(entryPath));
|
||||
const libnodeKey = libnodeCacheKey(opts.libnode);
|
||||
const routeOptions: Omit<
|
||||
EarlyExecutableCacheOptions,
|
||||
"implementation" | "implementationDependencies" | "nativeEnvironment"
|
||||
|
||||
@@ -186,12 +186,13 @@ export function readLibnodePack(
|
||||
return { root, manifest };
|
||||
}
|
||||
|
||||
/** The nearest `node_modules/<name>` directory walking up from `from`. */
|
||||
/** The nearest `node_modules/<name>` directory with a built pack (a
|
||||
* manifest.json) walking up from `from`. */
|
||||
function findInstalled(name: string, from: string): string | null {
|
||||
let dir = resolve(from);
|
||||
for (;;) {
|
||||
const candidate = join(dir, "node_modules", name);
|
||||
if (existsSync(join(candidate, "package.json"))) return candidate;
|
||||
if (existsSync(join(candidate, "manifest.json"))) return candidate;
|
||||
const parent = dirname(dir);
|
||||
if (parent === dir) return null;
|
||||
dir = parent;
|
||||
@@ -200,7 +201,9 @@ function findInstalled(name: string, from: string): string | null {
|
||||
|
||||
function resolveNextToCompiler(name: string): string | null {
|
||||
try {
|
||||
return dirname(createRequire(import.meta.url).resolve(`${name}/package.json`));
|
||||
const dir = dirname(createRequire(import.meta.url).resolve(`${name}/package.json`));
|
||||
// An unbuilt workspace package is not a pack.
|
||||
return existsSync(join(dir, "manifest.json")) ? dir : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -93,13 +93,8 @@ describe("the recorded libnode pack", () => {
|
||||
});
|
||||
|
||||
describe("the libnode pack in an executable's cache key", () => {
|
||||
test("is absent without --libnode, SCRIPTC_LIBNODE or an installed pack", () => {
|
||||
const installed = findInstalledLibnodePack({
|
||||
targetName: hostLibnodeTarget(),
|
||||
projectDir: "/nonexistent",
|
||||
});
|
||||
if (installed === null) expect(libnodeCacheKey(undefined, {}, "/nonexistent")).toBeUndefined();
|
||||
else expect(libnodeCacheKey(undefined, {}, "/nonexistent")).toContain(installed);
|
||||
test("is absent without --libnode or SCRIPTC_LIBNODE", () => {
|
||||
expect(libnodeCacheKey(undefined, {})).toBeUndefined();
|
||||
});
|
||||
|
||||
test("changes when the pack in the same directory is upgraded", () => {
|
||||
|
||||
@@ -119,24 +119,20 @@ export function libnodeRecord(
|
||||
}
|
||||
|
||||
/** The part of an executable's cache key that names its libnode pack, or
|
||||
* undefined when neither --libnode nor SCRIPTC_LIBNODE is set and no pack
|
||||
* is installed. It holds the option, the pack directory and a digest of the
|
||||
* pack's manifest.json, so that a pack upgraded in place (another Node
|
||||
* version, bridge ABI or file list) gives cached executables a new key
|
||||
* instead of their old record. */
|
||||
* undefined when neither --libnode nor SCRIPTC_LIBNODE is set. It holds the
|
||||
* option, the pack directory and a digest of the pack's manifest.json, so
|
||||
* that a pack upgraded in place (another Node version, bridge ABI or file
|
||||
* list) gives cached executables a new key instead of their old record.
|
||||
* An installed @scriptc/libnode-<platform> pack needs no part: it versions
|
||||
* in lockstep with the compiler, whose version every key already holds, so
|
||||
* the bootstrap's routed cache keeps serving builds where one is installed. */
|
||||
export function libnodeCacheKey(
|
||||
option: string | undefined,
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
projectDir: string = process.cwd(),
|
||||
): string | undefined {
|
||||
const fromEnv = env["SCRIPTC_LIBNODE"];
|
||||
const installed =
|
||||
option === undefined && fromEnv === undefined
|
||||
? findInstalledLibnodePack({ targetName: hostLibnodeTarget(), projectDir })
|
||||
: null;
|
||||
if (option === undefined && fromEnv === undefined && installed === null) return undefined;
|
||||
const source =
|
||||
installed ?? (option !== undefined && option !== "beside" ? option : (fromEnv ?? ""));
|
||||
if (option === undefined && fromEnv === undefined) return undefined;
|
||||
const source = option !== undefined && option !== "beside" ? option : (fromEnv ?? "");
|
||||
let manifest = "none";
|
||||
if (isAbsolute(source)) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user