Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

136 lines
3.6 KiB
JavaScript
Raw Permalink Normal View History

2022-05-10 15:42:11 +08:00
import path from "node:path";
import url from "node:url";
2025-04-23 23:42:19 +08:00
import {
prettierCliEntry,
prettierCliMockableEntry,
prettierMainEntry,
} from "./env.js";
2022-05-10 15:42:11 +08:00
2023-03-31 09:04:33 +08:00
const normalizeToPosix =
path.sep === "\\"
? (filepath) => replaceAll(filepath, "\\", "/")
: (filepath) => filepath;
const hasOwn =
Object.hasOwn ??
((object, property) =>
// eslint-disable-next-line prefer-object-has-own
Object.prototype.hasOwnProperty.call(object, property));
const replaceAll = (text, find, replacement) =>
text.replaceAll
? text.replaceAll(find, replacement)
: text.split(find).join(replacement);
2026-07-24 08:51:20 +08:00
const originalNodeVersion = process.versions.node;
2023-03-31 09:04:33 +08:00
2025-04-23 23:42:19 +08:00
async function getApiMockable() {
const prettier = await import(url.pathToFileURL(prettierMainEntry));
return prettier.__debug.mockable;
}
async function getCliMockable() {
const cli = await import(url.pathToFileURL(prettierCliMockableEntry));
return cli.mockable;
}
async function mockImplementations(options) {
const [apiMockable, cliMockable] = await Promise.all([
getApiMockable(),
getCliMockable(),
]);
cliMockable.mockImplementations({
clearStreamText(stream, text) {
2025-12-21 18:07:47 +08:00
let streamName;
if (stream === process.stdout) {
streamName = "process.stdout";
} else if (stream === process.stderr) {
streamName = "process.stderr";
} else {
streamName = "unknown stream";
}
2025-04-23 23:42:19 +08:00
stream.write(`\n[[Clear text(${streamName}): ${text}]]\n`);
},
// Time measure in format test
getTimestamp: () => 0,
isCI: () => Boolean(options.ci),
2025-12-21 18:07:47 +08:00
isStreamTTY(stream) {
if (stream === process.stdin) {
return Boolean(options.isTTY);
}
if (stream === process.stdout) {
return Boolean(options.stdoutIsTTY);
}
return stream.isTTY;
},
2025-04-23 23:42:19 +08:00
// eslint-disable-next-line require-await
async writeFormattedFile(filename, content) {
filename = normalizeToPosix(path.relative(process.cwd(), filename));
if (
options.mockWriteFileErrors &&
hasOwn(options.mockWriteFileErrors, filename)
) {
throw new Error(
options.mockWriteFileErrors[filename] + " (mocked error)",
);
}
process.send({
type: "cli:write-file",
data: { filename, content },
});
},
});
2025-04-23 23:42:19 +08:00
apiMockable.mockImplementations({
getPrettierConfigSearchStopDirectory: () =>
url.fileURLToPath(new URL("./cli", import.meta.url)),
});
}
2022-05-10 15:42:11 +08:00
2026-07-24 08:51:20 +08:00
let nodeVersionMocked = false;
2025-04-23 23:42:19 +08:00
async function run(options) {
await mockImplementations(options);
2022-05-10 15:42:11 +08:00
2026-07-24 08:51:20 +08:00
if (!nodeVersionMocked) {
nodeVersionMocked = true;
Object.defineProperty(process.versions, "node", {
get value() {
return options.mockNodeVersion || originalNodeVersion;
},
writable: false,
enumerable: true,
configurable: true,
});
}
2025-04-23 23:42:19 +08:00
const { __promise: promise } = await import(
url.pathToFileURL(prettierCliEntry)
);
2022-05-21 11:11:50 +08:00
await promise;
2022-05-10 15:42:11 +08:00
}
2025-04-21 18:58:44 +08:00
process.once("message", async (data) => {
2022-05-10 15:42:11 +08:00
try {
2025-04-21 18:58:44 +08:00
await run(data);
2025-04-23 23:42:19 +08:00
} catch (error) {
// For easier debugging
// eslint-disable-next-line no-console
console.error(error);
process.send({ type: "worker:fault", error });
throw error;
2022-05-10 15:42:11 +08:00
} finally {
2025-04-21 18:58:44 +08:00
// On MacOS, if we exit too quick the stdio won't received on main thread
if (process.platform === "darwin") {
await Promise.all(
["stdout", "stderr"].map(
(stream) =>
new Promise((resolve) => {
process[stream].once("finish", resolve);
process[stream].end();
}),
),
);
}
2022-05-10 15:42:11 +08:00
process.exit();
}
});