mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-22 05:59:31 +08:00
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks. - Preserve compiler import boundaries and protected fixtures while cleaning up lint findings. - Standardize source formatting and validate import, fixture, and embedded-source protections.
118 lines
4.6 KiB
JavaScript
118 lines
4.6 KiB
JavaScript
/** Exercise the packed npm command and its bundled host assets in isolation. */
|
|
import assert from "node:assert/strict";
|
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
import {
|
|
cpSync,
|
|
mkdirSync,
|
|
mkdtempSync,
|
|
readFileSync,
|
|
readdirSync,
|
|
rmSync,
|
|
statSync,
|
|
writeFileSync,
|
|
} from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { prepareNativeCommand } from "../packages/cli/scripts/prepare-native.mjs";
|
|
|
|
const repository = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
const platform = resolve(process.argv[2]);
|
|
const identity = JSON.parse(readFileSync(join(platform, "package.json"), "utf8"));
|
|
const root = mkdtempSync(
|
|
join(process.platform === "win32" ? tmpdir() : "/tmp", "scriptc-npm-smoke-"),
|
|
);
|
|
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
const env = {
|
|
...process.env,
|
|
npm_config_cache: join(root, "npm-cache"),
|
|
npm_config_update_notifier: "false",
|
|
NODE_PATH: "",
|
|
};
|
|
function command(executable, args, cwd, environment = env) {
|
|
return execFileSync(executable, args, {
|
|
cwd,
|
|
env: environment,
|
|
encoding: "utf8",
|
|
shell: process.platform === "win32" && executable.endsWith(".cmd"),
|
|
maxBuffer: 16 * 1024 * 1024,
|
|
});
|
|
}
|
|
function pack(directory) {
|
|
const result = JSON.parse(
|
|
command(npm, ["pack", "--ignore-scripts", "--json", "--pack-destination", root], directory),
|
|
);
|
|
return join(root, result[0].filename);
|
|
}
|
|
function bytes(directory) {
|
|
let size = 0;
|
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
if (entry.isSymbolicLink()) continue;
|
|
const path = join(directory, entry.name);
|
|
size += entry.isDirectory() ? bytes(path) : statSync(path).size;
|
|
}
|
|
return size;
|
|
}
|
|
try {
|
|
const platformTarball = pack(platform);
|
|
const wrapper = join(root, "wrapper");
|
|
mkdirSync(wrapper);
|
|
cpSync(join(repository, "packages/cli/scripts"), join(wrapper, "scripts"), { recursive: true });
|
|
const manifest = JSON.parse(readFileSync(join(repository, "packages/cli/package.json"), "utf8"));
|
|
assert.equal(manifest.version, identity.version);
|
|
assert.ok(
|
|
Object.keys(manifest.optionalDependencies).every((name) => name.startsWith("@scriptc/cli-")),
|
|
"the default CLI must only depend on native host packages",
|
|
);
|
|
manifest.optionalDependencies = Object.fromEntries(
|
|
Object.keys(manifest.optionalDependencies).map((name) => [
|
|
name,
|
|
name === identity.name ? "file:" + platformTarball : identity.version,
|
|
]),
|
|
);
|
|
delete manifest.devDependencies;
|
|
delete manifest.scripts.prepack;
|
|
writeFileSync(join(wrapper, "package.json"), JSON.stringify(manifest));
|
|
prepareNativeCommand(wrapper);
|
|
const tarball = pack(wrapper);
|
|
const project = join(root, "project");
|
|
mkdirSync(project);
|
|
command(npm, ["install", "--offline", "--no-audit", "--no-fund", tarball], project);
|
|
const executable = join(project, "node_modules/scriptc/bin/scriptc.exe");
|
|
assert.equal(
|
|
command(executable, ["--version"], project, { ...env, PATH: "" }).trim(),
|
|
identity.version,
|
|
);
|
|
const entry = join(project, "hello.ts");
|
|
writeFileSync(entry, 'console.log("Hello, world!");\n');
|
|
const binary = join(project, process.platform === "win32" ? "hello.exe" : "hello");
|
|
const compileEnv = { ...env, SCRIPTC_CACHE_DIR: join(root, "build-cache") };
|
|
command(executable, ["build", entry, "-o", binary], project, compileEnv);
|
|
const result = spawnSync(binary, [], { cwd: project, env: { PATH: "" }, encoding: "utf8" });
|
|
assert.equal(result.status, 0, result.stderr);
|
|
assert.equal(result.stdout, "Hello, world!\n");
|
|
assert.equal(result.stderr, "");
|
|
const helloBytes = statSync(binary).size;
|
|
writeFileSync(
|
|
entry,
|
|
'import { randomBytes, randomUUID } from "node:crypto";\nconst bytes = randomBytes(32);\nconsole.log(bytes.length === 32, randomUUID().length === 36, Math.random() >= 0);\n',
|
|
);
|
|
command(executable, ["build", entry, "-o", binary], project, compileEnv);
|
|
assert.equal(command(binary, [], project, { PATH: "" }), "true true true\n");
|
|
const installed = readdirSync(join(project, "node_modules/@scriptc"));
|
|
assert.deepEqual(installed, [identity.name.slice("@scriptc/".length)]);
|
|
console.log(
|
|
JSON.stringify({
|
|
package: identity.name,
|
|
version: identity.version,
|
|
installed_packages: ["scriptc", ...installed],
|
|
installed_file_bytes: bytes(join(project, "node_modules")),
|
|
hello_executable_bytes: helloBytes,
|
|
crypto_executable_bytes: statSync(binary).size,
|
|
output: result.stdout,
|
|
}),
|
|
);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|