diff --git a/Makefile b/Makefile index 162775b5fce..c948bd29966 100644 --- a/Makefile +++ b/Makefile @@ -342,6 +342,11 @@ lint-errors: @echo "Running error message quality linter..." @go run scripts/lint_error_messages.go +# Check file sizes and function counts +.PHONY: check-file-sizes +check-file-sizes: + @bash scripts/check-file-sizes.sh + # Validate all project files .PHONY: lint lint: fmt-check fmt-check-json lint-cjs golint diff --git a/scripts/check-file-sizes.sh b/scripts/check-file-sizes.sh new file mode 100755 index 00000000000..4972025cc33 --- /dev/null +++ b/scripts/check-file-sizes.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# check-file-sizes.sh - Monitor Go file sizes and function counts +# +# This script identifies Go files that exceed recommended thresholds: +# - 50+ functions: Consider splitting (warning) +# - 40-49 functions: Approaching threshold (info) +# +# Exit codes: +# 0 - No issues or only informational warnings +# Non-zero is never returned (non-blocking check) + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +# Thresholds +WARN_THRESHOLD=50 +INFO_THRESHOLD=40 + +# Counter for warnings +warn_count=0 +info_count=0 + +echo "Checking Go file sizes in pkg/ directory..." +echo "" + +# Find all .go files (excluding test files) and count functions +while IFS= read -r file; do + # Count function declarations (lines starting with "func ") + func_count=$(grep -c "^func " "$file" || true) + line_count=$(wc -l < "$file") + + # Only report files with 40+ functions + if [ "$func_count" -ge "$WARN_THRESHOLD" ]; then + echo -e "${RED}⚠️ WARNING${NC}: $file" + echo -e " Functions: ${RED}$func_count${NC} | Lines: $line_count" + echo -e " Consider splitting this file (threshold: ${WARN_THRESHOLD} functions)" + echo "" + warn_count=$((warn_count + 1)) + elif [ "$func_count" -ge "$INFO_THRESHOLD" ]; then + echo -e "${YELLOW}ℹ️ INFO${NC}: $file" + echo -e " Functions: ${YELLOW}$func_count${NC} | Lines: $line_count" + echo -e " Approaching threshold (${INFO_THRESHOLD}-${WARN_THRESHOLD} functions)" + echo "" + info_count=$((info_count + 1)) + fi +done < <(find pkg -name "*.go" ! -name "*_test.go" -type f | sort) + +# Summary +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "Summary:" +echo "" + +if [ "$warn_count" -eq 0 ] && [ "$info_count" -eq 0 ]; then + echo -e "${GREEN}✓ All files are within recommended size guidelines${NC}" + echo "" + echo "No files exceed the 40-function threshold." +elif [ "$warn_count" -eq 0 ]; then + echo -e "${BLUE}ℹ️ $info_count file(s) approaching threshold (${INFO_THRESHOLD}-${WARN_THRESHOLD} functions)${NC}" + echo "" + echo "These files are getting large but still within acceptable range." + echo "Consider reviewing them if adding significant functionality." +else + echo -e "${YELLOW}⚠️ $warn_count file(s) exceed recommended size (${WARN_THRESHOLD}+ functions)${NC}" + if [ "$info_count" -gt 0 ]; then + echo -e "${BLUE}ℹ️ $info_count file(s) approaching threshold (${INFO_THRESHOLD}-${WARN_THRESHOLD} functions)${NC}" + fi + echo "" + echo "Files exceeding ${WARN_THRESHOLD} functions should be evaluated for splitting." + echo "However, domain complexity may justify larger files." + echo "" + echo "See specs/code-organization.md for file size guidelines and justified large files." +fi + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "Note: This is an informational check only. Large files may be justified" +echo "by domain complexity. See specs/code-organization.md for guidelines." + +# Always exit 0 (non-blocking) +exit 0 diff --git a/specs/code-organization.md b/specs/code-organization.md index 5507ce987b5..ca4a96eb078 100644 --- a/specs/code-organization.md +++ b/specs/code-organization.md @@ -194,6 +194,23 @@ When implementing a feature: ## File Size Guidelines +### Function Count Threshold + +**Guideline**: Consider splitting files when they exceed **50 functions**. + +**Note**: This is a guideline, not a hard rule. Domain complexity may justify larger files. + +**Monitoring**: Run `make check-file-sizes` to identify files approaching the 50-function threshold. + +### Current Large Files + +The following files are justified despite their size due to domain complexity: + +- `js.go` (41 functions, 914 lines) - JavaScript bundling and execution with many embed directives +- `permissions.go` (37 functions, 945 lines) - Permission handling with many GitHub Actions permission types +- `scripts.go` (37 functions, 397 lines) - Script generation with specialized functions for workflow steps +- `compiler_safe_outputs_consolidated.go` (30 functions, 1267 lines) - Consolidated safe output handling + ### Recommended Sizes - **Small files**: 50-200 lines