1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-29 10:39:10 -05:00
denoland-deno/tools/node_compat/setup.ts
2023-06-02 15:05:32 +09:00

169 lines
4.6 KiB
TypeScript
Executable file

#!/usr/bin/env -S deno run --allow-read=. --allow-write=. --allow-run=git
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
/** This copies the test files according to the config file `cli/tests/node_compat/config.jsonc` */
import { walk } from "../../test_util/std/fs/walk.ts";
import { sep } from "../../test_util/std/path/mod.ts";
import { ensureFile } from "../../test_util/std/fs/ensure_file.ts";
import { writeAll } from "../../test_util/std/streams/write_all.ts";
import { withoutAll } from "../../test_util/std/collections/without_all.ts";
import { relative } from "../../test_util/std/path/posix.ts";
import { config, ignoreList } from "../../cli/tests/node_compat/common.ts";
const encoder = new TextEncoder();
const NODE_VERSION = config.nodeVersion;
const NODE_IGNORED_TEST_DIRS = [
"addons",
"async-hooks",
"cctest",
"common",
"doctool",
"embedding",
"fixtures",
"fuzzers",
"js-native-api",
"node-api",
"overlapped-checker",
"report",
"testpy",
"tick-processor",
"tools",
"v8-updates",
"wasi",
"wpt",
];
const VENDORED_NODE_TEST = new URL("node/test/", import.meta.url);
const NODE_COMPAT_TEST_DEST_URL = new URL(
"../../cli/tests/node_compat/test/",
import.meta.url,
);
async function getNodeTests(): Promise<string[]> {
const paths: string[] = [];
const rootPath = VENDORED_NODE_TEST.href.slice(7);
for await (
const item of walk(VENDORED_NODE_TEST, { exts: [".js"] })
) {
const path = relative(rootPath, item.path);
if (NODE_IGNORED_TEST_DIRS.every((dir) => !path.startsWith(dir))) {
paths.push(path);
}
}
return paths.sort();
}
function getDenoTests() {
return Object.entries(config.tests)
.filter(([testDir]) => !NODE_IGNORED_TEST_DIRS.includes(testDir))
.flatMap(([testDir, tests]) => tests.map((test) => testDir + "/" + test));
}
async function updateToDo() {
const file = await Deno.open(new URL("./TODO.md", import.meta.url), {
write: true,
create: true,
truncate: true,
});
const missingTests = withoutAll(await getNodeTests(), await getDenoTests());
await file.write(encoder.encode(`<!-- deno-fmt-ignore-file -->
# Remaining Node Tests
NOTE: This file should not be manually edited. Please edit \`cli/tests/node_compat/config.json\` and run \`deno task setup\` in \`tools/node_compat\` dir instead.
Total: ${missingTests.length}
`));
for (const test of missingTests) {
await file.write(
encoder.encode(
`- [${test}](https://github.com/nodejs/node/tree/v${NODE_VERSION}/test/${test})\n`,
),
);
}
file.close();
}
async function clearTests() {
console.log("Cleaning up previous tests");
for await (
const file of walk(NODE_COMPAT_TEST_DEST_URL, {
includeDirs: false,
skip: ignoreList,
})
) {
await Deno.remove(file.path);
}
}
/** Checks if file has entry in config.json */
function hasEntry(file: string, suite: string) {
return Array.isArray(config.tests[suite]) &&
config.tests[suite].includes(file);
}
async function copyTests() {
console.log("Copying test files...");
for await (const entry of walk(VENDORED_NODE_TEST, { skip: ignoreList })) {
const fragments = entry.path.split(sep);
// suite is the directory name after test/. For example, if the file is
// "node_comapt/node/test/fixtures/policy/main.mjs"
// then suite is "fixtures/policy"
const suite = fragments.slice(fragments.indexOf("node_compat") + 3, -1)
.join("/");
if (!hasEntry(entry.name, suite)) {
continue;
}
const dest = new URL(`${suite}/${entry.name}`, NODE_COMPAT_TEST_DEST_URL);
await ensureFile(dest);
const destFile = await Deno.open(dest, {
create: true,
truncate: true,
write: true,
});
const srcFile = await Deno.open(
new URL(`${suite}/${entry.name}`, VENDORED_NODE_TEST),
);
// Add header to js files
if (dest.pathname.endsWith("js")) {
await writeAll(
destFile,
encoder.encode(`// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node ${NODE_VERSION}
// This file is automatically generated by \`tools/node_compat/setup.ts\`. Do not modify this file manually.
`),
);
}
await srcFile.readable.pipeTo(destFile.writable);
}
}
// main
await clearTests();
await copyTests();
await updateToDo();
if (Deno.args[0] === "--check") {
const cmd = new Deno.Command("git", { args: ["status", "-s"] });
const { stdout } = await cmd.output();
if (stdout.length > 0) {
console.log("The following files have been changed:");
console.log(new TextDecoder().decode(stdout));
Deno.exit(1);
}
}