Skip to content

Comments

[tooling] Add pre-commit hooks using LeftHook#265

Open
jovnc wants to merge 1 commit intogit-mastery:mainfrom
jovnc:feat/left-hook
Open

[tooling] Add pre-commit hooks using LeftHook#265
jovnc wants to merge 1 commit intogit-mastery:mainfrom
jovnc:feat/left-hook

Conversation

@jovnc
Copy link
Collaborator

@jovnc jovnc commented Feb 17, 2026

@jovnc jovnc requested a review from Copilot February 17, 2026 13:59
@github-actions
Copy link

Hi @jovnc, thank you for your contribution! 🎉

This PR comes from your fork jovnc/exercises on branch feat/left-hook.

Before you request for a review, please ensure that you have tested your changes locally!

Important

The previously recommended way of using ./test-download.py is no longer the best way to test your changes locally.

Please read the following instructions for the latest instructions.

Prerequisites

Ensure that you have the gitmastery app installed locally (instructions)

Testing steps

If you already have a local Git-Mastery root to test, you can skip the following step.

Create a Git-Mastery root locally:

gitmastery setup

Navigate into the Git-Mastery root (defaults to gitmastery-exercises/):

cd gitmastery-exercises/

Edit the .gitmastery.json configuration file. You need to set the following values under the exercises_source key.

{
    # other fields...
    "exercises_source": {
        "username": "jovnc",
        "repository": "exercises",
        "branch": "feat/left-hook"
    }
}

Then, you can use the gitmastery app to download and verify your changes locally.

gitmastery download <your new change>
gitmastery verify

Checklist

  • (For exercises and hands-ons) I have verified that the downloading behavior works
  • (For exercises only) I have verified that the verification behavior is accurate

Important

To any reviewers of this pull request, please use the same instructions above to test the changes.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds pre-commit hooks using LeftHook to automatically run linting and type checking before commits. The implementation integrates with the existing CI tooling (ruff and mypy) to catch issues earlier in the development cycle.

Changes:

  • Added lefthook as a developer dependency
  • Modified setup script to install git hooks after dependency installation
  • Created lefthook configuration for pre-commit hooks (ruff linting, formatting, and mypy type checking)

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

File Description
requirements.txt Added lefthook package to developer tooling dependencies
setup.sh Added conditional logic to install lefthook git hooks after pip install
lefthook.yml Configured pre-commit hooks for ruff-lint, ruff-format, and mypy on Python files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


pip install -r requirements.txt -U --no-cache-dir

if ! command -v lefthook &>/dev/null; then
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The logic is inverted. The condition checks if the command does NOT exist (! command -v lefthook), but then attempts to run lefthook install. This will fail because lefthook won't be available. The installation should happen after pip installs the requirements (which includes lefthook), so the condition should check if lefthook DOES exist. Change the condition to if command -v lefthook &>/dev/null; then or remove the negation operator.

Suggested change
if ! command -v lefthook &>/dev/null; then
if command -v lefthook &>/dev/null; then

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +12
parallel: true
commands:
ruff-lint:
glob: "*.py"
run: ruff check --fix {staged_files}
stage_fixed: true

ruff-format:
glob: "*.py"
run: ruff format {staged_files}
stage_fixed: true
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

Running ruff-lint and ruff-format in parallel can cause race conditions since both commands may try to modify the same files simultaneously. The format command should run after lint completes to ensure consistent results. Consider setting parallel: false or using the piped: true option to run commands sequentially, or move ruff-format to a separate sequential group.

Copilot uses AI. Check for mistakes.

mypy:
glob: "*.py"
run: mypy {staged_files}
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

Running mypy on individual staged files may miss type errors related to imports and cross-module dependencies. The CI workflow runs mypy . to type-check the entire codebase. Consider changing this to run mypy . instead of mypy {staged_files} to maintain consistency with CI and catch all type errors. Alternatively, if you want to keep it file-specific for performance, you may want to add a flag like --follow-imports=silent to avoid false positives.

Suggested change
run: mypy {staged_files}
run: mypy .

Copilot uses AI. Check for mistakes.
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.

Implementing Git hooks for linting and formatting

1 participant