How to set-up pre-commit hooks on a project¶
We add pre-commit hooks in order to run various linting and auto-formatting tools over the source before they are committed and pushed to GitLab. This how-to guide covers how to add pre-commit hooks to an existing project.
Standard hooks to add to all projects¶
Info
If you are using one of our boilerplates, an appropriate set of hooks will already be present.
Add the following hooks to all projects, by placing them in .pre-commit-config.yaml
at the root
of the project:
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
args:
- --unsafe
- id: check-json
- id: check-toml
- id: check-xml
- id: check-added-large-files
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-symlinks
- id: detect-private-key
- id: mixed-line-ending
- id: pretty-format-json
args:
- --autofix
- --no-sort-keys
- id: debug-statements
- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.14.0
hooks:
- id: markdownlint-cli2
args: ["--fix"]
language_version: 22.10.0
Warning
As the rev
parameter above is hard-coded, you should also
set-up renovatebot to keep this and your project's other
dependencies up-to-date.
Installing pre-commit hooks¶
After adding a .pre-commit-config.yaml
or modifying it, the following should be run in order to
set-up the hooks:
pre-commit install
Testing pre-commit hooks¶
Normally, pre-commit will run against files which are staged to be committed. To test the hooks separately from a git commit against all files in your repository, for instance if to re-format all existing source code to conform to a relevant style guide, run:
pre-commit run --all-files
Language-specific hooks¶
Additionally, hooks should be added to process the particular source code languages contained in the project:
Python¶
The following pre-commit plugins should be added for Python projects (replacing the rev parameters with latest releases of the plugins):
- repo: https://github.com/python-poetry/poetry
rev: 1.5.1
hooks:
- id: poetry-check
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.7.2
hooks:
- id: editorconfig-checker
args: ["-disable-indent-size"]
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/timothycrosley/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
- id: mypy
additional_dependencies: [types-requests, types-oauthlib]
args: [--explicit-package-bases]
Java¶
To ensure your Java source is formatted consistently, use the
google-java-format
pre-commit hook by adding the following to your
.pre-commit-config.yaml
in the root of your project(s):
- repo: https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/precommit-google-java-format
rev: v1.2.0
hooks:
- id: google-java-format
files: "\\.java$"
args: ["-i"]
This plugin formats your code to match the
Google Java Style Guide on git commit
.
If your code already meets the required code format the plugin will pass and allow your commit to
continue. If your code requires formatting it will format the code automatically for you but fail
pre-commit. This allows you to review the changes and commit any updates to continue.
To run locally, the current v1.2.0
version of the pre-commit formatter requires Java 11 in your
path.
Warning
Minor differences in Java source formatting have been seen when running the
google-java-format
pre-commit hook locally with Java versions > 11 compared to the results
when the hook runs as part of a GitLab pipeline (which is currently running the formatter with
Java 11). To avoid inconsistencies it is recommended that you must run the formatter with
Java 11 in your path.
If your Java project requires a different version of Java to compile, you can use sdkman to easily switch between different versions at your command line.
Configuring Git to ignore bulk formatting commits¶
Adding the
google-java-format
pre-commit hook to an existing project can result in formatting a large number of files. If you
use git blame
to show changes from previous commits, a single commit with a large number of
formatting changes can reduce the usefulness. To avoid this issue, commit a file in the root of
your project called .git-blame-ignore-revs
(or similar) and add to it a list of the commit
SHAs to ignore. To configure git to ignore these commits, use:
git config blame.ignoreRevsFile .git-blame-ignore-revs
Summary¶
In this how-to you learned how to set-up a standard set of pre-commit hooks on a project.
Further information on using pre-commit: