Skip to content

Conversation

@rakazirut
Copy link
Member

@rakazirut rakazirut commented Sep 2, 2025

What's changing?

Enhanced pre-commit hooks configuration with comprehensive security and code quality tools

Added extensive pre-commit hook setup including secret detection, import sorting, static analysis, security scanning, and documentation validation. Created 5 new configuration files to support Django development best practices.

Why?

Issue #32 - Need robust pre-commit hooks to enforce code quality, security standards, and prevent sensitive data leaks before commits reach the repository. This implements a multi-layered approach to code validation.

How to test

  • Run pre-commit run --all-files to validate all existing code

  • Make a test commit with intentional issues (debug statements, secrets, import disorder)

  • Verify hooks catch and fix/block problematic code

  • Test Django-specific linting on templates and models

  • Confirm migrations and static files are properly excluded


Checklist

  • Tests pass locally (hooks run successfully)

  • No breaking changes (additive configuration only)

  • Ready for production

Notes for reviewer

Key additions:

  • Secret Detection: detect-secrets with baseline to catch API keys, passwords, tokens

  • Import Management: isort with Django profile for PEP8 compliance

  • Static Analysis: mypy, bandit, flake8, vulture for comprehensive code quality

  • Django-Specific: django-upgrade, djlint for framework best practices

  • Documentation: mdformat, pydocstyle for README and docstring validation

Files Created:

  • .pre-commit-config.yaml - Main configuration (135 lines added)

  • mypy.ini - Type checking config with Django stubs

  • .secrets.baseline - Secret detection baseline

  • .djlintrc - Django template linting rules

  • vulture_allowlist.py - Dead code detection allowlist

Exclusions: Properly excludes Django migrations, static files, media, and virtual environments to avoid false positives.

Summary by CodeRabbit

  • Chores
    • Introduced comprehensive pre-commit setup for formatting, linting, type checking, and security scanning.
    • Added DJLint configuration for consistent Django template formatting.
    • Added strict mypy configuration with Django plugin to improve type safety.
    • Updated Ruff settings to exclude common generated and environment paths.
    • Added detect-secrets baseline to prevent accidental secret leaks.
    • Included a Vulture allowlist to reduce false positives in dead-code detection.
    • No runtime or user-facing behavior changes.

@rakazirut rakazirut requested a review from slandath September 2, 2025 13:32
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 2, 2025

Walkthrough

Introduces repository-wide developer tooling and static analysis configuration: a comprehensive pre-commit setup with multiple hooks, a detect-secrets baseline, DJLint, Ruff, and MyPy configs, plus a Vulture allowlist module. No runtime code changes; all updates are configuration and analysis-oriented.

Changes

Cohort / File(s) Summary of Changes
Pre-commit and secrets scanning
./.pre-commit-config.yaml, ./.secrets.baseline
Adds extensive pre-commit hooks (formatting, linting, security, typing, Django tooling) with global excludes and per-hook settings; includes detect-secrets configuration referencing a new baseline (v1.4.0) with detectors and filters, initially empty results.
Static analysis and lint configs
./.djlintrc, ./mypy.ini, ./pyproject.toml
Adds DJLint settings for Django templates (formatting, rules, HTML targeting); introduces strict MyPy config with Django plugin and selective ignores; configures Ruff exclusions in pyproject for specific paths.
Vulture allowlist module
./vulture_allowlist.py
Adds a module listing Django-related symbols to prevent Vulture false positives for dynamically accessed components.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch commitHooks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (9)
.djlintrc (1)

1-17: Confirm close_void_tags with your HTML toolchain.

close_void_tags=true will self-close void elements (
, , etc.). That can conflict with some formatters or linters if they enforce HTML5-style void tags without trailing slashes. If you use other HTML tooling (Prettier, etc.), align settings to avoid ping-pong diffs.

mypy.ini (1)

1-16: Enable warn_unused_configs to catch typos in mypy.ini.

This helps surface mis-typed section names/keys early, especially with multiple plugin sections.

 [mypy]
 python_version = 3.13
+warn_unused_configs = true
 check_untyped_defs = true
 disallow_any_generics = true
 disallow_untyped_calls = true
vulture_allowlist.py (1)

1-47: Expand allowlist with common Django patterns that often false-positive.

These are frequent Vulture hits in Django apps (model Meta options, admin hooks, CBV/admin overrides). Keeping them here reduces churn.

 # Django views
 _.get_context_data  # Django class-based view method
 _.get_queryset  # Django class-based view method
 _.get_object  # Django class-based view method
+
+# Django model Meta/options and conveniences
+_.Meta  # Django model inner Meta class
+_.verbose_name
+_.verbose_name_plural
+_.ordering
+_.db_table
+_.get_absolute_url
+
+# Django admin/customizations
+_.save_model
+_.get_form
+_.get_readonly_fields
+_.get_urls
+
+# App configuration
+_.ready
.pre-commit-config.yaml (6)

1-11: Global excludes look solid; consider a couple more noisy dirs.
Add build/dist/coverage caches if present to avoid unnecessary scans.

   (?x)^(
     .*/migrations/.*|
     .*/static/.*|
     .*/media/.*|
     .*/node_modules/.*|
     .*/venv/.*|
     .*/\.venv/.*|
+    .*/dist/.*|
+    .*/build/.*|
+    .*/coverage/.*|
     .*\.min\.(js|css)$|
     vulture_allowlist\.py$
   )$

30-43: Enable all detect-secrets plugins for better coverage.
Baseline is good; enabling all plugins catches more patterns by default.

-      - id: detect-secrets
-        args: ['--baseline', '.secrets.baseline']
+      - id: detect-secrets
+        args: ['--baseline', '.secrets.baseline', '--use-all-plugins']

