149 lines
4.3 KiB
Bash
Executable File
149 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Code quality checker for Trax project
|
|
|
|
set -e
|
|
|
|
# Color codes
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
echo -e "${BLUE}🔍 Trax Code Quality Check${NC}"
|
|
echo "================================"
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
# Activate virtual environment
|
|
if [ -f ".venv/bin/activate" ]; then
|
|
source .venv/bin/activate
|
|
else
|
|
echo -e "${RED}❌ Virtual environment not found${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
FAILED=0
|
|
|
|
# Black formatting check
|
|
echo -e "\n${CYAN}📝 Black (formatting):${NC}"
|
|
if uv run black --check src/ tests/ 2>/dev/null; then
|
|
echo -e " ${GREEN}✅ Code is properly formatted${NC}"
|
|
else
|
|
echo -e " ${YELLOW}⚠️ Code needs formatting${NC}"
|
|
echo -e " ${YELLOW}💡 Run: uv run black src/ tests/${NC}"
|
|
((FAILED++))
|
|
fi
|
|
|
|
# Ruff linting
|
|
echo -e "\n${CYAN}🔍 Ruff (linting):${NC}"
|
|
if uv run ruff check src/ tests/ 2>/dev/null; then
|
|
echo -e " ${GREEN}✅ No linting issues${NC}"
|
|
else
|
|
echo -e " ${YELLOW}⚠️ Linting issues found${NC}"
|
|
echo -e " ${YELLOW}💡 Run: uv run ruff check --fix src/ tests/${NC}"
|
|
((FAILED++))
|
|
fi
|
|
|
|
# MyPy type checking
|
|
echo -e "\n${CYAN}🔤 MyPy (type checking):${NC}"
|
|
if uv run mypy src/ 2>/dev/null; then
|
|
echo -e " ${GREEN}✅ Type checks pass${NC}"
|
|
else
|
|
echo -e " ${YELLOW}⚠️ Type checking failed${NC}"
|
|
echo -e " ${YELLOW}💡 Fix type hints in reported files${NC}"
|
|
((FAILED++))
|
|
fi
|
|
|
|
# File size check (300 LOC limit)
|
|
echo -e "\n${CYAN}📏 File Size Check (300 LOC limit):${NC}"
|
|
LARGE_FILES=0
|
|
for file in $(find src tests -name "*.py" -type f 2>/dev/null); do
|
|
lines=$(wc -l < "$file")
|
|
if [ "$lines" -gt 300 ]; then
|
|
echo -e " ${YELLOW}⚠️ $file: $lines lines${NC}"
|
|
((LARGE_FILES++))
|
|
fi
|
|
done
|
|
|
|
if [ $LARGE_FILES -eq 0 ]; then
|
|
echo -e " ${GREEN}✅ All files under 300 LOC${NC}"
|
|
else
|
|
echo -e " ${YELLOW}Found $LARGE_FILES files over 300 LOC${NC}"
|
|
echo -e " ${YELLOW}💡 Consider splitting large files${NC}"
|
|
fi
|
|
|
|
# Check for missing docstrings
|
|
echo -e "\n${CYAN}📚 Docstring Check:${NC}"
|
|
python3 << 'EOF'
|
|
import ast
|
|
import os
|
|
from pathlib import Path
|
|
|
|
missing_docstrings = []
|
|
|
|
def check_docstrings(filepath):
|
|
with open(filepath, 'r') as f:
|
|
try:
|
|
tree = ast.parse(f.read())
|
|
except:
|
|
return []
|
|
|
|
missing = []
|
|
for node in ast.walk(tree):
|
|
if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
|
|
if not ast.get_docstring(node):
|
|
missing.append(f"{filepath}:{node.lineno} - {node.name}")
|
|
return missing
|
|
|
|
# Check all Python files
|
|
for root, dirs, files in os.walk('src'):
|
|
for file in files:
|
|
if file.endswith('.py') and not file.startswith('__'):
|
|
filepath = os.path.join(root, file)
|
|
missing = check_docstrings(filepath)
|
|
missing_docstrings.extend(missing)
|
|
|
|
if missing_docstrings:
|
|
print(f" ⚠️ Found {len(missing_docstrings)} missing docstrings")
|
|
for item in missing_docstrings[:5]:
|
|
print(f" - {item}")
|
|
if len(missing_docstrings) > 5:
|
|
print(f" ... and {len(missing_docstrings) - 5} more")
|
|
else:
|
|
print(" ✅ All functions/classes have docstrings")
|
|
EOF
|
|
|
|
# Check imports
|
|
echo -e "\n${CYAN}📦 Import Check:${NC}"
|
|
if uv run ruff check --select I src/ tests/ 2>/dev/null; then
|
|
echo -e " ${GREEN}✅ Imports are properly sorted${NC}"
|
|
else
|
|
echo -e " ${YELLOW}⚠️ Import issues found${NC}"
|
|
echo -e " ${YELLOW}💡 Run: uv run ruff check --select I --fix src/ tests/${NC}"
|
|
fi
|
|
|
|
# Test discovery
|
|
echo -e "\n${CYAN}🧪 Test Discovery:${NC}"
|
|
test_count=$(find tests -name "test_*.py" -o -name "*_test.py" 2>/dev/null | wc -l | tr -d ' ')
|
|
if [ "$test_count" -gt 0 ]; then
|
|
echo -e " ${GREEN}✅ Found $test_count test files${NC}"
|
|
else
|
|
echo -e " ${YELLOW}⚠️ No test files found${NC}"
|
|
echo -e " ${YELLOW}💡 Add tests in tests/ directory${NC}"
|
|
fi
|
|
|
|
# Summary
|
|
echo -e "\n${BLUE}Summary:${NC}"
|
|
echo "================================"
|
|
if [ $FAILED -eq 0 ] && [ $LARGE_FILES -eq 0 ]; then
|
|
echo -e "${GREEN}✅ All quality checks passed!${NC}"
|
|
exit 0
|
|
else
|
|
echo -e "${YELLOW}⚠️ Some quality issues found${NC}"
|
|
echo ""
|
|
echo "Quick fix command:"
|
|
echo -e "${CYAN}uv run black src/ tests/ && uv run ruff check --fix src/ tests/${NC}"
|
|
exit 1
|
|
fi |