Python and Git. Automatically Checking Code for Specification Compliance

Many teams do Code Review, others focus more on Design Review, and many do neither at all. But this article is not about why these are necessary; it is about how to partially automate the Code Review process. For my own projects, I decided to save a little time and human effort by using automated checks of project code for compliance with PEP 8, as well as checks of code quality (pyflakes) and message quality in Git. A full Code Review is still necessary, but there will be less to review, and sometimes it can even be skipped altogether.
So, to get this working, we need to install pep8 and pyflakes, and edit the Git hooks on developers’ workstations: “pre-commit” and “commit-msg”.
Server-side hooks are deliberately not used, because the commit will already have been made and the developer will have to roll it back, and so on, which does not save the developer any time at all.
Installation
Install the dependencies:
sudo apt-get install pyflakes pep8
Install the hooks:
cd ~/work
git clone git://github.com/adw0rd/pre-code-review.git pre-code-review
ln -s /home/<username>/work/pre-code-review/pre-commit.py /home/<username>/work/<project>/.git/hooks/pre-commit
ln -s /home/<username>/work/pre-code-review/commit-msg.py /home/<username>/work/<project>/.git/hooks/commit-msg
chmod +x /home/<username>/work/<project>/.git/hooks/pre-commit
chmod +x /home/<username>/work/<project>/.git/hooks/commit-msg
The code for the “pre-commit.py” hook was borrowed from here and subsequently modified. There were plans to add docstring checks in the future (the percentage of documentation relative to code, or some other metrics), along with running tests (though that is questionable, as it would affect commit performance).
For resource-intensive operations such as tests, there is a handy tool: Continuous Integration (CI), with options such as Hudson, Jenkins (django-jenkins), CruiseControl, and Atlassian Bamboo. I also recommend taking a look at the Code Review product Atlassian Crucible.
Examples
An example of checking code:
$ git commit -m "Something I"
*********************************
***** CODE REVIEW IS FAILED *****
*********************************
Check files: <project>/<app>/views.py, <project>/common/context_processors.py, <project>/common/decorators.py,
<project>/settings.py, <project>/<app>/models.py, <project>/urls.py
pep8:
./<project>/urls.py:14:19: E241 multiple spaces after ','
./<project>/<app>/models.py:18:1: E302 expected 2 blank lines, found 1
pyflakes:
./<project>/urls.py:3: 'include' imported but unused
./<project>/urls.py:4: undefined name 'User'
The “pre-commit” hook checks only staged changes (so after each fix, you will have to run git-add). To check the entire index at once, use “–debug”:
$ .git/hooks/pre-commit --debug
An example of checking a commit message:
$ git commit -m "Something II"
**********************************
***** CHECK COMMIT IS FAILED *****
**********************************
> check_task_tracking_identificator:
>> Wrong Issue ID! Use format: [{project_id}-{issue_number}], example: [PROJ-1027]
If you add the “–no-verify” option to the git-commit command, you can skip the hook checks.
-n, --no-verify
This option bypasses the pre-commit and commit-msg hooks. See also githooks(5).
This kind of checking improves the quality of code entering the repository, leaves fewer pitfalls in the code for developers to stumble over, and so on. All in all, this is the bare minimum needed to improve the quality of your project.
Comments are closed. Read the original discussion in Russian →