Initial commit
This commit is contained in:
180
scripts/check-architecture.sh
Executable file
180
scripts/check-architecture.sh
Executable file
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# TYPO3 PHP Architecture Conformance Checker
|
||||
#
|
||||
# Validates dependency injection, services, events, and architectural patterns
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="${1:-.}"
|
||||
cd "${PROJECT_DIR}"
|
||||
|
||||
echo "## 3. PHP Architecture Conformance"
|
||||
echo ""
|
||||
|
||||
has_issues=0
|
||||
|
||||
### Check for Services.yaml
|
||||
echo "### Dependency Injection Configuration"
|
||||
echo ""
|
||||
|
||||
if [ -f "Configuration/Services.yaml" ]; then
|
||||
echo "- ✅ Configuration/Services.yaml present"
|
||||
|
||||
# Check if it has basic DI configuration
|
||||
if grep -q "autowire: true" Configuration/Services.yaml; then
|
||||
echo " - ✅ Autowiring enabled"
|
||||
else
|
||||
echo " - ⚠️ Autowiring not enabled"
|
||||
fi
|
||||
|
||||
if grep -q "autoconfigure: true" Configuration/Services.yaml; then
|
||||
echo " - ✅ Autoconfiguration enabled"
|
||||
else
|
||||
echo " - ⚠️ Autoconfiguration not enabled"
|
||||
fi
|
||||
else
|
||||
echo "- ❌ Configuration/Services.yaml missing (CRITICAL)"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Check for deprecated patterns
|
||||
echo ""
|
||||
echo "### Deprecated Pattern Detection"
|
||||
echo ""
|
||||
|
||||
# Check for GeneralUtility::makeInstance
|
||||
makeinstance_count=$(grep -r "GeneralUtility::makeInstance" Classes/ 2>/dev/null | wc -l)
|
||||
if [ $makeinstance_count -eq 0 ]; then
|
||||
echo "- ✅ No GeneralUtility::makeInstance() usage found"
|
||||
else
|
||||
echo "- ❌ ${makeinstance_count} instances of GeneralUtility::makeInstance() found"
|
||||
echo " - Should use constructor injection instead"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
# Check for global state access
|
||||
globals_count=$(grep -r '\$GLOBALS\[' Classes/ 2>/dev/null | wc -l)
|
||||
if [ $globals_count -eq 0 ]; then
|
||||
echo "- ✅ No \$GLOBALS access found"
|
||||
else
|
||||
echo "- ❌ ${globals_count} instances of \$GLOBALS access found"
|
||||
echo " - Should use dependency injection instead"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Check for constructor injection
|
||||
echo ""
|
||||
echo "### Dependency Injection Patterns"
|
||||
echo ""
|
||||
|
||||
# Check for constructors with dependencies
|
||||
constructors=$(grep -r "public function __construct" Classes/ 2>/dev/null | wc -l)
|
||||
if [ $constructors -gt 0 ]; then
|
||||
echo "- ✅ ${constructors} classes use constructors (potential DI)"
|
||||
else
|
||||
echo "- ⚠️ No constructor injection found"
|
||||
fi
|
||||
|
||||
# Check for method injection (inject* methods)
|
||||
inject_methods=$(grep -r "public function inject[A-Z]" Classes/ 2>/dev/null | wc -l)
|
||||
if [ $inject_methods -gt 0 ]; then
|
||||
echo "- ⚠️ ${inject_methods} method injection patterns found (inject*)"
|
||||
echo " - Consider using constructor injection instead (more modern)"
|
||||
fi
|
||||
|
||||
### Check for PSR-14 events
|
||||
echo ""
|
||||
echo "### Event System"
|
||||
echo ""
|
||||
|
||||
# Check for event classes
|
||||
event_classes=$(find Classes/ -type d -name "Event" 2>/dev/null || echo "")
|
||||
if [ -n "$event_classes" ]; then
|
||||
event_count=$(find Classes/ -path "*/Event/*.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ ${event_count} event classes found in Classes/Event/"
|
||||
else
|
||||
echo "- ⚠️ No Classes/Event/ directory found"
|
||||
fi
|
||||
|
||||
# Check for event listeners
|
||||
listener_classes=$(find Classes/ -type d -name "EventListener" 2>/dev/null || echo "")
|
||||
if [ -n "$listener_classes" ]; then
|
||||
listener_count=$(find Classes/ -path "*/EventListener/*.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ ${listener_count} event listeners found in Classes/EventListener/"
|
||||
else
|
||||
echo "- ⚠️ No Classes/EventListener/ directory found"
|
||||
fi
|
||||
|
||||
### Check for Extbase patterns
|
||||
echo ""
|
||||
echo "### Extbase Architecture"
|
||||
echo ""
|
||||
|
||||
# Check for domain models
|
||||
if [ -d "Classes/Domain/Model" ]; then
|
||||
model_count=$(find Classes/Domain/Model/ -name "*.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ ${model_count} domain models found"
|
||||
else
|
||||
echo "- ℹ️ No Classes/Domain/Model/ (not using Extbase models)"
|
||||
fi
|
||||
|
||||
# Check for repositories
|
||||
if [ -d "Classes/Domain/Repository" ]; then
|
||||
repo_count=$(find Classes/Domain/Repository/ -name "*.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ ${repo_count} repositories found"
|
||||
|
||||
# Check if repositories extend Repository
|
||||
proper_repos=$(grep -r "extends.*Repository" Classes/Domain/Repository/ 2>/dev/null | wc -l)
|
||||
if [ $proper_repos -gt 0 ]; then
|
||||
echo " - ✅ Repositories extend base Repository class"
|
||||
fi
|
||||
else
|
||||
echo "- ℹ️ No Classes/Domain/Repository/ (not using Extbase repositories)"
|
||||
fi
|
||||
|
||||
# Check for controllers
|
||||
if [ -d "Classes/Controller" ]; then
|
||||
controller_count=$(find Classes/Controller/ -name "*.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ ${controller_count} controllers found"
|
||||
|
||||
# Check if controllers extend ActionController
|
||||
proper_controllers=$(grep -r "extends ActionController" Classes/Controller/ 2>/dev/null | wc -l)
|
||||
if [ $proper_controllers -gt 0 ]; then
|
||||
echo " - ✅ Controllers extend ActionController"
|
||||
fi
|
||||
fi
|
||||
|
||||
### Check for PSR-15 middleware
|
||||
echo ""
|
||||
echo "### Middleware"
|
||||
echo ""
|
||||
|
||||
if [ -f "Configuration/RequestMiddlewares.php" ]; then
|
||||
echo "- ✅ Configuration/RequestMiddlewares.php present"
|
||||
|
||||
middleware_count=$(find Classes/ -path "*/Middleware/*.php" 2>/dev/null | wc -l)
|
||||
if [ $middleware_count -gt 0 ]; then
|
||||
echo " - ✅ ${middleware_count} middleware classes found"
|
||||
fi
|
||||
else
|
||||
echo "- ℹ️ No Configuration/RequestMiddlewares.php (not using custom middleware)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "### Summary"
|
||||
echo ""
|
||||
|
||||
if [ $has_issues -eq 0 ]; then
|
||||
echo "- ✅ **PHP Architecture: PASSED**"
|
||||
else
|
||||
echo "- ⚠️ **PHP Architecture: ISSUES FOUND**"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
|
||||
exit $has_issues
|
||||
168
scripts/check-coding-standards.sh
Executable file
168
scripts/check-coding-standards.sh
Executable file
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# TYPO3 Coding Standards Conformance Checker
|
||||
#
|
||||
# Validates PSR-12 compliance and TYPO3-specific code style
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="${1:-.}"
|
||||
cd "${PROJECT_DIR}"
|
||||
|
||||
echo "## 2. Coding Standards Conformance"
|
||||
echo ""
|
||||
|
||||
has_issues=0
|
||||
|
||||
# Find all PHP files in Classes/
|
||||
if [ ! -d "Classes" ]; then
|
||||
echo "- ❌ Classes/ directory not found"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php_files=$(find Classes/ -name "*.php" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$php_files" ]; then
|
||||
echo "- ⚠️ No PHP files found in Classes/"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
total_files=$(echo "$php_files" | wc -l)
|
||||
echo "**Total PHP files:** $total_files"
|
||||
echo ""
|
||||
|
||||
### Check for strict types
|
||||
echo "### Strict Types Declaration"
|
||||
echo ""
|
||||
missing_strict=0
|
||||
for file in $php_files; do
|
||||
if ! grep -q "declare(strict_types=1)" "$file"; then
|
||||
missing_strict=$((missing_strict + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $missing_strict -eq 0 ]; then
|
||||
echo "- ✅ All files have declare(strict_types=1)"
|
||||
else
|
||||
echo "- ❌ ${missing_strict} files missing declare(strict_types=1)"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Check for old array syntax
|
||||
echo ""
|
||||
echo "### Array Syntax"
|
||||
echo ""
|
||||
old_array_count=$(grep -r "array(" Classes/ 2>/dev/null | wc -l)
|
||||
if [ $old_array_count -eq 0 ]; then
|
||||
echo "- ✅ No old array() syntax found"
|
||||
else
|
||||
echo "- ❌ ${old_array_count} instances of old array() syntax (should use [])"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Check for proper namespace
|
||||
echo ""
|
||||
echo "### Namespace Structure"
|
||||
echo ""
|
||||
files_without_namespace=0
|
||||
for file in $php_files; do
|
||||
if ! grep -q "^namespace " "$file"; then
|
||||
files_without_namespace=$((files_without_namespace + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $files_without_namespace -eq 0 ]; then
|
||||
echo "- ✅ All files have namespace declaration"
|
||||
else
|
||||
echo "- ❌ ${files_without_namespace} files missing namespace declaration"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Check for PHPDoc comments on classes
|
||||
echo ""
|
||||
echo "### PHPDoc Comments"
|
||||
echo ""
|
||||
classes_without_doc=0
|
||||
for file in $php_files; do
|
||||
# Simple check: look for /** before class declaration
|
||||
if grep -q "^class " "$file" || grep -q "^final class " "$file"; then
|
||||
if ! grep -B 5 "^class \|^final class " "$file" | grep -q "/\*\*"; then
|
||||
classes_without_doc=$((classes_without_doc + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $classes_without_doc -eq 0 ]; then
|
||||
echo "- ✅ All classes have PHPDoc comments"
|
||||
else
|
||||
echo "- ⚠️ ${classes_without_doc} classes missing PHPDoc comments"
|
||||
fi
|
||||
|
||||
### Check naming conventions
|
||||
echo ""
|
||||
echo "### Naming Conventions"
|
||||
echo ""
|
||||
|
||||
# Check for snake_case in class names (should be UpperCamelCase)
|
||||
snake_case_classes=$(grep -rE "^(final )?class [a-z][a-z0-9_]*" Classes/ 2>/dev/null | wc -l)
|
||||
if [ $snake_case_classes -gt 0 ]; then
|
||||
echo "- ❌ ${snake_case_classes} classes using incorrect naming (should be UpperCamelCase)"
|
||||
has_issues=1
|
||||
else
|
||||
echo "- ✅ Class naming follows UpperCamelCase convention"
|
||||
fi
|
||||
|
||||
### Check for tabs instead of spaces
|
||||
echo ""
|
||||
echo "### Indentation"
|
||||
echo ""
|
||||
files_with_tabs=0
|
||||
for file in $php_files; do
|
||||
if grep -qP "\t" "$file"; then
|
||||
files_with_tabs=$((files_with_tabs + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $files_with_tabs -eq 0 ]; then
|
||||
echo "- ✅ No tabs found (using spaces for indentation)"
|
||||
else
|
||||
echo "- ❌ ${files_with_tabs} files using tabs instead of spaces"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Check for proper use statements
|
||||
echo ""
|
||||
echo "### Use Statements"
|
||||
echo ""
|
||||
|
||||
# Check if use statements are present and not duplicated
|
||||
duplicate_uses=$(grep -rh "^use " Classes/ 2>/dev/null | sort | uniq -d | wc -l)
|
||||
if [ $duplicate_uses -gt 0 ]; then
|
||||
echo "- ⚠️ ${duplicate_uses} duplicate use statements found"
|
||||
else
|
||||
echo "- ✅ No duplicate use statements"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "### Summary"
|
||||
echo ""
|
||||
|
||||
if [ $has_issues -eq 0 ]; then
|
||||
echo "- ✅ **Coding standards: PASSED**"
|
||||
else
|
||||
echo "- ⚠️ **Coding standards: ISSUES FOUND**"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
|
||||
exit $has_issues
|
||||
197
scripts/check-conformance.sh
Executable file
197
scripts/check-conformance.sh
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# TYPO3 Extension Conformance Checker
|
||||
#
|
||||
# Main script to orchestrate all conformance checks
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Configuration
|
||||
PROJECT_DIR="${1:-.}"
|
||||
REPORT_DIR="${PROJECT_DIR}/.conformance-reports"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
REPORT_FILE="${REPORT_DIR}/conformance_${TIMESTAMP}.md"
|
||||
|
||||
# Script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ TYPO3 Extension Conformance Checker ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Standards Compliance Check:${NC}"
|
||||
echo -e " • TYPO3 Version: ${YELLOW}12.4 LTS / 13.x${NC}"
|
||||
echo -e " • PHP Version: ${YELLOW}8.1 / 8.2 / 8.3 / 8.4${NC}"
|
||||
echo -e " • PSR Standard: ${YELLOW}PSR-12 (Extended Coding Style)${NC}"
|
||||
echo -e " • Architecture: ${YELLOW}Dependency Injection, PSR-14 Events${NC}"
|
||||
echo ""
|
||||
|
||||
# Create report directory
|
||||
mkdir -p "${REPORT_DIR}"
|
||||
|
||||
# Check if directory exists
|
||||
if [ ! -d "${PROJECT_DIR}" ]; then
|
||||
echo -e "${RED}✗ Error: Directory ${PROJECT_DIR} not found${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${PROJECT_DIR}"
|
||||
|
||||
# Check if this is a TYPO3 extension
|
||||
if [ ! -f "composer.json" ] && [ ! -f "ext_emconf.php" ]; then
|
||||
echo -e "${RED}✗ Error: Not a TYPO3 extension (composer.json or ext_emconf.php not found)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓ TYPO3 Extension detected${NC}"
|
||||
echo ""
|
||||
|
||||
# Initialize report
|
||||
cat > "${REPORT_FILE}" <<'EOF'
|
||||
# TYPO3 Extension Conformance Report
|
||||
|
||||
**Generated:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||
**Project:** $(basename "$(pwd)")
|
||||
|
||||
## Standards Checked
|
||||
|
||||
This conformance check validates your extension against the following standards:
|
||||
|
||||
| Standard | Version/Specification |
|
||||
|----------|----------------------|
|
||||
| **TYPO3 Core** | 12.4 LTS / 13.x |
|
||||
| **PHP** | 8.1 / 8.2 / 8.3 / 8.4 |
|
||||
| **Coding Style** | PSR-12 (Extended Coding Style) |
|
||||
| **Architecture** | Dependency Injection (PSR-11), PSR-14 Events, PSR-15 Middleware |
|
||||
| **Testing** | PHPUnit 10+, TYPO3 Testing Framework |
|
||||
| **Documentation** | reStructuredText (RST), TYPO3 Documentation Standards |
|
||||
|
||||
**Reference Documentation:**
|
||||
- [TYPO3 Extension Architecture](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/)
|
||||
- [TYPO3 Coding Guidelines](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/CodingGuidelines/)
|
||||
- [PHP Architecture](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/PhpArchitecture/)
|
||||
- [Testing Standards](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Testing/)
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Category | Score | Status |
|
||||
|----------|-------|--------|
|
||||
EOF
|
||||
|
||||
# Initialize scores
|
||||
total_score=0
|
||||
max_score=100
|
||||
|
||||
echo -e "${YELLOW}Running conformance checks...${NC}"
|
||||
echo ""
|
||||
|
||||
# 1. File Structure Check
|
||||
echo -e "${BLUE}[1/5] Checking file structure...${NC}"
|
||||
if bash "${SCRIPT_DIR}/check-file-structure.sh" "${PROJECT_DIR}" >> "${REPORT_FILE}"; then
|
||||
echo -e "${GREEN} ✓ File structure check complete${NC}"
|
||||
structure_score=18
|
||||
else
|
||||
echo -e "${YELLOW} ⚠ File structure issues found${NC}"
|
||||
structure_score=10
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. Coding Standards Check
|
||||
echo -e "${BLUE}[2/5] Checking coding standards...${NC}"
|
||||
if bash "${SCRIPT_DIR}/check-coding-standards.sh" "${PROJECT_DIR}" >> "${REPORT_FILE}"; then
|
||||
echo -e "${GREEN} ✓ Coding standards check complete${NC}"
|
||||
coding_score=18
|
||||
else
|
||||
echo -e "${YELLOW} ⚠ Coding standards issues found${NC}"
|
||||
coding_score=12
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Architecture Check
|
||||
echo -e "${BLUE}[3/5] Checking PHP architecture...${NC}"
|
||||
if bash "${SCRIPT_DIR}/check-architecture.sh" "${PROJECT_DIR}" >> "${REPORT_FILE}"; then
|
||||
echo -e "${GREEN} ✓ Architecture check complete${NC}"
|
||||
arch_score=18
|
||||
else
|
||||
echo -e "${YELLOW} ⚠ Architecture issues found${NC}"
|
||||
arch_score=10
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. Testing Check
|
||||
echo -e "${BLUE}[4/6] Checking testing infrastructure...${NC}"
|
||||
if bash "${SCRIPT_DIR}/check-testing.sh" "${PROJECT_DIR}" >> "${REPORT_FILE}"; then
|
||||
echo -e "${GREEN} ✓ Testing check complete${NC}"
|
||||
test_score=16
|
||||
else
|
||||
echo -e "${YELLOW} ⚠ Testing issues found${NC}"
|
||||
test_score=8
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 5. PHPStan Baseline Check
|
||||
echo -e "${BLUE}[5/6] Checking PHPStan baseline hygiene...${NC}"
|
||||
if bash "${SCRIPT_DIR}/check-phpstan-baseline.sh" "${PROJECT_DIR}"; then
|
||||
echo -e "${GREEN} ✓ PHPStan baseline hygiene check passed${NC}"
|
||||
baseline_score=10
|
||||
else
|
||||
echo -e "${RED} ✗ PHPStan baseline violation detected${NC}"
|
||||
baseline_score=0
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 6. Generate comprehensive report
|
||||
echo -e "${BLUE}[6/6] Generating final report...${NC}"
|
||||
bash "${SCRIPT_DIR}/generate-report.sh" "${PROJECT_DIR}" "${REPORT_FILE}" \
|
||||
"${structure_score}" "${coding_score}" "${arch_score}" "${test_score}"
|
||||
echo ""
|
||||
|
||||
# Calculate total (including baseline hygiene score)
|
||||
total_score=$((structure_score + coding_score + arch_score + test_score + baseline_score))
|
||||
|
||||
# Display summary
|
||||
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ Conformance Results ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " File Structure: ${structure_score}/20"
|
||||
echo -e " Coding Standards: ${coding_score}/20"
|
||||
echo -e " PHP Architecture: ${arch_score}/20"
|
||||
echo -e " Testing Standards: ${test_score}/20"
|
||||
echo -e " Baseline Hygiene: ${baseline_score}/10"
|
||||
echo -e " Best Practices: 10/10"
|
||||
echo ""
|
||||
echo -e " ${BLUE}Total Score: ${total_score}/100${NC}"
|
||||
echo ""
|
||||
|
||||
if [ ${total_score} -ge 80 ]; then
|
||||
echo -e "${GREEN}✓ EXCELLENT conformance level${NC}"
|
||||
elif [ ${total_score} -ge 60 ]; then
|
||||
echo -e "${YELLOW}⚠ GOOD conformance level (some improvements recommended)${NC}"
|
||||
elif [ ${total_score} -ge 40 ]; then
|
||||
echo -e "${YELLOW}⚠ FAIR conformance level (several issues to address)${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ POOR conformance level (major improvements needed)${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Report saved to: ${REPORT_FILE}${NC}"
|
||||
echo ""
|
||||
|
||||
# Exit with appropriate code
|
||||
if [ ${total_score} -ge 60 ]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
197
scripts/check-file-structure.sh
Executable file
197
scripts/check-file-structure.sh
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# TYPO3 File Structure Conformance Checker
|
||||
#
|
||||
# Validates extension directory structure and required files
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="${1:-.}"
|
||||
cd "${PROJECT_DIR}"
|
||||
|
||||
echo "## 1. File Structure Conformance"
|
||||
echo ""
|
||||
|
||||
# Track issues
|
||||
has_issues=0
|
||||
|
||||
echo "### Required Files"
|
||||
echo ""
|
||||
|
||||
# Check required files
|
||||
if [ -f "composer.json" ]; then
|
||||
echo "- ✅ composer.json present"
|
||||
else
|
||||
echo "- ❌ composer.json missing (CRITICAL)"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
if [ -f "ext_emconf.php" ]; then
|
||||
echo "- ✅ ext_emconf.php present"
|
||||
else
|
||||
echo "- ⚠️ ext_emconf.php missing (required for TER publication)"
|
||||
fi
|
||||
|
||||
if [ -f "Documentation/Index.rst" ]; then
|
||||
echo "- ✅ Documentation/Index.rst present"
|
||||
else
|
||||
echo "- ⚠️ Documentation/Index.rst missing (required for docs.typo3.org)"
|
||||
fi
|
||||
|
||||
if [ -f "Documentation/Settings.cfg" ]; then
|
||||
echo "- ✅ Documentation/Settings.cfg present"
|
||||
else
|
||||
echo "- ⚠️ Documentation/Settings.cfg missing (required for docs.typo3.org)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "### Directory Structure"
|
||||
echo ""
|
||||
|
||||
# Check core directories
|
||||
if [ -d "Classes" ]; then
|
||||
echo "- ✅ Classes/ directory present"
|
||||
# Check for common subdirectories
|
||||
if [ -d "Classes/Controller" ]; then
|
||||
echo " - ✅ Classes/Controller/ found"
|
||||
fi
|
||||
if [ -d "Classes/Domain/Model" ]; then
|
||||
echo " - ✅ Classes/Domain/Model/ found"
|
||||
fi
|
||||
if [ -d "Classes/Domain/Repository" ]; then
|
||||
echo " - ✅ Classes/Domain/Repository/ found"
|
||||
fi
|
||||
else
|
||||
echo "- ❌ Classes/ directory missing (CRITICAL)"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
if [ -d "Configuration" ]; then
|
||||
echo "- ✅ Configuration/ directory present"
|
||||
if [ -d "Configuration/TCA" ]; then
|
||||
echo " - ✅ Configuration/TCA/ found"
|
||||
fi
|
||||
if [ -f "Configuration/Services.yaml" ]; then
|
||||
echo " - ✅ Configuration/Services.yaml found"
|
||||
else
|
||||
echo " - ⚠️ Configuration/Services.yaml missing (recommended)"
|
||||
fi
|
||||
if [ -d "Configuration/Backend" ]; then
|
||||
echo " - ✅ Configuration/Backend/ found"
|
||||
fi
|
||||
else
|
||||
echo "- ⚠️ Configuration/ directory missing"
|
||||
fi
|
||||
|
||||
if [ -d "Resources" ]; then
|
||||
echo "- ✅ Resources/ directory present"
|
||||
if [ -d "Resources/Private" ] && [ -d "Resources/Public" ]; then
|
||||
echo " - ✅ Resources/Private/ and Resources/Public/ properly separated"
|
||||
else
|
||||
echo " - ⚠️ Resources/ not properly separated into Private/ and Public/"
|
||||
fi
|
||||
else
|
||||
echo "- ⚠️ Resources/ directory missing"
|
||||
fi
|
||||
|
||||
if [ -d "Tests" ]; then
|
||||
echo "- ✅ Tests/ directory present"
|
||||
if [ -d "Tests/Unit" ]; then
|
||||
echo " - ✅ Tests/Unit/ found"
|
||||
else
|
||||
echo " - ⚠️ Tests/Unit/ missing"
|
||||
fi
|
||||
if [ -d "Tests/Functional" ]; then
|
||||
echo " - ✅ Tests/Functional/ found"
|
||||
else
|
||||
echo " - ⚠️ Tests/Functional/ missing"
|
||||
fi
|
||||
else
|
||||
echo "- ⚠️ Tests/ directory missing"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "### Anti-Patterns Check"
|
||||
echo ""
|
||||
|
||||
# Check for PHP files in root (except ext_* files)
|
||||
# Show all files but distinguish between tracked (issues) and untracked (info)
|
||||
tracked_files=()
|
||||
untracked_files=()
|
||||
all_root_php_files=()
|
||||
|
||||
# Find all PHP files in root (except ext_* files)
|
||||
while IFS= read -r file; do
|
||||
filename=$(basename "$file")
|
||||
if [[ "$filename" != ext_*.php ]]; then
|
||||
all_root_php_files+=("$filename")
|
||||
fi
|
||||
done < <(find . -maxdepth 1 -name "*.php" 2>/dev/null || true)
|
||||
|
||||
# Check if files are tracked in git (if git repository exists)
|
||||
if [ -d ".git" ]; then
|
||||
for file in "${all_root_php_files[@]}"; do
|
||||
if git ls-files --error-unmatch "$file" >/dev/null 2>&1; then
|
||||
tracked_files+=("$file")
|
||||
else
|
||||
untracked_files+=("$file")
|
||||
fi
|
||||
done
|
||||
else
|
||||
# No git repository - treat all files as tracked (potential issues)
|
||||
tracked_files=("${all_root_php_files[@]}")
|
||||
fi
|
||||
|
||||
# Report tracked files (these are issues)
|
||||
if [ ${#tracked_files[@]} -gt 0 ]; then
|
||||
if [ -d ".git" ]; then
|
||||
echo "- ❌ ${#tracked_files[@]} PHP file(s) in root directory committed to repository:"
|
||||
else
|
||||
echo "- ❌ ${#tracked_files[@]} PHP file(s) found in root directory:"
|
||||
fi
|
||||
for file in "${tracked_files[@]}"; do
|
||||
echo " - ${file} (ISSUE: should be in Classes/ or Build/)"
|
||||
done
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
# Report untracked files (informational only)
|
||||
if [ ${#untracked_files[@]} -gt 0 ]; then
|
||||
echo "- ℹ️ ${#untracked_files[@]} untracked PHP file(s) in root (ignored, not committed):"
|
||||
for file in "${untracked_files[@]}"; do
|
||||
echo " - ${file} (local file, not in repository)"
|
||||
done
|
||||
fi
|
||||
|
||||
# Success message if no files found
|
||||
if [ ${#all_root_php_files[@]} -eq 0 ]; then
|
||||
echo "- ✅ No PHP files in root (except ext_* files)"
|
||||
fi
|
||||
|
||||
# Check for deprecated ext_tables.php
|
||||
if [ -f "ext_tables.php" ]; then
|
||||
echo "- ⚠️ ext_tables.php present (consider migrating to Configuration/Backend/)"
|
||||
fi
|
||||
|
||||
# Check for wrong directory naming
|
||||
if [ -d "Classes/Controllers" ]; then
|
||||
echo "- ❌ Classes/Controllers/ found (should be Controller/ singular)"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
if [ -d "Classes/Helpers" ]; then
|
||||
echo "- ⚠️ Classes/Helpers/ found (should use Utility/ instead)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
|
||||
# Return appropriate exit code
|
||||
if [ ${has_issues} -eq 0 ]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
110
scripts/check-phpstan-baseline.sh
Executable file
110
scripts/check-phpstan-baseline.sh
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# TYPO3 Extension Conformance Checker - PHPStan Baseline Validation
|
||||
# Verifies that new code does not add errors to phpstan-baseline.neon
|
||||
#
|
||||
# Usage:
|
||||
# ./check-phpstan-baseline.sh [path-to-extension]
|
||||
#
|
||||
# Returns:
|
||||
# 0 = No baseline additions detected
|
||||
# 1 = New errors added to baseline (violation)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Parse arguments
|
||||
PROJECT_ROOT="${1:-.}"
|
||||
cd "$PROJECT_ROOT" || exit 1
|
||||
|
||||
echo "Checking PHPStan baseline hygiene in: $PROJECT_ROOT"
|
||||
echo
|
||||
|
||||
# Check if git repository
|
||||
if [ ! -d ".git" ]; then
|
||||
echo -e "${YELLOW}⚠️ Not a git repository - skipping baseline check${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Find baseline file
|
||||
BASELINE_FILE=""
|
||||
for path in "Build/phpstan-baseline.neon" "phpstan-baseline.neon" ".phpstan/baseline.neon"; do
|
||||
if [ -f "$path" ]; then
|
||||
BASELINE_FILE="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$BASELINE_FILE" ]; then
|
||||
echo -e "${GREEN}✅ No baseline file found - all code passes PHPStan level 10!${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found baseline file: $BASELINE_FILE"
|
||||
echo
|
||||
|
||||
# Check if baseline is modified in current changes
|
||||
if ! git diff --quiet "$BASELINE_FILE" 2>/dev/null; then
|
||||
echo -e "${YELLOW}⚠️ Baseline file has uncommitted changes${NC}"
|
||||
echo
|
||||
|
||||
# Extract error counts from diff
|
||||
BEFORE_COUNT=$(git show "HEAD:$BASELINE_FILE" 2>/dev/null | grep -E "^\s+count:\s+[0-9]+" | head -1 | grep -oE "[0-9]+" || echo "0")
|
||||
AFTER_COUNT=$(grep -E "^\s+count:\s+[0-9]+" "$BASELINE_FILE" | head -1 | grep -oE "[0-9]+" || echo "0")
|
||||
|
||||
if [ "$AFTER_COUNT" -gt "$BEFORE_COUNT" ]; then
|
||||
ADDED=$((AFTER_COUNT - BEFORE_COUNT))
|
||||
echo -e "${RED}❌ BASELINE VIOLATION DETECTED${NC}"
|
||||
echo
|
||||
echo "Error count increased: $BEFORE_COUNT → $AFTER_COUNT (+$ADDED errors)"
|
||||
echo
|
||||
echo "New code added $ADDED errors to the baseline!"
|
||||
echo
|
||||
echo "The baseline exists only for legacy code."
|
||||
echo "All new code MUST pass PHPStan level 10 without baseline suppression."
|
||||
echo
|
||||
echo -e "${YELLOW}How to fix:${NC}"
|
||||
echo "1. Run: composer ci:php:stan"
|
||||
echo "2. Review the new errors reported"
|
||||
echo "3. Fix the underlying issues (see coding-guidelines.md for patterns)"
|
||||
echo "4. Revert baseline changes: git checkout $BASELINE_FILE"
|
||||
echo "5. Verify: composer ci:php:stan should pass with original baseline"
|
||||
echo
|
||||
exit 1
|
||||
elif [ "$AFTER_COUNT" -lt "$BEFORE_COUNT" ]; then
|
||||
REMOVED=$((BEFORE_COUNT - AFTER_COUNT))
|
||||
echo -e "${GREEN}✅ Excellent! Baseline reduced by $REMOVED errors${NC}"
|
||||
echo
|
||||
echo "You fixed existing baseline issues - great work!"
|
||||
echo
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Baseline modified but count unchanged${NC}"
|
||||
echo
|
||||
echo "Review the baseline diff to ensure changes are intentional:"
|
||||
echo " git diff $BASELINE_FILE"
|
||||
echo
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}✅ No changes to baseline file${NC}"
|
||||
fi
|
||||
|
||||
# Check for baseline in staged changes
|
||||
if git diff --cached --quiet "$BASELINE_FILE" 2>/dev/null; then
|
||||
echo -e "${GREEN}✅ No baseline changes staged for commit${NC}"
|
||||
else
|
||||
echo
|
||||
echo -e "${YELLOW}⚠️ Warning: Baseline file is staged for commit${NC}"
|
||||
echo
|
||||
echo "Review staged baseline changes:"
|
||||
echo " git diff --cached $BASELINE_FILE"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e "${GREEN}✅ PHPStan baseline hygiene check passed${NC}"
|
||||
exit 0
|
||||
199
scripts/check-testing.sh
Executable file
199
scripts/check-testing.sh
Executable file
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# TYPO3 Testing Standards Conformance Checker
|
||||
#
|
||||
# Validates testing infrastructure and test coverage
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="${1:-.}"
|
||||
cd "${PROJECT_DIR}"
|
||||
|
||||
echo "## 4. Testing Standards Conformance"
|
||||
echo ""
|
||||
|
||||
has_issues=0
|
||||
|
||||
### Check for Tests directory
|
||||
echo "### Test Infrastructure"
|
||||
echo ""
|
||||
|
||||
if [ ! -d "Tests" ]; then
|
||||
echo "- ❌ Tests/ directory missing (CRITICAL)"
|
||||
has_issues=1
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "- ✅ Tests/ directory present"
|
||||
|
||||
### Check for PHPUnit configuration
|
||||
echo ""
|
||||
echo "### PHPUnit Configuration"
|
||||
echo ""
|
||||
|
||||
if [ -f "Build/phpunit/UnitTests.xml" ] || [ -f "phpunit.xml" ]; then
|
||||
echo "- ✅ Unit test configuration found"
|
||||
else
|
||||
echo "- ❌ No Unit test configuration (Build/phpunit/UnitTests.xml or phpunit.xml)"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
if [ -f "Build/phpunit/FunctionalTests.xml" ]; then
|
||||
echo "- ✅ Functional test configuration found"
|
||||
else
|
||||
echo "- ⚠️ No Functional test configuration (Build/phpunit/FunctionalTests.xml)"
|
||||
fi
|
||||
|
||||
### Unit Tests
|
||||
echo ""
|
||||
echo "### Unit Tests"
|
||||
echo ""
|
||||
|
||||
if [ -d "Tests/Unit" ]; then
|
||||
unit_test_count=$(find Tests/Unit/ -name "*Test.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ Tests/Unit/ directory present"
|
||||
echo " - **${unit_test_count} unit test files found**"
|
||||
|
||||
if [ $unit_test_count -eq 0 ]; then
|
||||
echo " - ⚠️ No unit tests found"
|
||||
fi
|
||||
|
||||
# Check if tests mirror Classes structure
|
||||
if [ -d "Classes/Controller" ] && [ ! -d "Tests/Unit/Controller" ]; then
|
||||
echo " - ⚠️ Tests/Unit/Controller/ missing (Classes/Controller/ exists)"
|
||||
fi
|
||||
|
||||
if [ -d "Classes/Service" ] && [ ! -d "Tests/Unit/Service" ]; then
|
||||
echo " - ⚠️ Tests/Unit/Service/ missing (Classes/Service/ exists)"
|
||||
fi
|
||||
|
||||
if [ -d "Classes/Domain/Repository" ] && [ ! -d "Tests/Unit/Domain/Repository" ]; then
|
||||
echo " - ⚠️ Tests/Unit/Domain/Repository/ missing (Classes/Domain/Repository/ exists)"
|
||||
fi
|
||||
else
|
||||
echo "- ❌ Tests/Unit/ directory missing"
|
||||
has_issues=1
|
||||
fi
|
||||
|
||||
### Functional Tests
|
||||
echo ""
|
||||
echo "### Functional Tests"
|
||||
echo ""
|
||||
|
||||
if [ -d "Tests/Functional" ]; then
|
||||
func_test_count=$(find Tests/Functional/ -name "*Test.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ Tests/Functional/ directory present"
|
||||
echo " - **${func_test_count} functional test files found**"
|
||||
|
||||
# Check for fixtures
|
||||
if [ -d "Tests/Functional/Fixtures" ]; then
|
||||
fixture_count=$(find Tests/Functional/Fixtures/ -name "*.csv" -o -name "*.xml" 2>/dev/null | wc -l)
|
||||
echo " - ✅ Tests/Functional/Fixtures/ found (${fixture_count} fixture files)"
|
||||
else
|
||||
if [ $func_test_count -gt 0 ]; then
|
||||
echo " - ⚠️ No Tests/Functional/Fixtures/ (functional tests may need fixtures)"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "- ⚠️ Tests/Functional/ directory missing"
|
||||
echo " - Functional tests recommended for repository and database operations"
|
||||
fi
|
||||
|
||||
### Acceptance Tests
|
||||
echo ""
|
||||
echo "### Acceptance Tests"
|
||||
echo ""
|
||||
|
||||
if [ -d "Tests/Acceptance" ]; then
|
||||
accept_test_count=$(find Tests/Acceptance/ -name "*Cest.php" 2>/dev/null | wc -l)
|
||||
echo "- ✅ Tests/Acceptance/ directory present"
|
||||
echo " - **${accept_test_count} acceptance test files found**"
|
||||
|
||||
if [ -f "Tests/codeception.yml" ]; then
|
||||
echo " - ✅ codeception.yml configuration found"
|
||||
else
|
||||
echo " - ⚠️ codeception.yml configuration missing"
|
||||
fi
|
||||
else
|
||||
echo "- ℹ️ Tests/Acceptance/ not found (optional for most extensions)"
|
||||
fi
|
||||
|
||||
### Test Coverage Estimate
|
||||
echo ""
|
||||
echo "### Test Coverage Estimate"
|
||||
echo ""
|
||||
|
||||
if [ -d "Classes" ]; then
|
||||
class_count=$(find Classes/ -name "*.php" 2>/dev/null | wc -l)
|
||||
|
||||
if [ -d "Tests/Unit" ]; then
|
||||
unit_count=$(find Tests/Unit/ -name "*Test.php" 2>/dev/null | wc -l)
|
||||
else
|
||||
unit_count=0
|
||||
fi
|
||||
|
||||
if [ -d "Tests/Functional" ]; then
|
||||
func_count=$(find Tests/Functional/ -name "*Test.php" 2>/dev/null | wc -l)
|
||||
else
|
||||
func_count=0
|
||||
fi
|
||||
|
||||
total_tests=$((unit_count + func_count))
|
||||
|
||||
echo "- **Total Classes:** $class_count"
|
||||
echo "- **Total Tests:** $total_tests"
|
||||
|
||||
if [ $class_count -gt 0 ]; then
|
||||
coverage_ratio=$((total_tests * 100 / class_count))
|
||||
echo "- **Test Ratio:** ${coverage_ratio}%"
|
||||
|
||||
if [ $coverage_ratio -ge 70 ]; then
|
||||
echo " - ✅ Good test coverage (≥70%)"
|
||||
elif [ $coverage_ratio -ge 50 ]; then
|
||||
echo " - ⚠️ Moderate test coverage (50-70%)"
|
||||
else
|
||||
echo " - ❌ Low test coverage (<50%)"
|
||||
has_issues=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
### Check for testing framework dependency
|
||||
echo ""
|
||||
echo "### Testing Framework Dependency"
|
||||
echo ""
|
||||
|
||||
if [ -f "composer.json" ]; then
|
||||
if grep -q "typo3/testing-framework" composer.json; then
|
||||
echo "- ✅ typo3/testing-framework in composer.json"
|
||||
else
|
||||
echo "- ⚠️ typo3/testing-framework not found in composer.json"
|
||||
fi
|
||||
|
||||
if grep -q "phpunit/phpunit" composer.json; then
|
||||
echo "- ✅ phpunit/phpunit in composer.json"
|
||||
else
|
||||
echo "- ⚠️ phpunit/phpunit not found in composer.json"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "### Summary"
|
||||
echo ""
|
||||
|
||||
if [ $has_issues -eq 0 ]; then
|
||||
echo "- ✅ **Testing Standards: PASSED**"
|
||||
else
|
||||
echo "- ⚠️ **Testing Standards: ISSUES FOUND**"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
|
||||
exit $has_issues
|
||||
143
scripts/generate-report.sh
Executable file
143
scripts/generate-report.sh
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# Generate final conformance report with recommendations
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="${1}"
|
||||
REPORT_FILE="${2}"
|
||||
STRUCTURE_SCORE="${3:-15}"
|
||||
CODING_SCORE="${4:-15}"
|
||||
ARCH_SCORE="${5:-15}"
|
||||
TEST_SCORE="${6:-15}"
|
||||
|
||||
cd "${PROJECT_DIR}"
|
||||
|
||||
# Calculate total
|
||||
TOTAL_SCORE=$((STRUCTURE_SCORE + CODING_SCORE + ARCH_SCORE + TEST_SCORE + 10))
|
||||
|
||||
# Update summary table
|
||||
sed -i "s/| Extension Architecture .*/| Extension Architecture | ${STRUCTURE_SCORE}\/20 | $(if [ ${STRUCTURE_SCORE} -ge 15 ]; then echo "✅ Passed"; else echo "⚠️ Issues"; fi) |/" "${REPORT_FILE}"
|
||||
sed -i "/| Extension Architecture /a | Coding Guidelines | ${CODING_SCORE}/20 | $(if [ ${CODING_SCORE} -ge 15 ]; then echo "✅ Passed"; else echo "⚠️ Issues"; fi) |" "${REPORT_FILE}" 2>/dev/null || true
|
||||
sed -i "/| Coding Guidelines /a | PHP Architecture | ${ARCH_SCORE}/20 | $(if [ ${ARCH_SCORE} -ge 15 ]; then echo "✅ Passed"; else echo "⚠️ Issues"; fi) |" "${REPORT_FILE}" 2>/dev/null || true
|
||||
sed -i "/| PHP Architecture /a | Testing Standards | ${TEST_SCORE}/20 | $(if [ ${TEST_SCORE} -ge 15 ]; then echo "✅ Passed"; else echo "⚠️ Issues"; fi) |" "${REPORT_FILE}" 2>/dev/null || true
|
||||
sed -i "/| Testing Standards /a | Best Practices | 10/20 | ℹ️ Partial |" "${REPORT_FILE}" 2>/dev/null || true
|
||||
sed -i "/| Best Practices /a | **TOTAL** | **${TOTAL_SCORE}/100** | $(if [ ${TOTAL_SCORE} -ge 80 ]; then echo "✅ Excellent"; elif [ ${TOTAL_SCORE} -ge 60 ]; then echo "✅ Good"; else echo "⚠️ Fair"; fi) |" "${REPORT_FILE}" 2>/dev/null || true
|
||||
|
||||
# Add final sections
|
||||
cat >> "${REPORT_FILE}" <<EOF
|
||||
|
||||
---
|
||||
|
||||
## 5. Best Practices Assessment
|
||||
|
||||
### Project Infrastructure
|
||||
- **README.md:** $(if [ -f "README.md" ]; then echo "✅ Present"; else echo "❌ Missing"; fi)
|
||||
- **LICENSE:** $(if [ -f "LICENSE" ]; then echo "✅ Present"; else echo "❌ Missing"; fi)
|
||||
- **.editorconfig:** $(if [ -f ".editorconfig" ]; then echo "✅ Present"; else echo "⚠️ Missing"; fi)
|
||||
- **.gitignore:** $(if [ -f ".gitignore" ]; then echo "✅ Present"; else echo "⚠️ Missing"; fi)
|
||||
|
||||
### Code Quality Tools
|
||||
- **php-cs-fixer:** $(if [ -f ".php-cs-fixer.dist.php" ] || [ -f ".php-cs-fixer.php" ] || [ -f "Build/.php-cs-fixer.dist.php" ] || [ -f "Build/.php-cs-fixer.php" ]; then echo "✅ Configured"; else echo "⚠️ Not configured"; fi)
|
||||
- **phpstan:** $(if [ -f "phpstan.neon" ] || [ -f "phpstan.neon.dist" ] || [ -f "Build/phpstan.neon" ] || [ -f "Build/phpstan.neon.dist" ]; then echo "✅ Configured"; else echo "⚠️ Not configured"; fi)
|
||||
- **rector:** $(if [ -f "rector.php" ] || [ -f "Build/rector.php" ]; then echo "✅ Configured"; else echo "ℹ️ Not configured"; fi)
|
||||
|
||||
### CI/CD Pipeline
|
||||
- **GitHub Actions:** $(if [ -d ".github/workflows" ]; then echo "✅ Configured"; else echo "⚠️ Not found"; fi)
|
||||
- **GitLab CI:** $(if [ -f ".gitlab-ci.yml" ]; then echo "✅ Configured"; else echo "ℹ️ Not found"; fi)
|
||||
|
||||
---
|
||||
|
||||
## Overall Assessment
|
||||
|
||||
**Total Score: ${TOTAL_SCORE}/100**
|
||||
|
||||
$(if [ ${TOTAL_SCORE} -ge 80 ]; then
|
||||
cat <<END
|
||||
### ✅ EXCELLENT Conformance Level
|
||||
|
||||
Your TYPO3 extension demonstrates strong adherence to official standards and best practices.
|
||||
|
||||
**Strengths:**
|
||||
- Well-structured architecture following TYPO3 conventions
|
||||
- Modern PHP patterns with dependency injection
|
||||
- Good code quality and testing coverage
|
||||
- Proper documentation and infrastructure
|
||||
|
||||
**Minor Improvements:**
|
||||
- Continue maintaining high standards
|
||||
- Keep dependencies updated
|
||||
- Monitor code coverage trends
|
||||
END
|
||||
elif [ ${TOTAL_SCORE} -ge 60 ]; then
|
||||
cat <<END
|
||||
### ✅ GOOD Conformance Level
|
||||
|
||||
Your TYPO3 extension follows most standards with some areas for improvement.
|
||||
|
||||
**Next Steps:**
|
||||
1. Address critical issues identified above
|
||||
2. Improve test coverage
|
||||
3. Add missing configuration files
|
||||
4. Update deprecated patterns
|
||||
|
||||
**Timeline:** 2-4 weeks for improvements
|
||||
END
|
||||
else
|
||||
cat <<END
|
||||
### ⚠️ FAIR Conformance Level
|
||||
|
||||
Your TYPO3 extension requires significant improvements to meet TYPO3 standards.
|
||||
|
||||
**Priority Actions:**
|
||||
1. Fix critical file structure issues
|
||||
2. Migrate deprecated patterns (GeneralUtility::makeInstance, \$GLOBALS)
|
||||
3. Add comprehensive testing infrastructure
|
||||
4. Improve code quality (strict types, PHPDoc, PSR-12)
|
||||
5. Add project infrastructure (CI/CD, quality tools)
|
||||
|
||||
**Timeline:** 4-8 weeks for comprehensive improvements
|
||||
END
|
||||
fi)
|
||||
|
||||
---
|
||||
|
||||
## Quick Action Checklist
|
||||
|
||||
### High Priority (Fix Now)
|
||||
$(if [ ${STRUCTURE_SCORE} -lt 15 ]; then echo "- [ ] Fix critical file structure issues (missing required files/directories)"; fi)
|
||||
$(if grep -q "GeneralUtility::makeInstance" Classes/ 2>/dev/null; then echo "- [ ] Migrate GeneralUtility::makeInstance to constructor injection"; fi)
|
||||
$(if grep -q '\$GLOBALS\[' Classes/ 2>/dev/null; then echo "- [ ] Remove \$GLOBALS access, use dependency injection"; fi)
|
||||
$(if [ ! -f "Configuration/Services.yaml" ]; then echo "- [ ] Add Configuration/Services.yaml with DI configuration"; fi)
|
||||
|
||||
### Medium Priority (Fix Soon)
|
||||
$(if [ ${CODING_SCORE} -lt 15 ]; then echo "- [ ] Add declare(strict_types=1) to all PHP files"; fi)
|
||||
$(if [ ${CODING_SCORE} -lt 15 ]; then echo "- [ ] Replace array() with [] short syntax"; fi)
|
||||
$(if [ ${TEST_SCORE} -lt 15 ]; then echo "- [ ] Add unit tests for untested classes"; fi)
|
||||
$(if [ ! -d "Tests/Functional" ]; then echo "- [ ] Add functional tests for repositories"; fi)
|
||||
|
||||
### Low Priority (Improve When Possible)
|
||||
$(if [ ! -f ".php-cs-fixer.dist.php" ] && [ ! -f ".php-cs-fixer.php" ] && [ ! -f "Build/.php-cs-fixer.dist.php" ] && [ ! -f "Build/.php-cs-fixer.php" ]; then echo "- [ ] Configure PHP CS Fixer"; fi)
|
||||
$(if [ ! -f "phpstan.neon" ] && [ ! -f "phpstan.neon.dist" ] && [ ! -f "Build/phpstan.neon" ] && [ ! -f "Build/phpstan.neon.dist" ]; then echo "- [ ] Configure PHPStan for static analysis"; fi)
|
||||
$(if [ ! -d ".github/workflows" ]; then echo "- [ ] Set up CI/CD pipeline (GitHub Actions)"; fi)
|
||||
- [ ] Improve PHPDoc comments coverage
|
||||
- [ ] Add .editorconfig for consistent formatting
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **TYPO3 Extension Architecture:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/
|
||||
- **Coding Guidelines:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/CodingGuidelines/
|
||||
- **Dependency Injection:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/DependencyInjection/
|
||||
- **Testing Documentation:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/Testing/
|
||||
- **Tea Extension (Best Practice):** https://github.com/TYPO3BestPractices/tea
|
||||
|
||||
---
|
||||
|
||||
*Report generated by TYPO3 Extension Conformance Checker*
|
||||
EOF
|
||||
|
||||
echo "Final report generated successfully"
|
||||
Reference in New Issue
Block a user