From fc34eecd8112ec22940ab34c779714184bc26eb4 Mon Sep 17 00:00:00 2001 From: velkuns Date: Wed, 24 Dec 2025 17:15:51 +0100 Subject: [PATCH] Component deployer upgrade - Support PHP 8.3+ only - Use some promoted properties - Replace Platform class with const by Backed Enum - Update Makefile - Update GitHub workflow - Now use eureka console ^6.0||^7.0 - Add shipmonk dependency analyzer - Drop maglnet dependency analyzer --- .github/workflows/ci.yml | 28 ++---- .github/workflows/sonarcloud.yml | 46 ++++++++++ .php-cs-fixer.dist.php | 2 +- CHANGELOG.md | 16 ++++ Makefile | 66 +++++++------- README.md | 20 ++--- ci/composer-dependency-analyser.php | 13 +++ ...ibility.neon => phpmax-compatibility.neon} | 2 +- ...ibility.neon => phpmin-compatibility.neon} | 0 composer.json | 18 ++-- phpstan.neon.dist | 8 +- phpunit.xml.dist | 16 ++-- src/Common/AbstractCommonScript.php | 86 +++++++++++-------- src/Common/PathBuilder.php | 82 ++++-------------- src/Enumerator/Platform.php | 33 ++----- src/Script/Deploy.php | 8 +- src/Script/Install.php | 18 ++-- src/Script/Install/Clean/Cache.php | 14 +-- src/Script/Install/Clean/Files.php | 17 +--- src/Script/Install/Composer/Reinstall.php | 18 +--- src/Script/Install/Copy/Config.php | 17 ++-- src/Script/Install/Init/Directories.php | 15 ---- src/Script/Install/Init/Symlink.php | 16 +--- src/Script/Install/Yarn/EncoreBuild.php | 11 +-- src/Script/Install/Yarn/Install.php | 11 +-- src/Script/Link.php | 2 +- tests/unit/PathBuilderTest.php | 42 ++++----- 27 files changed, 274 insertions(+), 351 deletions(-) create mode 100644 .github/workflows/sonarcloud.yml create mode 100644 ci/composer-dependency-analyser.php rename ci/{php81-compatibility.neon => phpmax-compatibility.neon} (92%) rename ci/{php83-compatibility.neon => phpmin-compatibility.neon} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index deef99c..10b872c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,17 +7,17 @@ on: branches: [ master ] jobs: - build: + ci: runs-on: ubuntu-latest strategy: matrix: - php-versions: [ '8.1', '8.2', '8.3' ] + php-versions: [ '8.3', '8.4', '8.5' ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: - fetch-depth: 0 # To avoid "Shallow clone detected" error in SonarCloud report + fetch-depth: 0 #~ PHP Setup - name: Setup PHP ${{ matrix.php-versions }} @@ -48,30 +48,18 @@ jobs: #~ CI part - name: Dependencies - run: make deps + run: make php/deps - name: Check Code Style - run: make phpcs + run: make php/check - name: Units Tests - run: make tests + run: make php/tests - name: Fix unit tests report path run: | sed -i 's+'$GITHUB_WORKSPACE'+/github/workspace+g' build/reports/phpunit/clover.xml sed -i 's+'$GITHUB_WORKSPACE'+/github/workspace+g' build/reports/phpunit/unit.xml - - name: PHP 8.1 Compatibility - run: make php81compatibility - - - name: PHP 8.3 Compatibility - run: make php83compatibility - - name: PHP Static Analyze - run: make analyze - - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@v2.1.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: make php/analyze diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 0000000..9130fbb --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,46 @@ +name: SonarQube + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + sonarcloud: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # To avoid "Shallow clone detected" error in SonarCloud report + + #~ PHP Setup + - name: Setup PHP 8.3 # Minimum version + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + + #~ Composer Cache + - name: Get Composer Cache Directory + id: composer-cache + run: | + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: make install + + - name: Units Tests + run: make php/tests # To generate the coverage report + + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@v7 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index b0ac8d3..d21eb4c 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,7 +4,7 @@ //~ Rules ->setRules( [ - '@PER-CS2.0' => true, + '@PER-CS3x0' => true, ] ) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62576ae..89d7493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ``` ---- +## [4.0.0] - 2025-12-24 +[4.0.0]: https://github.com/eureka-framework/component-deployer/compare/3.0.0...4.0.0 +### Changed +- Support PHP 8.3+ only +- Use some promoted properties +- Replace Platform class with const by Backed Enum +- Update Makefile +- Update GitHub workflow +- Now use eureka console ^6.0||^7.0 +### Added +- Add shipmonk dependency analyzer +### Removed +- Drop maglnet dependency analyzer + +---- + ## [3.0.0] - 2024-03-12 [3.0.0]: https://github.com/eureka-framework/component-deployer/compare/2.1.0...3.0.0 ### Changed diff --git a/Makefile b/Makefile index b3857ec..a0a98ed 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ -.PHONY: validate install update deps phpcs phpcsf php81compatibility php83compatibility phpstan analyze tests testdox ci clean build/reports/phpunit build/reports/phpcs build/reports/phpstan +.PHONY: validate install update php/deps php/check php/fix php/min-compatibility php/max-compatibility php/phpstan php/analyze php/tests php/test php/testdox ci clean +PHP_MIN_VERSION := "8.3" +PHP_MAX_VERSION := "8.5" +COMPOSER_BIN := composer define header = @if [ -t 1 ]; then printf "\n\e[37m\e[100m \e[104m $(1) \e[0m\n"; else printf "\n### $(1)\n"; fi endef @@ -7,78 +10,71 @@ endef #~ Composer dependency validate: $(call header,Composer Validation) - @composer validate + @${COMPOSER_BIN} validate install: $(call header,Composer Install) - @composer install + @${COMPOSER_BIN} install update: $(call header,Composer Update) - @composer update - @composer bump --dev-only + @${COMPOSER_BIN} update + @${COMPOSER_BIN} bump --dev-only composer.lock: install #~ Vendor binaries dependencies -vendor/bin/php-cs-fixer: -vendor/bin/phpstan: -vendor/bin/phpunit: +vendor/bin/php-cs-fixer: composer.lock +vendor/bin/phpstan: composer.lock +vendor/bin/phpunit: composer.lock #~ Report directories dependencies build/reports/phpunit: @mkdir -p build/reports/phpunit -build/reports/phpcs: - @mkdir -p build/reports/cs - build/reports/phpstan: @mkdir -p build/reports/phpstan #~ main commands -deps: composer.json +php/deps: composer.json $(call header,Checking Dependencies) - @XDEBUG_MODE=off ./vendor/bin/composer-require-checker check + @XDEBUG_MODE=off ./vendor/bin/composer-dependency-analyser --config ./ci/composer-dependency-analyser.php # for shadow, unused required dependencies and ext-* missing dependencies -phpcs: vendor/bin/php-cs-fixer build/reports/phpcs +php/check: vendor/bin/php-cs-fixer $(call header,Checking Code Style) - @./vendor/bin/php-cs-fixer check - -phpcsf: vendor/bin/php-cs-fixer + @XDEBUG_MODE=off ./vendor/bin/php-cs-fixer check +php/fix: vendor/bin/php-cs-fixer $(call header,Fixing Code Style) - @./vendor/bin/php-cs-fixer fix -v + @XDEBUG_MODE=off ./vendor/bin/php-cs-fixer fix -v -php81compatibility: vendor/bin/phpstan build/reports/phpstan - $(call header,Checking PHP 8.1 compatibility) - @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/php81-compatibility.neon --error-format=table +php/min-compatibility: vendor/bin/phpstan build/reports/phpstan + $(call header,Checking PHP ${PHP_MIN_VERSION} compatibility) + @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/phpmin-compatibility.neon --error-format=table -php83compatibility: vendor/bin/phpstan build/reports/phpstan - $(call header,Checking PHP 8.3 compatibility) - @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/php83-compatibility.neon --error-format=table +php/max-compatibility: vendor/bin/phpstan build/reports/phpstan #ci + $(call header,Checking PHP ${PHP_MAX_VERSION} compatibility) + @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --configuration=./ci/phpmax-compatibility.neon --error-format=table -phpstan: vendor/bin/phpstan build/reports/phpstan - $(call header,Running Static Analyze) - @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --error-format=checkstyle > ./build/reports/phpstan/phpstan.xml - -analyze: vendor/bin/phpstan build/reports/phpstan +php/analyze: vendor/bin/phpstan build/reports/phpstan #manual & ci $(call header,Running Static Analyze - Pretty tty format) @XDEBUG_MODE=off ./vendor/bin/phpstan analyse --error-format=table -tests: vendor/bin/phpunit build/reports/phpunit #ci +php/tests: vendor/bin/phpunit build/reports/phpunit #ci $(call header,Running Unit Tests) - @rm -rf ./tests/unit/Generated/Entity ./tests/unit/Generated/Infrastructure ./tests/unit/Generated/Repository @XDEBUG_MODE=coverage php -dzend_extension=xdebug.so ./vendor/bin/phpunit --testsuite=unit --coverage-clover=./build/reports/phpunit/clover.xml --log-junit=./build/reports/phpunit/unit.xml --coverage-php=./build/reports/phpunit/unit.cov --coverage-html=./build/reports/coverage/ --fail-on-warning -integration: vendor/bin/phpunit build/reports/phpunit #manual +php/test: php/tests + +php/integration: vendor/bin/phpunit build/reports/phpunit #manual $(call header,Running Integration Tests) @XDEBUG_MODE=coverage php -dzend_extension=xdebug.so ./vendor/bin/phpunit --testsuite=integration --fail-on-warning -testdox: vendor/bin/phpunit #manual +php/testdox: vendor/bin/phpunit #manual $(call header,Running Unit Tests (Pretty format)) @XDEBUG_MODE=coverage php -dzend_extension=xdebug.so ./vendor/bin/phpunit --testsuite=unit --fail-on-warning --testdox clean: - $(call header,Cleaning previous build) + $(call header,Cleaning previous build) #manual @if [ "$(shell ls -A ./build)" ]; then rm -rf ./build/*; fi; echo " done" -ci: clean validate deps install phpcs tests integration php81compatibility php83compatibility analyze +ci: clean validate install php/deps php/check php/tests php/integration php/min-compatibility php/max-compatibility php/analyze diff --git a/README.md b/README.md index 8cdeba5..9fba571 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # component-deployer [![Current version](https://img.shields.io/packagist/v/eureka/component-deployer.svg?logo=composer)](https://packagist.org/packages/eureka/component-deployer) -[![Supported PHP version](https://img.shields.io/static/v1?logo=php&label=PHP&message=8.1%20-%208.3&color=777bb4)](https://packagist.org/packages/eureka/component-deployer) +[![Supported PHP version](https://img.shields.io/static/v1?logo=php&label=PHP&message=>%3D8.3&color=777bb4)](https://packagist.org/packages/eureka/component-deployer) ![CI](https://github.com/eureka-framework/component-deployer/workflows/CI/badge.svg) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_component-deployer&metric=alert_status)](https://sonarcloud.io/dashboard?id=eureka-framework_component-deployer) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=eureka-framework_component-deployer&metric=coverage)](https://sonarcloud.io/dashboard?id=eureka-framework_component-deployer) @@ -157,40 +157,40 @@ NB: For the components, the `composer.lock` file is not committed. #### Tests You can run unit tests (with coverage) on your side with following command: ```bash -make tests +make php/tests ``` You can run integration tests (without coverage) on your side with following command: ```bash -make integration +make php/integration ``` For prettier output (but without coverage), you can use the following command: ```bash -make testdox # run tests without coverage reports but with prettified output +make php/testdox # run tests without coverage reports but with prettified output ``` #### Code Style You also can run code style check with following commands: ```bash -make phpcs +make php/check ``` You also can run code style fixes with following commands: ```bash -make phpcsf +make php/fix ``` #### Check for missing explicit dependencies You can check if any explicit dependency is missing with the following command: ```bash -make deps +make php/deps ``` #### Static Analysis To perform a static analyze of your code (with phpstan, lvl 9 at default), you can use the following command: ```bash -make analyse +make php/analyse ``` To ensure you code still compatible with current supported version at Deezer and futures versions of php, you need to @@ -198,12 +198,12 @@ run the following commands (both are required for full support): Minimal supported version: ```bash -make php81compatibility +make php/min-compatibility ``` Maximal supported version: ```bash -make php83compatibility +make php/max-compatibility ``` #### CI Simulation diff --git a/ci/composer-dependency-analyser.php b/ci/composer-dependency-analyser.php new file mode 100644 index 0000000..fe34c5b --- /dev/null +++ b/ci/composer-dependency-analyser.php @@ -0,0 +1,13 @@ +addPathToScan(__DIR__ . '/../src', isDev: false) + ->addPathToScan(__DIR__ . '/../tests', isDev: true) +; + + +return $config; diff --git a/ci/php81-compatibility.neon b/ci/phpmax-compatibility.neon similarity index 92% rename from ci/php81-compatibility.neon rename to ci/phpmax-compatibility.neon index fbd2148..085b5a0 100644 --- a/ci/php81-compatibility.neon +++ b/ci/phpmax-compatibility.neon @@ -3,7 +3,7 @@ includes: - ./../vendor/phpstan/phpstan-phpunit/rules.neon parameters: - phpVersion: 80100 + phpVersion: 80500 level: 0 paths: - ./../src diff --git a/ci/php83-compatibility.neon b/ci/phpmin-compatibility.neon similarity index 100% rename from ci/php83-compatibility.neon rename to ci/phpmin-compatibility.neon diff --git a/composer.json b/composer.json index c1435de..9a72b2c 100644 --- a/composer.json +++ b/composer.json @@ -29,18 +29,18 @@ }, "require": { - "php": "8.1.*||8.2.*||8.3.*", + "php": ">=8.3", - "eureka/component-console": "^6.0" + "eureka/component-console": "^6.0||^7.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.51.0", - "maglnet/composer-require-checker": "^4.7.1", - "phpstan/phpstan": "^1.10.60", - "phpstan/phpstan-phpunit": "^1.3.16", - "phpstan/phpstan-strict-rules": "^1.5.2", - "phpunit/phpcov": "^9.0.2", - "phpunit/phpunit": "^10.5.13" + "friendsofphp/php-cs-fixer": "^3.92.3", + "phpstan/phpstan": "^2.1.33", + "phpstan/phpstan-phpunit": "^2.0.11", + "phpstan/phpstan-strict-rules": "^2.0.7", + "phpunit/phpcov": "^11.0.3", + "phpunit/phpunit": "^12.5.4", + "shipmonk/composer-dependency-analyser": "^1.8.4" } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f3c423d..b09c76b 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,7 +3,7 @@ includes: - ./vendor/phpstan/phpstan-phpunit/rules.neon parameters: - phpVersion: 80100 + phpVersion: 80300 level: max paths: - ./src @@ -13,5 +13,7 @@ parameters: - ./vendor/autoload.php ignoreErrors: - - '`Property .+?AbstractCommonScript::\$config type has no value type specified in iterable type array\.`' - - '`Method .+?AbstractCommonScript::setConfig\(\) has parameter \$config with no value type specified in iterable type array\.`' + - + identifier: isset.initializedProperty + count: 1 + path: src/Common/AbstractCommonScript.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 925796d..004765f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,14 +4,20 @@ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" colors="true" cacheDirectory="./build/.phpunit.cache"> - - - ./tests/unit - - + + + + ./src + + + + ./tests/unit + + + diff --git a/src/Common/AbstractCommonScript.php b/src/Common/AbstractCommonScript.php index a967f52..f5c5783 100644 --- a/src/Common/AbstractCommonScript.php +++ b/src/Common/AbstractCommonScript.php @@ -11,18 +11,13 @@ namespace Eureka\Component\Deployer\Common; -use Eureka\Component\Console\Argument\Argument; -use Eureka\Component\Console\Color\Bit4Color; use Eureka\Component\Console\Color\Bit8HighColor; -use Eureka\Component\Console\Color\Bit8RGBColor; use Eureka\Component\Console\Color\Bit8StandardColor; use Eureka\Component\Console\Help; use Eureka\Component\Console\Option\Option; use Eureka\Component\Console\Option\Options; use Eureka\Component\Deployer\Enumerator\Platform; use Eureka\Component\Console\AbstractScript; -use Eureka\Component\Console\IO\Out; -use Eureka\Component\Console\Style\Color; use Eureka\Component\Console\Style\Style; /** @@ -30,15 +25,36 @@ * * @author Romain Cottard * @codeCoverageIgnore + * @phpstan-type ConfigData array{ + * "app.name": string, + * "app.tag": string, + * "app.domain": string, + * install: array{ + * "step.start": int, + * "step.end": int, + * "step.list": array, + * init: array{ + * directories: array, + * symlinks: array, + * }, + * copy: array{ + * files: array, + * }, + * clean: array{ + * files: list, + * directories: list, + * }, + * }, + * } */ abstract class AbstractCommonScript extends AbstractScript { - /** @var array $config */ + /** @var ConfigData $config */ protected array $config; protected string $rootDir; protected float $time; - private string $appPlatform; + private Platform $appPlatform; private string $appTag; private string $appName; private string $appDomain; @@ -52,7 +68,7 @@ public function setRootDir(string $rootDir): self } /** - * @param array $config + * @param ConfigData $config * @return $this */ public function setConfig(array $config): self @@ -81,52 +97,52 @@ public function before(): void (new Options()) ->add( new Option( - shortName: 'p', - longName: 'platform', + shortName: 'p', + longName: 'platform', description: 'Platform where installation is executed (default from config)', hasArgument: true, - default: Platform::PROD, - ) + default: Platform::Prod->value, + ), ) ->add( new Option( - shortName: 't', - longName: 'tag', + shortName: 't', + longName: 'tag', description: 'Tag version to install (default from config)', hasArgument: true, - default: $this->config['app.tag'] ?? '1.0.0', - ) + default: $this->config['app.tag'] ?? '1.0.0', + ), ) ->add( new Option( - shortName: 'd', - longName: 'domain', + shortName: 'd', + longName: 'domain', description: 'Application domain (ie: www.my-app.com) (default from config)', hasArgument: true, - default: $this->config['app.domain'] ?? '', - ) + default: $this->config['app.domain'] ?? '', + ), ) ->add( new Option( - shortName: 'n', - longName: 'name', + shortName: 'n', + longName: 'name', description: 'Application name, used to retrieve config (default from config)', hasArgument: true, - default: $this->config['app.domain'] ?? '', - ) + default: $this->config['app.domain'] ?? '', + ), ) ->add( new Option( - shortName: 's', - longName: 'step', + shortName: 's', + longName: 'step', description: 'From which step the deployer should start (default is from beginning)', hasArgument: true, - ) - ) + ), + ), ); //~ Init installer main vars - $this->appPlatform = (string) $this->options()->value('platform', 'p'); + $this->appPlatform = Platform::from((string) $this->options()->value('platform', 'p')); $this->appTag = (string) $this->options()->value('tag', 't'); $this->appName = (string) $this->options()->value('name', 'n'); $this->appDomain = (string) $this->options()->value('domain', 'd'); @@ -135,7 +151,7 @@ public function before(): void if ($this->options()->value('step') !== null) { $this->displayStep( (string) $this->options()->value('step'), - $this->getDescription() + $this->getDescription(), ); } } @@ -162,7 +178,7 @@ protected function getAppDomain(): string return $this->appDomain; } - protected function getAppPlatform(): string + protected function getAppPlatform(): Platform { return $this->appPlatform; } @@ -179,7 +195,7 @@ protected function getAppTag(): string protected function startTimer(): void { - $this->time = -microtime(true); + $this->time = -\microtime(true); } protected function displayHeader(string $title): void @@ -290,7 +306,7 @@ protected function chdirSource(): void { $pathSource = $this->getRootDirSource(); - if (!chdir($pathSource)) { + if (!\chdir($pathSource)) { $this->throw('Cannot change directory to "' . $pathSource . '"'); } } @@ -302,12 +318,12 @@ protected function getRootDirSource(bool $forceAppendTag = true): string $this->getAppName(), $this->getAppDomain(), $this->getAppTag(), - $forceAppendTag + $forceAppendTag, ); } private function getTime(): float { - return round($this->time + microtime(true), 1); + return \round($this->time + \microtime(true), 1); } } diff --git a/src/Common/PathBuilder.php b/src/Common/PathBuilder.php index 92280c5..c58b8d8 100644 --- a/src/Common/PathBuilder.php +++ b/src/Common/PathBuilder.php @@ -13,45 +13,19 @@ use Eureka\Component\Deployer\Enumerator\Platform; -/** - * Class PathBuilder - * - * @author Romain Cottard - */ class PathBuilder { - /** @var string $pathSource */ - private string $pathSource; - - /** @var string $pathLink */ - private string $pathLink; + public function __construct( + private string $pathSource, + private string $pathLink, + ) {} - /** - * PathBuilder constructor. - * - * @param string $pathSource - * @param string $pathLink - */ - public function __construct(string $pathSource, string $pathLink) - { - $this->pathSource = $pathSource; - $this->pathLink = $pathLink; - } - - /** - * @param string $platform - * @param string $app - * @param string $domain - * @param string $tag - * @param bool $forceAppendTag - * @return string - */ public function buildPathSource( - string $platform, + Platform $platform, string $app, string $domain, string $tag, - bool $forceAppendTag = true + bool $forceAppendTag = true, ): string { $suffix = $this->getSuffix($platform, $domain, $tag, $forceAppendTag); $prefix = $this->getPrefix($platform); @@ -59,12 +33,7 @@ public function buildPathSource( return $this->getPathSource() . DIRECTORY_SEPARATOR . $app . DIRECTORY_SEPARATOR . $prefix . $suffix; } - /** - * @param string $platform - * @param string $domain - * @return string - */ - public function buildPathLink(string $platform, string $domain): string + public function buildPathLink(Platform $platform, string $domain): string { $suffix = $domain; $prefix = $this->getPrefix($platform); @@ -72,58 +41,37 @@ public function buildPathLink(string $platform, string $domain): string return $this->getPathLink() . DIRECTORY_SEPARATOR . $prefix . $suffix; } - /** - * @return string - */ public function getPathSource(): string { return $this->pathSource; } - /** - * @return string - */ public function getPathLink(): string { return $this->pathLink; } - /** - * @param string $platform - * @return string - */ - private function getPrefix(string $platform): string + private function getPrefix(Platform $platform): string { - return match ($platform) { - Platform::LOCAL => 'local-', - Platform::DOCKER => 'docker-', - Platform::DEV => 'dev-', - Platform::TEST => 'test-', - Platform::STAGING => 'staging-', - Platform::PREPROD => 'preprod-', - Platform::DEMO => 'demo-', - default => '', - }; + if ($platform === Platform::Prod) { + return ''; + } + + return $platform->value . '-'; } /** * By default, adding tag only for test, preprod & prod platform. * With forceAppendTag option, tag is append for all platform. - * - * @param string $platform - * @param string $domain - * @param string $tag - * @param bool $forceAppendTag - * @return string */ - private function getSuffix(string $platform, string $domain, string $tag, bool $forceAppendTag): string + private function getSuffix(Platform $platform, string $domain, string $tag, bool $forceAppendTag): string { if ($forceAppendTag) { return $domain . '_v' . $tag; } return match ($platform) { - Platform::LOCAL, Platform::DOCKER, Platform::DEV, Platform::STAGING => $domain, + Platform::Local, Platform::Docker, Platform::Dev, Platform::Staging => $domain, default => $domain . '_v' . $tag, }; } diff --git a/src/Enumerator/Platform.php b/src/Enumerator/Platform.php index 3182064..fdf2168 100644 --- a/src/Enumerator/Platform.php +++ b/src/Enumerator/Platform.php @@ -16,29 +16,14 @@ * * @author Romain Cottard */ -final class Platform +enum Platform: string { - /** @var string LOCAL Usually user pc (but NOT IN docker) */ - public const LOCAL = 'local'; - - /** @var string DOCKER Usually user pc (but IN docker) */ - public const DOCKER = 'docker'; - - /** @var string DEV Usually on "distant" dev server */ - public const DEV = 'dev'; - - /** @var string TEST Usually on "distant" testing server */ - public const TEST = 'test'; - - /** @var string STAGING Usually on distant staging server */ - public const STAGING = 'staging'; - - /** @var string PREPROD Usually on distant pre-production server */ - public const PREPROD = 'preprod'; - - /** @var string DEMO Usually on distant "demonstration" server */ - public const DEMO = 'demo'; - - /** @var string PROD Usually on distant production server */ - public const PROD = 'prod'; + case Local = 'local'; // Usually user pc (but NOT IN docker) + case Docker = 'docker'; // Usually user pc (but IN docker) + case Dev = 'dev'; // Usually on "distant" dev server + case Test = 'test'; // Usually on "distant" testing server + case Staging = 'staging'; // Usually on distant staging server + case Preprod = 'preprod'; // Usually on distant pre-production server + case Demo = 'demo'; // Usually on distant "demonstration" server + case Prod = 'prod'; // Usually on distant production server } diff --git a/src/Script/Deploy.php b/src/Script/Deploy.php index 7f25112..6dbf284 100644 --- a/src/Script/Deploy.php +++ b/src/Script/Deploy.php @@ -35,10 +35,10 @@ public function __construct() */ public function run(): void { - $platformArg = '--platform=' . escapeshellarg($this->getAppPlatform()); - $tagArg = '--tag=' . escapeshellarg($this->getAppTag()); - $nameArg = '--app=' . escapeshellarg($this->getAppName()); - $domainArg = '--domain=' . escapeshellarg($this->getAppDomain()); + $platformArg = '--platform=' . \escapeshellarg($this->getAppPlatform()->value); + $tagArg = '--tag=' . \escapeshellarg($this->getAppTag()); + $nameArg = '--app=' . \escapeshellarg($this->getAppName()); + $domainArg = '--domain=' . \escapeshellarg($this->getAppDomain()); $this->exec('export', $platformArg, $tagArg, $nameArg, $domainArg); $this->exec('install', $platformArg, $tagArg, $nameArg, $domainArg); diff --git a/src/Script/Install.php b/src/Script/Install.php index eb0df73..e8a2c19 100644 --- a/src/Script/Install.php +++ b/src/Script/Install.php @@ -75,20 +75,20 @@ public function run(): void private function runStep( string $step, string $script, - string $pathSource + string $pathSource, ): void { $this->startTimer(); - $scriptArg = escapeshellarg($script); - $stepArg = '--step=' . escapeshellarg($step); - $platformArg = '--platform=' . escapeshellarg($this->getAppPlatform()); - $tagArg = '--tag=' . escapeshellarg($this->getAppTag()); - $nameArg = '--app=' . escapeshellarg($this->getAppName()); - $domainArg = '--domain=' . escapeshellarg($this->getAppDomain()); + $scriptArg = \escapeshellarg($script); + $stepArg = '--step=' . \escapeshellarg($step); + $platformArg = '--platform=' . \escapeshellarg($this->getAppPlatform()->value); + $tagArg = '--tag=' . \escapeshellarg($this->getAppTag()); + $nameArg = '--app=' . \escapeshellarg($this->getAppName()); + $domainArg = '--domain=' . \escapeshellarg($this->getAppDomain()); passthru( "$pathSource/bin/console $scriptArg $stepArg $platformArg $tagArg $nameArg $domainArg", - $status + $status, ); if ($status !== 0) { @@ -105,7 +105,7 @@ private function stepStart(): void { $this->displayStep('000', 'Starting install'); - $this->output()->writeln(' Platform: ' . $this->getAppPlatform()); + $this->output()->writeln(' Platform: ' . $this->getAppPlatform()->value); $this->output()->writeln(' Application: ' . $this->getAppName()); $this->output()->writeln(' Domain: ' . $this->getAppDomain()); $this->output()->writeln(' Tag: ' . $this->getAppTag()); diff --git a/src/Script/Install/Clean/Cache.php b/src/Script/Install/Clean/Cache.php index 3df92d3..c914bae 100644 --- a/src/Script/Install/Clean/Cache.php +++ b/src/Script/Install/Clean/Cache.php @@ -14,25 +14,16 @@ use Eureka\Component\Deployer\Common\AbstractCommonScript; /** - * Class Files - * - * @author Romain Cottard * @codeCoverageIgnore */ class Cache extends AbstractCommonScript { - /** - * Files constructor. - */ public function __construct() { $this->setDescription('Cleaning cache app directory'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->cleanDirectories(['var/cache/', 'var/log/']); @@ -40,7 +31,6 @@ public function run(): void /** * @param string[] $directories - * @return void */ protected function cleanDirectories(array $directories): void { @@ -52,8 +42,8 @@ protected function cleanDirectories(array $directories): void $this->displayInfo('Removing ' . $dir . '...'); - if (is_dir($dir)) { - passthru('rm -rf ' . escapeshellarg($dir), $status); + if (\is_dir($dir)) { + \passthru('rm -rf ' . \escapeshellarg($dir), $status); } if ($status !== 0) { diff --git a/src/Script/Install/Clean/Files.php b/src/Script/Install/Clean/Files.php index 1cc6acb..8ccd8c1 100644 --- a/src/Script/Install/Clean/Files.php +++ b/src/Script/Install/Clean/Files.php @@ -14,25 +14,16 @@ use Eureka\Component\Deployer\Common\AbstractCommonScript; /** - * Class Files - * - * @author Romain Cottard * @codeCoverageIgnore */ class Files extends AbstractCommonScript { - /** - * Files constructor. - */ public function __construct() { $this->setDescription('Cleaning files & directories'); $this->setExecutable(true); } - /** - * @return void - */ public function run(): void { $this->cleanFiles($this->config['install']['clean']['files']); @@ -41,7 +32,6 @@ public function run(): void /** * @param string[] $files - * @return void */ protected function cleanFiles(array $files): void { @@ -54,7 +44,7 @@ protected function cleanFiles(array $files): void $this->displayInfo('Removing ' . $file . '...'); - if (is_file($file) && !unlink($file)) { + if (\is_file($file) && !\unlink($file)) { $this->displayInfoFailed(); } $this->displayInfoDone(); @@ -63,7 +53,6 @@ protected function cleanFiles(array $files): void /** * @param string[] $directories - * @return void */ protected function cleanDirectories(array $directories): void { @@ -75,8 +64,8 @@ protected function cleanDirectories(array $directories): void $this->displayInfo('Removing ' . $dir . '...'); - if (is_dir($dir)) { - passthru('rm -rf ' . escapeshellarg($dir), $status); + if (\is_dir($dir)) { + passthru('rm -rf ' . \escapeshellarg($dir), $status); } if ($status !== 0) { diff --git a/src/Script/Install/Composer/Reinstall.php b/src/Script/Install/Composer/Reinstall.php index 8a4c6d9..92fbf77 100644 --- a/src/Script/Install/Composer/Reinstall.php +++ b/src/Script/Install/Composer/Reinstall.php @@ -15,25 +15,16 @@ use Eureka\Component\Deployer\Enumerator\Platform; /** - * Class Reinstall - * - * @author Romain Cottard * @codeCoverageIgnore */ class Reinstall extends AbstractCommonScript { - /** - * ComposerClean constructor. - */ public function __construct() { $this->setDescription('Composer clean reinstall (no dev)'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->chdirSource(); @@ -42,9 +33,6 @@ public function run(): void $this->install(); } - /** - * @return void - */ private function clean(): void { $vendor = $this->getRootDirSource() . '/vendor'; @@ -55,7 +43,7 @@ private function clean(): void $this->displayInfo('Removing "vendor/" directory...'); - passthru('rm -rf ' . $vendor, $status); + \passthru('rm -rf ' . $vendor, $status); if ($status !== 0) { $this->displayInfoFailed(); @@ -70,11 +58,11 @@ public function install(): void $this->displayInfo('Installing composer without dev dependencies...'); $args = ' --no-interaction --no-dev'; - if ($this->getAppPlatform() === Platform::PROD) { + if ($this->getAppPlatform() === Platform::Prod) { $args .= ' --optimize-autoloader'; } - passthru("composer install $args", $status); + \passthru("composer install $args", $status); if ($status !== 0) { $this->displayInfoFailed(); diff --git a/src/Script/Install/Copy/Config.php b/src/Script/Install/Copy/Config.php index 72e5d3c..62c321c 100644 --- a/src/Script/Install/Copy/Config.php +++ b/src/Script/Install/Copy/Config.php @@ -14,34 +14,29 @@ use Eureka\Component\Deployer\Common\AbstractCommonScript; /** - * Class Config - * - * @author Romain Cottard * @codeCoverageIgnore */ class Config extends AbstractCommonScript { - /** - * Config constructor. - */ public function __construct() { $this->setDescription('Copying files'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->chdirSource(); foreach ($this->config['install']['copy']['files'] as $file => $destination) { - $source = str_replace(['{platform}', '{domain}'], [$this->getAppPlatform(), $this->getAppDomain()], $file); + $source = \str_replace( + ['{platform}', '{domain}'], + [$this->getAppPlatform()->value, $this->getAppDomain()], + $file, + ); $this->displayInfo("Copying $source to $destination"); - if (!copy($source, $destination)) { + if (!\copy($source, $destination)) { $this->displayInfoFailed(); $this->throw("Could not copy $source to $destination"); } diff --git a/src/Script/Install/Init/Directories.php b/src/Script/Install/Init/Directories.php index defb5f6..baf4c1a 100644 --- a/src/Script/Install/Init/Directories.php +++ b/src/Script/Install/Init/Directories.php @@ -14,25 +14,16 @@ use Eureka\Component\Deployer\Common\AbstractCommonScript; /** - * Class Directories - * - * @author Romain Cottard * @codeCoverageIgnore */ class Directories extends AbstractCommonScript { - /** - * Directories constructor. - */ public function __construct() { $this->setDescription('Initializing / Fixing directories'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->chdirSource(); @@ -41,9 +32,6 @@ public function run(): void $this->fixPermissions(); } - /** - * @return void - */ private function createDirectories(): void { $rootDir = $this->getRootDirSource(); @@ -61,9 +49,6 @@ private function createDirectories(): void $this->displayInfoDone(); } - /** - * @return void - */ private function fixPermissions(): void { $rootDir = $this->getRootDirSource(); diff --git a/src/Script/Install/Init/Symlink.php b/src/Script/Install/Init/Symlink.php index b65c44d..3c2e181 100644 --- a/src/Script/Install/Init/Symlink.php +++ b/src/Script/Install/Init/Symlink.php @@ -14,25 +14,16 @@ use Eureka\Component\Deployer\Common\AbstractCommonScript; /** - * Class Link - * - * @author Romain Cottard * @codeCoverageIgnore */ class Symlink extends AbstractCommonScript { - /** - * Directories constructor. - */ public function __construct() { $this->setDescription('Initializing links (symlinks)'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->chdirSource(); @@ -40,18 +31,15 @@ public function run(): void $this->createSymlinks(); } - /** - * @return void - */ private function createSymlinks(): void { $rootDir = $this->getRootDirSource(); $this->displayInfo('Create symlinks'); foreach ($this->config['install']['init']['symlinks'] as $source => $destination) { - $destination = str_replace('//', '/', $rootDir . DIRECTORY_SEPARATOR . $destination); + $destination = \str_replace('//', '/', $rootDir . DIRECTORY_SEPARATOR . $destination); - if (!symlink($source, $destination)) { + if (!\symlink($source, $destination)) { $this->displayInfoFailed(); $this->throw("Could not create symlink from $source to $destination"); } diff --git a/src/Script/Install/Yarn/EncoreBuild.php b/src/Script/Install/Yarn/EncoreBuild.php index 08352ef..9c906a5 100644 --- a/src/Script/Install/Yarn/EncoreBuild.php +++ b/src/Script/Install/Yarn/EncoreBuild.php @@ -15,30 +15,21 @@ use Eureka\Component\Deployer\Enumerator\Platform; /** - * Class EncoreBuild - * - * @author Romain Cottard * @codeCoverageIgnore */ class EncoreBuild extends AbstractCommonScript { - /** - * EncoreBuild constructor. - */ public function __construct() { $this->setDescription('Yarn build dependencies with Encore'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->chdirSource(); - passthru('yarn encore ' . ($this->getAppPlatform() === Platform::PROD ? 'production' : 'dev'), $status); + \passthru('yarn encore ' . ($this->getAppPlatform() === Platform::Prod ? 'production' : 'dev'), $status); if ($status !== 0) { $this->throw('Error with yarn build with Encore'); diff --git a/src/Script/Install/Yarn/Install.php b/src/Script/Install/Yarn/Install.php index 4efc7bb..355baca 100644 --- a/src/Script/Install/Yarn/Install.php +++ b/src/Script/Install/Yarn/Install.php @@ -14,30 +14,21 @@ use Eureka\Component\Deployer\Common\AbstractCommonScript; /** - * Class Install - * - * @author Romain Cottard * @codeCoverageIgnore */ class Install extends AbstractCommonScript { - /** - * Install constructor. - */ public function __construct() { $this->setDescription('Yarn install dependencies'); $this->setExecutable(); } - /** - * @return void - */ public function run(): void { $this->chdirSource(); - passthru('yarn install', $status); + \passthru('yarn install', $status); if ($status !== 0) { $this->throw('Error with yarn installation'); diff --git a/src/Script/Link.php b/src/Script/Link.php index 6f92d0c..cf53036 100644 --- a/src/Script/Link.php +++ b/src/Script/Link.php @@ -43,7 +43,7 @@ public function run(): void $pathSource = $this->getRootDirSource(); $pathLink = $this->getPathBuilder()->buildPathLink( $this->getAppPlatform(), - $this->getAppDomain() + $this->getAppDomain(), ); $this->cleanLink($pathLink); $this->linkToWebServer($pathSource, $pathLink); diff --git a/tests/unit/PathBuilderTest.php b/tests/unit/PathBuilderTest.php index e087e4e..2cb4aa8 100644 --- a/tests/unit/PathBuilderTest.php +++ b/tests/unit/PathBuilderTest.php @@ -22,21 +22,11 @@ */ class PathBuilderTest extends TestCase { - /** - * @return void - */ - public function testICanInitializePathBuilder(): void - { - $builder = new PathBuilder('/var/src', '/var/www'); - - $this->assertInstanceOf(PathBuilder::class, $builder); - } - public function testICanBuildPathAndLinkForDev(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::DEV, 'example', 'www.example.com', '1.0.0'); - $pathLink = $builder->buildPathLink(Platform::DEV, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Dev, 'example', 'www.example.com', '1.0.0'); + $pathLink = $builder->buildPathLink(Platform::Dev, 'www.example.com'); $this->assertSame('/var/src/example/dev-www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/dev-www.example.com', $pathLink); @@ -45,8 +35,8 @@ public function testICanBuildPathAndLinkForDev(): void public function testICanBuildPathAndLinkForLocal(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::LOCAL, 'example', 'www.example.com', '1.0.0', false); - $pathLink = $builder->buildPathLink(Platform::LOCAL, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Local, 'example', 'www.example.com', '1.0.0', false); + $pathLink = $builder->buildPathLink(Platform::Local, 'www.example.com'); $this->assertSame('/var/src/example/local-www.example.com', $pathSrc); $this->assertSame('/var/www/local-www.example.com', $pathLink); @@ -55,8 +45,8 @@ public function testICanBuildPathAndLinkForLocal(): void public function testICanBuildPathAndLinkForDocker(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::DOCKER, 'example', 'www.example.com', '1.0.0'); - $pathLink = $builder->buildPathLink(Platform::DOCKER, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Docker, 'example', 'www.example.com', '1.0.0'); + $pathLink = $builder->buildPathLink(Platform::Docker, 'www.example.com'); $this->assertSame('/var/src/example/docker-www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/docker-www.example.com', $pathLink); @@ -65,8 +55,8 @@ public function testICanBuildPathAndLinkForDocker(): void public function testICanBuildPathAndLinkForStaging(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::STAGING, 'example', 'www.example.com', '1.0.0'); - $pathLink = $builder->buildPathLink(Platform::STAGING, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Staging, 'example', 'www.example.com', '1.0.0'); + $pathLink = $builder->buildPathLink(Platform::Staging, 'www.example.com'); $this->assertSame('/var/src/example/staging-www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/staging-www.example.com', $pathLink); @@ -75,8 +65,8 @@ public function testICanBuildPathAndLinkForStaging(): void public function testICanBuildPathAndLinkForTest(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::TEST, 'example', 'www.example.com', '1.0.0'); - $pathLink = $builder->buildPathLink(Platform::TEST, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Test, 'example', 'www.example.com', '1.0.0'); + $pathLink = $builder->buildPathLink(Platform::Test, 'www.example.com'); $this->assertSame('/var/src/example/test-www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/test-www.example.com', $pathLink); @@ -85,8 +75,8 @@ public function testICanBuildPathAndLinkForTest(): void public function testICanBuildPathAndLinkForDemo(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::DEMO, 'example', 'www.example.com', '1.0.0'); - $pathLink = $builder->buildPathLink(Platform::DEMO, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Demo, 'example', 'www.example.com', '1.0.0'); + $pathLink = $builder->buildPathLink(Platform::Demo, 'www.example.com'); $this->assertSame('/var/src/example/demo-www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/demo-www.example.com', $pathLink); @@ -95,8 +85,8 @@ public function testICanBuildPathAndLinkForDemo(): void public function testICanBuildPathAndLinkForPreprod(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::PREPROD, 'example', 'www.example.com', '1.0.0', false); - $pathLink = $builder->buildPathLink(Platform::PREPROD, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Preprod, 'example', 'www.example.com', '1.0.0', false); + $pathLink = $builder->buildPathLink(Platform::Preprod, 'www.example.com'); $this->assertSame('/var/src/example/preprod-www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/preprod-www.example.com', $pathLink); @@ -105,8 +95,8 @@ public function testICanBuildPathAndLinkForPreprod(): void public function testICanBuildPathAndLinkForProd(): void { $builder = new PathBuilder('/var/src', '/var/www'); - $pathSrc = $builder->buildPathSource(Platform::PROD, 'example', 'www.example.com', '1.0.0', false); - $pathLink = $builder->buildPathLink(Platform::PROD, 'www.example.com'); + $pathSrc = $builder->buildPathSource(Platform::Prod, 'example', 'www.example.com', '1.0.0', false); + $pathLink = $builder->buildPathLink(Platform::Prod, 'www.example.com'); $this->assertSame('/var/src/example/www.example.com_v1.0.0', $pathSrc); $this->assertSame('/var/www/www.example.com', $pathLink);