A tiny crate to make it easy to share and apply Git hooks for Rust projects. Inspired by Husky.
- Zero dependencies.
- No magic, uses Git's
config core.hooksPathto set a custom hooks path. Use native/regular shell scripts for git hooks. - Makes use of Cargo's build script.
- IDE/Code editor agnostic.
- Customizable setup.
Sloughi is an ancient breed of domesticated dog originating from North Africa (i.e. Algeria, where I live 👋).
-
Add sloughi to your
build-dependencies(notdev-dependencies):[build-dependencies] sloughi = "0.3.0"
-
Create a
build.rsfile at the root of your project to install Sloughi (besidesCargo.toml, not insidesrc/):use sloughi::Sloughi; fn main() { let _ = Sloughi::new().install(); // This will fail silently. Won't interrupt the build. }
That's it!
The next time cargo build is triggered (by VSCode, or by running cargo run/cargo test), you will notice a .sloughi folder is created with a sample pre-commit hook inside.
This crate uses the builder pattern, you can chain options on top ::new() to adjust the install:
let _ = Sloughi::new()
.custom_path(".git_hooks"). // Choose a custom Git hooks relative path (default is ".sloughi")
.ignore_env("CI"). // Ignore setup when `CI` environment variable is set (like in CircleCI ..etc)
.ignore_env("GITHUB_ACTIONS") // Do not run in Github Actions as well
.install();The above snippets for build.rs will not interrupt the build in case Sloughi install failed (e.g. not a git repo, permission error ..etc). It's explicitly silenced with let _ =, you can handle the error however you like, or just yell with:
Sloughi::new().install().expect("Sloughi install failed");Cargo lacks install hooks (like postinstall in npm's package.json), this makes it challenging to have a way to share git hooks automatically in a upstream repository.
Cargo's build script is a nice & transparent way to:
- Act on the project at build/compile time.
- Customize the setup without extra config files and formats.
The install() call is idempotent. It won't modify the existing setup and hooks.
No:
build.rsitself is only built when it's changed (by default).- The setup will first check if you already have
.sloughi(or the custom path) created. If so, it skips installs.
No, release mode is a no-op.
- Optional feature flags. I.e. conventional commits as pre-commit, rustfmt as pre-commit.
- A [optiona] companion binary to manage hooks.
- Check Cargo workspaces compatiblity.
- Introduce the
uninstall()call to the exportedSloughistruct. - Integration tests.
