Skip to content

Commit 64c9598

Browse files
committed
[FIX] PostgreSQL support.
1 parent 1919258 commit 64c9598

2 files changed

Lines changed: 98 additions & 10 deletions

File tree

bin/evo

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ final class EvoBootstrapper
349349
// Fallback: walk up a few levels and look for a composer root with vendor metadata.
350350
$dir = $this->packageRoot;
351351
for ($i = 0; $i < 6; $i++) {
352-
if (is_file($dir . '/composer.json') && is_file($dir . '/vendor/composer/installed.json')) {
352+
if ($this->looksLikeComposerRoot($dir)) {
353353
return $dir;
354354
}
355355
$parent = dirname($dir);
@@ -364,20 +364,46 @@ final class EvoBootstrapper
364364

365365
private function detectComposerRootFromVendorLayout(): ?string
366366
{
367-
$vendorDir = dirname($this->packageRoot, 2);
368-
if (basename($vendorDir) !== 'vendor') {
369-
return null;
367+
// Locate the nearest parent "vendor" directory. Typical layouts:
368+
// - <root>/vendor/evolution-cms/installer/bin/evo
369+
// - <root>/vendor-php/evolution-cms/installer/bin/evo (repo/dev)
370+
$dir = $this->packageRoot;
371+
for ($i = 0; $i < 10; $i++) {
372+
$base = basename($dir);
373+
if ($base === 'vendor' || $base === 'vendor-php') {
374+
$root = dirname($dir);
375+
if ($this->looksLikeComposerRoot($root)) {
376+
return $root;
377+
}
378+
return null;
379+
}
380+
$parent = dirname($dir);
381+
if ($parent === $dir) {
382+
break;
383+
}
384+
$dir = $parent;
370385
}
371386

372-
$root = dirname($vendorDir);
373-
if (!is_file($root . '/composer.json')) {
374-
return null;
387+
return null;
388+
}
389+
390+
private function looksLikeComposerRoot(string $dir): bool
391+
{
392+
if (!is_file($dir . '/composer.json')) {
393+
return false;
375394
}
376-
if (!is_file($vendorDir . '/composer/installed.json') && !is_file($vendorDir . '/composer/installed.php')) {
377-
return null;
395+
396+
foreach (['vendor', 'vendor-php'] as $vendorBase) {
397+
$composerMeta = $dir . '/' . $vendorBase . '/composer';
398+
if (!is_dir($composerMeta)) {
399+
continue;
400+
}
401+
if (is_file($composerMeta . '/installed.json') || is_file($composerMeta . '/installed.php')) {
402+
return true;
403+
}
378404
}
379405

380-
return $root;
406+
return false;
381407
}
382408

383409
/**

src/Commands/InstallCommand.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,6 +1962,10 @@ protected function runMigrations(string $projectPath, array $options): void
19621962

19631963
$this->ensureArtisanDependencies($projectPath);
19641964

1965+
if (($options['database']['type'] ?? null) === 'pgsql') {
1966+
$this->patchPostgresInetDefaultsInMigrations($projectPath);
1967+
}
1968+
19651969
$artisanScript = null;
19661970
foreach (['core/artisan', 'artisan'] as $candidate) {
19671971
if (file_exists($projectPath . '/' . $candidate)) {
@@ -2087,6 +2091,64 @@ protected function runMigrations(string $projectPath, array $options): void
20872091
}
20882092
}
20892093

2094+
protected function patchPostgresInetDefaultsInMigrations(string $projectPath): void
2095+
{
2096+
$dirs = [
2097+
$projectPath . '/core/database/migrations',
2098+
$projectPath . '/install/stubs/migrations',
2099+
];
2100+
2101+
$totalReplacements = 0;
2102+
$touchedFiles = 0;
2103+
2104+
foreach ($dirs as $dir) {
2105+
if (!is_dir($dir)) {
2106+
continue;
2107+
}
2108+
2109+
$files = glob($dir . '/*.php') ?: [];
2110+
foreach ($files as $file) {
2111+
$original = @file_get_contents($file);
2112+
if (!is_string($original) || $original === '') {
2113+
continue;
2114+
}
2115+
2116+
$patched = $original;
2117+
$count = 0;
2118+
2119+
// PostgreSQL uses the `inet` type for Laravel's `ipAddress()` / `inet()`.
2120+
// An empty-string default is invalid for `inet` and breaks migrations.
2121+
$patched = preg_replace(
2122+
'/(->(?:ipAddress|inet)\\s*\\([^;]*?)->default\\(\\s*(?:\'\'|"")\\s*\\)/s',
2123+
'$1',
2124+
$patched,
2125+
-1,
2126+
$count
2127+
);
2128+
2129+
if (!is_string($patched) || $count <= 0 || $patched === $original) {
2130+
continue;
2131+
}
2132+
2133+
if (is_file($file) && !is_writable($file)) {
2134+
@chmod($file, 0644);
2135+
}
2136+
2137+
if (@file_put_contents($file, $patched) !== false) {
2138+
$totalReplacements += $count;
2139+
$touchedFiles++;
2140+
}
2141+
}
2142+
}
2143+
2144+
if ($totalReplacements > 0) {
2145+
$this->tui->addLog(
2146+
"PostgreSQL compatibility: removed {$totalReplacements} empty inet default(s) in {$touchedFiles} migration file(s).",
2147+
'warning'
2148+
);
2149+
}
2150+
}
2151+
20902152
protected function runPackageDiscovery(string $projectPath, string $artisanScript): void
20912153
{
20922154
$this->tui->addLog('Running package discovery...');

0 commit comments

Comments
 (0)