Skip to content

Commit ac4f619

Browse files
committed
chore: wip
1 parent becb708 commit ac4f619

File tree

11 files changed

+265
-222
lines changed

11 files changed

+265
-222
lines changed

.github/workflows/precompile-php.yml

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,11 @@ jobs:
573573
if [[ "$POSTGRESQL_AVAILABLE" == "true" ]]; then
574574
echo "PostgreSQL found and working"
575575
else
576-
echo "PostgreSQL not found or not working, will disable PostgreSQL support"
576+
if [[ "${{ matrix.config }}" == "laravel-postgres" ]]; then
577+
echo "❌ PostgreSQL not available; cannot build laravel-postgres binary on this runner"
578+
exit 1
579+
fi
580+
echo "PostgreSQL not found or not working, will disable PostgreSQL support for non-postgres configs"
577581
# Remove PostgreSQL extensions from CONFIGURE_EXTENSIONS
578582
export CONFIGURE_EXTENSIONS=$(echo "$CONFIGURE_EXTENSIONS" | sed 's/--with-pdo-pgsql//g' | sed 's/--with-pgsql//g' | sed 's/ */ /g')
579583
echo "Updated CONFIGURE_EXTENSIONS: $CONFIGURE_EXTENSIONS"
@@ -682,6 +686,8 @@ jobs:
682686
if [[ "${{ matrix.platform }}" == "darwin" ]]; then
683687
CXXFLAGS="$CXXFLAGS" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" CC="$CC" CXX="$CXX" ./configure \
684688
--prefix="$INSTALL_PREFIX" \
689+
--with-config-file-path="$INSTALL_PREFIX/lib" \
690+
--with-config-file-scan-dir="$INSTALL_PREFIX/lib/conf.d" \
685691
--disable-debug \
686692
--enable-shared \
687693
--with-pic \
@@ -691,6 +697,8 @@ jobs:
691697
else
692698
./configure \
693699
--prefix="$INSTALL_PREFIX" \
700+
--with-config-file-path="$INSTALL_PREFIX/lib" \
701+
--with-config-file-scan-dir="$INSTALL_PREFIX/lib/conf.d" \
694702
--disable-debug \
695703
--enable-shared \
696704
--with-pic \
@@ -886,6 +894,51 @@ jobs:
886894
"$INSTALL_PREFIX/bin/php" --version
887895
"$INSTALL_PREFIX/bin/php" -m # Show loaded modules
888896
897+
# Generate a default php.ini to ensure DB extensions are enabled by default
898+
echo "Generating default php.ini for configuration: ${{ matrix.config }}"
899+
EXT_DIR=$("$INSTALL_PREFIX/bin/php-config" --extension-dir 2>/dev/null || echo "")
900+
PHP_INI_DIR="$INSTALL_PREFIX/lib"
901+
mkdir -p "$PHP_INI_DIR"
902+
PHP_INI="$PHP_INI_DIR/php.ini"
903+
{
904+
echo "; Launchpad php.ini (auto-generated in CI)"
905+
echo "memory_limit = 512M"
906+
echo "max_execution_time = 300"
907+
echo "upload_max_filesize = 64M"
908+
echo "post_max_size = 64M"
909+
echo "display_errors = On"
910+
echo "error_reporting = E_ALL"
911+
if [ -n "$EXT_DIR" ]; then
912+
echo "extension_dir = \"$EXT_DIR\""
913+
fi
914+
case "${{ matrix.config }}" in
915+
"laravel-postgres")
916+
echo "extension=pdo_pgsql"
917+
echo "extension=pgsql"
918+
;;
919+
"laravel-mysql")
920+
echo "extension=pdo_mysql"
921+
echo "extension=mysqli"
922+
;;
923+
"laravel-sqlite")
924+
echo "extension=pdo_sqlite"
925+
echo "extension=sqlite3"
926+
;;
927+
"enterprise"|"full-stack")
928+
echo "extension=pdo_pgsql"
929+
echo "extension=pgsql"
930+
echo "extension=pdo_mysql"
931+
echo "extension=mysqli"
932+
echo "extension=pdo_sqlite"
933+
echo "extension=sqlite3"
934+
;;
935+
*)
936+
:
937+
;;
938+
esac
939+
} > "$PHP_INI"
940+
echo "Created $PHP_INI"
941+
889942
- name: Create binary package
890943
run: |
891944
cd ${{ env.OUTPUT_DIR }}

