217 lines
7.3 KiB
Bash
Executable File
217 lines
7.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Formatting Validation Script
|
|
# Checks code formatting and linting compliance
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
# Function to check if a file is Python code
|
|
is_python_file() {
|
|
local file="$1"
|
|
[[ "$file" == *.py ]]
|
|
}
|
|
|
|
# Function to check code formatting with black
|
|
check_black_formatting() {
|
|
echo -e "${BLUE}🎨 Checking code formatting with black...${NC}"
|
|
|
|
if command -v black >/dev/null 2>&1; then
|
|
if cd "$PROJECT_ROOT" && python -m black --check --diff src/ tests/ 2>/dev/null; then
|
|
echo -e " ${GREEN}✅ Code formatting OK${NC}"
|
|
return 0
|
|
else
|
|
echo -e " ${RED}❌ Code formatting issues detected${NC}"
|
|
echo -e " ${YELLOW} Run: uv run black src/ tests/ to fix${NC}"
|
|
return 1
|
|
fi
|
|
else
|
|
echo -e " ${YELLOW}⚠️ black not available - skipping formatting check${NC}"
|
|
echo -e " ${YELLOW} Install with: uv pip install black${NC}"
|
|
return 0 # Not a failure, just unavailable
|
|
fi
|
|
}
|
|
|
|
# Function to check code linting with ruff
|
|
check_ruff_linting() {
|
|
echo -e "${BLUE}🔍 Checking code linting with ruff...${NC}"
|
|
|
|
if command -v ruff >/dev/null 2>&1; then
|
|
if cd "$PROJECT_ROOT" && python -m ruff check src/ tests/ 2>/dev/null; then
|
|
echo -e " ${GREEN}✅ Linting OK${NC}"
|
|
return 0
|
|
else
|
|
echo -e " ${RED}❌ Linting issues detected${NC}"
|
|
echo -e " ${YELLOW} Run: uv run ruff check --fix src/ tests/ to fix${NC}"
|
|
return 1
|
|
fi
|
|
else
|
|
echo -e " ${YELLOW}⚠️ ruff not available - skipping linting check${NC}"
|
|
echo -e " ${YELLOW} Install with: uv pip install ruff${NC}"
|
|
return 0 # Not a failure, just unavailable
|
|
fi
|
|
}
|
|
|
|
# Function to check import organization
|
|
check_import_organization() {
|
|
echo -e "${BLUE}📦 Checking import organization...${NC}"
|
|
|
|
local import_issues=0
|
|
|
|
while IFS= read -r -d '' file; do
|
|
if is_python_file "$file"; then
|
|
# Check for multiple import statements that could be combined
|
|
local import_lines=$(grep -c "^import\|^from " "$file" 2>/dev/null || echo 0)
|
|
local from_lines=$(grep -c "^from " "$file" 2>/dev/null || echo 0)
|
|
|
|
if [[ $import_lines -gt 5 ]]; then
|
|
echo -e " ${YELLOW}⚠️ Many import statements in $file ($import_lines) - consider organizing${NC}"
|
|
import_issues=$((import_issues + 1))
|
|
fi
|
|
|
|
# Check for unused imports (basic check)
|
|
if [[ $from_lines -gt 0 ]]; then
|
|
local unused_imports=0
|
|
while IFS= read -r import_line; do
|
|
local module=$(echo "$import_line" | sed 's/^from \([^ ]*\) import.*/\1/')
|
|
if [[ -n "$module" ]] && ! grep -q "$module\." "$file" 2>/dev/null; then
|
|
if [[ $unused_imports -eq 0 ]]; then
|
|
echo -e " ${YELLOW}⚠️ Potential unused imports in $file${NC}"
|
|
fi
|
|
unused_imports=$((unused_imports + 1))
|
|
import_issues=$((import_issues + 1))
|
|
fi
|
|
done < <(grep "^from " "$file" 2>/dev/null)
|
|
fi
|
|
fi
|
|
done < <(find "$PROJECT_ROOT/src" -name "*.py" -print0)
|
|
|
|
if [[ $import_issues -eq 0 ]]; then
|
|
echo -e " ${GREEN}✅ Import organization looks good${NC}"
|
|
return 0
|
|
else
|
|
echo -e " ${YELLOW}⚠️ $import_issues import organization issues found${NC}"
|
|
return 0 # Warning, not error
|
|
fi
|
|
}
|
|
|
|
# Function to check line length compliance
|
|
check_line_length() {
|
|
echo -e "${BLUE}📏 Checking line length compliance...${NC}"
|
|
|
|
local long_lines=0
|
|
local max_length=100 # Black default
|
|
|
|
while IFS= read -r -d '' file; do
|
|
if is_python_file "$file"; then
|
|
local file_long_lines=$(awk "length(\$0) > $max_length" "$file" 2>/dev/null | wc -l)
|
|
if [[ $file_long_lines -gt 0 ]]; then
|
|
echo -e " ${YELLOW}⚠️ $file_long_lines long lines in $file (max: $max_length chars)${NC}"
|
|
long_lines=$((long_lines + file_long_lines))
|
|
fi
|
|
fi
|
|
done < <(find "$PROJECT_ROOT/src" -name "*.py" -print0)
|
|
|
|
if [[ $long_lines -eq 0 ]]; then
|
|
echo -e " ${GREEN}✅ All lines within length limits${NC}"
|
|
return 0
|
|
else
|
|
echo -e " ${YELLOW}⚠️ $long_lines long lines found - consider breaking them up${NC}"
|
|
return 0 # Warning, not error
|
|
fi
|
|
}
|
|
|
|
# Function to provide formatting improvement recommendations
|
|
suggest_formatting_improvements() {
|
|
echo -e "${BLUE}💡 Formatting Improvement Recommendations:${NC}"
|
|
|
|
echo -e " ${YELLOW}• Use black for consistent code formatting${NC}"
|
|
echo -e " ${YELLOW}• Use ruff for fast Python linting${NC}"
|
|
echo -e " ${YELLOW}• Organize imports: standard library, third-party, local${NC}"
|
|
echo -e " ${YELLOW}• Keep lines under 100 characters${NC}"
|
|
echo -e " ${YELLOW}• Use consistent indentation (4 spaces)${NC}"
|
|
echo -e " ${YELLOW}• Remove trailing whitespace${NC}"
|
|
echo -e " ${YELLOW}• Use meaningful variable and function names${NC}"
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
local exit_code=0
|
|
local formatting_issues=0
|
|
local linting_issues=0
|
|
|
|
echo -e "${BLUE}🎨 Formatting Validation for Project${NC}"
|
|
echo -e "${BLUE}Focus: Code formatting, linting, and style compliance${NC}"
|
|
echo ""
|
|
|
|
# Check black formatting
|
|
if ! check_black_formatting; then
|
|
formatting_issues=$((formatting_issues + 1))
|
|
exit_code=1
|
|
fi
|
|
echo ""
|
|
|
|
# Check ruff linting
|
|
if ! check_ruff_linting; then
|
|
linting_issues=$((linting_issues + 1))
|
|
exit_code=1
|
|
fi
|
|
echo ""
|
|
|
|
# Check import organization
|
|
check_import_organization
|
|
echo ""
|
|
|
|
# Check line length
|
|
check_line_length
|
|
echo ""
|
|
|
|
# Provide improvement recommendations
|
|
suggest_formatting_improvements
|
|
echo ""
|
|
|
|
# Summary
|
|
echo -e "${BLUE}📋 Formatting Validation Summary:${NC}"
|
|
if [[ $formatting_issues -eq 0 ]]; then
|
|
echo -e " ${GREEN}✅ Code formatting: PASSED${NC}"
|
|
else
|
|
echo -e " ${RED}❌ Code formatting: FAILED${NC}"
|
|
fi
|
|
|
|
if [[ $linting_issues -eq 0 ]]; then
|
|
echo -e " ${GREEN}✅ Code linting: PASSED${NC}"
|
|
else
|
|
echo -e " ${RED}❌ Code linting: FAILED${NC}"
|
|
fi
|
|
|
|
if [[ $exit_code -eq 0 ]]; then
|
|
echo ""
|
|
echo -e "${GREEN}🎉 All formatting checks passed!${NC}"
|
|
echo -e "${GREEN}✅ Code meets formatting and style standards${NC}"
|
|
else
|
|
echo ""
|
|
echo -e "${RED}🚫 Formatting validation failed - must be resolved before task completion${NC}"
|
|
echo -e "${YELLOW} Fix all formatting issues before proceeding${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${BLUE}🔧 Quick Fix Commands:${NC}"
|
|
echo -e " ${BLUE}• Format code:${NC} uv run black src/ tests/"
|
|
echo -e " ${BLUE}• Fix linting:${NC} uv run ruff check --fix src/ tests/"
|
|
echo -e " ${BLUE}• Re-validate:${NC} $0"
|
|
|
|
exit $exit_code
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|