Hooked 🪝

# Hooked.toml
[[pre_commit]]
name = "Cargo Check"
command = "cargo check"
# Install Hooked to ".git/hooks".
$ hooked install

# Commit away!
$ git commit -m 'Start using Hooked!'
Hooked: Running 1 pre-commit hook.
	✓ Cargo Check
[main b386e59] Start using Hooked!
 1 file changed, 3 insertions(+)
 create mode 100644 Hooked.toml

Hooked is a manager for Git hooks. It is language-agnostic (not built for any specific language or ecosystem), has a low barrier to entry (hooks can be one-liners in a configuration file) and is extensible (most of what Hooked does can be replaced through its configuration).

If you've been convinced and would like to give it a shot, Getting Started is the place to be.

Getting Started

To see the available ways to install Hooked, see the Installation chapter.

The basics of making hooks is explained in Creating Hooks.

And if you already have a configuration set up, head to the Git side of things chapter.

Installation

Cargo

With Rust and Cargo installed, Hooked can be installed from Crates.io.

cargo install hooked-cli

Binaries

Precompiled x86_64-unknown-linux-gnu binaries are available on the Releases page.

Debian & Derivatives

An amd64 .deb file is available on the Releases page.

# Don't forget to change <version>.
dpkg --install hooked-cli_<version>_amd64.deb

Creating hooks

All of Hooked's configuration is done inside the Hooked.toml file. It should be placed inside the same directory your .git directory is.

your-awesome-project
├── Hooked.toml      <- !
├── .git             <- !
│   └── ...
├── source
│   └── ...
└── ...

Inside Hooked.toml, hooks are defined as arrays of tables with a name (optional but highly encouraged) and either a command or script.

A simple pre-commit hook is defined like the following:

[[pre_commit]]
name = "Hook name, optional but highly encouraged"
command = "echo \"Hey, $USER!\""

To test that this works, use the run CLI command and you should see something like this.

$ hooked run pre-commit
Hooked: Running 1 pre-commit hook.
	✓ Hook name, optional but highly encouraged

To see what happens when a command fails, append && exit 1 to your configured command and run it again.

If you want to run a script, create a hooks directory and place your script there. Then in your configuration file use the "script" field for your hook. Make sure that your script is executable!

[[pre_commit]]
name = "Hook name, optional but highly encouraged"
command = "cargo test"
+
+ [[pre_commit]]
+ name = "A script hook"
+ script = "run-tests.sh"

Defining both a command and a script for a hook will make only the command run.

The directory Hooked looks in can be configured via the general.directory field, should you wish to change it.

+ [general]
+ # Use the same directory where Hooked.toml is.
+ directory = "."
+
[[pre_commit]]
name = "Hook name, optional but highly encouraged"
command = "echo \"Hey, $USER!\""

[[pre_commit]]
name = "A script hook"
script = "run-tests.sh"

For a full list of everything you can configure in Hooked.toml see the Configuration Reference. And for the CLI there is the CLI Reference.

Those are the basics of creating hooks! Now to make Git use these hooks continue on to the next chapter.

The Git side of things

In the previous chapter you manually tested hooks using the CLI run command. Now to install those hooks and have Git use them, we'll use the CLI install command.

hooked install

What this command does is create the scripts inside the .git/hooks directory that Git will run whenever you do Git stuffs. By default, these scripts are a simple call to the CLI run command.

So unless you change anything in the hook templates, you only need to run this once, as it will read your current configuration any time those scripts get called.

Uninstalling hooks

If at any point you want to remove the scripts from your .git/hooks directory, use the CLI uninstall command.

hooked uninstall

Configuration Reference

Below you can find tables describing all the possible configuration you can do, as well as TOML examples below those tables showing what that configuration would look like.

General

The general table is for main Hooked configuration.

KeyTypeDefaultDescription
configStringHooked.tomlThe configuration file to use. If your configuration file isn't Hooked.toml you should set this accordingly.
directoryStringhooksThe directory Hooked looks in for anything related to files. For example: scripts, templates, etc.
templateOptional stringPath to a custom template to be used when installing scripts. See the install CLI command for more details.
[general]
config = "Hooked.toml"
directory = "hooks"
template = "template.sh"

Pre-commit

Pre-commit hooks are defined using pre_commit arrays of tables.

KeyTypeDefaultDescription
nameStringUnnamed HookThe name of the hook, useful for figuring out which hook failed after it ran.
command1StringA command to run when the hook is called.
script1StringA script to run when the hook is called. This script should be executable and be located inside the configured general directory.
on_failureStringstopWhat to do when the hook task returns a non-zero status code. Can be either "continue" or "stop".
[[pre_commit]]
name = "Command Example"
command = "echo \"Hey, $USER!\""

[[pre_commit]]
name = "Script Example"
script = "example.sh"
on_failure = "continue"

Footnotes

1

When both a command and script are defined in a hook, only the command will be run.

CLI Reference

In the following chapters you will find the reference to all of Hooked's CLI subcommands.

Global Options

These options can be used in all commands.

OptionDefaultDescription
-c, --configHooked.tomlPath to a Hooked configuration.
-h, --helpPrint help information.
-V, --versionPrint version information.

Other

Hooked checks for the NO_COLOR environment variable and will disable styling output if present.

Install

The install command creates the scripts inside .git/hooks.

$ hooked install --help
Install Hooked into ".git/hooks"

Usage: hooked install [OPTIONS]

Options:
      --overwrite        Overwrite existing files
  -c, --config <CONFIG>  Path to a Hooked configuration [default: Hooked.toml]
  -h, --help             Print help information
  -V, --version          Print version information

Below is the default script template that Hooked uses, where hook_type is the type of hook to run (like pre-commit) and config_path is the general.config field from the parsed configuration.

#!/usr/bin/env bash

# Installed by Hooked.

hooked run {{ hook_type }} --config {{ config_path }}

You can provide your own template by using the general.template configuration setting. If you do, make sure you include a line somewhere that says # Installed by Hooked. for the uninstall CLI command.

Run

The run command manually runs configured hooks.

$ hooked run --help
Manually run hooks

Usage: hooked run [OPTIONS] <HOOK_TYPE>

Arguments:
  <HOOK_TYPE>  The hook type to run [possible values: pre-commit]

Options:
  -c, --config <CONFIG>  Path to a Hooked configuration [default: Hooked.toml]
  -h, --help             Print help information
  -V, --version          Print version information

Uninstall

The uninstall command removes script files inside .git/hooks.

$ hooked uninstall --help
Remove installed hooks

Usage: hooked uninstall [OPTIONS]

Options:
      --all              Remove hooks not installed by Hooked
  -c, --config <CONFIG>  Path to a Hooked configuration [default: Hooked.toml]
  -h, --help             Print help information
  -V, --version          Print version information

By default Hooked will only remove scripts that have a # Installed by Hooked. line in them, using --all however will remove all script files.

Changelog

0.1.0 (2022-11-03)

  • First Hooked version!