deno/tools/build_bench.ts

137 lines
3.3 KiB
TypeScript
Executable File

#!/usr/bin/env -S deno run --allow-env --allow-read --allow-write --allow-run
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import $ from "https://deno.land/x/dax@0.32.0/mod.ts";
if (Deno.args.length === 0) {
$.log(
"Usage: build_bench [-v] [--profile release|debug] commit1 [commit2 [comment3...]]",
);
Deno.exit(1);
}
const args = Deno.args.slice();
let verbose = false;
if (args[0] == "-v") {
args.shift();
verbose = true;
}
let profile = "release";
if (args[0] == "--profile") {
args.shift();
profile = args.shift();
}
function exit(msg: string) {
$.logError(msg);
Deno.exit(1);
}
// Make sure the .git dir exists
const gitDir = Deno.cwd() + "/.git";
await Deno.stat(gitDir);
async function runCommand(human: string, cmd) {
if (verbose) {
const out = await cmd.noThrow();
if (out.code != 0) {
exit(human);
}
} else {
const out = await cmd.stdout("piped").stderr("piped").noThrow();
if (out.code != 0) {
$.logLight("stdout");
$.logGroup();
$.log(out.stdout);
$.logGroupEnd();
$.logLight("stderr");
$.logGroup();
$.log(out.stderr);
$.logGroupEnd();
exit(human);
}
}
}
async function buildGitCommit(progress, commit) {
const tempDir = $.path(await Deno.makeTempDir());
const gitInfo =
await $`git log --pretty=oneline --abbrev-commit -n1 ${commit}`.stdout(
"piped",
).stderr("piped").noThrow();
if (gitInfo.code != 0) {
$.log(gitInfo.stdout);
$.log(gitInfo.stderr);
exit(`Failed to get git info for commit ${commit}`);
}
const hash = gitInfo.stdout.split(" ")[0];
progress.message(`${commit} is ${hash}`);
progress.message(`clone ${hash}`);
await runCommand(
`Failed to clone commit ${commit}`,
$`git clone ${gitDir} ${tempDir}`,
);
progress.message(`reset ${hash}`);
await runCommand(
`Failed to reset commit ${commit}`,
$`git reset --hard ${hash}`.cwd(tempDir),
);
progress.message(`build ${hash} (please wait)`);
const now = Date.now();
const interval = setInterval(() => {
const elapsed = Math.round((Date.now() - now) / 1000);
progress.message(`build ${hash} (${elapsed}s)`);
}, 100);
try {
if (profile === "debug") {
await runCommand(
`Failed to build commit ${commit}`,
$`cargo build`.cwd(tempDir),
);
} else {
await runCommand(
`Failed to build commit ${commit}`,
$`cargo build --profile ${profile}`.cwd(tempDir),
);
}
} finally {
clearInterval(interval);
}
const elapsed = Math.round((Date.now() - now) / 1000);
let file;
if (profile === "release") {
file = `deno-${hash}`;
} else {
file = `deno-${profile}-${hash}`;
}
progress.message(`copy ${hash}`);
await tempDir.join("target").join(profile).join("deno").copyFile(file);
progress.message(`cleanup ${hash}`);
await tempDir.remove({ recursive: true });
progress.message("done");
$.log(`Built ./${file} (${commit}) in ${elapsed}s: ${gitInfo.stdout}`);
}
const promises = [];
for (const arg of args) {
if (verbose) {
promises.push(buildGitCommit({ message() {} }, arg));
} else {
const progress = $.progress(`${arg}`);
promises.push(progress.with(async () => {
await buildGitCommit(progress, arg);
}));
}
}
await Promise.all(promises);