diff options
author | Matt Mastracci <matthew@mastracci.com> | 2023-06-06 12:53:41 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-06 18:53:41 +0000 |
commit | 40d77c56055cca89437b36bb5763a820ef931539 (patch) | |
tree | 8f1e5ca490a3619c167808cc382d9e0d20a97109 /tools/build_bench.ts | |
parent | 1c3d2132c28f4d47aeebeb5b863bbbda05db7147 (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-x | tools/build_bench.ts | 136 |
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); |