fix: stabilise staging sync

This commit is contained in:
2025-11-01 19:39:28 +01:00
parent 5a79646daf
commit b76064d94a
6 changed files with 7 additions and 146 deletions

View File

@@ -57,7 +57,9 @@ services:
[ -f /run/secrets/GIT_TOKEN ] && export GIT_TOKEN="$(cat /run/secrets/GIT_TOKEN)" || true [ -f /run/secrets/GIT_TOKEN ] && export GIT_TOKEN="$(cat /run/secrets/GIT_TOKEN)" || true
# Fix Git ownership issue # Fix Git ownership issue
# Ensure Git treats the mounted repository as safe regardless of owner
git config --global --add safe.directory /var/www/html 2>/dev/null || true git config --global --add safe.directory /var/www/html 2>/dev/null || true
git config --system --add safe.directory /var/www/html 2>/dev/null || true
# Git Clone/Pull functionality # Git Clone/Pull functionality
if [ -n "$GIT_REPOSITORY_URL" ]; then if [ -n "$GIT_REPOSITORY_URL" ]; then
@@ -84,7 +86,7 @@ services:
fi fi
TEMP_CLONE="${GIT_TARGET_DIR}.tmp" TEMP_CLONE="${GIT_TARGET_DIR}.tmp"
rm -rf "$TEMP_CLONE" 2>/dev/null || true rm -rf "$TEMP_CLONE" 2>/dev/null || true
if git clone --branch "$GIT_BRANCH" --depth 1 "$GIT_URL_WITH_AUTH" "$TEMP_CLONE"; then if git -c safe.directory=/var/www/html clone --branch "$GIT_BRANCH" --depth 1 "$GIT_URL_WITH_AUTH" "$TEMP_CLONE"; then
find "$GIT_TARGET_DIR" -mindepth 1 -maxdepth 1 ! -name "storage" -exec rm -rf {} \; 2>/dev/null || true find "$GIT_TARGET_DIR" -mindepth 1 -maxdepth 1 ! -name "storage" -exec rm -rf {} \; 2>/dev/null || true
find "$TEMP_CLONE" -mindepth 1 -maxdepth 1 ! -name "." ! -name ".." -exec mv {} "$GIT_TARGET_DIR/" \; 2>/dev/null || true find "$TEMP_CLONE" -mindepth 1 -maxdepth 1 ! -name "." ! -name ".." -exec mv {} "$GIT_TARGET_DIR/" \; 2>/dev/null || true
rm -rf "$TEMP_CLONE" 2>/dev/null || true rm -rf "$TEMP_CLONE" 2>/dev/null || true
@@ -93,9 +95,9 @@ services:
else else
echo "🔄 Pulling latest changes from $GIT_BRANCH..." echo "🔄 Pulling latest changes from $GIT_BRANCH..."
cd "$GIT_TARGET_DIR" cd "$GIT_TARGET_DIR"
git fetch origin "$GIT_BRANCH" || echo "⚠️ Git fetch failed" git -c safe.directory=/var/www/html fetch origin "$GIT_BRANCH" || echo "⚠️ Git fetch failed"
git reset --hard "origin/$GIT_BRANCH" || echo "⚠️ Git reset failed" git -c safe.directory=/var/www/html reset --hard "origin/$GIT_BRANCH" || echo "⚠️ Git reset failed"
git clean -fd || true git -c safe.directory=/var/www/html clean -fd || true
fi fi
# Install dependencies # Install dependencies

View File

@@ -25,7 +25,7 @@ use App\Framework\Logging\ValueObjects\LogContext;
name: 'detect:n-plus-one', name: 'detect:n-plus-one',
description: 'Detect N+1 query problems and generate optimization recommendations' description: 'Detect N+1 query problems and generate optimization recommendations'
)] )]
final readonly class DetectN+1Command final readonly class DetectNPlusOneCommand
{ {
public function __construct( public function __construct(
private NPlusOneDetectionService $detectionService, private NPlusOneDetectionService $detectionService,

View File

@@ -1,141 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Framework\Discovery\Processing;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Filesystem\File;
use App\Framework\Filesystem\FileSystemService;
use Throwable;
/**
* Extracts class information from PHP files efficiently
*/
final readonly class ClassExtractor
{
private const PATTERNS = [
'namespace' => '/^\s*namespace\s+([^;]+);/m',
'class' => '/^\s*(?:final\s+)?(?:abstract\s+)?(?:readonly\s+)?class\s+([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/mi',
'interface' => '/^\s*interface\s+([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/mi',
'trait' => '/^\s*trait\s+([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/mi',
'enum' => '/^\s*enum\s+([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/mi',
];
public function __construct(
private FileSystemService $fileSystemService
) {
}
/**
* Extract class names from a file
* @return array<ClassName>
*/
public function extractFromFile(File $file): array
{
try {
// Read file content once
$content = $this->fileSystemService->readFile($file);
// Extract namespace
$namespace = $this->extractNamespace($content);
// Extract all class-like declarations
$classNames = [];
foreach (['class', 'interface', 'trait', 'enum'] as $type) {
$names = $this->extractDeclarations($content, $type, $namespace);
foreach ($names as $name) {
$classNames[] = $name;
}
}
return $this->deduplicateClassNames($classNames);
} catch (Throwable) {
// Silently fail for files that can't be processed
return [];
}
}
/**
* Extract namespace from content
*/
private function extractNamespace(string $content): string
{
if (preg_match(self::PATTERNS['namespace'], $content, $matches)) {
return trim($matches[1]);
}
return '';
}
/**
* Extract declarations of a specific type
* @return array<ClassName>
*/
private function extractDeclarations(string $content, string $type, string $namespace): array
{
$pattern = self::PATTERNS[$type] ?? null;
if (! $pattern) {
return [];
}
$classNames = [];
if (preg_match_all($pattern, $content, $matches)) {
foreach ($matches[1] as $name) {
$fullName = $namespace ? $namespace . '\\' . $name : $name;
$classNames[] = ClassName::create($fullName);
}
}
return $classNames;
}
/**
* Remove duplicate class names
* @param array<ClassName> $classNames
* @return array<ClassName>
*/
private function deduplicateClassNames(array $classNames): array
{
$seen = [];
$unique = [];
foreach ($classNames as $className) {
$fqn = $className->getFullyQualified();
if (! isset($seen[$fqn])) {
$seen[$fqn] = true;
$unique[] = $className;
}
}
return $unique;
}
/**
* Quick check if content likely contains PHP classes
*/
public function likelyContainsClasses(string $content): bool
{
// Quick checks to avoid regex on files that definitely don't have classes
if (strlen($content) < 10) {
return false;
}
// Must have PHP opening tag
if (! str_contains($content, '<?php')) {
return false;
}
// Check for class-like keywords
$keywords = ['class ', 'interface ', 'trait ', 'enum '];
foreach ($keywords as $keyword) {
if (str_contains($content, $keyword)) {
return true;
}
}
return false;
}
}