-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
delete nu and bash scripts, polish up TS one
- Loading branch information
1 parent
53592cd
commit 86a848b
Showing
3 changed files
with
61 additions
and
132 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,28 @@ | |
* | ||
* Copyright Oxide Computer Company | ||
*/ | ||
import * as flags from 'https://deno.land/[email protected]/flags/mod.ts' | ||
import { exists } from 'https://deno.land/[email protected]/fs/mod.ts' | ||
import { $, CommandBuilder } from 'https://deno.land/x/[email protected]/mod.ts' | ||
|
||
const HELP = ` | ||
Display changes to API client caused by a given Omicron PR. Works by downloading | ||
the OpenAPI spec before and after, generating clients in temp dirs, and diffing. | ||
Requirements: | ||
- Deno (which you have if you're seeing this message) | ||
- GitHub CLI (gh) | ||
Usage: | ||
./tools/deno/api-diff.ts [options] <PR number> | ||
PR number is optional. If left out, interactive picker is shown. | ||
Options: | ||
-f, --force Download spec and regen client even if dir already exists | ||
-h, --help Show this help message | ||
`.trim() | ||
|
||
// inspired by: https://github.com/dsherret/dax/issues/137#issuecomment-1603848769 | ||
declare module 'https://deno.land/x/[email protected]/mod.ts' { | ||
interface CommandBuilder { | ||
|
@@ -25,32 +45,46 @@ CommandBuilder.prototype.pipe = function (next: CommandBuilder): CommandBuilder | |
// my stupid bash function to show up here. I'm sure it's possible | ||
async function pickPr() { | ||
const listPRs = () => | ||
$`gh pr list -R oxidecomputer/omicron --limit 100 --json number,title,updatedAt,author --template '{{range .}}{{tablerow .number .title .author.name (timeago .updatedAt)}}{{end}}'` | ||
$`gh pr list -R oxidecomputer/omicron --limit 100 | ||
--json number,title,updatedAt,author | ||
--template '{{range .}}{{tablerow .number .title .author.name (timeago .updatedAt)}}{{end}}'` | ||
const picker = () => $`fzf --height 25% --reverse` | ||
const cut = () => $`cut -f1 -d ' '` | ||
|
||
return listPRs().pipe(picker()).pipe(cut()).text() | ||
const prNum = await listPRs().pipe(picker()).pipe(cut()).text() | ||
if (!/^\d+$/.test(prNum)) { | ||
console.error(`Error picking PR. Expected number, got '${prNum}'`) | ||
Deno.exit() | ||
} | ||
return parseInt(prNum, 10) | ||
} | ||
|
||
async function getPrRange(prNum: string) { | ||
const pr = await $`gh api graphql -f query='{ | ||
repository(owner: "oxidecomputer", name: "omicron") { | ||
pullRequest(number: ${prNum}) { | ||
async function getPrRange(prNum: number) { | ||
const query = `{ | ||
repository(owner: "oxidecomputer", name: "omicron") { | ||
pullRequest(number: ${prNum}) { | ||
baseRefOid | ||
headRefOid | ||
} | ||
} | ||
}'`.json() | ||
}` | ||
const pr = await $`gh api graphql -f query=${query}`.json() | ||
const { baseRefOid: base, headRefOid: head } = pr.data.repository.pullRequest | ||
return { base, head } as { base: string; head: string } | ||
} | ||
|
||
async function genForCommit(commit: string) { | ||
async function genForCommit(commit: string, force: boolean) { | ||
const tmpDir = `/tmp/api-diff/${commit}` | ||
await $`rm -rf ${tmpDir}` | ||
await $`mkdir -p ${tmpDir}` | ||
await $`npm run --silent --prefix ../oxide.ts gen-from ${commit} ${tmpDir}` | ||
await $`npx prettier --write --log-level error ${tmpDir}` | ||
const alreadyExists = await exists(tmpDir) | ||
|
||
// if the directory already exists, skip it | ||
if (force || !alreadyExists) { | ||
await $`rm -rf ${tmpDir}` | ||
await $`mkdir -p ${tmpDir}` | ||
await $`npm run --silent --prefix ../oxide.ts gen-from ${commit} ${tmpDir}` | ||
await $`npx prettier --write --log-level error ${tmpDir}` | ||
} | ||
|
||
return tmpDir | ||
} | ||
|
||
|
@@ -60,17 +94,27 @@ async function genForCommit(commit: string) { | |
|
||
if (!$.commandExistsSync('gh')) throw Error('Need gh (GitHub CLI)') | ||
|
||
const prNum = await pickPr() | ||
const args = flags.parse(Deno.args, { | ||
alias: { force: ['f'], h: 'help' }, | ||
boolean: ['force', 'help'], | ||
}) | ||
|
||
if (args.help) { | ||
console.log(HELP) | ||
Deno.exit() | ||
} | ||
|
||
const prNum = args._[0] ? args._[0] : await pickPr() | ||
|
||
if (!/^\d+$/.test(prNum)) { | ||
console.error(`Error picking PR. Expected number, got '${prNum}'`) | ||
if (typeof prNum !== 'number') { | ||
console.error(`PR number must be a number. Got '${prNum}' instead.`) | ||
Deno.exit() | ||
} | ||
|
||
const { base, head } = await getPrRange(prNum) | ||
|
||
const tmpDirBase = await genForCommit(base) | ||
const tmpDirHead = await genForCommit(head) | ||
const tmpDirBase = await genForCommit(base, args.force) | ||
const tmpDirHead = await genForCommit(head, args.force) | ||
|
||
// git difftool is a trick to diff with whatever you have git set to use | ||
await $`git --no-pager difftool ${tmpDirBase}/Api.ts ${tmpDirHead}/Api.ts || true` |