summaryrefslogtreecommitdiff
path: root/tools/build_bench.ts
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2023-06-06 12:53:41 -0600
committerGitHub <noreply@github.com>2023-06-06 18:53:41 +0000
commit40d77c56055cca89437b36bb5763a820ef931539 (patch)
tree8f1e5ca490a3619c167808cc382d9e0d20a97109 /tools/build_bench.ts
parent1c3d2132c28f4d47aeebeb5b863bbbda05db7147 (diff)
chore(core): build_bench tool (#19387)
This is a quick tool that I've been using to build benchmarking builds for Deno. Usage: Build a benchmark `HEAD~1` and `origin/main` executable: ```sh deno run tools/build_bench.ts HEAD~1 origin/main ``` Build debug benchmark executables of the last three commits: ```sh deno run tools/build_bench.ts --profile debug HEAD HEAD~1 HEAD~2 ```
Diffstat (limited to 'tools/build_bench.ts')
-rwxr-xr-xtools/build_bench.ts136
1 files changed, 136 insertions, 0 deletions
diff --git a/tools/build_bench.ts b/tools/build_bench.ts
new file mode 100755
index 000000000..dbbe02967
--- /dev/null
+++ b/tools/build_bench.ts
@@ -0,0 +1,136 @@
+#!/usr/bin/env -S deno run --unstable --allow-env --allow-read --allow-write --allow-run
+// Copyright 2018-2023 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);