packages/launchpad/bin/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ cli
904904
.alias('add')
905905
.option('--verbose', 'Enable verbose output')
906906
.option('--path <path>', 'Custom installation path')
907-
.option('--global-deps', 'Install all global dependencies found across the machine')
907+
.option('-g, --global-deps', 'Install all global dependencies found across the machine')
908908
.option('--deps-only', 'Install only the dependencies of packages, not the packages themselves')
909909
.option('--dry-run', 'Show packages that would be installed without installing them')
910910
.option('--quiet', 'Suppress non-error output')

packages/launchpad/launchpad.config.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -68,47 +68,6 @@ export const defaultConfig: LaunchpadConfig = {
6868
enabled: true,
6969
version: '8.4.11',
7070
},
71-
frameworks: {
72-
laravel: {
73-
postSetup: {
74-
enabled: true,
75-
commands: [
76-
{
77-
name: 'migrate',
78-
command: 'php artisan migrate',
79-
description: 'Run database migrations',
80-
runInBackground: false,
81-
required: false,
82-
},
83-
{
84-
name: 'seed',
85-
command: 'php artisan db:seed',
86-
description: 'Seed the database with sample data',
87-
runInBackground: false,
88-
required: false,
89-
},
90-
{
91-
name: 'storage-link',
92-
command: 'php artisan storage:link',
93-
description: 'Create symbolic link for storage',
94-
runInBackground: false,
95-
required: false,
96-
},
97-
{
98-
name: 'optimize',
99-
command: 'php artisan optimize',
100-
description: 'Optimize Laravel for production',
101-
runInBackground: false,
102-
required: false,
103-
},
104-
],
105-
},
106-
},
107-
stacks: {
108-
enabled: true,
109-
autoDetect: true,
110-
},
111-
},
11271
},
11372
}
11473