69-83: Make Bandit output readable in pre-commit.
JSON is hard to consume in local runs; default text suits hooks better.

-        args: ['-r', '.', '-f', 'json', '--skip', 'B101,B601']
+        args: ['-r', '.', '--skip', 'B101,B601']

98-110: Ruff already covers these Flake8 plugins; consider removing Flake8 to cut runtime.
Ruff implements B, C4, DJ, PIE, SIM rules; running both duplicates work.

-  # Code complexity and quality
-  - repo: https://github.com/PyCQA/flake8
-    rev: 6.1.0
-    hooks:
-      - id: flake8
-        additional_dependencies:
-          - flake8-bugbear
-          - flake8-comprehensions
-          - flake8-django
-          - flake8-pie
-          - flake8-simplify
-        args: [--max-complexity=10, --max-line-length=88, --extend-ignore, E203,W503]

If you keep Flake8, disable overlapping Ruff rules to avoid double-reporting.

Also applies to: 51-60


127-135: Avoid formatter conflicts (mdformat-black vs ruff-format/Black style).
mdformat-black formats Python code blocks with Black; ensure your ruff/formatter config matches Black’s 88 wrap to prevent churn, or drop mdformat-black.

       - id: mdformat
         additional_dependencies:
           - mdformat-gfm
-          - mdformat-black
         args: [--wrap=100]

Also applies to: 51-60


61-68: In .pre-commit-config.yaml (lines 61–68): bump mypy to v1.17.1 and trim deps

  • Change rev to v1.17.1.
  • Replace additional_dependencies: [django-stubs, types-requests, psycopg2-binary] with [django-stubs, django-stubs-ext, types-requests].
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1f1a8c1 and 2b16eb9.

📒 Files selected for processing (6)
  • .djlintrc (1 hunks)
  • .pre-commit-config.yaml (1 hunks)
  • .secrets.baseline (1 hunks)
  • mypy.ini (1 hunks)
  • pyproject.toml (1 hunks)
  • vulture_allowlist.py (1 hunks)
🔇 Additional comments (3)
.secrets.baseline (1)

1-112: No changes needed; detect-secrets hook is already pinned to v1.4.0

.pre-commit-config.yaml (2)

13-29: Nice baseline of core checks.
These hooks catch common issues early; no changes needed.


52-60: Revert hook id change. The correct hook ids are ruff-check and ruff-format, and rev: v0.12.1 is a valid tag; no changes needed. Optionally bump to v0.12.10 to align with the latest examples.

Comment on lines +84 to +90
# Django-specific checks
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.15.0
hooks:
- id: django-upgrade
args: [--target-version, "5.0"]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Confirm Django target before auto-upgrading.
Ensure the project targets Django 5.0; adjust if running 4.x or 5.1+.


🏁 Script executed:

#!/bin/bash
# Grep common dep files for Django version to validate django-upgrade target.
rg -nP '(?i)django[>=<~]*\s*[\d.]+' -g 'requirements*.txt' -g 'Pipfile' -g 'pyproject.toml' -n -C1 || true

Length of output: 215


Set django-upgrade target-version to 5.2
pyproject.toml declares Django>=5.2.3, so update the hook in .pre-commit-config.yaml (lines 84–90) to args: [--target-version, "5.2"].

🤖 Prompt for AI Agents
.pre-commit-config.yaml around lines 84 to 90: the django-upgrade hook is
configured with --target-version "5.0" but pyproject.toml requires
Django>=5.2.3; update the hook args to use --target-version "5.2" so the
pre-commit check matches the declared Django version.

Comment on lines +111 to +117
# Dead code detection
- repo: https://github.com/jendrikseipp/vulture
rev: v2.10
hooks:
- id: vulture
args: [--min-confidence, '80', --sort-by-size, vulture_allowlist.py]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Vulture allowlist not applied due to argument position.
Pre-commit appends filenames after args, so the allowlist won’t be last and will be ignored. Scan the repo and place the allowlist last.

   - repo: https://github.com/jendrikseipp/vulture
     rev: v2.10
     hooks:
       - id: vulture
-        args: [--min-confidence, '80', --sort-by-size, vulture_allowlist.py]
+        pass_filenames: false
+        args: [--min-confidence, '80', --sort-by-size, '.', 'vulture_allowlist.py']
🤖 Prompt for AI Agents
In .pre-commit-config.yaml around lines 111 to 117, the vulture hook's args
place the allowlist before filenames so it's ignored; reorder the args so the
allowlist filename (vulture_allowlist.py) is the final argument in the args
array (after --min-confidence and --sort-by-size) so pre-commit appends
filenames after it and the allowlist is applied.

Comment on lines +13 to +19
[tool.ruff]
exclude = [
"vulture_allowlist.py",
"migrations",
".venv",
"venv",
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use extend-exclude to preserve Ruff’s defaults.

Setting exclude resets Ruff’s built-in ignores (.git, pycache, node_modules, etc.), which can slow linting and create noise. Prefer extend-exclude so you keep defaults and only add project-specific paths.

-[tool.ruff]
-exclude = [
+[tool.ruff]
+extend-exclude = [
     "vulture_allowlist.py",
     "migrations",
     ".venv",
     "venv",
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[tool.ruff]
exclude = [
"vulture_allowlist.py",
"migrations",
".venv",
"venv",
]
[tool.ruff]
extend-exclude = [
"vulture_allowlist.py",
"migrations",
".venv",
"venv",
]
🤖 Prompt for AI Agents
In pyproject.toml around lines 13 to 19, replace the [tool.ruff] exclude = [...]
table with extend-exclude = [...] (keeping the same list entries) so Ruff’s
built-in ignores are preserved; update the key name only and leave the array
contents and formatting intact.

@rakazirut rakazirut merged commit 1013bdc into main Sep 2, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants