How to add git hooks for your python projects using the pre-commit framework
转载自 towardsdatascience.com/how-to-add-…
PC: Wikimedia (commons.wikimedia.org/wiki/File:F…)
Why we need git hooks?
As a developer, we need to ensure readability, writability, and reliability of the program we are writing. If we take a git repo multiple contributors write or modify hundreds of lines of codes each day, new contributors come in as few go out. So to make the codebase consistent, we have to follow certain standards. For example certain code formatting styles (black) or linting style (flake8) etc. Usually, these sanity checks take place before submitting (commit) the code for review, also there can be actions that need to be done after submitting, something like maintaining an internal log.
Before deep dive let me tell you what we going to see today,
- What is Git Hooks?
- What is pre-commit framework?
- How to use the pre-commit framework with python projects?
What is Git Hooks?
As I mentioned at the top there are certain actions (tasks) we need to perform when an event happens in the development workflow, which is known as hooks.
Git hooks are scripts that run automatically every time a particular event occurs in a git repository.
For example, running black formatting and flake8 linting before each commit. Literally, we can add hooks at various stages of the git events.
- pre-commit:- run certain hook before commit, if fails abort the commit
- pre-merge-commit:- run certain hook before the merge, if fails abort the merge
- pre-push:- run certain hook before pushing to the remote repo, if fails abort push
- post-commit:- hook to be run immediately after a successful commit
- post-checkout:- hook to be run immediately after checkout from one branch
- post-merge:- hook to be run immediately after a successful merge
- etc
When we do git initit adds the most commonly used git hooks into .git/hooks/, we can write our own hooks using the most commonly used scripting languages. But today we going to see about a framework designed to ease this process.
What is pre-commit framework?
It is a framework for managing and maintaining multi-language git hooks. You may have a question, why do we need a framework for hooks.
As we create more libraries and projects we might find that sharing our pre-commit hooks across projects is painful. We have to copy and paste unwieldy bash scripts from project to project and had to manually change the hooks to work for different project structures. And also sometimes some good linters or other testing tools we need, might be not written in the same language we using for our project.
Pre-commit is a multi-language package manager for pre-commit hooks. We can simply specify the list of hooks we want and pre-commit manages the installation and execution of any hook written in any language without any root permission.
How to use the pre-commit framework with python projects?
- Install pre-commit framework
pip install pre-commit
or
conda install -c conda-forge pre-commit
Add .pre-commit-config.yaml to your project’s root folder. In this example, I am going to show how to add black formatting and flake8 linting for each commit and push.
default_stages: [commit, push]
default_language_version:
python: python3.8
repos:
- repo: https://github.com/psf/black
rev: 21.8b0
hooks:
- id: black
args: [
--line-length=80,
--target-version=py38
]
exclude: ^(venv/|docs/)
types: ['python']
- repo: https://github.com/PyCQA/flake8
rev: 3.8.2
hooks:
- id: flake8
args: [
--max-line-length=80
]
exclude: ^(venv/|docs/)
types: ['python']
let us break down each component here,
- default_stages:- a configuration-wide default for the stages property of hooks. This will only override individual hooks that do not set stages.
- default_language_version:- default language version that should be used if language_version is not set for individual hooks.
- repos:- list of repository mappings
- repo:- the repository URL to git clone, the code for the hook will be taken from here.
- rev:- which version of repo needs to be used (tag)
- hooks:- A list of hook mappings, hook mapping lets the user select which hook needs to be used from the repo and allows customizations.
- id: hook name from the repo.
- args: command-line arguments need to be passed for that hook.
- exclude:- regex for file/folder names to be excluded for that hook.
- types:- file types to be considered for that hook.
There are many more components, to customize the hooks.
- After adding the config file, run the below command to install hooks
pre-commit install --hook-type pre-commit hook-type pre-post
this will install the hooks that should be run before commits and push.
- Modify any of the files in your project and try to commit them
Failed pre-commit (PC: Author)
here my hooks have failed due to some code reformatting and lint errors. Note, if any of the hooks failed then the commit will be aborted. Fix the issue and re-commit.
Successful pre-push (PC: Author)
Successful pre-commit (PC: Author)
This will be the same if you have configured any pre-push hooks.
You can find the complete source code here, github.com/Mathanraj-S…
In conclusion, git hooks is simply any script that we wish to trigger during the occurrence of a git event. It helps use to automate the repetitive workload to maintain the consistency of the code being written. It may not seem effective at the early stage, but as the projects grows and more contributors comes in we can feel the benefits of git hooks.
Happy Coding!!!