packages/launchpad/src/binary-downloader.ts

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export class PrecompiledBinaryDownloader {
194194
// eslint-disable-next-line ts/no-require-imports
195195
const fs = require('node:fs')
196196

197-
// Check for Laravel
197+
// Check for Laravel (or Laravel-like) projects
198198
if (fs.existsSync('artisan') && fs.existsSync('composer.json')) {
199199
try {
200200
const composerJson = JSON.parse(fs.readFileSync('composer.json', 'utf-8'))
@@ -233,6 +233,20 @@ export class PrecompiledBinaryDownloader {
233233
}
234234
}
235235

236+
// Even if composer does not indicate Laravel explicitly, infer from .env alone
237+
try {
238+
if (fs.existsSync('.env')) {
239+
const envContent = fs.readFileSync('.env', 'utf-8')
240+
if (envContent.includes('DB_CONNECTION=pgsql') || envContent.includes('DB_CONNECTION=postgres')) {
241+
return 'laravel-postgres'
242+
}
243+
if (envContent.includes('DB_CONNECTION=sqlite')) {
244+
return 'laravel-sqlite'
245+
}
246+
}
247+
}
248+
catch {}
249+
236250
// Check for WordPress without Laravel
237251
if (fs.existsSync('wp-config.php') || fs.existsSync('wp-config-sample.php')) {
238252
return 'wordpress'
@@ -697,6 +711,20 @@ Thanks for helping us make Launchpad better! 🙏
697711

698712
// Find Launchpad-installed libraries for PHP dependencies
699713
const launchpadLibraryPaths = await this.findLaunchpadLibraryPaths()
714+
// Ensure readline from pantry is included as many PHP builds reference it
715+
const readlineLocal = path.join(this.installPath, 'gnu.org/readline')
716+
const readlineGlobal = path.join(process.env.HOME || '', '.local', 'share', 'launchpad', 'global', 'gnu.org/readline')
717+
for (const base of [readlineLocal, readlineGlobal]) {
718+
if (fs.existsSync(base)) {
719+
const versions = fs.readdirSync(base).filter(v => v.startsWith('v'))
720+
for (const v of versions) {
721+
const libDir = path.join(base, v, 'lib')
722+
if (fs.existsSync(libDir) && !launchpadLibraryPaths.includes(libDir)) {
723+
launchpadLibraryPaths.push(libDir)
724+
}
725+
}
726+
}
727+
}
700728

701729
// Get all PHP binaries
702730
const binaries = fs.readdirSync(binDir).filter((file) => {
@@ -705,6 +733,40 @@ Thanks for helping us make Launchpad better! 🙏
705733
return stat.isFile() && (stat.mode & 0o111) // is executable
706734
})
707735

736+
// Prepare a project-level php.ini with database extensions based on detected project usage
737+
const projectPhpIni = path.join(this.installPath, 'php.ini')
738+
try {
739+
const detected = await this.detectFrameworkAndDatabase()
740+
const dbExtensions: string[] = []
741+
if (detected === 'laravel-postgres') {
742+
dbExtensions.push('pdo_pgsql', 'pgsql')
743+
}
744+
else if (detected === 'laravel-mysql') {
745+
dbExtensions.push('pdo_mysql', 'mysqli')
746+
}
747+
else if (detected === 'laravel-sqlite') {
748+
dbExtensions.push('pdo_sqlite', 'sqlite3')
749+
}
750+
751+
const ini = [
752+
'; Launchpad php.ini (auto-generated)',
753+
'memory_limit = 512M',
754+
'max_execution_time = 300',
755+
'upload_max_filesize = 64M',
756+
'post_max_size = 64M',
757+
'display_errors = On',
758+
'error_reporting = E_ALL',
759+
'',
760+
'; Enable database extensions based on project detection',
761+
...dbExtensions.map(ext => `extension=${ext}`),
762+
'',
763+
].join('\n')
764+
fs.writeFileSync(projectPhpIni, ini, 'utf8')
765+
}
766+
catch (err) {
767+
console.warn(`⚠️ Could not write project php.ini: ${err instanceof Error ? err.message : String(err)}`)
768+
}
769+
708770
for (const binary of binaries) {
709771
const originalBinary = path.join(binDir, binary)
710772
const shimPath = path.join(binDir, `${binary}.original`)
@@ -735,6 +797,11 @@ export DYLD_LIBRARY_PATH="${libraryPaths}:$DYLD_LIBRARY_PATH"
735797
export DYLD_FALLBACK_LIBRARY_PATH="${libraryPaths}:$DYLD_FALLBACK_LIBRARY_PATH"
736798
export LD_LIBRARY_PATH="${libraryPaths}:$LD_LIBRARY_PATH"
737799
800+
# Prefer project-level php.ini when present
801+
if [ -f "${projectPhpIni.replace(/"/g, '\\"')}" ]; then
802+
export PHPRC="${projectPhpIni.replace(/"/g, '\\"')}"
803+
fi
804+
738805
# Execute the original binary
739806
exec "${shimPath}" "$@"
740807
`
@@ -1288,6 +1355,48 @@ export async function downloadPhpBinary(installPath: string, requestedVersion?:
12881355
throw new Error(`Failed to install PHP binary: ${result.error}`)
12891356
}
12901357

1358+
// Generate a project-level php.ini that enables DB extensions based on simple detection
1359+
try {
1360+
const phpIniPath = path.join(installPath, 'php.ini')
1361+
const iniLines: string[] = [
1362+
'; Launchpad php.ini (auto-generated)',
1363+
'memory_limit = 512M',
1364+
'max_execution_time = 300',
1365+
'upload_max_filesize = 64M',
1366+
'post_max_size = 64M',
1367+
'display_errors = On',
1368+
'error_reporting = E_ALL',
1369+
'',
1370+
'; Enable database extensions based on project detection',
1371+
]
1372+
1373+
// Basic detection using .env
1374+
try {
1375+
const envPath = path.join(process.cwd(), '.env')
1376+
if (fs.existsSync(envPath)) {
1377+
const envContent = fs.readFileSync(envPath, 'utf-8')
1378+
const dbConnMatch = envContent.match(/^DB_CONNECTION=(.*)$/m)
1379+
const dbConn = dbConnMatch?.[1]?.trim().toLowerCase()
1380+
if (dbConn === 'pgsql' || dbConn === 'postgres' || dbConn === 'postgresql') {
1381+
iniLines.push('extension=pdo_pgsql')
1382+
iniLines.push('extension=pgsql')
1383+
}
1384+
else if (dbConn === 'mysql' || dbConn === 'mariadb') {
1385+
iniLines.push('extension=pdo_mysql')
1386+
iniLines.push('extension=mysqli')
1387+
}
1388+
else if (dbConn === 'sqlite') {
1389+
iniLines.push('extension=pdo_sqlite')
1390+
iniLines.push('extension=sqlite3')
1391+
}
1392+
}
1393+
}
1394+
catch {}
1395+
1396+
fs.writeFileSync(phpIniPath, iniLines.join('\n'))
1397+
}
1398+
catch {}
1399+
12911400
// Create shims in installPath/bin and sbin so php is available on PATH
12921401
try {
12931402
const installedBinaries = await createShims(result.packageDir, installPath, 'php.net', result.version)

packages/launchpad/src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const defaultConfig: LaunchpadConfig = {
5151
installMethod: 'curl',
5252
installPath: getDefaultInstallPath(),
5353
postSetup: {
54-
enabled: process.env.LAUNCHPAD_POST_SETUP_ENABLED === 'true',
54+
enabled: process.env.LAUNCHPAD_POST_SETUP_ENABLED !== 'false',
5555
commands: [],
5656
},
5757
services: {

0 commit comments

Comments
 (0)