Last active
June 10, 2023 01:51
-
-
Save kawarimidoll/91ed1caeb86213aea77fae2254521258 to your computer and use it in GitHub Desktop.
setup deno_hooks from deno.json
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
// Usage: | |
// 1. Create a deno.json(c) file in the root of your project | |
// 2. Add hook scripts in "tasks" key like: | |
// { | |
// "tasks": { | |
// "pre-commit": "deno fmt", | |
// "pre-push": "deno test" | |
// }, | |
// "hooks_dir": ".my-hooks" // optional, default: ".hooks" | |
// } | |
// 3. Run `deno run --allow-read --allow-run ./setup-deno-hooks.ts` | |
// Thank you for https://github.com/Yakiyo/deno_hooks | |
import { exists } from "https://deno.land/std/fs/exists.ts"; | |
import { parse } from "https://deno.land/std/jsonc/parse.ts"; | |
import { join } from "https://deno.land/std/path/mod.ts"; | |
const KNOWN_HOOKS = [ | |
"applypatch-msg", | |
"commit-msg", | |
"post-applypatch", | |
"post-checkout", | |
"post-commit", | |
"post-merge", | |
"post-rewrite", | |
"post-update", | |
"pre-applypatch", | |
"pre-commit", | |
"pre-merge-commit", | |
"pre-push", | |
"pre-rebase", | |
"prepare-commit-msg", | |
"push-to-checkout", | |
]; | |
// type guard | |
type DenoJson = { | |
tasks: Record<string, string>; | |
hooks_dir?: string; | |
[key: string]: unknown; | |
}; | |
const isDenoJson = (json: unknown): json is DenoJson => | |
!!json && typeof json === "object" && Object.hasOwn(json, "tasks"); | |
// load deno.json(c) | |
const filename = await exists("./deno.jsonc") | |
? "deno.jsonc" | |
: await exists("./deno.json") | |
? "deno.json" | |
: ""; | |
if (!filename) { | |
throw new Error("No deno configuration file found"); | |
} | |
// parse deno.json(c) | |
const json = parse(await Deno.readTextFile(filename)); | |
if (!isDenoJson(json)) { | |
throw new Error(`'${filename}' must be a valid json file with 'tasks' key`); | |
} | |
const hooks_dir = json.hooks_dir || ".hooks"; | |
// convert hooks to array of commands | |
const hooks = Object.entries(json.tasks) | |
.filter(([hook]) => KNOWN_HOOKS.includes(hook)) | |
.map(([hook, script]) => ["add", join(hooks_dir, hook), script]); | |
hooks.unshift(["install", hooks_dir]); | |
// remove .hooks directory (for idempotency) | |
await (new Deno.Command("rm", { args: ["-rf", hooks_dir] })).output(); | |
// define deno command variables | |
const cmd = "deno"; | |
const baseArgs = [ | |
"run", | |
"--allow-read", | |
"--allow-run", | |
"--allow-write", | |
"https://deno.land/x/deno_hooks/mod.ts", | |
]; | |
const decoder = new TextDecoder(); | |
// setup hooks | |
for await (const hook of hooks) { | |
console.log(">", hook.join(" ")); | |
const command = new Deno.Command(cmd, { args: [...baseArgs, ...hook] }); | |
const { code, stdout, stderr } = await command.output(); | |
if (code === 0) { | |
console.info(decoder.decode(stdout)); | |
} else { | |
console.error(decoder.decode(stderr)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment