diff --git a/CHANGELOG.md b/CHANGELOG.md index f0613e9..4cfe2a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [1.1.0] - 2025-04-24 +### Added +- New database option: MySQL. +- New configuration option: `options.environment.database.rootPassword`. + +### Changed +- Changed the default database for new environments to MySQL (from SQLite). + ## [1.0.4] - 2025-04-24 ### Fixed - Fixed a critical autoloading issue after the package is globally installed. diff --git a/README.md b/README.md index 81b235c..61a8f8b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Loom Spinner CLI

-Version 1.0.4 +Version 1.1.0

A streamlined environment management tool for PHP developers. @@ -21,16 +21,13 @@ Effortlessly create custom Docker environments for each of your PHP projects. Ou - **PHP 8.4** (includes XDebug & OpCache) - **Nginx** -- **SQLite3** +- **MySQL 9.3** - **NodeJS 23** (Node, NPM, & NPX) Your project directory is automatically mounted to the PHP container, and the `public` directory is served via Nginx at `http://localhost:`. Access the container directly from your terminal to execute unit tests or other commands, all within an isolated environment. -> **Note:** Loom Spinner CLI is in early development. For now, only SQLite is supported as the database, but more options -> are on the way in future updates. - # Installation **Requirements:** diff --git a/composer.json b/composer.json index 05de60c..eb6bd2e 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "loomlabs/loom-spinner-cli", "description": "A simple command-line Docker environment spinner for PHP.", - "version": "1.0.4", + "version": "1.1.0", "autoload": { "psr-4": { "Loom\\Spinner\\": "src/" diff --git a/config/.template.env b/config/.template.env index 77e79d6..b3ad961 100644 --- a/config/.template.env +++ b/config/.template.env @@ -7,4 +7,8 @@ PHP_VERSION=%s PHP_PORT=%s # Nginx -NGINX_PORT=%s \ No newline at end of file +SERVER_PORT=%s + +# Database +DATABASE_PORT=%s +ROOT_PASSWORD=%s \ No newline at end of file diff --git a/config/mysql.yaml b/config/mysql.yaml new file mode 100644 index 0000000..cad47a5 --- /dev/null +++ b/config/mysql.yaml @@ -0,0 +1,12 @@ +services: + mysql: + image: mysql:9.3.0 + command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci + ports: + - ${DATABASE_PORT}:3306 + expose: + - "3306" + environment: + MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD} + volumes: + - ./data/${PROJECT_NAME}/mysql:/var/lib/mysql:cached \ No newline at end of file diff --git a/config/nginx.yaml b/config/nginx.yaml index 6bb2d62..6e96ec9 100644 --- a/config/nginx.yaml +++ b/config/nginx.yaml @@ -3,7 +3,7 @@ services: build: context: ./nginx ports: - - ${NGINX_PORT}:80 + - ${SERVER_PORT}:80 volumes: - ${PROJECT_DIRECTORY}:/var/www/html:cached - ./nginx/conf.d:/etc/nginx/conf.d diff --git a/config/spinner.yaml b/config/spinner.yaml index 1be09f7..ab34b00 100644 --- a/config/spinner.yaml +++ b/config/spinner.yaml @@ -9,4 +9,5 @@ options: enabled: true database: enabled: true - driver: sqlite3 \ No newline at end of file + driver: mysql + rootPassword: docker \ No newline at end of file diff --git a/src/Classes/File/DockerComposeFileBuilder.php b/src/Classes/File/DockerComposeFileBuilder.php index 4a9300b..af1dc29 100644 --- a/src/Classes/File/DockerComposeFileBuilder.php +++ b/src/Classes/File/DockerComposeFileBuilder.php @@ -13,7 +13,7 @@ class DockerComposeFileBuilder extends AbstractFileBuilder /** * @throws \Exception */ - public function __construct(Config $config) + public function __construct(Config $config, private array $ports) { return parent::__construct($config->getDataDirectory() . '/docker-compose.yaml', $config); } @@ -25,8 +25,16 @@ class DockerComposeFileBuilder extends AbstractFileBuilder { $this->content = $this->config->getConfigFileContents('php.yaml'); - if ($this->config->isDatabaseEnabled($input) && in_array($this->config->getDatabaseDriver($input), ['sqlite3', 'sqlite'])) { - $this->addSqliteDatabaseConfig(); + if ($this->config->isDatabaseEnabled($input)) { + $databaseDriver = strtolower($this->config->getDatabaseDriver($input)); + + if (in_array($databaseDriver, ['sqlite3', 'sqlite'])) { + $this->addSqliteDatabaseConfig(); + } + + if ($databaseDriver === 'mysql') { + $this->addMysqlDatabaseConfig(); + } } if ($this->config->isServerEnabled($input)) { @@ -56,4 +64,12 @@ class DockerComposeFileBuilder extends AbstractFileBuilder $sqlLiteConfig = str_replace('volumes:', '', $sqlLiteConfig); $this->content .= $sqlLiteConfig; } + + private function addMysqlDatabaseConfig(): void + { + $mysqlConfig = str_replace('services:', '', $this->config->getConfigFileContents('mysql.yaml')); + $mysqlConfig = str_replace('${ROOT_PASSWORD}', $this->config->getEnvironmentOption('database', 'rootPassword'), $mysqlConfig); + $mysqlConfig = str_replace('${DATABASE_PORT}', (string) $this->ports['database'], $mysqlConfig); + $this->content.= $mysqlConfig; + } } \ No newline at end of file diff --git a/src/Classes/File/PHPDockerFileBuilder.php b/src/Classes/File/PHPDockerFileBuilder.php index 8fa5b00..d5f2cd5 100644 --- a/src/Classes/File/PHPDockerFileBuilder.php +++ b/src/Classes/File/PHPDockerFileBuilder.php @@ -31,9 +31,11 @@ class PHPDockerFileBuilder extends AbstractFileBuilder $this->config->getConfigFileContents('php-fpm/opcache.ini') ); - if ($this->config->isDatabaseEnabled($input) && in_array($this->config->getDatabaseDriver($input), ['sqlite3', 'sqlite'])) { - $this->addNewLine(); - $this->content .= $this->config->getConfigFileContents('php-fpm/Sqlite.Dockerfile'); + if ($this->config->isDatabaseEnabled($input)) { + if (in_array($this->config->getDatabaseDriver($input), ['sqlite3', 'sqlite'])) { + $this->addNewLine(); + $this->content .= $this->config->getConfigFileContents('php-fpm/Sqlite.Dockerfile'); + } } $this->content = str_replace('${NODE_VERSION}', (string) $this->config->getNodeVersion($input), $this->content); diff --git a/src/Command/SpinCommand.php b/src/Command/SpinCommand.php index b60a89c..35f6bb3 100644 --- a/src/Command/SpinCommand.php +++ b/src/Command/SpinCommand.php @@ -28,7 +28,8 @@ class SpinCommand extends AbstractSpinnerCommand $this->portGenerator = new PortGenerator(); $this->ports = [ 'php' => $this->portGenerator->generateRandomPort(), - 'nginx' => $this->portGenerator->generateRandomPort(), + 'server' => $this->portGenerator->generateRandomPort(), + 'database' => $this->portGenerator->generateRandomPort(), ]; parent::__construct(); @@ -66,7 +67,7 @@ class SpinCommand extends AbstractSpinnerCommand InputOption::VALUE_NONE, 'Set this flag to not include a database for your environment.' ) - ->addOption('database', null, InputOption::VALUE_REQUIRED, 'The type of database to use (e.g., mysql, postgresql, sqlite).', null, ['sqlite']) + ->addOption('database', null, InputOption::VALUE_REQUIRED, 'The type of database to use (e.g., mysql, sqlite).', null, ['mysql', 'sqlite']) ->addOption('node', null, InputOption::VALUE_OPTIONAL, 'The Node.js version to use (e.g. 20).'); } @@ -154,7 +155,9 @@ class SpinCommand extends AbstractSpinnerCommand $input->getArgument('name'), $this->config->getPhpVersion($input), $this->ports['php'], - $this->ports['nginx'], + $this->ports['server'], + $this->ports['database'], + $this->config->getEnvironmentOption('database', 'rootPassword') ) ); } @@ -166,7 +169,7 @@ class SpinCommand extends AbstractSpinnerCommand { $this->createProjectDataSubDirectory('php-fpm'); - (new DockerComposeFileBuilder($this->config))->build($input)->save(); + (new DockerComposeFileBuilder($this->config, $this->ports))->build($input)->save(); } /**