pre-commit: Block files based on name with a custom “fail” hook

Make sure your team mates hit the target!

This post is an adapted extract from my book Boost Your Django DX, as updated last week.

pre-commit’s “fail” virtual language fails all files that it matches. Combine it with pre-commit’s file name and type matching to block unwanted files in your repository.

Let’s try it out with an example from working with Django’s fixtures system. Imagine you’ve recently transitioned your project from JSON to YAML fixtures because you prefer YAML’s readability. After converting all of your existing fixtures, you’re concerned that JSON fixtures may still get added in the future, complicating ongoing maintenance.

You can prevent non-YAML fixtures from being added with a “fail” hook. Define such a hook in your .pre-commit-config.yaml as below.

repos:
-   repo: local
    hooks:
    -   id: check-fixture-types
        name: Check fixture types
        language: fail
        entry: Please convert non-YAML fixtures to YAML.
        files: /fixtures/
        exclude_types: [yaml]

Let’s take apart the hook definition.

The first thing to note is that the hook appears under a repo: local declaration. This special repository location indicates that the hooks are defined in this repository rather than another.

Several keys then define the hook:

After adding a hook, you need to stage your configuration:

$ git add .pre-commit-config.yaml

You can then test the hook against a known bad file:

$ pre-commit run --files example/fixtures/books.json
Check fixture types......................................................Failed
- hook id: check-fixture-types
- exit code: 1

Please convert non-YAML fixtures to YAML.

example/fixtures/books.json

The failure message lists the matched files.

Before you commit a new hook, you should check that all files pass:

$ pre-commit run check-fixture-types --all-files

Check fixture types......................................................Passed

All looks in order - commit as usual:

$ git commit -m "Add pre-commit hook to block non-YAML fixtures"
Check fixture types..................................(no files to check)Skipped
[main 13d1507] Add pre-commit hook to block non-YAML fixtures
 1 file changed, 8 insertions(+)

Such “fail” hooks are ideal for blocking unwanted files, matching based on file name and type. But you can also prevent files from being committed with Git’s .gitignore file. In general:

Fin

May you have great success with “fail”,

—Adam


Learn more about pre-commit in my Git DX book.


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: ,