-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
Copy pathsetup.ts
executable file
·178 lines (150 loc) · 5.04 KB
/
setup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env -S deno run --allow-read=. --allow-write=. --allow-run=git --config=tests/config/deno.json
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file no-console
/** This copies the test files according to the config file `tests/node_compat/config.jsonc` */
import { walk } from "@std/fs/walk";
import { SEPARATOR } from "@std/path/constants";
import { ensureFile } from "@std/fs/ensure-file";
import { writeAll } from "@std/io/write-all";
import { withoutAll } from "@std/collections/without-all";
import { relative } from "@std/path/posix/relative";
import { version } from "./suite/node_version.ts";
import { config, ignoreList } from "../common.ts";
const encoder = new TextEncoder();
const NODE_VERSION = version;
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("./suite/test/", import.meta.url);
const NODE_COMPAT_TEST_DEST_URL = new URL(
"../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() {
using file = await Deno.open(new URL("./TODO.md", import.meta.url), {
write: true,
create: true,
truncate: true,
});
const nodeTests = await getNodeTests();
const portedTests = getDenoTests();
const remainingTests = withoutAll(nodeTests, portedTests);
const numPorted = portedTests.length;
const numMissing = remainingTests.length;
const numTotal = nodeTests.length;
const portedPercentage = (numPorted / numTotal * 100).toFixed(2);
const remainingPercentage = (numMissing / numTotal * 100).toFixed(2);
await file.write(encoder.encode(`<!-- deno-fmt-ignore-file -->
# Remaining Node Tests
${numPorted} tests out of ${numTotal} have been ported from Node ${NODE_VERSION} (${portedPercentage}% ported, ${remainingPercentage}% remaining).
NOTE: This file should not be manually edited. Please edit \`tests/node_compat/config.json\` and run \`deno task setup\` in \`tests/node_compat/runner\` dir instead.
`));
for (const test of remainingTests) {
await file.write(
encoder.encode(
`- [${test}](https://github.com/nodejs/node/tree/v${NODE_VERSION}/test/${test})\n`,
),
);
}
}
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(SEPARATOR);
// suite is the directory name after test/. For example, if the file is
// "node_compat/node/test/fixtures/policy/main.mjs"
// then suite is "fixtures/policy"
const suite = fragments.slice(fragments.indexOf("node_compat") + 4, -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 \`tests/node_compat/runner/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);
}
}