Maintaining Clean Codebase in Django: The Power of pre-commit
What is pre-commit?
Pre-commit hooks check the codebase and best practices and make necessary changes before it gets committed to the version control system. In this article, we will explore the significance of pre-commit in web development, with a specific focus on its importance in Django projects.
These hooks can be customized to perform a variety of tasks, such as code formatting, linting, running tests, and checking for security vulnerabilities.
At the end of this article, I will show my.pre-commit-config.yaml
file for reference.
Importance of the pre-commit in web development.
- Ensuring Code Quality and Consistency
It is so natural that, in the team, each member has own coding style. They may write code with different styles. In this scenario, pre-commit hooks help us to standardize the codebase and uniform code style across the project. This consistency not only makes the code easier to read and maintain but also fosters smoother collaboration among developers.
2. Early Detection of Bugs and Issues
Pre-commit hooks can perform code analysis and static checks to identify potential issues before committing the code. It checks syntax errors, unused imports, commit message syntaxis, and other common mistakes.
3. Integration with Continuous Integration (CI) Pipelines
Pre-commit hooks are an integral part of the continuous integration (CI) pipeline. By integrating pre-commit checks into CI pipelines, the development team ensures that only well-validated and high-quality code reaches production, enhancing the overall reliability of the application.
How to install and use pre-commit?
To install pre-commit
, you need to have Python installed on your system as it is a Python package.
pip install pre-commit
Once the installation is finished, You can check and verify it:
pre-commit --version
If the installation was successfully finished, the above command will show the installed version.
To use pre-commit
in a project, you'll need to set up a .pre-commit-config.yaml
file in the root of your project directory. This configuration file defines the hooks to be used.
To initialize pre-commit
for your project, navigate to the root directory of your project and run the following command:
pre-commit install
This command will set up the necessary hooks based on the configuration defined in the .pre-commit-config.yaml
file. From now every time when you try to make a commit, pre-commit will run based on the .pre-commit-config.yaml
Example .pre-commit-config.yaml
# Exclusion rules for files and directories that should be skipped during hook checks
# Any files or directories under the 'docs/' directory and the top-level '/migrations/' directory will be excluded.
exclude: '^docs/|/migrations/'
# Default stages during which hooks should run
# Hooks will run during the 'commit' stage by default.
default_stages: [commit]
# List of repositories containing pre-commit hooks
repos:
# Ensures commit messages adhere to conventional commit standards.
# The hook runs during the 'commit-msg' stage.
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v2.1.1
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
# Hooks in this repository will run during the 'commit' stage.
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
# Trims trailing whitespace at the end of lines.
- id: end-of-file-fixer
# Adds a missing newline at the end of each file.
- id: check-json
# Validates JSON files for correct syntax and structure.
# Excludes a specific file from JSON validation (in this case, '.devcontainer/devcontainer.json').
exclude: ".devcontainer/devcontainer.json"
- id: check-toml
# Validates TOML files for correct syntax and structure.
- id: check-xml
# Validates XML files for correct syntax and structure.
- id: check-yaml
# Validates YAML files for correct syntax and structure.
- id: debug-statements
# Checks for any remaining debug statements (e.g., print statements) in code.
- id: check-builtin-literals
# Checks for built-in literals (e.g., None, True, False) used as variables.
- id: check-case-conflict
# Checks for file paths with case conflicts (e.g., 'File.txt' and 'file.txt' on case-sensitive filesystems).
- id: check-docstring-first
# Checks that docstrings appear before any other statements in Python code.
- id: detect-private-key
# Scans code for potential private keys that should not be committed.
# Converts relative imports to absolute imports in Python code.
- repo: https://github.com/MarcoGorelli/absolufy-imports
rev: v0.3.1
hooks:
- id: absolufy-imports
# Uses the 'black' code formatter to ensure consistent Python code style.
# Excludes the '.*/migrations/.*' directory to avoid formatting migrations.
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
exclude: .*/migrations/.*
# Sorts import statements in Python code to maintain a consistent order.
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
# Performs static code analysis and checks for Python code style violations.
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
# Uses a Docker container to check Django migrations for correctness and consistency.
# This hook is specific to the project and runs during the 'commit' stage.
- repo: local
hooks:
- id: check-django-migrations
name: Check Django Migrations
entry: docker-compose -f local.yml run --rm django python manage.py makemigrations --dry-run --check
language: system
types: [python]
pass_filenames: false
Conclusion
In conclusion, pre-commit is a powerful tool in the web development process, particularly when working with a team. By enforcing coding standards, catching bugs early, enhancing security, and saving development time, pre-commit contributes significantly to maintaining a clean, reliable, and secure codebase.
Thanks for reading. I hope you enjoyed it ❤. If you found the article useful don’t forget to clap and follow me.
This is my #26/52 story in 2023, I’m on a challenge to write 52 stories in 2023.
Keep Learning..!