Skip to content

pre-commit `

Source: Notion | Last edited: 2025-05-07 | ID: 1ec2d2dc-3ef...


#!/usr/bin/env bash
# Pre-commit hook to:
# 1. Automatically remove unused imports from Python files
# To install:
# 1. Copy this file to .git/hooks/pre-commit
# 2. Make it executable: chmod +x .git/hooks/pre-commit
# Exit on error
set -e
# Debugging can be enabled for troubleshooting
DEBUG=false
echo "🔍 [$(date '+%Y-%m-%d %H:%M:%S')] Starting pre-commit hook checks..."
# Get list of staged Python files only
STAGED_PY_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.py$' || true)
if [ -n "$STAGED_PY_FILES" ]; then
# Multi-level approach to find Python and autoflake
find_best_python() {
# 1. Try the active virtual environment first
if [ -n "$VIRTUAL_ENV" ] && [ -f "$VIRTUAL_ENV/bin/python" ]; then
echo "$VIRTUAL_ENV/bin/python"
return
fi
# 2. Look for a .venv in the repository root
REPO_ROOT=$(git rev-parse --show-toplevel)
if [ -f "$REPO_ROOT/.venv/bin/python" ]; then
echo "$REPO_ROOT/.venv/bin/python"
return
fi
# 3. Fall back to system PATH
PYTHON_IN_PATH=$(command -v python || command -v python3)
if [ -n "$PYTHON_IN_PATH" ]; then
echo "$PYTHON_IN_PATH"
return
fi
# 4. Try pyenv as a last resort
if [ -d "$HOME/.pyenv/shims" ] && [ -f "$HOME/.pyenv/shims/python" ]; then
echo "$HOME/.pyenv/shims/python"
return
fi
# No Python found
echo ""
}
find_best_autoflake() {
local PYTHON_PATH="$1"
# 1. Check if autoflake exists in the same directory as Python
PYTHON_DIR=$(dirname "$PYTHON_PATH")
if [ -f "$PYTHON_DIR/autoflake" ]; then
echo "$PYTHON_DIR/autoflake"
return
fi
# 2. Ask Python to find autoflake's location
if [ -n "$PYTHON_PATH" ]; then
AUTOFLAKE_FROM_PYTHON=$("$PYTHON_PATH" -c "import shutil; print(shutil.which('autoflake') or '')" 2>/dev/null || echo "")
if [ -n "$AUTOFLAKE_FROM_PYTHON" ]; then
echo "$AUTOFLAKE_FROM_PYTHON"
return
fi
# 3. Try to find autoflake in site-packages
# This works for both venv and global installs
SITE_PACKAGES=$("$PYTHON_PATH" -c "import site; print(site.getsitepackages()[0])" 2>/dev/null || echo "")
if [ -n "$SITE_PACKAGES" ] && [ -d "$SITE_PACKAGES/../bin" ] && [ -f "$SITE_PACKAGES/../bin/autoflake" ]; then
echo "$SITE_PACKAGES/../bin/autoflake"
return
fi
fi
# 4. Fall back to system PATH
AUTOFLAKE_IN_PATH=$(command -v autoflake)
if [ -n "$AUTOFLAKE_IN_PATH" ]; then
echo "$AUTOFLAKE_IN_PATH"
return
fi
# No autoflake found
echo ""
}
# Find Python and autoflake
PYTHON_PATH=$(find_best_python)
if [ -z "$PYTHON_PATH" ]; then
echo "❌ [$(date '+%Y-%m-%d %H:%M:%S')] Error: Python not found in PATH or virtual environment"
exit 1
fi
AUTOFLAKE_PATH=$(find_best_autoflake "$PYTHON_PATH")
if $DEBUG; then
echo "Debug: Python found at $PYTHON_PATH"
echo "Debug: Autoflake found at $AUTOFLAKE_PATH"
"$PYTHON_PATH" -c "import sys; print(f'Python version: {sys.version}')"
fi
echo "⚡ [$(date '+%Y-%m-%d %H:%M:%S')] Running autoflake on staged Python files..."
# Check if autoflake exists
if [ -z "$AUTOFLAKE_PATH" ]; then
# Try to install autoflake if not found
echo "🔄 [$(date '+%Y-%m-%d %H:%M:%S')] Autoflake not found, attempting to install..."
"$PYTHON_PATH" -m pip install autoflake
# Check again after installation
AUTOFLAKE_PATH=$(find_best_autoflake "$PYTHON_PATH")
if [ -z "$AUTOFLAKE_PATH" ]; then
echo "❌ [$(date '+%Y-%m-%d %H:%M:%S')] Error: autoflake not found and could not be installed"
echo " Please install it manually with: pip install autoflake"
exit 1
fi
fi
# Run autoflake only on staged Python files
echo "$STAGED_PY_FILES" | xargs "$AUTOFLAKE_PATH" --remove-unused-variables --remove-all-unused-imports --in-place --ignore-init-module-imports
# Check if autoflake made any changes
if ! git diff --exit-code --quiet; then
echo "📝 [$(date '+%Y-%m-%d %H:%M:%S')] Autoflake cleaned up unused imports in:"
echo "$STAGED_PY_FILES" | sed 's/^/ /'
# Automatically stage the changes made by autoflake
echo "$STAGED_PY_FILES" | xargs git add
echo "✅ [$(date '+%Y-%m-%d %H:%M:%S')] Changes staged successfully! Continuing with commit..."
else
echo "✨ [$(date '+%Y-%m-%d %H:%M:%S')] No unused imports found in staged Python files."
fi
else
echo "ℹ️ [$(date '+%Y-%m-%d %H:%M:%S')] No Python files staged for commit."
fi
echo "🎉 [$(date '+%Y-%m-%d %H:%M:%S')] Pre-commit hook completed successfully!"
exit 0