Git hooks are scripts that Git runs before or after events such as committing, pushing, and receiving. Pre-commit hooks are incredibly useful for automating code quality checks. For a broad overview of what's possible with git hooks, check out https://githooks.com.

In this article, I'll share the pre-commit hook script that I use in my Elixir projects.

It consists of three steps: validating code formatting, running test and performing Credo checks.

Code formatting

To check the formatting of code in Elixir, I run the command:

mix format --check-formatted

It checks the formatting of all files in the project and shows any formatting errors. If there are errors, the command returns a non-zero code.

Tests

Then I run tests with the mix test task. But I'd like to stop execution of the pre-commit hook as soon as any test fails, so I pass the --max-failures option:

mix test --max-failures=1

Credo

Credo is a helpful tool for finding code style and design issues.

It’s possible to configure different checks via .credo.exs file: docs.
For a basic setup, I’ll just take the default configuration and use the checks with the highest priority: --min-priority=high. I’ll also add a —format=oneline option to reduce the amount of text written to the console:

mix credo suggest --format=oneline --min-priority=high

Result

So, here’s the whole script:

#!/usr/bin/env bash

# exit immediately if any command fails
set -e

# Check code formatting
echo "Checking formatting"
mix format --check-formatted

# Run tests
echo "Running tests"
mix test --max-failures=1

# Run Credo checks
echo "Running credo checks"
mix credo suggest --format=oneline --min-priority=high

Giving a try

To try it yourself you need to create .git/hooks folder if it doesn’t exist yet. Then, place a file called pre-commit inside the folder and fill it with the code provided above.
Make the pre-commit file executable by running

chmod a+x .git/hooks/pre-commit

The final step is to install Credo. Add it to dependencies:

mix.exs
defp deps do [ {:credo, "~> 1.6", only: [:dev, :test], runtime: false} ] end

Download the package:

mix deps.get

That’s it! To check that the hook is working correctly, you can try committing some changes to your Elixir project. The pre-commit hook should run before the commit is finalized, and if any of the checks fail, the commit will be aborted and you will see an error message indicating what went wrong.

If you want to test the pre-commit hook without actually committing any changes, you can run it manually just by executing the script in console: .git/hooks/pre-commit

Sharing

To share the script with other colleagues, you can store it in your repository instead of .git/hooks/pre-commit. For example, you can place it in a pre-commit.sh file at the root of the repo. Then, to enable the hook, one just needs to create a soft link:

ln -s ../../pre-commit.sh .git/hooks/pre-commit

In conclusion, setting up a pre-commit git hook is a simple and effective way to automate certain checks and tasks in your Elixir development workflow. By using a pre-commit hook, you can ensure that your code is always well-formatted, tested, and meets certain standards before it is committed to your repository.