109 lines
3.6 KiB
Bash
Executable file
109 lines
3.6 KiB
Bash
Executable file
#!/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
|