biome/benchmark/bench.js
Emanuele Stoppa 836fa1e94c
fix: resolve settings based on path (#6175)
Co-authored-by: arendjr <533294+arendjr@users.noreply.github.com>
2025-05-30 12:09:24 +01:00

249 lines
6.9 KiB
JavaScript

#!/usr/bin/node
import { execSync } from "node:child_process";
import * as fs from "node:fs";
import * as path from "node:path";
import * as process from "node:process";
import * as util from "node:util";
const REPOSITORIES = {
eslint: {
repository: "https://github.com/eslint/eslint.git",
lintedDirs: ["lib", "messages", "tests/lib", "tests/performance", "tools"],
},
prettier: {
repository: "https://github.com/prettier/prettier.git",
formattedDirs: ["src", "scripts"],
},
webpack: {
repository: "https://github.com/webpack/webpack.git",
formattedDirs: ["lib", "examples", "benchmark"],
lintedDirs: ["lib"],
},
};
const TMP_DIR = path.resolve("./target");
function benchmarkFormatter(biomeBin, options) {
// Run Dprint once to run the installer
execSync("npx dprint --version");
for (const [name, config] of Object.entries(REPOSITORIES)) {
if (
!config.formattedDirs ||
("repository" in options && options.repository !== name)
) {
continue;
}
console.info(`\n⌛ repository: ${name}`);
const projectDirectory = cloneProject(
name,
config.repository,
config.formattedDirs,
);
console.info("");
const dirs = config.formattedDirs.join(" ");
const dirGlobs = config.formattedDirs.map((dir) => `"${dir}/**"`).join(" ");
const biomeCommand = `${biomeBin} format --config-path=../../ --write --max-diagnostics=0 ${dirs}`;
const benchCommands = {
prettier: `../../node_modules/.bin/prettier --config=../../.prettierrc.json --ignore-path=../../.prettierignore --write --log-level=error ${dirs}`,
// FIXME: Parallel Prettier is crashing on Node 22
// "parallel-prettier": `../../node_modules/.bin/pprettier --write --concurrency ${os.cpus().length} ${dirGlobs}`,
dprint: `../../node_modules/dprint/dprint fmt --config=../../dprint.json ${dirGlobs}`,
biome: biomeCommand,
"biome-1-thread": withEnvVariable("RAYON_NUM_THREADS", "1", biomeCommand),
};
let suite = "";
for (const benchName of Object.keys(benchCommands)) {
if ("bench" in options && !options.bench.includes(benchName)) {
continue;
}
suite += ` -n "${benchName}" '${benchCommands[benchName]}'`;
}
if (suite.length === 0) {
console.error(`Benchmark '${options.bench}' doesn't exist.`);
process.exit(1);
}
// Run 2 warmups to make sure the files are formatted correctly
let hyperfineCommand = `hyperfine --warmup 2 --shell=${shellOption()} ${suite}`;
if (options.verbose) {
hyperfineCommand += " --show-output";
console.info(`${hyperfineCommand}\n`);
}
execSync(hyperfineCommand, {
cwd: projectDirectory,
stdio: "inherit",
});
}
}
function benchmarkLinter(biomeBin, options) {
for (const [name, config] of Object.entries(REPOSITORIES)) {
if (
!config.lintedDirs ||
("repository" in options && options.repository !== name)
) {
continue;
}
console.info(`\n⌛ repository: ${name}`);
const projectDirectory = cloneProject(
name,
config.repository,
config.formattedDirs,
);
console.info("");
const dirs = config.lintedDirs.map((dir) => `"${dir}"`).join(" ");
const biomeCmd = `"${biomeBin}" lint --config-path=../../ --max-diagnostics=0 ${dirs}`;
const benchCommands = {
eslint: `../../node_modules/.bin/eslint --quiet --config=../../eslint.config.js --no-ignore ${dirs}`,
"ts-eslint": `../../node_modules/.bin/eslint --quiet --config=../../ts-eslint.config.js --no-ignore ${dirs}`,
biome: biomeCmd,
"biome-1-thread": withEnvVariable("RAYON_NUM_THREADS", "1", biomeCmd),
"ts-biome": `"${biomeBin}" lint --config-path=../../ts-biome.json --max-diagnostics=0 ${dirs}`,
};
let suite = "";
for (const benchName of Object.keys(benchCommands)) {
if ("bench" in options && !options.bench.includes(benchName)) {
continue;
}
suite += ` -n "${benchName}" '${benchCommands[benchName]}'`;
}
if (suite.length === 0) {
console.error(`Benchmark '${options.bench}' doesn't exist.`);
process.exit(1);
}
let hyperfineCommand = `hyperfine --ignore-failure --shell=${shellOption()} ${suite}`;
if (options.verbose) {
hyperfineCommand += " --show-output";
console.info(`${hyperfineCommand}\n`);
}
execSync(hyperfineCommand, {
cwd: projectDirectory,
stdio: "inherit",
});
}
}
function shellOption() {
if (process.platform === "win32") {
// Use Powershell so that it is possible to set an environment variable for a single command (ugh!)
return "powershell";
}
return "default";
}
function withEnvVariable(name, value, command) {
switch (process.platform) {
case "win32": {
return `$Env:${name}=${value}; ${command}`;
}
default:
return `${name}="${value}" ${command}`;
}
}
function withDirectory(cwd) {
return {
run(command, options) {
execSync(command, {
cwd,
...options,
});
},
};
}
function cloneProject(name, repository, dirs = []) {
const projectDirectory = path.join(TMP_DIR, name);
const inProjectDirectory = withDirectory(projectDirectory);
if (fs.existsSync(projectDirectory)) {
inProjectDirectory.run("git reset --hard @{u}");
inProjectDirectory.run("git clean -df");
inProjectDirectory.run("git pull --quiet --depth=1 --ff-only");
} else {
withDirectory(TMP_DIR).run(
`git clone --quiet --depth=1 ${dirs.length > 0 ? "--sparse" : ""} ${repository}`,
{
stdio: "inherit",
},
);
}
if (dirs.length > 0) {
console.info(
`Adding directories ${dirs.join()} to sparse checkout in ${projectDirectory}`,
);
inProjectDirectory.run(`git sparse-checkout add ${dirs.join(" ")}`);
}
return projectDirectory;
}
function buildBiome() {
console.info("Building Biome...");
execSync(
withEnvVariable(
"BIOME_VERSION",
"0.0.0",
"cargo build --bin biome --release",
),
{
stdio: "inherit",
},
);
return path.resolve("../target/release/biome");
}
function run({ positionals, values: options }) {
fs.mkdirSync(TMP_DIR, { recursive: true });
let biomeBinPath;
if ("biome" in options) {
biomeBinPath = options.biome;
} else {
biomeBinPath = buildBiome();
}
switch (positionals[0]) {
case "formatter":
benchmarkFormatter(biomeBinPath, options);
break;
case "linter":
benchmarkLinter(biomeBinPath, options);
break;
default:
console.error(
`A positional argument among 'formatter' and 'linter' must be passed.`,
);
process.exit(1);
}
}
run(
util.parseArgs({
allowPositionals: true,
options: {
bench: {
multiple: true,
type: "string",
},
biome: {
type: "string",
},
repository: {
type: "string",
},
verbose: {
type: "boolean",
},
},
}),
);