#!/bin/bash # ci-checks.sh - CI enforcement for maintainability rules # Usage: ./scripts/ci-checks.sh set -e echo "=== FetchML Maintainability CI Checks ===" echo "" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color FAILED=0 # Check 1: No internal/ -> cmd/ imports echo "1. Checking for illegal internal/ -> cmd/ imports..." if go list -f '{{.ImportPath}}: {{.Imports}}' ./internal/... 2>/dev/null | grep -q 'github.com/jfraeys/fetch_ml/cmd'; then echo -e "${RED}FAIL: Found internal/ package importing from cmd/${NC}" go list -f '{{.ImportPath}}: {{.Imports}}' ./internal/... | grep 'github.com/jfraeys/fetch_ml/cmd' FAILED=1 else echo -e "${GREEN}PASS: No internal/ -> cmd/ imports found${NC}" fi echo "" # Check 2: domain package has zero internal imports (only stdlib) echo "2. Checking domain package has no internal imports..." DOMAIN_IMPORTS=$(go list -f '{{join .Imports "\n"}}' ./internal/domain/... 2>/dev/null | grep 'github.com/jfraeys/fetch_ml' || true) if [ -n "$DOMAIN_IMPORTS" ]; then echo -e "${RED}FAIL: domain/ package imports internal packages:${NC}" echo "$DOMAIN_IMPORTS" FAILED=1 else echo -e "${GREEN}PASS: domain/ package has no internal imports${NC}" fi echo "" # Check 3: Check file size limits (warn if >500 lines) echo "3. Checking file size limits (warn if >500 lines)..." OVERSIZED=$(find ./internal ./cmd -name '*.go' -type f -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {print $2}' | head -10) if [ -n "$OVERSIZED" ]; then echo -e "${YELLOW}WARNING: Files exceeding 500 lines:${NC}" find ./internal ./cmd -name '*.go' -type f -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {print " " $1 " lines: " $2}' # Not failing the build for this, just warning else echo -e "${GREEN}PASS: All files under 500 lines${NC}" fi echo "" # Check 4: Verify no circular imports echo "4. Checking for circular imports..." CIRCULAR=$(go list -deps ./internal/... 2>&1 | grep -i 'circular' || true) if [ -n "$CIRCULAR" ]; then echo -e "${RED}FAIL: Circular imports detected:${NC}" echo "$CIRCULAR" FAILED=1 else echo -e "${GREEN}PASS: No circular imports detected${NC}" fi echo "" # Check 5: Verify package naming conventions echo "5. Checking package naming conventions..." NAMING_ISSUES=$(find ./internal ./cmd -name '*.go' -type f | while read f; do # Skip vendor and generated files if echo "$f" | grep -qE '(vendor|_test\.go|\.pb\.go|generated)'; then continue fi # Check file name matches content (basic check) pkg=$(grep '^package ' "$f" 2>/dev/null | head -1 | awk '{print $2}') if [ -z "$pkg" ]; then continue fi # Skip main packages if [ "$pkg" = "main" ]; then continue fi # Check that file is in correct directory for its package dir=$(dirname "$f") expected_pkg=$(basename "$dir") if [ "$pkg" != "$expected_pkg" ] && [ "$pkg" != "${expected_pkg}_test" ]; then # Allow common exceptions if echo "$f" | grep -qE '(factory|config|helper|util)'; then continue fi echo " $f: package '$pkg' doesn't match directory '$expected_pkg'" fi done) if [ -n "$NAMING_ISSUES" ]; then echo -e "${YELLOW}WARNING: Potential naming convention issues:${NC}" echo "$NAMING_ISSUES" else echo -e "${GREEN}PASS: Package naming conventions look good${NC}" fi echo "" # Summary echo "=== Summary ===" if [ $FAILED -eq 0 ]; then echo -e "${GREEN}All critical checks passed!${NC}" exit 0 else echo -e "${RED}Some checks failed. Please fix the issues above.${NC}" exit 1 fi