Test fixes (all 41 test packages now pass): - Fix ComputeTaskProvenance - add dataset_specs JSON output - Fix EnforceTaskProvenance - populate all metadata fields in best-effort mode - Fix PrewarmNextOnce - preserve prewarm state when queue empty - Fix RunManifest directory creation in SetupJobDirectories - Add ManifestWriter to test worker (simpleManifestWriter) - Fix worker ID mismatch (use cfg.WorkerID) - Fix WebSocket binary protocol responses - Implement all WebSocket handlers: QueueJob, QueueJobWithSnapshot, StatusRequest, CancelJob, Prune, ValidateRequest (with run manifest validation), LogMetric, GetExperiment, DatasetList/Register/Info/Search Maintainability phases completed: - Phases 1-6: Domain types, error system, config boundaries, worker/API/queue splits - Phase 7: TUI cleanup - reorganize model package (jobs.go, messages.go, styles.go, keys.go) - Phase 8: MLServer unification - consolidate worker + TUI into internal/network/mlserver.go - Phase 9: CI enforcement - add scripts/ci-checks.sh with 5 checks: * No internal/ -> cmd/ imports * domain/ has zero internal imports * File size limit (500 lines, rigid) * No circular imports * Package naming conventions Documentation: - Add docs/src/file-naming-conventions.md - Add make ci-checks target Lines changed: +756/-36 (WebSocket fixes), +518/-320 (TUI), +263/-20 (Phase 8-9)
109 lines
3.5 KiB
Bash
Executable file
109 lines
3.5 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 (no file >500 lines)
|
|
echo "3. Checking file size limits (max 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 "${RED}FAIL: 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}'
|
|
FAILED=1
|
|
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
|