Skip to content

utility for setting up git hooks - a Deno port of husky

License

Notifications You must be signed in to change notification settings

vnphanquang/githooks

Repository files navigation

Utility for setting up git hooks. A Deno port of husky

JSR JSR MIT codecov

Note

This library was written in Deno 2, tested on Windows, MacOS, and Linux. See code coverage for more information.

Usage as CLI

  1. Make sure your project is within a git directory...

    git init .
  2. Run initialization script...

    deno run -A jsr:@vnphanquang/githooks/bin init

    init will search up and run at the nearest git root directory, if any, or fail otherwise. Alternatively, run with verbose permissions at project root:

    deno run --allow-read="." --allow-write=".githooks" --allow-run="git" jsr:@vnphanquang/githooks/bin init
  3. Edit ./githooks/pre-commit to your needs. You can create, edit, or remove any git hook script .githooks/<your_hook>. For example:

    #!/usr/bin/env sh
    deno fmt
    
    # file: .githooks/pre-push
  4. Optionally, add script as Deno task. See Running as Deno Task for more information.

Usage as Library

You may use this library as a Deno module. See jsr:@vnphanquang/githooks.

import { init } from 'jsr:@vnphanquang/githooks';

await init(Deno.cwd());

Changelog

See CHANGELOG for more information.

Recipes

Running as Deno Task

It is helpful to save the script as a Deno task:

{
	"tasks": {
		"githooks": "deno run --allow-read=\".\" --allow-write=\".githooks\" --allow-run=\"git\" jsr:@vnphanquang/githooks/bin init"
	}
}

Subsequent runs can be simplified as:

deno task githooks

Adding Hook

Simply add your git hook script to .githooks/<hook_name>. For example, you can quickly add/update pre-commit by running:

echo "deno test" > .githooks/pre-commit

(No) Automatic Initialization

Unlike Node, Deno does not support pre- or post- script pattern. Prefer to use Deno task and include explicit instruction for your team to run it after each git clone or upgrade.

Usage with lint-staged

Invoke lint-staged in your hook script. For example:

#!/usr/bin/env sh
deno run -A npm:lint-staged

# file: .githooks/pre-commit

As expected, this should look for any lint-staged config files at the project root. See lint-staged configuration documentation for more information.

Skipping Certain Hooks

If your git command supports --no-verify. You may skip running hooks by adding this flag.

git commit --no-verify -m "skip hooks"

Alternatively, you may also set the GITHOOKS env to 0 to skip the running hooks.

# assuming pre-commit hook has been set up at ./.githooks/pre-commit
GITHOOKS=0 git commit -m "skip hooks"

Pre-Hook Setup Script

You may execute some commands before a triggered hook actually runs by having one of the following scripts:

  • on UNIX:
    • $XDG_CONFIG_HOME/githooks/init
    • ~/.config/githooks/init
  • on Windows:
    • C:\Users\<user_name>\.config\githooks\init.sh

For example:

#!/usr/bin/env sh

# run some global setup
echo "This runs before running $GITHOOKS_TRIGGER"

# skip hook that meets certain condition
if [ "$GITHOOKS_TRIGGER" = "pre-push" ]; then
	export GITHOOKS=0
fi

# file: ~/.config/githooks/init

Note

Within the setup script, you have access to the GITHOOKS_TRIGGER env - the name of the hook that is about to run.

Shell Debug Mode

You may set the GITHOOKS env to 2 to enable more verbose output from hook scripts. Underneath, this run set -x.

# assuming pre-commit hook has been set up at ./.githooks/pre-commit
GITHOOKS=2 git commit -m "verbose run"

Prior Arts & Acknowledgements

Comparison vs husky

This project is greatly inspired by husky; it is even fair to consider this as a direct Deno port of huksy . Credits should go to @typicode. Please show support over there. In fact, today, you can use husky directly in Deno:

deno run -A npm:husky

This project builds upon ideas from husky while trying to stay minimal and only extend on some functionality that satisfies my personal needs. It is also an attempt to utilize Deno for more explicit permissions and idiomatic testing (husky uses bash for tests, which is totally fine but simply not my preference).

Regarding performance, jsr:@vnphanquang/githooks is relatively faster compared to npm:husky in the latest benchmarks. You can try the benchmark on your own machine by cloning the project and running:

deno task bench

Important

Benchmarks can be flawed. I encourage you to inspect them at benchmarks/*. Feedback is welcome.

Similar Projects

Other projects with similar objective exists. Please show them some love too.

  • Yakiyo/deno_hooks: also inspired by husky, written in Deno 1; no tests have been implemented as of this writing.
  • xCykrix/githooked: also inspired by husky, originally written in Deno but has likely been migrated away from Deno towards a standalone shell script, which is probably the most lightweight & cross-platform solution.
  • lefthook: a more complex Go-based git hooks manager, definitely worth a look!

Contributing

See CONTRIBUTING for more information.