UNPKG

cvm-cli

Version:

A unified CLI tool for managing PHP, Node.js, and Python versions with virtual environment and dependency management support.

195 lines (160 loc) 7.14 kB
const BaseVersionManager = require('./baseVersionManager'); const fetch = require('node-fetch'); const fs = require('fs-extra'); const chalk = require('chalk'); const path = require('path'); class PHPVersionManager extends BaseVersionManager { constructor() { super('php'); } async getAvailableVersions() { // For simplicity, return a list of commonly used PHP versions // In a real implementation, you'd fetch from php.net or use phpenv's list return [ '8.3.0', '8.2.14', '8.2.13', '8.2.12', '8.2.11', '8.2.10', '8.2.9', '8.2.8', '8.2.7', '8.2.6', '8.2.5', '8.2.4', '8.2.3', '8.2.2', '8.2.1', '8.2.0', '8.1.27', '8.1.26', '8.1.25', '8.1.24', '8.1.23', '8.1.22', '8.1.21', '8.1.20', '8.1.19', '8.1.18', '8.1.17', '8.1.16', '8.1.15', '8.1.14', '8.1.13', '8.1.12', '8.1.11', '8.1.10', '8.1.9', '8.1.8', '8.1.7', '8.1.6', '8.1.5', '8.1.4', '8.1.3', '8.1.2', '8.1.1', '8.1.0', '8.0.30', '8.0.29', '8.0.28', '8.0.27', '8.0.26', '8.0.25', '8.0.24', '8.0.23', '8.0.22', '8.0.21', '8.0.20', '8.0.19', '8.0.18', '8.0.17', '8.0.16', '8.0.15', '8.0.14', '8.0.13', '8.0.12', '8.0.11', '8.0.10', '8.0.9', '8.0.8', '8.0.7', '8.0.6', '8.0.5', '8.0.3', '8.0.2', '8.0.1', '8.0.0', '7.4.33', '7.4.32', '7.4.30', '7.4.29', '7.4.28', '7.4.27', '7.4.26', '7.4.25', '7.4.24', '7.4.23', '7.4.22', '7.4.21', '7.4.20', '7.4.19', '7.4.18', '7.4.16', '7.4.15', '7.4.14', '7.4.13', '7.4.12', '7.4.11', '7.4.10', '7.4.9', '7.4.8', '7.4.7', '7.4.6', '7.4.5', '7.4.4', '7.4.3', '7.4.2', '7.4.1', '7.4.0' ]; } async install(version) { if (await this.isVersionInstalled(version)) { console.log(chalk.yellow(`PHP ${version} is already installed.`)); return true; } console.log(chalk.blue(`Installing PHP ${version}...`)); const platform = this.getPlatform(); const versionDir = path.join(this.languageDir, version); try { if (platform === 'linux') { await this.installOnLinux(version, versionDir); } else if (platform === 'darwin') { await this.installOnMacOS(version, versionDir); } else if (platform === 'win32') { await this.installOnWindows(version, versionDir); } else { throw new Error(`Unsupported platform: ${platform}`); } console.log(chalk.green(`✓ PHP ${version} installed successfully`)); return true; } catch (error) { console.error(chalk.red(`Failed to install PHP ${version}:`), error.message); // Clean up partially installed version if (await fs.pathExists(versionDir)) { await fs.remove(versionDir); } return false; } } async installOnLinux(version, versionDir) { // For Linux, we'll compile from source const downloadUrl = `https://www.php.net/distributions/php-${version}.tar.gz`; const downloadDir = path.join(this.languageDir, 'downloads'); const downloadPath = path.join(downloadDir, `php-${version}.tar.gz`); const sourceDir = path.join(downloadDir, `php-${version}`); console.log(chalk.yellow(' Downloading PHP source...')); await this.downloadFile(downloadUrl, downloadPath); console.log(chalk.yellow(' Extracting source...')); await this.extractTarGz(downloadPath, sourceDir); console.log(chalk.yellow(' Configuring build...')); const configureFlags = [ `--prefix="${versionDir}"`, '--enable-fpm', '--enable-opcache', '--enable-mbstring', '--enable-soap', '--enable-zip', '--enable-calendar', '--enable-bcmath', '--enable-exif', '--enable-intl', '--with-curl', '--with-pdo-mysql', '--with-pdo-pgsql', '--with-readline', '--with-openssl', '--with-zlib', '--with-bz2', '--with-gd' ].join(' '); await this.executeCommand(`./configure ${configureFlags}`, { cwd: sourceDir }); console.log(chalk.yellow(' Building PHP (this may take a while)...')); await this.executeCommand('make -j$(nproc)', { cwd: sourceDir }); console.log(chalk.yellow(' Installing PHP...')); await this.executeCommand('make install', { cwd: sourceDir }); // Clean up await fs.remove(downloadDir); } async installOnMacOS(version, versionDir) { // Similar to Linux but may need different configure options const downloadUrl = `https://www.php.net/distributions/php-${version}.tar.gz`; const downloadDir = path.join(this.languageDir, 'downloads'); const downloadPath = path.join(downloadDir, `php-${version}.tar.gz`); const sourceDir = path.join(downloadDir, `php-${version}`); console.log(chalk.yellow(' Downloading PHP source...')); await this.downloadFile(downloadUrl, downloadPath); console.log(chalk.yellow(' Extracting source...')); await this.extractTarGz(downloadPath, sourceDir); console.log(chalk.yellow(' Configuring build...')); const configureFlags = [ `--prefix="${versionDir}"`, '--enable-fpm', '--enable-opcache', '--enable-mbstring', '--enable-soap', '--enable-zip', '--enable-calendar', '--enable-bcmath', '--enable-exif', '--with-curl', '--with-pdo-mysql', '--with-readline', '--with-openssl', '--with-zlib', '--with-bz2' ].join(' '); await this.executeCommand(`./configure ${configureFlags}`, { cwd: sourceDir }); console.log(chalk.yellow(' Building PHP (this may take a while)...')); await this.executeCommand('make -j$(sysctl -n hw.ncpu)', { cwd: sourceDir }); console.log(chalk.yellow(' Installing PHP...')); await this.executeCommand('make install', { cwd: sourceDir }); // Clean up await fs.remove(downloadDir); } async installOnWindows(version, versionDir) { // For Windows, we'd download pre-compiled binaries throw new Error('Windows PHP installation not implemented yet. Please install manually.'); } getBinDir(versionDir) { return path.join(versionDir, 'bin'); } async installComposer(version) { const versionDir = path.join(this.languageDir, version); const binDir = this.getBinDir(versionDir); const composerPath = path.join(binDir, 'composer'); if (await fs.pathExists(composerPath)) { console.log(chalk.yellow('Composer is already installed for this PHP version')); return; } console.log(chalk.blue('Installing Composer...')); try { // Download composer installer const installerUrl = 'https://getcomposer.org/installer'; const installerPath = path.join(versionDir, 'composer-installer.php'); await this.downloadFile(installerUrl, installerPath); // Install composer const phpBin = path.join(binDir, 'php'); await this.executeCommand(`"${phpBin}" "${installerPath}" --install-dir="${binDir}" --filename=composer`); // Clean up installer await fs.remove(installerPath); console.log(chalk.green('✓ Composer installed successfully')); } catch (error) { console.error(chalk.red('Failed to install Composer:'), error.message); } } } module.exports = PHPVersionManager;