diff --git a/.circleci/config.yml b/.circleci/config.yml index d4d60c64a..b6abd34b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -615,57 +615,6 @@ jobs: # Use custom cache key for this workflow to make sure that caches from # the main workflow are separated from this one. DREVOPS_CI_DB_CACHE_BRANCH: drevops-dev-didi-ii - - #----------------------------------------------------------------------------- - # Publish installer to install.drevops.com - # @todo Move this to GitHub Actions. - #----------------------------------------------------------------------------- - drevops-dev-deploy-installer: - <<: *runner_config - steps: - - checkout - - *step_process_codebase - - *step_setup_remote_docker - - *step_setup_docker_network - - add_ssh_keys: - fingerprints: - - "f6:b2:bb:a8:1d:9d:fb:03:c6:39:27:1e:71:bb:9a:9b" - - run: - name: Prepare installer. - command: | - cd .drevops/installer - composer install - sed -i "s/\"git-tag-ci\": \"dev\"/\"git-tag-ci\": \"${CIRCLE_TAG:-${CIRCLE_SHA1}}\"/g" box.json - composer build - mkdir -p /tmp/installer/docs - cp .build/install.phar /tmp/installer/docs/index.html - echo "install.drevops.com" > /tmp/installer/docs/CNAME - - run: - name: Configure SSH. - command: | - DEPLOY_DOCS_SSH_FINGERPRINT="f6:b2:bb:a8:1d:9d:fb:03:c6:39:27:1e:71:bb:9a:9b" - # Configure SSH to configure git and SSH to connect to remote servers for deployment. - [ "$(git config --global user.name)" == "" ] && git config --global user.name "Deployment robot" - [ "$(git config --global user.email)" == "" ] && git config --global user.email "deploy@drevops.com" - mkdir -p "${HOME}/.ssh/" - echo -e "Host *\n\tStrictHostKeyChecking no\n" > "${HOME}/.ssh/config" - DEPLOY_DOCS_SSH_FILE="${DEPLOY_DOCS_SSH_FINGERPRINT//:}" - DEPLOY_DOCS_SSH_FILE="${HOME}/.ssh/id_rsa_${DEPLOY_DOCS_SSH_FILE//\"}" - if [ -f "${DEPLOY_DOCS_SSH_FILE}" ]; then - echo "Found Deploy SSH key file ${DEPLOY_DOCS_SSH_FILE}" - ssh-add -D > /dev/null - ssh-add "${DEPLOY_DOCS_SSH_FILE}" - fi - - run: - name: Deploy installer - command: | - cd /tmp/installer - git init - git checkout -b main - git add -A - git commit -m "Automatically pushed from drevops/drevops" - git remote add origin git@github.com:drevops/installer.git - git push origin main --force #============================================================================= #;> DREVOPS_DEV @@ -776,16 +725,6 @@ workflows: tags: only: /^[0-9]+(\.[0-9]+)+(-rc[0-9]+)?$/ - # Publish DrevOps installer. - - drevops-dev-deploy-installer: - requires: - - drevops-dev-test - filters: - branches: - only: /^feature\/installer-update$/ - tags: - only: /^[0-9]+(\.[0-9]+)+(-rc[0-9]+)?$/ - # Test workflow to test DREVOPS_DB_DOCKER_IMAGE workflow for DB from file. drevops-dev-didi-fi: jobs: diff --git a/.drevops/installer/.gitignore b/.drevops/installer/.gitignore index 015028a5a..c134353d7 100644 --- a/.drevops/installer/.gitignore +++ b/.drevops/installer/.gitignore @@ -1,3 +1,7 @@ -.build +/.build +/.coverage-html +/.phpunit.cache +/cobertura.xml +/composer.lock /vendor /vendor-bin diff --git a/.drevops/installer/composer.json b/.drevops/installer/composer.json index 53095084e..f02d876e3 100644 --- a/.drevops/installer/composer.json +++ b/.drevops/installer/composer.json @@ -1,7 +1,7 @@ { "name": "drevops/installer", "type": "library", - "description": "Provides installer functionality.", + "description": "Provides DrevOps installer functionality.", "license": "GPL-2.0-or-later", "authors": [ { @@ -17,16 +17,19 @@ "source": "https://github.com/drevops/drevops" }, "require": { - "php": ">=8.2", - "symfony/console": "^6.3" + "php": ">=8.1", + "symfony/console": "^6.3 || ^7" }, "require-dev": { - "phpunit/phpunit": "^10", + "bamarni/composer-bin-plugin": "^1.8", "dealerdirect/phpcodesniffer-composer-installer": "^1", "drupal/coder": "^8.3", + "mikey179/vfsstream": "^1.6", + "opis/closure": "^3.6", "phpmd/phpmd": "^2.13", "phpstan/phpstan": "^1.10", - "bamarni/composer-bin-plugin": "^1.8" + "phpunit/phpunit": "^10", + "rector/rector": "^0.19.0" }, "autoload": { "psr-4": { @@ -43,24 +46,28 @@ }, "config": { "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true, - "bamarni/composer-bin-plugin": true + "bamarni/composer-bin-plugin": true, + "dealerdirect/phpcodesniffer-composer-installer": true } }, "scripts": { "lint": [ "phpcs", - "phpmd --exclude vendor,node_modules . text phpmd.xml || true", - "phpstan" + "phpstan", + "rector --dry-run" + ], + "lint-fix": [ + "rector --clear-cache", + "phpcbf" ], - "lint:fix": "phpcbf", - "test": "phpunit tests/phpunit/unit", + "test": "if [ \"${XDEBUG_MODE}\" = 'coverage' ]; then phpunit; else phpunit --no-coverage; fi", "build": [ "@composer bin box require --dev humbug/box", "box validate", - "box compile", - "ls -al .build/install.phar" + "box compile" ] }, - "bin": ["install"] + "bin": [ + "install" + ] } diff --git a/.drevops/installer/composer.lock b/.drevops/installer/composer.lock deleted file mode 100644 index b3e045d42..000000000 --- a/.drevops/installer/composer.lock +++ /dev/null @@ -1,3543 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "82389d0dacac8c7a50be452b6c58f91e", - "packages": [ - { - "name": "psr/container", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" - }, - "time": "2021-11-05T16:47:00+00:00" - }, - { - "name": "symfony/console", - "version": "v6.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0254811a143e6bc6c8deea08b589a7e68a37f625", - "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v6.4.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-12-10T16:15:48+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-05-23T14:45:45+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "875e90aeea2777b6f135677f618529449334a612" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", - "reference": "875e90aeea2777b6f135677f618529449334a612", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-07-28T09:04:16+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.4.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-12-26T14:02:43+00:00" - }, - { - "name": "symfony/string", - "version": "v7.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/cc78f14f91f5e53b42044d0620961c48028ff9f5", - "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" - }, - "require-dev": { - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v7.0.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-12-10T16:54:46+00:00" - } - ], - "packages-dev": [ - { - "name": "bamarni/composer-bin-plugin", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/bamarni/composer-bin-plugin.git", - "reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", - "reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^2.0", - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "composer/composer": "^2.0", - "ext-json": "*", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", - "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", - "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Bamarni\\Composer\\Bin\\BamarniBinPlugin" - }, - "autoload": { - "psr-4": { - "Bamarni\\Composer\\Bin\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "No conflicts for your bin dependencies", - "keywords": [ - "composer", - "conflict", - "dependency", - "executable", - "isolation", - "tool" - ], - "support": { - "issues": "https://github.com/bamarni/composer-bin-plugin/issues", - "source": "https://github.com/bamarni/composer-bin-plugin/tree/1.8.2" - }, - "time": "2022-10-31T08:38:03+00:00" - }, - { - "name": "composer/pcre", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/composer/pcre.git", - "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", - "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Pcre\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], - "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.1" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2023-10-11T07:11:09+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", - "shasum": "" - }, - "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" - }, - "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" - } - ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2022-02-25T21:32:43+00:00" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "4be43904336affa5c2f70744a348312336afd0da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", - "reference": "4be43904336affa5c2f70744a348312336afd0da", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "ext-json": "*", - "ext-zip": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0", - "yoast/phpunit-polyfills": "^1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/composer-installer/issues", - "source": "https://github.com/PHPCSStandards/composer-installer" - }, - "time": "2023-01-05T11:28:13+00:00" - }, - { - "name": "drupal/coder", - "version": "8.3.22", - "source": { - "type": "git", - "url": "https://github.com/pfrenssen/coder.git", - "reference": "ba6e62303d567863275fb086941f50a06dc7d08f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pfrenssen/coder/zipball/ba6e62303d567863275fb086941f50a06dc7d08f", - "reference": "ba6e62303d567863275fb086941f50a06dc7d08f", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1 || ^1.0.0", - "ext-mbstring": "*", - "php": ">=7.2", - "sirbrillig/phpcs-variable-analysis": "^2.11.7", - "slevomat/coding-standard": "^8.11", - "squizlabs/php_codesniffer": "^3.7.1", - "symfony/yaml": ">=3.4.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.7.12", - "phpunit/phpunit": "^8.0" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "Drupal\\": "coder_sniffer/Drupal/", - "DrupalPractice\\": "coder_sniffer/DrupalPractice/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0-or-later" - ], - "description": "Coder is a library to review Drupal code.", - "homepage": "https://www.drupal.org/project/coder", - "keywords": [ - "code review", - "phpcs", - "standards" - ], - "support": { - "issues": "https://www.drupal.org/project/issues/coder", - "source": "https://www.drupal.org/project/coder" - }, - "time": "2023-10-15T09:55:50+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2023-03-08T13:26:56+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v5.0.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", - "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0" - }, - "time": "2024-01-07T17:17:35+00:00" - }, - { - "name": "pdepend/pdepend", - "version": "2.16.2", - "source": { - "type": "git", - "url": "https://github.com/pdepend/pdepend.git", - "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58", - "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58", - "shasum": "" - }, - "require": { - "php": ">=5.3.7", - "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0", - "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0", - "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0", - "symfony/polyfill-mbstring": "^1.19" - }, - "require-dev": { - "easy-doc/easy-doc": "0.0.0|^1.2.3", - "gregwar/rst": "^1.0", - "squizlabs/php_codesniffer": "^2.0.0" - }, - "bin": [ - "src/bin/pdepend" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "PDepend\\": "src/main/php/PDepend" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Official version of pdepend to be handled with Composer", - "keywords": [ - "PHP Depend", - "PHP_Depend", - "dev", - "pdepend" - ], - "support": { - "issues": "https://github.com/pdepend/pdepend/issues", - "source": "https://github.com/pdepend/pdepend/tree/2.16.2" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", - "type": "tidelift" - } - ], - "time": "2023-12-17T18:09:59+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpmd/phpmd", - "version": "2.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpmd/phpmd.git", - "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0", - "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0", - "shasum": "" - }, - "require": { - "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", - "ext-xml": "*", - "pdepend/pdepend": "^2.16.1", - "php": ">=5.3.9" - }, - "require-dev": { - "easy-doc/easy-doc": "0.0.0 || ^1.3.2", - "ext-json": "*", - "ext-simplexml": "*", - "gregwar/rst": "^1.0", - "mikey179/vfsstream": "^1.6.8", - "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2" - }, - "bin": [ - "src/bin/phpmd" - ], - "type": "library", - "autoload": { - "psr-0": { - "PHPMD\\": "src/main/php" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Manuel Pichler", - "email": "github@manuel-pichler.de", - "homepage": "https://github.com/manuelpichler", - "role": "Project Founder" - }, - { - "name": "Marc Würth", - "email": "ravage@bluewin.ch", - "homepage": "https://github.com/ravage84", - "role": "Project Maintainer" - }, - { - "name": "Other contributors", - "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", - "role": "Contributors" - } - ], - "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", - "homepage": "https://phpmd.org/", - "keywords": [ - "dev", - "mess detection", - "mess detector", - "pdepend", - "phpmd", - "pmd" - ], - "support": { - "irc": "irc://irc.freenode.org/phpmd", - "issues": "https://github.com/phpmd/phpmd/issues", - "source": "https://github.com/phpmd/phpmd/tree/2.15.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", - "type": "tidelift" - } - ], - "time": "2023-12-11T08:22:20+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.24.5", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc", - "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5" - }, - "time": "2023-12-16T09:33:33+00:00" - }, - { - "name": "phpstan/phpstan", - "version": "1.10.55", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", - "reference": "9a88f9d18ddf4cf54c922fbeac16c4cb164c5949", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0" - }, - "conflict": { - "phpstan/phpstan-shim": "*" - }, - "bin": [ - "phpstan", - "phpstan.phar" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "keywords": [ - "dev", - "static analysis" - ], - "support": { - "docs": "https://phpstan.org/user-guide/getting-started", - "forum": "https://github.com/phpstan/phpstan/discussions", - "issues": "https://github.com/phpstan/phpstan/issues", - "security": "https://github.com/phpstan/phpstan/security/policy", - "source": "https://github.com/phpstan/phpstan-src" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" - } - ], - "time": "2024-01-08T12:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "10.1.11", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "78c3b7625965c2513ee96569a4dbb62601784145" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145", - "reference": "78c3b7625965c2513ee96569a4dbb62601784145", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.1" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-21T15:38:30+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T06:24:48+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:56:09+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T14:07:24+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:57:52+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "10.5.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e5c5b397a95cb0db013270a985726fcae93e61b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e5c5b397a95cb0db013270a985726fcae93e61b8", - "reference": "e5c5b397a95cb0db013270a985726fcae93e61b8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.5", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-invoker": "^4.0", - "phpunit/php-text-template": "^3.0", - "phpunit/php-timer": "^6.0", - "sebastian/cli-parser": "^2.0", - "sebastian/code-unit": "^2.0", - "sebastian/comparator": "^5.0", - "sebastian/diff": "^5.0", - "sebastian/environment": "^6.0", - "sebastian/exporter": "^5.1", - "sebastian/global-state": "^6.0.1", - "sebastian/object-enumerator": "^5.0", - "sebastian/recursion-context": "^5.0", - "sebastian/type": "^4.0", - "sebastian/version": "^4.0" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.7" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2024-01-14T16:40:30+00:00" - }, - { - "name": "psr/log", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" - }, - "time": "2021-07-14T16:46:02+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:15+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:59:15+00:00" - }, - { - "name": "sebastian/comparator", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-14T13:18:12+00:00" - }, - { - "name": "sebastian/complexity", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-21T08:37:17+00:00" - }, - { - "name": "sebastian/diff", - "version": "5.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f", - "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-22T10:55:06+00:00" - }, - { - "name": "sebastian/environment", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", - "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-04-11T05:39:26+00:00" - }, - { - "name": "sebastian/exporter", - "version": "5.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-09-24T13:22:09+00:00" - }, - { - "name": "sebastian/global-state", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-07-19T07:19:23+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-21T08:38:20+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:08:32+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:06:18+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:05:40+00:00" - }, - { - "name": "sebastian/type", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:10:45+00:00" - }, - { - "name": "sebastian/version", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-07T11:34:05+00:00" - }, - { - "name": "sirbrillig/phpcs-variable-analysis", - "version": "v2.11.17", - "source": { - "type": "git", - "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", - "reference": "3b71162a6bf0cde2bff1752e40a1788d8273d049" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/3b71162a6bf0cde2bff1752e40a1788d8273d049", - "reference": "3b71162a6bf0cde2bff1752e40a1788d8273d049", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "squizlabs/php_codesniffer": "^3.5.6" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", - "phpcsstandards/phpcsdevcs": "^1.1", - "phpstan/phpstan": "^1.7", - "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0", - "sirbrillig/phpcs-import-detection": "^1.1", - "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0@beta" - }, - "type": "phpcodesniffer-standard", - "autoload": { - "psr-4": { - "VariableAnalysis\\": "VariableAnalysis/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Sam Graham", - "email": "php-codesniffer-variableanalysis@illusori.co.uk" - }, - { - "name": "Payton Swick", - "email": "payton@foolord.com" - } - ], - "description": "A PHPCS sniff to detect problems with variables.", - "keywords": [ - "phpcs", - "static analysis" - ], - "support": { - "issues": "https://github.com/sirbrillig/phpcs-variable-analysis/issues", - "source": "https://github.com/sirbrillig/phpcs-variable-analysis", - "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" - }, - "time": "2023-08-05T23:46:11+00:00" - }, - { - "name": "slevomat/coding-standard", - "version": "8.14.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "fea1fd6f137cc84f9cba0ae30d549615dbc6a926" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/fea1fd6f137cc84f9cba0ae30d549615dbc6a926", - "reference": "fea1fd6f137cc84f9cba0ae30d549615dbc6a926", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.23.1", - "squizlabs/php_codesniffer": "^3.7.1" - }, - "require-dev": { - "phing/phing": "2.17.4", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.10.37", - "phpstan/phpstan-deprecation-rules": "1.1.4", - "phpstan/phpstan-phpunit": "1.3.14", - "phpstan/phpstan-strict-rules": "1.5.1", - "phpunit/phpunit": "8.5.21|9.6.8|10.3.5" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "8.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "keywords": [ - "dev", - "phpcs" - ], - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.14.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2023-10-08T07:28:08+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.8.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5805f7a4e4958dbb5e944ef1e6edae0a303765e7", - "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" - }, - "funding": [ - { - "url": "https://github.com/PHPCSStandards", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", - "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" - } - ], - "time": "2023-12-08T12:32:31+00:00" - }, - { - "name": "symfony/config", - "version": "v7.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/8789646600f4e7e451dde9e1dc81cfa429f3857a", - "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^6.4|^7.0", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/finder": "<6.4", - "symfony/service-contracts": "<2.5" - }, - "require-dev": { - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/config/tree/v7.0.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-11-09T08:30:23+00:00" - }, - { - "name": "symfony/dependency-injection", - "version": "v7.0.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f6667642954bce638733f254c39e5b5700b47ba4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6667642954bce638733f254c39e5b5700b47ba4", - "reference": "f6667642954bce638733f254c39e5b5700b47ba4", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^3.3", - "symfony/var-exporter": "^6.4|^7.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2", - "symfony/config": "<6.4", - "symfony/finder": "<6.4", - "symfony/yaml": "<6.4" - }, - "provide": { - "psr/container-implementation": "1.1|2.0", - "symfony/service-implementation": "1.1|2.0|3.0" - }, - "require-dev": { - "symfony/config": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows you to standardize and centralize the way objects are constructed in your application", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.0.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-12-01T15:10:06+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v7.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7da8ea2362a283771478c5f7729cfcb43a76b8b7", - "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-07-27T06:33:22+00:00" - }, - { - "name": "symfony/var-exporter", - "version": "v7.0.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-exporter.git", - "reference": "a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3", - "reference": "a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "symfony/var-dumper": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\VarExporter\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows exporting any serializable PHP data structure to plain PHP code", - "homepage": "https://symfony.com", - "keywords": [ - "clone", - "construct", - "export", - "hydrate", - "instantiate", - "lazy-loading", - "proxy", - "serialize" - ], - "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.0.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-11-30T11:38:21+00:00" - }, - { - "name": "symfony/yaml", - "version": "v7.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "0055b230c408428b9b5cde7c55659555be5c0278" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/0055b230c408428b9b5cde7c55659555be5c0278", - "reference": "0055b230c408428b9b5cde7c55659555be5c0278", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v7.0.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-11-07T10:26:03+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.2" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2023-11-20T00:12:19+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.2" - }, - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/.drevops/installer/phpstan.neon b/.drevops/installer/phpstan.neon index 50b8f8a2a..aeb474883 100644 --- a/.drevops/installer/phpstan.neon +++ b/.drevops/installer/phpstan.neon @@ -13,5 +13,11 @@ parameters: excludePaths: - vendor/* - # ignoreErrors: - # - "#^Error message#" + ignoreErrors: + - + # Since tests and data providers do not have to have parameter docblocks, + # it is not possible to specify the type of the parameter, so we ignore + # this error. + message: '#.*no value type specified in iterable type array.#' + path: tests/phpunit/* + reportUnmatched: false diff --git a/.drevops/installer/phpunit.xml b/.drevops/installer/phpunit.xml new file mode 100644 index 000000000..ead316b26 --- /dev/null +++ b/.drevops/installer/phpunit.xml @@ -0,0 +1,37 @@ + + + + + tests/phpunit + + + + + + src + + + + + + + + + + diff --git a/.drevops/installer/rector.php b/.drevops/installer/rector.php new file mode 100644 index 000000000..a158b559c --- /dev/null +++ b/.drevops/installer/rector.php @@ -0,0 +1,65 @@ +paths([ + __DIR__ . '/**', + ]); + + $rectorConfig->sets([ + SetList::PHP_80, + SetList::PHP_81, + SetList::CODE_QUALITY, + SetList::CODING_STYLE, + SetList::DEAD_CODE, + SetList::INSTANCEOF, + SetList::TYPE_DECLARATION, + ]); + + $rectorConfig->skip([ + // Rules added by Rector's rule sets. + ArraySpreadInsteadOfArrayMergeRector::class, + CountArrayToEmptyArrayComparisonRector::class, + DisallowedEmptyRuleFixerRector::class, + InlineArrayReturnAssignRector::class, + NewlineAfterStatementRector::class, + NewlineBeforeNewAssignSetRector::class, + PostIncDecToPreIncDecRector::class, + RemoveAlwaysTrueIfConditionRector::class, + SimplifyEmptyCheckOnEmptyArrayRector::class, + // Dependencies. + '*/vendor/*', + '*/node_modules/*', + ]); + + $rectorConfig->fileExtensions([ + 'php', + 'inc', + ]); + + $rectorConfig->importNames(TRUE, FALSE); + $rectorConfig->importShortClasses(FALSE); +}; diff --git a/.drevops/installer/src/Command/InstallCommand.php b/.drevops/installer/src/Command/InstallCommand.php index 8052720a2..8f4ca843e 100644 --- a/.drevops/installer/src/Command/InstallCommand.php +++ b/.drevops/installer/src/Command/InstallCommand.php @@ -19,32 +19,32 @@ class InstallCommand extends Command { /** * Defines installer exit codes. */ - const EXIT_SUCCESS = 0; + final const EXIT_SUCCESS = 0; - const EXIT_ERROR = 1; + final const EXIT_ERROR = 1; /** * Defines error level to be reported as an error. */ - const ERROR_LEVEL = E_USER_WARNING; + final const ERROR_LEVEL = E_USER_WARNING; /** * Defines installer status message flags. */ - const INSTALLER_STATUS_SUCCESS = 0; + final const INSTALLER_STATUS_SUCCESS = 0; - const INSTALLER_STATUS_ERROR = 1; + final const INSTALLER_STATUS_ERROR = 1; - const INSTALLER_STATUS_MESSAGE = 2; + final const INSTALLER_STATUS_MESSAGE = 2; - const INSTALLER_STATUS_DEBUG = 3; + final const INSTALLER_STATUS_DEBUG = 3; /** * Defines "yes" and "no" answer strings. */ - const ANSWER_YES = 'y'; + final const ANSWER_YES = 'y'; - const ANSWER_NO = 'n'; + final const ANSWER_NO = 'n'; /** * Defines current working directory. @@ -78,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int /** * Main functionality. */ - protected function main(InputInterface $input, OutputInterface $output) { + protected function main(InputInterface $input, OutputInterface $output): int { self::$currentDir = getcwd(); $this->initConfig($input); @@ -138,13 +138,13 @@ protected function prepareDestination() { $this->status('Done', self::INSTALLER_STATUS_SUCCESS); } - if (is_readable("$dst/.git")) { + if (is_readable($dst . '/.git')) { $this->status(sprintf('Git repository exists in "%s" - skipping initialisation.', $dst), self::INSTALLER_STATUS_MESSAGE, FALSE); } else { $this->status(sprintf('Initialising Git repository in directory "%s".', $dst), self::INSTALLER_STATUS_MESSAGE, FALSE); - $this->doExec("git --work-tree=\"$dst\" --git-dir=\"$dst/.git\" init > /dev/null"); - if (!is_readable("$dst/.git")) { + $this->doExec(sprintf('git --work-tree="%s" --git-dir="%s/.git" init > /dev/null', $dst, $dst)); + if (!is_readable($dst . '/.git')) { throw new \RuntimeException(sprintf('Unable to init git project in directory "%s".', $dst)); } } @@ -206,10 +206,10 @@ protected function copyFiles() { $this->status('Copying files', self::INSTALLER_STATUS_DEBUG); foreach ($valid_files as $filename) { - $relative_file = str_replace($src . DIRECTORY_SEPARATOR, '.' . DIRECTORY_SEPARATOR, $filename); + $relative_file = str_replace($src . DIRECTORY_SEPARATOR, '.' . DIRECTORY_SEPARATOR, (string) $filename); if (static::isInternalPath($relative_file)) { - $this->status("Skipped file $relative_file as an internal DrevOps file.", self::INSTALLER_STATUS_DEBUG); + $this->status(sprintf('Skipped file %s as an internal DrevOps file.', $relative_file), self::INSTALLER_STATUS_DEBUG); unlink($filename); continue; } @@ -270,8 +270,8 @@ protected function processDemo() { $this->status('Done', self::INSTALLER_STATUS_SUCCESS); } - protected static function copyRecursive($source, $dest, $permissions = 0755, $copy_empty_dirs = FALSE) { - $parent = dirname($dest); + protected static function copyRecursive($source, $dest, $permissions = 0755, $copy_empty_dirs = FALSE): bool { + $parent = dirname((string) $dest); if (!is_dir($parent)) { mkdir($parent, $permissions, TRUE); @@ -284,8 +284,8 @@ protected static function copyRecursive($source, $dest, $permissions = 0755, $co $cur_dir = getcwd(); chdir($parent); $ret = TRUE; - if (!is_readable(basename($dest))) { - $ret = symlink(readlink($source), basename($dest)); + if (!is_readable(basename((string) $dest))) { + $ret = symlink(readlink($source), basename((string) $dest)); } chdir($cur_dir); @@ -310,7 +310,7 @@ protected static function copyRecursive($source, $dest, $permissions = 0755, $co if ($entry == '.' || $entry == '..') { continue; } - static::copyRecursive("$source/$entry", "$dest/$entry", $permissions, FALSE); + static::copyRecursive(sprintf('%s/%s', $source, $entry), sprintf('%s/%s', $dest, $entry), $permissions, FALSE); } $dir && $dir->close(); @@ -318,11 +318,11 @@ protected static function copyRecursive($source, $dest, $permissions = 0755, $co return TRUE; } - protected function gitFileIsTracked($path, $dir) { + protected function gitFileIsTracked($path, string $dir): bool { if (is_dir($dir . DIRECTORY_SEPARATOR . '.git')) { $cwd = getcwd(); chdir($dir); - $this->doExec("git ls-files --error-unmatch \"{$path}\" 2>&1 >/dev/null", $output, $code); + $this->doExec(sprintf('git ls-files --error-unmatch "%s" 2>&1 >/dev/null', $path), $output, $code); chdir($cwd); return $code === 0; @@ -331,7 +331,7 @@ protected function gitFileIsTracked($path, $dir) { return FALSE; } - protected function drupalCoreProfiles() { + protected function drupalCoreProfiles(): array { return [ 'standard', 'minimal', @@ -347,19 +347,19 @@ protected function processAnswer($name, $dir) { return $this->executeCallback('process', $name, $dir); } - protected function processProfile($dir) { + protected function processProfile(string $dir) { $webroot = $this->getAnswer('webroot'); // For core profiles - remove custom profile and direct links to it. if (in_array($this->getAnswer('profile'), $this->drupalCoreProfiles())) { - static::rmdirRecursive("{$dir}/{$webroot}/profiles/your_site_profile"); - static::rmdirRecursive("{$dir}/{$webroot}/profiles/custom/your_site_profile"); - static::dirReplaceContent("{$webroot}/profiles/your_site_profile,", '', $dir); - static::dirReplaceContent("{$webroot}/profiles/custom/your_site_profile,", '', $dir); + static::rmdirRecursive(sprintf('%s/%s/profiles/your_site_profile', $dir, $webroot)); + static::rmdirRecursive(sprintf('%s/%s/profiles/custom/your_site_profile', $dir, $webroot)); + static::dirReplaceContent($webroot . '/profiles/your_site_profile,', '', $dir); + static::dirReplaceContent($webroot . '/profiles/custom/your_site_profile,', '', $dir); } static::dirReplaceContent('your_site_profile', $this->getAnswer('profile'), $dir); } - protected function processProvisionUseProfile($dir) { + protected function processProvisionUseProfile(string $dir) { if ($this->getAnswer('provision_use_profile') == self::ANSWER_YES) { static::fileReplaceContent('/DREVOPS_PROVISION_USE_PROFILE=.*/', "DREVOPS_PROVISION_USE_PROFILE=1", $dir . '/.env'); $this->removeTokenWithContent('!PROVISION_USE_PROFILE', $dir); @@ -370,9 +370,9 @@ protected function processProvisionUseProfile($dir) { } } - protected function processDatabaseDownloadSource($dir) { + protected function processDatabaseDownloadSource(string $dir) { $type = $this->getAnswer('database_download_source'); - static::fileReplaceContent('/DREVOPS_DB_DOWNLOAD_SOURCE=.*/', "DREVOPS_DB_DOWNLOAD_SOURCE=$type", $dir . '/.env'); + static::fileReplaceContent('/DREVOPS_DB_DOWNLOAD_SOURCE=.*/', 'DREVOPS_DB_DOWNLOAD_SOURCE=' . $type, $dir . '/.env'); if ($type == 'docker_registry') { $this->removeTokenWithContent('!DREVOPS_DB_DOWNLOAD_SOURCE_DOCKER_REGISTRY', $dir); @@ -382,9 +382,9 @@ protected function processDatabaseDownloadSource($dir) { } } - protected function processDatabaseImage($dir) { + protected function processDatabaseImage(string $dir) { $image = $this->getAnswer('database_image'); - static::fileReplaceContent('/DREVOPS_DB_DOCKER_IMAGE=.*/', "DREVOPS_DB_DOCKER_IMAGE=$image", $dir . '/.env'); + static::fileReplaceContent('/DREVOPS_DB_DOCKER_IMAGE=.*/', 'DREVOPS_DB_DOCKER_IMAGE=' . $image, $dir . '/.env'); if ($image) { $this->removeTokenWithContent('!DREVOPS_DB_DOCKER_IMAGE', $dir); @@ -394,7 +394,7 @@ protected function processDatabaseImage($dir) { } } - protected function processOverrideExistingDb($dir) { + protected function processOverrideExistingDb(string $dir) { if ($this->getAnswer('override_existing_db') == self::ANSWER_YES) { static::fileReplaceContent('/DREVOPS_PROVISION_OVERRIDE_DB=.*/', "DREVOPS_PROVISION_OVERRIDE_DB=1", $dir . '/.env'); } @@ -403,47 +403,47 @@ protected function processOverrideExistingDb($dir) { } } - protected function processDeployType($dir) { + protected function processDeployType(string $dir) { $type = $this->getAnswer('deploy_type'); if ($type != 'none') { - static::fileReplaceContent('/DREVOPS_DEPLOY_TYPES=.*/', "DREVOPS_DEPLOY_TYPES=$type", $dir . '/.env'); + static::fileReplaceContent('/DREVOPS_DEPLOY_TYPES=.*/', 'DREVOPS_DEPLOY_TYPES=' . $type, $dir . '/.env'); - if (strpos($type, 'artifact') === FALSE) { - @unlink("$dir/.gitignore.deployment"); + if (!str_contains((string) $type, 'artifact')) { + @unlink($dir . '/.gitignore.deployment'); } $this->removeTokenWithContent('!DEPLOYMENT', $dir); } else { - @unlink("$dir/docs/deployment.md"); - @unlink("$dir/.gitignore.deployment"); + @unlink($dir . '/docs/deployment.md'); + @unlink($dir . '/.gitignore.deployment'); $this->removeTokenWithContent('DEPLOYMENT', $dir); } } - protected function processPreserveAcquia($dir) { + protected function processPreserveAcquia(string $dir) { if ($this->getAnswer('preserve_acquia') == self::ANSWER_YES) { $this->removeTokenWithContent('!ACQUIA', $dir); } else { - static::rmdirRecursive("$dir/hooks"); + static::rmdirRecursive($dir . '/hooks'); $this->removeTokenWithContent('ACQUIA', $dir); } } - protected function processPreserveLagoon($dir) { + protected function processPreserveLagoon(string $dir) { if ($this->getAnswer('preserve_lagoon') == self::ANSWER_YES) { $this->removeTokenWithContent('!LAGOON', $dir); } else { - @unlink("$dir/drush/sites/lagoon.site.yml"); - @unlink("$dir/.lagoon.yml"); - @unlink("$dir/.github/workflows/dispatch-webhook-lagoon.yml"); + @unlink($dir . '/drush/sites/lagoon.site.yml'); + @unlink($dir . '/.lagoon.yml'); + @unlink($dir . '/.github/workflows/dispatch-webhook-lagoon.yml'); $this->removeTokenWithContent('LAGOON', $dir); } } - protected function processPreserveFtp($dir) { + protected function processPreserveFtp(string $dir) { if ($this->getAnswer('preserve_ftp') == self::ANSWER_YES) { $this->removeTokenWithContent('!FTP', $dir); } @@ -452,23 +452,23 @@ protected function processPreserveFtp($dir) { } } - protected function processPreserveRenovatebot($dir) { + protected function processPreserveRenovatebot(string $dir) { if ($this->getAnswer('preserve_renovatebot') == self::ANSWER_YES) { $this->removeTokenWithContent('!RENOVATEBOT', $dir); } else { - @unlink("$dir/renovate.json"); + @unlink($dir . '/renovate.json'); $this->removeTokenWithContent('RENOVATEBOT', $dir); } } - protected function processStringTokens($dir) { - $machine_name_hyphenated = str_replace('_', '-', $this->getAnswer('machine_name')); + protected function processStringTokens(string $dir) { + $machine_name_hyphenated = str_replace('_', '-', (string) $this->getAnswer('machine_name')); $machine_name_camel_cased = static::toCamelCase($this->getAnswer('machine_name'), TRUE); $module_prefix_camel_cased = static::toCamelCase($this->getAnswer('module_prefix'), TRUE); - $module_prefix_uppercase = strtoupper($module_prefix_camel_cased); + $module_prefix_uppercase = strtoupper((string) $module_prefix_camel_cased); $theme_camel_cased = static::toCamelCase($this->getAnswer('theme'), TRUE); - $drevops_version_urlencoded = str_replace('-', '--', $this->getConfig('DREVOPS_VERSION')); + $drevops_version_urlencoded = str_replace('-', '--', (string) $this->getConfig('DREVOPS_VERSION')); $webroot = $this->getAnswer('webroot'); @@ -480,10 +480,10 @@ protected function processStringTokens($dir) { static::dirReplaceContent('your_org', $this->getAnswer('org_machine_name'), $dir); static::dirReplaceContent('YOURORG', $this->getAnswer('org'), $dir); static::dirReplaceContent('your-site-url.example', $this->getAnswer('url'), $dir); - static::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . "/{$webroot}/modules/custom"); - static::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . "/{$webroot}/themes/custom"); + static::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/modules/custom', $webroot)); + static::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/themes/custom', $webroot)); static::dirReplaceContent('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . '/scripts/custom'); - static::dirReplaceContent('YsCore', $module_prefix_camel_cased . 'Core', $dir . "/{$webroot}/modules/custom"); + static::dirReplaceContent('YsCore', $module_prefix_camel_cased . 'Core', $dir . sprintf('/%s/modules/custom', $webroot)); static::dirReplaceContent('YSCODE', $module_prefix_uppercase, $dir); static::dirReplaceContent('your-site', $machine_name_hyphenated, $dir); static::dirReplaceContent('your_site', $this->getAnswer('machine_name'), $dir); @@ -493,8 +493,8 @@ protected function processStringTokens($dir) { static::replaceStringFilename('YourSiteTheme', $theme_camel_cased, $dir); static::replaceStringFilename('your_site_theme', $this->getAnswer('theme'), $dir); static::replaceStringFilename('YourSite', $machine_name_camel_cased, $dir); - static::replaceStringFilename('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . "/{$webroot}/modules/custom"); - static::replaceStringFilename('YsCore', $module_prefix_camel_cased . 'Core', $dir . "/{$webroot}/modules/custom"); + static::replaceStringFilename('ys_core', $this->getAnswer('module_prefix') . '_core', $dir . sprintf('/%s/modules/custom', $webroot)); + static::replaceStringFilename('YsCore', $module_prefix_camel_cased . 'Core', $dir . sprintf('/%s/modules/custom', $webroot)); static::replaceStringFilename('your_org', $this->getAnswer('org_machine_name'), $dir); static::replaceStringFilename('your_site', $this->getAnswer('machine_name'), $dir); @@ -505,7 +505,7 @@ protected function processStringTokens($dir) { // phpcs:enable Drupal.WhiteSpace.Comma.TooManySpaces } - protected function processPreserveDocComments($dir) { + protected function processPreserveDocComments(string $dir) { if ($this->getAnswer('preserve_doc_comments') == self::ANSWER_YES) { // Replace special "#: " comments with normal "#" comments. static::dirReplaceContent('#:', '#', $dir); @@ -515,7 +515,7 @@ protected function processPreserveDocComments($dir) { } } - protected function processDemoMode($dir) { + protected function processDemoMode(string $dir) { // Only discover demo mode if not explicitly set. if (is_null($this->getConfig('DREVOPS_INSTALL_DEMO'))) { if ($this->getAnswer('provision_use_profile') == self::ANSWER_NO) { @@ -551,7 +551,7 @@ protected function processDemoMode($dir) { } } - protected function processPreserveDrevopsInfo($dir) { + protected function processPreserveDrevopsInfo(string $dir) { if ($this->getAnswer('preserve_drevops_info') == self::ANSWER_NO) { // Remove code required for DrevOps maintenance. $this->removeTokenWithContent('DREVOPS_DEV', $dir); @@ -561,13 +561,13 @@ protected function processPreserveDrevopsInfo($dir) { } } - protected function processDrevopsInternal($dir) { + protected function processDrevopsInternal(string $dir) { // Remove DrevOps internal files. - static::rmdirRecursive("$dir/.drevops/docs"); - static::rmdirRecursive("$dir/.drevops/tests"); - static::rmdirRecursive("$dir/scripts/drevops/utils"); - @unlink("$dir/.github/FUNDING.yml"); - foreach (glob("$dir/.github/drevops-*.yml") as $file) { + static::rmdirRecursive($dir . '/.drevops/docs'); + static::rmdirRecursive($dir . '/.drevops/tests'); + static::rmdirRecursive($dir . '/scripts/drevops/utils'); + @unlink($dir . '/.github/FUNDING.yml'); + foreach (glob($dir . '/.github/drevops-*.yml') as $file) { @unlink($file); } @@ -576,12 +576,12 @@ protected function processDrevopsInternal($dir) { $this->removeTokenLine('#;>', $dir); } - protected function processEnableCommentedCode($dir) { + protected function processEnableCommentedCode(string $dir) { // Enable_commented_code. static::dirReplaceContent('##### ', '', $dir); } - protected function processWebroot($dir) { + protected function processWebroot(string $dir) { $new_name = $this->getAnswer('webroot', 'web'); if ($new_name != 'web') { @@ -614,7 +614,7 @@ protected function downloadLocal() { $this->status(sprintf('Downloading DrevOps from the local repository "%s" at ref "%s".', $repo, $ref), self::INSTALLER_STATUS_MESSAGE, FALSE); - $command = "git --git-dir=\"{$repo}/.git\" --work-tree=\"{$repo}\" archive --format=tar \"{$ref}\" | tar xf - -C \"{$dst}\""; + $command = sprintf('git --git-dir="%s/.git" --work-tree="%s" archive --format=tar "%s" | tar xf - -C "%s"', $repo, $repo, $ref, $dst); $this->doExec($command, $output, $code); $this->status(implode(PHP_EOL, $output), self::INSTALLER_STATUS_DEBUG); @@ -642,9 +642,9 @@ protected function downloadRemote() { $this->setConfig('DREVOPS_VERSION', $ref); } - $url = "https://github.com/{$org}/{$project}/archive/{$ref}.tar.gz"; + $url = sprintf('https://github.com/%s/%s/archive/%s.tar.gz', $org, $project, $ref); $this->status(sprintf('Downloading DrevOps from the remote repository "%s" at ref "%s".', $url, $ref), self::INSTALLER_STATUS_MESSAGE, FALSE); - $this->doExec("curl -sS -L \"$url\" | tar xzf - -C \"{$dst}\" --strip 1", $output, $code); + $this->doExec(sprintf('curl -sS -L "%s" | tar xzf - -C "%s" --strip 1', $url, $dst), $output, $code); if ($code != 0) { throw new \RuntimeException(implode(PHP_EOL, $output)); @@ -656,7 +656,7 @@ protected function downloadRemote() { } protected function findLatestDrevopsRelease($org, $project, $release_prefix) { - $release_url = "https://api.github.com/repos/{$org}/{$project}/releases"; + $release_url = sprintf('https://api.github.com/repos/%s/%s/releases', $org, $project); $release_contents = file_get_contents($release_url, FALSE, stream_context_create([ 'http' => ['method' => 'GET', 'header' => ['User-Agent: PHP']], ])); @@ -667,7 +667,7 @@ protected function findLatestDrevopsRelease($org, $project, $release_prefix) { $records = json_decode($release_contents, TRUE); foreach ($records as $record) { - if (isset($record['tag_name']) && ($release_prefix && str_contains($record['tag_name'], $release_prefix) || !$release_prefix)) { + if (isset($record['tag_name']) && ($release_prefix && str_contains((string) $record['tag_name'], (string) $release_prefix) || !$release_prefix)) { return $record['tag_name']; } } @@ -759,7 +759,7 @@ protected function collectAnswers() { } } - protected function askShouldProceed() { + protected function askShouldProceed(): bool { $proceed = self::ANSWER_YES; if (!$this->isQuiet()) { @@ -772,7 +772,7 @@ protected function askShouldProceed() { $proceed = self::ANSWER_NO; } - return strtolower($proceed) == self::ANSWER_YES; + return strtolower((string) $proceed) == self::ANSWER_YES; } protected function askForAnswer($name, $question) { @@ -788,7 +788,7 @@ protected function ask($question, $default, $close_handle = FALSE) { return $default; } - $question = "> $question [$default] "; + $question = sprintf('> %s [%s] ', $question, $default); $this->out($question, 'question', FALSE); $handle = $this->getStdinHandle(); @@ -798,7 +798,7 @@ protected function ask($question, $default, $close_handle = FALSE) { $this->closeStdinHandle(); } - return !empty($answer) ? $answer : $default; + return empty($answer) ? $default : $answer; } /** @@ -962,32 +962,32 @@ protected function isInstallDebug() { */ protected function getDefaultValue($name) { // Allow to override default values from config variables. - $config_name = strtoupper($name); + $config_name = strtoupper((string) $name); return $this->getConfig($config_name, $this->executeCallback('getDefaultValue', $name)); } - protected function getDefaultValueName() { - return static::toHumanName(static::getenvOrDefault('DREVOPS_PROJECT', basename($this->getDstDir()))); + protected function getDefaultValueName(): ?string { + return static::toHumanName(static::getenvOrDefault('DREVOPS_PROJECT', basename((string) $this->getDstDir()))); } - protected function getDefaultValueMachineName() { + protected function getDefaultValueMachineName(): string { return static::toMachineName($this->getAnswer('name')); } - protected function getDefaultValueOrg() { + protected function getDefaultValueOrg(): string { return $this->getAnswer('name') . ' Org'; } - protected function getDefaultValueOrgMachineName() { + protected function getDefaultValueOrgMachineName(): string { return static::toMachineName($this->getAnswer('org')); } - protected function getDefaultValueModulePrefix() { + protected function getDefaultValueModulePrefix(): string|array { return $this->toAbbreviation($this->getAnswer('machine_name')); } - protected function getDefaultValueProfile() { + protected function getDefaultValueProfile(): string { return self::ANSWER_NO; } @@ -995,63 +995,62 @@ protected function getDefaultValueTheme() { return $this->getAnswer('machine_name'); } - protected function getDefaultValueUrl() { + protected function getDefaultValueUrl(): string { $value = $this->getAnswer('machine_name'); - $value = str_replace('_', '-', $value); - $value .= '.com'; + $value = str_replace('_', '-', (string) $value); - return $value; + return $value . '.com'; } - protected function getDefaultValueWebroot() { + protected function getDefaultValueWebroot(): string { return 'web'; } - protected function getDefaultValueProvisionUseProfile() { + protected function getDefaultValueProvisionUseProfile(): string { return self::ANSWER_NO; } - protected function getDefaultValueDatabaseDownloadSource() { + protected function getDefaultValueDatabaseDownloadSource(): string { return 'curl'; } - protected function getDefaultValueDatabaseStoreType() { + protected function getDefaultValueDatabaseStoreType(): string { return 'file'; } - protected function getDefaultValueDatabaseImage() { + protected function getDefaultValueDatabaseImage(): string { return 'drevops/mariadb-drupal-data:latest'; } - protected function getDefaultValueOverrideExistingDb() { + protected function getDefaultValueOverrideExistingDb(): string { return self::ANSWER_NO; } - protected function getDefaultValueDeployType() { + protected function getDefaultValueDeployType(): string { return 'artifact'; } - protected function getDefaultValuePreserveAcquia() { + protected function getDefaultValuePreserveAcquia(): string { return self::ANSWER_NO; } - protected function getDefaultValuePreserveLagoon() { + protected function getDefaultValuePreserveLagoon(): string { return self::ANSWER_NO; } - protected function getDefaultValuePreserveFtp() { + protected function getDefaultValuePreserveFtp(): string { return self::ANSWER_NO; } - protected function getDefaultValuePreserveRenovatebot() { + protected function getDefaultValuePreserveRenovatebot(): string { return self::ANSWER_YES; } - protected function getDefaultValuePreserveDocComments() { + protected function getDefaultValuePreserveDocComments(): string { return self::ANSWER_YES; } - protected function getDefaultValuePreserveDrevopsInfo() { + protected function getDefaultValuePreserveDrevopsInfo(): string { return self::ANSWER_NO; } @@ -1066,63 +1065,55 @@ protected function getDefaultValuePreserveDrevopsInfo() { protected function discoverValue($name) { $value = $this->executeCallback('discoverValue', $name); - return !is_null($value) ? $value : $this->getDefaultValue($name); + return is_null($value) ? $this->getDefaultValue($name) : $value; } - protected function discoverValueName() { + protected function discoverValueName(): ?string { $value = $this->getComposerJsonValue('description'); - if ($value && preg_match('/Drupal [0-9]+ .* of ([0-9a-zA-Z\- ]+) for ([0-9a-zA-Z\- ]+)/', $value, $matches)) { - if (!empty($matches[1])) { - return $matches[1]; - } + if ($value && preg_match('/Drupal \d+ .* of ([0-9a-zA-Z\- ]+) for ([0-9a-zA-Z\- ]+)/', (string) $value, $matches) && !empty($matches[1])) { + return $matches[1]; } return NULL; } - protected function discoverValueMachineName() { + protected function discoverValueMachineName(): ?string { $value = $this->getComposerJsonValue('name'); - if ($value && preg_match('/([^\/]+)\/(.+)/', $value, $matches)) { - if (!empty($matches[2])) { - return $matches[2]; - } + if ($value && preg_match('/([^\/]+)\/(.+)/', (string) $value, $matches) && !empty($matches[2])) { + return $matches[2]; } return NULL; } - protected function discoverValueOrg() { + protected function discoverValueOrg(): ?string { $value = $this->getComposerJsonValue('description'); - if ($value && preg_match('/Drupal [0-9]+ .* of ([0-9a-zA-Z\- ]+) for ([0-9a-zA-Z\- ]+)/', $value, $matches)) { - if (!empty($matches[2])) { - return $matches[2]; - } + if ($value && preg_match('/Drupal \d+ .* of ([0-9a-zA-Z\- ]+) for ([0-9a-zA-Z\- ]+)/', (string) $value, $matches) && !empty($matches[2])) { + return $matches[2]; } return NULL; } - protected function discoverValueOrgMachineName() { + protected function discoverValueOrgMachineName(): ?string { $value = $this->getComposerJsonValue('name'); - if ($value && preg_match('/([^\/]+)\/(.+)/', $value, $matches)) { - if (!empty($matches[1])) { - return $matches[1]; - } + if ($value && preg_match('/([^\/]+)\/(.+)/', (string) $value, $matches) && !empty($matches[1])) { + return $matches[1]; } return NULL; } - protected function discoverValueModulePrefix() { + protected function discoverValueModulePrefix(): null|string|array { $webroot = $this->getAnswer('webroot'); $locations = [ - $this->getDstDir() . "/{$webroot}/modules/custom/*_core", - $this->getDstDir() . "/{$webroot}/sites/all/modules/custom/*_core", - $this->getDstDir() . "/{$webroot}/profiles/*/modules/*_core", - $this->getDstDir() . "/{$webroot}/profiles/*/modules/custom/*_core", - $this->getDstDir() . "/{$webroot}/profiles/custom/*/modules/*_core", - $this->getDstDir() . "/{$webroot}/profiles/custom/*/modules/custom/*_core", + $this->getDstDir() . sprintf('/%s/modules/custom/*_core', $webroot), + $this->getDstDir() . sprintf('/%s/sites/all/modules/custom/*_core', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/*/modules/*_core', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/*/modules/custom/*_core', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/custom/*/modules/*_core', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/custom/*/modules/custom/*_core', $webroot), ]; $name = $this->findMatchingPath($locations); @@ -1132,7 +1123,7 @@ protected function discoverValueModulePrefix() { } if ($name) { - $name = basename($name); + $name = basename((string) $name); $name = str_replace('_core', '', $name); } @@ -1150,10 +1141,10 @@ protected function discoverValueProfile() { } $locations = [ - $this->getDstDir() . "/{$webroot}/profiles/*/*.info", - $this->getDstDir() . "/{$webroot}/profiles/*/*.info.yml", - $this->getDstDir() . "/{$webroot}/profiles/custom/*/*.info", - $this->getDstDir() . "/{$webroot}/profiles/custom/*/*.info.yml", + $this->getDstDir() . sprintf('/%s/profiles/*/*.info', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/*/*.info.yml', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/custom/*/*.info', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/custom/*/*.info.yml', $webroot), ]; $name = $this->findMatchingPath($locations, 'Drupal 10 profile implementation of'); @@ -1163,7 +1154,7 @@ protected function discoverValueProfile() { } if ($name) { - $name = basename($name); + $name = basename((string) $name); $name = str_replace(['.info.yml', '.info'], '', $name); } @@ -1181,14 +1172,14 @@ protected function discoverValueTheme() { } $locations = [ - $this->getDstDir() . "/{$webroot}/themes/custom/*/*.info", - $this->getDstDir() . "/{$webroot}/themes/custom/*/*.info.yml", - $this->getDstDir() . "/{$webroot}/sites/all/themes/custom/*/*.info", - $this->getDstDir() . "/{$webroot}/sites/all/themes/custom/*/*.info.yml", - $this->getDstDir() . "/{$webroot}/profiles/*/themes/custom/*/*.info", - $this->getDstDir() . "/{$webroot}/profiles/*/themes/custom/*/*.info.yml", - $this->getDstDir() . "/{$webroot}/profiles/custom/*/themes/custom/*/*.info", - $this->getDstDir() . "/{$webroot}/profiles/custom/*/themes/custom/*/*.info.yml", + $this->getDstDir() . sprintf('/%s/themes/custom/*/*.info', $webroot), + $this->getDstDir() . sprintf('/%s/themes/custom/*/*.info.yml', $webroot), + $this->getDstDir() . sprintf('/%s/sites/all/themes/custom/*/*.info', $webroot), + $this->getDstDir() . sprintf('/%s/sites/all/themes/custom/*/*.info.yml', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/*/themes/custom/*/*.info', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/*/themes/custom/*/*.info.yml', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/custom/*/themes/custom/*/*.info', $webroot), + $this->getDstDir() . sprintf('/%s/profiles/custom/*/themes/custom/*/*.info.yml', $webroot), ]; $name = $this->findMatchingPath($locations); @@ -1198,7 +1189,7 @@ protected function discoverValueTheme() { } if ($name) { - $name = basename($name); + $name = basename((string) $name); $name = str_replace(['.info.yml', '.info'], '', $name); } @@ -1209,7 +1200,7 @@ protected function discoverValueUrl() { $webroot = $this->getAnswer('webroot'); $origin = NULL; - $path = $this->getDstDir() . "/{$webroot}/sites/default/settings.php"; + $path = $this->getDstDir() . sprintf('/%s/sites/default/settings.php', $webroot); if (!is_readable($path)) { return NULL; @@ -1233,7 +1224,7 @@ protected function discoverValueUrl() { $origin = parse_url($origin, PHP_URL_HOST); } - return !empty($origin) ? $origin : NULL; + return empty($origin) ? NULL : $origin; } protected function discoverValueWebroot() { @@ -1250,7 +1241,7 @@ protected function discoverValueWebroot() { return $webroot; } - protected function discoverValueProvisionUseProfile() { + protected function discoverValueProvisionUseProfile(): string { return $this->getValueFromDstDotenv('DREVOPS_PROVISION_USE_PROFILE') ? self::ANSWER_YES : self::ANSWER_NO; } @@ -1258,7 +1249,7 @@ protected function discoverValueDatabaseDownloadSource() { return $this->getValueFromDstDotenv('DREVOPS_DB_DOWNLOAD_SOURCE'); } - protected function discoverValueDatabaseStoreType() { + protected function discoverValueDatabaseStoreType(): string { return $this->discoverValueDatabaseImage() ? 'docker_image' : 'file'; } @@ -1266,7 +1257,7 @@ protected function discoverValueDatabaseImage() { return $this->getValueFromDstDotenv('DREVOPS_DB_DOCKER_IMAGE'); } - protected function discoverValueOverrideExistingDb() { + protected function discoverValueOverrideExistingDb(): string { return $this->getValueFromDstDotenv('DREVOPS_PROVISION_OVERRIDE_DB') ? self::ANSWER_YES : self::ANSWER_NO; } @@ -1274,7 +1265,7 @@ protected function discoverValueDeployType() { return $this->getValueFromDstDotenv('DREVOPS_DEPLOY_TYPES'); } - protected function discoverValuePreserveAcquia() { + protected function discoverValuePreserveAcquia(): ?string { if (is_readable($this->getDstDir() . '/hooks')) { return self::ANSWER_YES; } @@ -1287,7 +1278,7 @@ protected function discoverValuePreserveAcquia() { return $value == 'acquia' ? self::ANSWER_YES : self::ANSWER_NO; } - protected function discoverValuePreserveLagoon() { + protected function discoverValuePreserveLagoon(): ?string { if (is_readable($this->getDstDir() . '/.lagoon.yml')) { return self::ANSWER_YES; } @@ -1307,7 +1298,7 @@ protected function discoverValuePreserveLagoon() { return self::ANSWER_YES; } - protected function discoverValuePreserveFtp() { + protected function discoverValuePreserveFtp(): ?string { $value = $this->getValueFromDstDotenv('DREVOPS_DB_DOWNLOAD_SOURCE'); if (is_null($value)) { return NULL; @@ -1316,7 +1307,7 @@ protected function discoverValuePreserveFtp() { return $value == 'ftp' ? self::ANSWER_YES : self::ANSWER_NO; } - protected function discoverValuePreserveRenovatebot() { + protected function discoverValuePreserveRenovatebot(): ?string { if (!$this->isInstalled()) { return NULL; } @@ -1324,7 +1315,7 @@ protected function discoverValuePreserveRenovatebot() { return is_readable($this->getDstDir() . '/renovate.json') ? self::ANSWER_YES : self::ANSWER_NO; } - protected function discoverValuePreserveDocComments() { + protected function discoverValuePreserveDocComments(): ?string { $file = $this->getDstDir() . '/.ahoy.yml'; if (!is_readable($file)) { return NULL; @@ -1333,7 +1324,7 @@ protected function discoverValuePreserveDocComments() { return static::fileContains('Ahoy configuration file', $file) ? self::ANSWER_YES : self::ANSWER_NO; } - protected function discoverValuePreserveDrevopsInfo() { + protected function discoverValuePreserveDrevopsInfo(): ?string { $file = $this->getDstDir() . '/.ahoy.yml'; if (!is_readable($file)) { return NULL; @@ -1387,7 +1378,7 @@ protected function findMatchingPath($paths, $text = NULL) { /** * Check that DrevOps is installed for this project. */ - protected function isInstalled() { + protected function isInstalled(): bool { $path = $this->getDstDir() . DIRECTORY_SEPARATOR . 'README.md'; return file_exists($path) && preg_match('/badge\/DrevOps\-/', file_get_contents($path)); @@ -1402,23 +1393,23 @@ protected function normaliseAnswer($name, $value) { return $normalised ?? $value; } - protected function normaliseAnswerName($value) { - return ucfirst(static::toHumanName($value)); + protected function normaliseAnswerName($value): string { + return ucfirst((string) static::toHumanName($value)); } - protected function normaliseAnswerMachineName($value) { + protected function normaliseAnswerMachineName($value): string { return static::toMachineName($value); } - protected function normaliseAnswerOrgMachineName($value) { + protected function normaliseAnswerOrgMachineName($value): string { return static::toMachineName($value); } - protected function normaliseAnswerModulePrefix($value) { + protected function normaliseAnswerModulePrefix($value): string { return static::toMachineName($value); } - protected function normaliseAnswerProfile($value) { + protected function normaliseAnswerProfile($value): string { $profile = static::toMachineName($value); if (empty($profile) || strtolower($profile) == self::ANSWER_NO) { $profile = 'standard'; @@ -1427,83 +1418,56 @@ protected function normaliseAnswerProfile($value) { return $profile; } - protected function normaliseAnswerTheme($value) { + protected function normaliseAnswerTheme($value): string { return static::toMachineName($value); } - protected function normaliseAnswerUrl($url) { - return str_replace([' ', '_'], '-', $url); + protected function normaliseAnswerUrl($url): string|array { + return str_replace([' ', '_'], '-', (string) $url); } - protected function normaliseAnswerWebroot($value) { - return strtolower(trim($value, '/')); + protected function normaliseAnswerWebroot($value): string { + return strtolower(trim((string) $value, '/')); } - protected function normaliseAnswerProvisionUseProfile($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerProvisionUseProfile($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerDatabaseDownloadSource($value) { - $value = strtolower($value); - - switch ($value) { - case 'f': - case 'ftp': - return 'ftp'; - - case 'a': - case 'acquia': - return 'acquia'; - - case 'i': - case 'd': - case 'image': - case 'docker': - case 'docker_image': - case 'docker_registry': - return 'docker_registry'; + protected function normaliseAnswerDatabaseDownloadSource($value): string { + $value = strtolower((string) $value); - case 'c': - case 'curl': - return 'curl'; - - default: - return $this->getDefaultValueDatabaseDownloadSource(); - } + return match ($value) { + 'f', 'ftp' => 'ftp', + 'a', 'acquia' => 'acquia', + 'i', 'd', 'image', 'docker', 'docker_image', 'docker_registry' => 'docker_registry', + 'c', 'curl' => 'curl', + default => $this->getDefaultValueDatabaseDownloadSource(), + }; } - protected function normaliseAnswerDatabaseStoreType($value) { - $value = strtolower($value); - - switch ($value) { - case 'i': - case 'd': - case 'image': - case 'docker_image': - case 'docker': - return 'docker_image'; - - case 'f': - case 'file': - return 'file'; + protected function normaliseAnswerDatabaseStoreType($value): string { + $value = strtolower((string) $value); - default: - return $this->getDefaultValueDatabaseStoreType(); - } + return match ($value) { + 'i', 'd', 'image', 'docker_image', 'docker' => 'docker_image', + 'f', 'file' => 'file', + default => $this->getDefaultValueDatabaseStoreType(), + }; } - protected function normaliseAnswerDatabaseImage($value) { + protected function normaliseAnswerDatabaseImage($value): string { $value = static::toMachineName($value, ['-', '/', ':', '.']); - return strpos($value, ':') !== FALSE ? $value : $value . ':latest'; + return str_contains($value, ':') ? $value : $value . ':latest'; } - protected function normaliseAnswerOverrideExistingDb($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerOverrideExistingDb($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerDeployType($value) { - $types = explode(',', $value); + protected function normaliseAnswerDeployType($value): ?string { + $types = explode(',', (string) $value); $normalised = []; foreach ($types as $type) { @@ -1547,34 +1511,34 @@ protected function normaliseAnswerDeployType($value) { return implode(',', $normalised); } - protected function normaliseAnswerPreserveAcquia($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerPreserveAcquia($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerPreserveLagoon($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerPreserveLagoon($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerPreserveFtp($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerPreserveFtp($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerPreserveRenovatebot($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerPreserveRenovatebot($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerPreserveDocComments($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerPreserveDocComments($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } - protected function normaliseAnswerPreserveDrevopsInfo($value) { - return strtolower($value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; + protected function normaliseAnswerPreserveDrevopsInfo($value): string { + return strtolower((string) $value) != self::ANSWER_YES ? self::ANSWER_NO : self::ANSWER_YES; } /** * Print help. */ - protected function printHelp() { + protected function printHelp(): string { return <<isInstalled()) { @@ -1626,7 +1590,7 @@ protected function printHeaderQuiet() { $content .= 'This will install the latest version of DrevOps into your project.' . PHP_EOL; } else { - $content .= "This will install DrevOps into your project at commit \"$commit\"." . PHP_EOL; + $content .= sprintf('This will install DrevOps into your project at commit "%s".', $commit) . PHP_EOL; } $content .= PHP_EOL; if ($this->isInstalled()) { @@ -1664,7 +1628,7 @@ protected function printSummary() { $values['Database download source'] = $this->getAnswer('database_download_source'); $image = $this->getAnswer('database_image'); - $values['Database store type'] = !empty($image) ? 'docker_image' : 'file'; + $values['Database store type'] = empty($image) ? 'file' : 'docker_image'; if ($image) { $values['Database image name'] = $image; } @@ -1709,9 +1673,9 @@ protected function printFooter() { } } - protected function printTitle($text, $fill = '-', $width = 80, $cols = '|', $has_content = FALSE) { + protected function printTitle($text, $fill = '-', $width = 80, string $cols = '|', $has_content = FALSE) { $this->printDivider($fill, $width, 'down'); - $lines = explode(PHP_EOL, wordwrap($text, $width - 4, PHP_EOL)); + $lines = explode(PHP_EOL, wordwrap((string) $text, $width - 4, PHP_EOL)); foreach ($lines as $line) { $line = ' ' . $line . ' '; print $cols . str_pad($line, $width - 2, ' ', STR_PAD_BOTH) . $cols . PHP_EOL; @@ -1720,7 +1684,7 @@ protected function printTitle($text, $fill = '-', $width = 80, $cols = '|', $has } protected function printSubtitle($text, $fill = '=', $width = 80) { - $is_multiline = strlen($text) + 4 >= $width; + $is_multiline = strlen((string) $text) + 4 >= $width; if ($is_multiline) { $this->printTitle($text, $fill, $width, 'both'); } @@ -1750,16 +1714,16 @@ protected function printDivider($fill = '-', $width = 80, $direction = 'none') { break; } - print $start . str_repeat($fill, $width - 2) . $finish . PHP_EOL; + print $start . str_repeat((string) $fill, $width - 2) . $finish . PHP_EOL; } protected function printBox($content, $title = '', $fill = '─', $padding = 2, $width = 80) { $cols = '│'; $max_width = $width - 2 - $padding * 2; - $lines = explode(PHP_EOL, wordwrap(rtrim($content, PHP_EOL), $max_width, PHP_EOL)); + $lines = explode(PHP_EOL, wordwrap(rtrim((string) $content, PHP_EOL), $max_width, PHP_EOL)); $pad = str_pad(' ', $padding); - $mask = "{$cols}{$pad}%-{$max_width}s{$pad}{$cols}" . PHP_EOL; + $mask = sprintf('%s%s%%-%ss%s%s', $cols, $pad, $max_width, $pad, $cols) . PHP_EOL; print PHP_EOL; if (!empty($title)) { @@ -1789,23 +1753,23 @@ protected function printTick($text = NULL) { } } - protected function formatValuesList($values, $delim = '', $width = 80) { + protected function formatValuesList($values, $delim = '', $width = 80): string { // Line width - length of delimiters * 2 - 2 spacers. - $line_width = $width - strlen($delim) * 2 - 2; + $line_width = $width - strlen((string) $delim) * 2 - 2; // Max name length + spaced on the sides + colon. $max_name_width = max(array_map('strlen', array_keys($values))) + 2 + 1; // Whole width - (name width + 2 delimiters on the sides + 1 delimiter in // the middle + 2 spaces on the sides + 2 spaces for the center delimiter). - $value_width = $width - ($max_name_width + strlen($delim) * 2 + strlen($delim) + 2 + 2); + $value_width = $width - ($max_name_width + strlen((string) $delim) * 2 + strlen((string) $delim) + 2 + 2); - $mask1 = "{$delim} %{$max_name_width}s {$delim} %-{$value_width}.{$value_width}s {$delim}" . PHP_EOL; - $mask2 = "{$delim}%2\${$line_width}s{$delim}" . PHP_EOL; + $mask1 = sprintf('%s %%%ds %s %%-%s.%ss %s', $delim, $max_name_width, $delim, $value_width, $value_width, $delim) . PHP_EOL; + $mask2 = sprintf('%s%%2$%ss%s', $delim, $line_width, $delim) . PHP_EOL; $output = []; foreach ($values as $name => $value) { - $is_multiline_value = strlen($value) > $value_width; + $is_multiline_value = strlen((string) $value) > $value_width; if (is_numeric($name)) { $name = ''; @@ -1818,7 +1782,7 @@ protected function formatValuesList($values, $delim = '', $width = 80) { } if ($is_multiline_value) { - $lines = array_filter(explode(PHP_EOL, chunk_split($value, $value_width, PHP_EOL))); + $lines = array_filter(explode(PHP_EOL, chunk_split((string) $value, $value_width, PHP_EOL))); $first_line = array_shift($lines); $output[] = sprintf($mask, $name, $first_line); foreach ($lines as $line) { @@ -1833,19 +1797,19 @@ protected function formatValuesList($values, $delim = '', $width = 80) { return implode('', $output); } - protected function formatEnabled($value) { - return $value && strtolower($value) != 'n' ? 'Enabled' : 'Disabled'; + protected function formatEnabled($value): string { + return $value && strtolower((string) $value) != 'n' ? 'Enabled' : 'Disabled'; } - protected function formatYesNo($value) { + protected function formatYesNo($value): string { return $value == self::ANSWER_YES ? 'Yes' : 'No'; } protected function formatNotEmpty($value, $default) { - return !empty($value) ? $value : $default; + return empty($value) ? $default : $value; } - public static function fileContains($needle, $file) { + public static function fileContains($needle, $file): int|bool { if (!is_readable($file)) { return FALSE; } @@ -1856,10 +1820,10 @@ public static function fileContains($needle, $file) { return preg_match($needle, $content); } - return str_contains($content, $needle); + return str_contains($content, (string) $needle); } - protected static function dirContains($needle, $dir) { + protected static function dirContains($needle, string $dir): bool { $files = static::scandirRecursive($dir, static::ignorePaths()); foreach ($files as $filename) { if (static::fileContains($needle, $filename)) { @@ -1870,8 +1834,8 @@ protected static function dirContains($needle, $dir) { return FALSE; } - protected static function isRegex($str) { - if ($str === '' || strlen($str) < 3) { + protected static function isRegex($str): bool { + if ($str === '' || strlen((string) $str) < 3) { return FALSE; } @@ -1886,7 +1850,7 @@ protected static function fileReplaceContent($needle, $replacement, $filename) { $content = file_get_contents($filename); if (static::isRegex($needle)) { - $replaced = preg_replace($needle, $replacement, $content); + $replaced = preg_replace($needle, (string) $replacement, $content); } else { $replaced = str_replace($needle, $replacement, $content); @@ -1896,21 +1860,21 @@ protected static function fileReplaceContent($needle, $replacement, $filename) { } } - protected static function dirReplaceContent($needle, $replacement, $dir) { + protected static function dirReplaceContent($needle, $replacement, string $dir) { $files = static::scandirRecursive($dir, static::ignorePaths()); foreach ($files as $filename) { static::fileReplaceContent($needle, $replacement, $filename); } } - protected function removeTokenWithContent($token, $dir) { + protected function removeTokenWithContent(string $token, string $dir) { $files = static::scandirRecursive($dir, static::ignorePaths()); foreach ($files as $filename) { - static::removeTokenFromFile($filename, "#;< $token", "#;> $token", TRUE); + static::removeTokenFromFile($filename, '#;< ' . $token, '#;> ' . $token, TRUE); } } - protected function removeTokenLine($token, $dir) { + protected function removeTokenLine($token, string $dir) { if (!empty($token)) { $files = static::scandirRecursive($dir, static::ignorePaths()); foreach ($files as $filename) { @@ -1919,7 +1883,7 @@ protected function removeTokenLine($token, $dir) { } } - public static function removeTokenFromFile($filename, $token_begin, $token_end = NULL, $with_content = FALSE) { + public static function removeTokenFromFile($filename, $token_begin, $token_end = NULL, $with_content = FALSE): void { if (self::fileIsExcludedFromProcessing($filename)) { return; } @@ -1929,9 +1893,9 @@ public static function removeTokenFromFile($filename, $token_begin, $token_end = $content = file_get_contents($filename); if ($token_begin != $token_end) { - $token_begin_count = preg_match_all('/' . preg_quote($token_begin) . '/', $content); - $token_end_count = preg_match_all('/' . preg_quote($token_end) . '/', $content); - if ($token_begin_count != $token_end_count) { + $token_begin_count = preg_match_all('/' . preg_quote((string) $token_begin) . '/', $content); + $token_end_count = preg_match_all('/' . preg_quote((string) $token_end) . '/', $content); + if ($token_begin_count !== $token_end_count) { throw new \RuntimeException(sprintf('Invalid begin and end token count in file %s: begin is %s(%s), end is %s(%s).', $filename, $token_begin, $token_begin_count, $token_end, $token_end_count)); } } @@ -1941,13 +1905,13 @@ public static function removeTokenFromFile($filename, $token_begin, $token_end = $lines = file($filename); foreach ($lines as $line) { - if (strpos($line, $token_begin) !== FALSE) { + if (str_contains($line, (string) $token_begin)) { if ($with_content) { $within_token = TRUE; } continue; } - elseif (strpos($line, $token_end) !== FALSE) { + elseif (str_contains($line, (string) $token_end)) { if ($with_content) { $within_token = FALSE; } @@ -1965,10 +1929,10 @@ public static function removeTokenFromFile($filename, $token_begin, $token_end = file_put_contents($filename, implode('', $out)); } - protected static function replaceStringFilename($search, $replace, $dir) { + protected static function replaceStringFilename($search, $replace, string $dir) { $files = static::scandirRecursive($dir, static::ignorePaths()); foreach ($files as $filename) { - $new_filename = str_replace($search, $replace, $filename); + $new_filename = str_replace($search, $replace, (string) $filename); if ($filename != $new_filename) { $new_dir = dirname($new_filename); if (!is_dir($new_dir)) { @@ -1979,7 +1943,10 @@ protected static function replaceStringFilename($search, $replace, $dir) { } } - protected static function scandirRecursive($dir, $ignore_paths = [], $include_dirs = FALSE) { + /** + * Recursively scan directory for files. + */ + protected static function scandirRecursive(string $dir, $ignore_paths = [], $include_dirs = FALSE): array { $discovered = []; if (is_dir($dir)) { @@ -1988,7 +1955,7 @@ protected static function scandirRecursive($dir, $ignore_paths = [], $include_di $path = $dir . '/' . $path; foreach ($ignore_paths as $ignore_path) { // Exlude based on sub-path match. - if (strpos($path, $ignore_path) !== FALSE) { + if (str_contains($path, (string) $ignore_path)) { continue(2); } } @@ -2007,16 +1974,16 @@ protected static function scandirRecursive($dir, $ignore_paths = [], $include_di return $discovered; } - protected function globRecursive($pattern, $flags = 0) { + protected function globRecursive($pattern, $flags = 0): array|false { $files = glob($pattern, $flags | GLOB_BRACE); - foreach (glob(dirname($pattern) . '/{,.}*[!.]', GLOB_BRACE | GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { - $files = array_merge($files, $this->globRecursive($dir . '/' . basename($pattern), $flags)); + foreach (glob(dirname((string) $pattern) . '/{,.}*[!.]', GLOB_BRACE | GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { + $files = array_merge($files, $this->globRecursive($dir . '/' . basename((string) $pattern), $flags)); } return $files; } - protected static function ignorePaths() { + protected static function ignorePaths(): array { return array_merge([ '/.git/', '/.idea/', @@ -2026,7 +1993,7 @@ protected static function ignorePaths() { ], static::internalPaths()); } - protected static function internalPaths() { + protected static function internalPaths(): array { return [ '/.drevops/installer/install', '/LICENSE', @@ -2036,13 +2003,13 @@ protected static function internalPaths() { ]; } - protected static function isInternalPath($relative_path) { - $relative_path = '/' . ltrim($relative_path, './'); + protected static function isInternalPath($relative_path): bool { + $relative_path = '/' . ltrim((string) $relative_path, './'); return in_array($relative_path, static::internalPaths()); } - protected static function fileIsExcludedFromProcessing($filename) { + protected static function fileIsExcludedFromProcessing($filename): int|false { $excluded_patterns = [ '.+\.png', '.+\.jpg', @@ -2051,19 +2018,19 @@ protected static function fileIsExcludedFromProcessing($filename) { '.+\.tiff', ]; - return preg_match('/^(' . implode('|', $excluded_patterns) . ')$/', $filename); + return preg_match('/^(' . implode('|', $excluded_patterns) . ')$/', (string) $filename); } /** * Execute command wrapper. */ - protected function doExec($command, array &$output = NULL, &$return_var = NULL) { + protected function doExec($command, array &$output = NULL, &$return_var = NULL): string|false { if ($this->isInstallDebug()) { $this->status(sprintf('COMMAND: %s', $command), self::INSTALLER_STATUS_DEBUG); } $result = exec($command, $output, $return_var); if ($this->isInstallDebug()) { - $this->status(sprintf(' OUTPUT: %s', implode($output)), self::INSTALLER_STATUS_DEBUG); + $this->status(sprintf(' OUTPUT: %s', implode('', $output)), self::INSTALLER_STATUS_DEBUG); $this->status(sprintf(' CODE : %s', $return_var), self::INSTALLER_STATUS_DEBUG); $this->status(sprintf(' RESULT: %s', $result), self::INSTALLER_STATUS_DEBUG); } @@ -2071,7 +2038,7 @@ protected function doExec($command, array &$output = NULL, &$return_var = NULL) return $result; } - protected static function rmdirRecursive($directory, $options = []) { + protected static function rmdirRecursive($directory, array $options = []) { if (!isset($options['traverseSymlinks'])) { $options['traverseSymlinks'] = FALSE; } @@ -2092,7 +2059,7 @@ protected static function rmdirRecursive($directory, $options = []) { unlink($item); } } - if (is_dir($directory = rtrim($directory, '\\/'))) { + if (is_dir($directory = rtrim((string) $directory, '\\/'))) { if (is_link($directory)) { unlink($directory); } @@ -2105,15 +2072,15 @@ protected static function rmdirRecursive($directory, $options = []) { protected static function rmdirRecursiveEmpty($directory, $options = []) { if (static::dirIsEmpty($directory)) { static::rmdirRecursive($directory, $options); - static::rmdirRecursiveEmpty(dirname($directory), $options); + static::rmdirRecursiveEmpty(dirname((string) $directory), $options); } } - protected static function dirIsEmpty($directory) { + protected static function dirIsEmpty($directory): bool { return is_dir($directory) && count(scandir($directory)) === 2; } - protected function status($message, $level = self::INSTALLER_STATUS_MESSAGE, $eol = TRUE, $use_prefix = TRUE) { + protected function status(string $message, $level = self::INSTALLER_STATUS_MESSAGE, $eol = TRUE, $use_prefix = TRUE) { $prefix = ''; $color = NULL; @@ -2143,7 +2110,7 @@ protected function status($message, $level = self::INSTALLER_STATUS_MESSAGE, $eo } } - protected static function parseDotenv($filename = '.env') { + protected static function parseDotenv($filename = '.env'): false|array { if (!is_readable($filename)) { return FALSE; } @@ -2194,18 +2161,18 @@ protected static function getenvOrDefault($name, $default = NULL) { return $vars[$name]; } - public static function tempdir($dir = NULL, $prefix = 'tmp_', $mode = 0700, $max_attempts = 1000) { + public static function tempdir($dir = NULL, $prefix = 'tmp_', $mode = 0700, $max_attempts = 1000): false|string { if (is_null($dir)) { $dir = sys_get_temp_dir(); } - $dir = rtrim($dir, DIRECTORY_SEPARATOR); + $dir = rtrim((string) $dir, DIRECTORY_SEPARATOR); if (!is_dir($dir) || !is_writable($dir)) { return FALSE; } - if (strpbrk($prefix, '\\/:*?"<>|') !== FALSE) { + if (strpbrk((string) $prefix, '\\/:*?"<>|') !== FALSE) { return FALSE; } $attempts = 0; @@ -2221,56 +2188,54 @@ public static function tempdir($dir = NULL, $prefix = 'tmp_', $mode = 0700, $max return $path; } - protected function commandExists($command) { - $this->doExec("command -v $command", $lines, $ret); + protected function commandExists(string $command) { + $this->doExec('command -v ' . $command, $lines, $ret); if ($ret === 1) { throw new \RuntimeException(sprintf('Command "%s" does not exist in the current environment.', $command)); } } - protected static function toHumanName($value) { - $value = preg_replace('/[^a-zA-Z0-9]/', ' ', $value); + protected static function toHumanName($value): ?string { + $value = preg_replace('/[^a-zA-Z0-9]/', ' ', (string) $value); $value = trim($value); - $value = preg_replace('/\s{2,}/', ' ', $value); - return $value; + return preg_replace('/\s{2,}/', ' ', $value); } - protected static function toMachineName($value, $preserve_chars = []) { + protected static function toMachineName($value, $preserve_chars = []): string { $preserve = ''; foreach ($preserve_chars as $char) { - $preserve .= preg_quote($char, '/'); + $preserve .= preg_quote((string) $char, '/'); } $pattern = '/[^a-zA-Z0-9' . $preserve . ']/'; - $value = preg_replace($pattern, '_', $value); - $value = strtolower($value); + $value = preg_replace($pattern, '_', (string) $value); - return $value; + return strtolower($value); } - protected static function toCamelCase($value, $capitalise_first = FALSE) { - $value = str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9]/', ' ', $value))); + protected static function toCamelCase($value, $capitalise_first = FALSE): string|array { + $value = str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9]/', ' ', (string) $value))); return $capitalise_first ? $value : lcfirst($value); } - protected function toAbbreviation($value, $length = 2, $word_delim = '_') { - $value = trim($value); + protected function toAbbreviation($value, $length = 2, $word_delim = '_'): string|array { + $value = trim((string) $value); $value = str_replace(' ', '_', $value); $parts = explode($word_delim, $value); if (count($parts) == 1) { return strlen($parts[0]) > $length ? substr($parts[0], 0, $length) : $value; } - $value = implode('', array_map(function ($word) { - return substr($word, 0, 1); + $value = implode('', array_map(static function ($word) : string { + return substr($word, 0, 1); }, $parts)); return substr($value, 0, $length); } - protected function executeCallback($prefix, $name) { + protected function executeCallback(string $prefix, $name) { $args = func_get_args(); $args = array_slice($args, 2); @@ -2284,8 +2249,8 @@ protected function executeCallback($prefix, $name) { return NULL; } - protected function snakeToPascal($string) { - return str_replace(' ', '', ucwords(str_replace('_', ' ', $string))); + protected function snakeToPascal($string): string { + return str_replace(' ', '', ucwords(str_replace('_', ' ', (string) $string))); } protected function getComposerJsonValue($name) { @@ -2334,7 +2299,7 @@ protected function out($text, $color = NULL, $new_line = TRUE) { printf($format, $text); } - protected function debug($value, $name = '') { + protected function debug($value, string $name = '') { print PHP_EOL; print trim($name . ' DEBUG START') . PHP_EOL; print print_r($value, TRUE) . PHP_EOL; diff --git a/.drevops/installer/tests/.gitkeep b/.drevops/installer/tests/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/dir/file_in_dir.txt b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/file_in_dir.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/dir/file_in_dir.txt rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/file_in_dir.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/dir/subdir/file_in_subdir.txt b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/subdir/file_in_subdir.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/dir/subdir/file_in_subdir.txt rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/subdir/file_in_subdir.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/dir/subdir/file_link_from_subdir.txt b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/subdir/file_link_from_subdir.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/dir/subdir/file_link_from_subdir.txt rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/subdir/file_link_from_subdir.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/dir/subdir_link b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/subdir_link similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/dir/subdir_link rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/dir/subdir_link diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/dir_link b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/dir_link similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/dir_link rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/dir_link diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/file.txt b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/file.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/file.txt rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/file.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/file_link.txt b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/file_link.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/file_link.txt rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/file_link.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/copyfiles/subdir_link_root b/.drevops/installer/tests/phpunit/Fixtures/copyfiles/subdir_link_root similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/copyfiles/subdir_link_root rename to .drevops/installer/tests/phpunit/Fixtures/copyfiles/subdir_link_root diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/dir1/foobar_b.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/dir1/foobar_b.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/dir1/foobar_b.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/dir1/foobar_b.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/dir1/foofoo_b.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/dir1/foofoo_b.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/dir1/foofoo_b.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/dir1/foofoo_b.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/empty.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/empty.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/empty.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/empty.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foo/foobar_b.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foo/foobar_b.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foo/foobar_b.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foo/foobar_b.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foo/foofoo_b.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foo/foofoo_b.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foo/foofoo_b.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foo/foofoo_b.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foobar_b.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foobar_b.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foobar_b.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foobar_b.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foobar_e.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foobar_e.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foobar_e.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foobar_e.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foobar_m.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foobar_m.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foobar_m.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foobar_m.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foofoo_b.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foofoo_b.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foofoo_b.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foofoo_b.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foofoo_e.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foofoo_e.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foofoo_e.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foofoo_e.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/foofoo_m.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/foofoo_m.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/foofoo_m.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/foofoo_m.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/lines_1.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/lines_1.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/lines_1.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/lines_1.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/lines_123.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/lines_123.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/lines_123.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/lines_123.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/lines_1234.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/lines_1234.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/lines_1234.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/lines_1234.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/lines_14.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/lines_14.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/lines_14.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/lines_14.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/lines_234.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/lines_234.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/lines_234.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/lines_234.txt diff --git a/.drevops/installer/tests/phpunit/fixtures/tokens/lines_4.txt b/.drevops/installer/tests/phpunit/Fixtures/tokens/lines_4.txt similarity index 100% rename from .drevops/installer/tests/phpunit/fixtures/tokens/lines_4.txt rename to .drevops/installer/tests/phpunit/Fixtures/tokens/lines_4.txt diff --git a/.drevops/installer/tests/phpunit/Traits/ReflectionTrait.php b/.drevops/installer/tests/phpunit/Traits/ReflectionTrait.php new file mode 100644 index 000000000..f74b451a9 --- /dev/null +++ b/.drevops/installer/tests/phpunit/Traits/ReflectionTrait.php @@ -0,0 +1,100 @@ +hasMethod($name)) { + throw new \InvalidArgumentException(sprintf('Method %s does not exist', $name)); + } + + $method = $class->getMethod($name); + + $original_accessibility = $method->isPublic(); + + // Set method accessibility to true, so it can be invoked. + $method->setAccessible(TRUE); + + // If the method is static, we won't pass an object instance to invokeArgs() + // Otherwise, we ensure to pass the object instance. + $invoke_object = $method->isStatic() ? NULL : (is_object($object) ? $object : NULL); + + // Ensure we have an object for non-static methods. + if (!$method->isStatic() && $invoke_object === NULL) { + throw new \InvalidArgumentException("An object instance is required for non-static methods"); + } + + $result = $method->invokeArgs($invoke_object, $args); + + // Reset the method's accessibility to its original state. + $method->setAccessible($original_accessibility); + + return $result; + } + + /** + * Set protected property value. + * + * @param object $object + * Object to set the value on. + * @param string $property + * Property name to set the value. Property should exists in the object. + * @param mixed $value + * Value to set to the property. + */ + protected static function setProtectedValue($object, $property, mixed $value): void { + $class = new \ReflectionClass($object::class); + $property = $class->getProperty($property); + $property->setAccessible(TRUE); + + $property->setValue($object, $value); + } + + /** + * Get protected value from the object. + * + * @param object $object + * Object to set the value on. + * @param string $property + * Property name to get the value. Property should exists in the object. + * + * @return mixed + * Protected property value. + */ + protected static function getProtectedValue($object, $property) { + $class = new \ReflectionClass($object::class); + $property = $class->getProperty($property); + $property->setAccessible(TRUE); + + return $property->getValue($class); + } + +} diff --git a/.drevops/installer/tests/phpunit/unit/Command/InstallCommandTest.php b/.drevops/installer/tests/phpunit/Unit/Command/InstallCommandTest.php similarity index 88% rename from .drevops/installer/tests/phpunit/unit/Command/InstallCommandTest.php rename to .drevops/installer/tests/phpunit/Unit/Command/InstallCommandTest.php index 96aaad2af..0317d8cc6 100644 --- a/.drevops/installer/tests/phpunit/unit/Command/InstallCommandTest.php +++ b/.drevops/installer/tests/phpunit/Unit/Command/InstallCommandTest.php @@ -13,14 +13,16 @@ * * This is a unit test for the RunCommand class. * - * @package DrevOps\Installer\Tests\Command + * @coversDefaultClass \DrevOps\Installer\Command\InstallCommand */ class InstallCommandTest extends TestCase { /** * Test the execute method. + * + * @covers ::execute */ - public function testExecute() { + public function testExecute(): void { $application = new Application(); $application->add(new InstallCommand()); diff --git a/.drevops/installer/tests/phpunit/unit/CopyRecursiveTest.php b/.drevops/installer/tests/phpunit/Unit/CopyRecursiveTest.php similarity index 90% rename from .drevops/installer/tests/phpunit/unit/CopyRecursiveTest.php rename to .drevops/installer/tests/phpunit/Unit/CopyRecursiveTest.php index ddecdccdf..578f3b440 100644 --- a/.drevops/installer/tests/phpunit/unit/CopyRecursiveTest.php +++ b/.drevops/installer/tests/phpunit/Unit/CopyRecursiveTest.php @@ -9,12 +9,14 @@ * * InstallerCopyRecursiveTest fixture class. * + * @coversDefaultClass \DrevOps\Installer\Command\InstallCommand + * * phpcs:disable Drupal.Commenting.FunctionComment.Missing * phpcs:disable Drupal.Commenting.DocComment.MissingShort */ class CopyRecursiveTest extends UnitTestBase { - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->prepareFixtureDir(); } @@ -24,7 +26,10 @@ protected function tearDown(): void { $this->cleanupFixtureDir(); } - public function testCopyRecursive() { + /** + * @covers ::copyRecursive + */ + public function testCopyRecursive(): void { $files_dir = $this->getFixtureDir('copyfiles'); $this->callProtectedMethod(InstallCommand::class, 'copyRecursive', [$files_dir, $this->fixtureDir]); diff --git a/.drevops/installer/tests/phpunit/unit/DotEnvTest.php b/.drevops/installer/tests/phpunit/Unit/DotEnvTest.php similarity index 89% rename from .drevops/installer/tests/phpunit/unit/DotEnvTest.php rename to .drevops/installer/tests/phpunit/Unit/DotEnvTest.php index c0c853dce..7b4235ff0 100644 --- a/.drevops/installer/tests/phpunit/unit/DotEnvTest.php +++ b/.drevops/installer/tests/phpunit/Unit/DotEnvTest.php @@ -9,6 +9,9 @@ * * InstallerDotEnvTest fixture class. * + * @coversDefaultClass \DrevOps\Installer\Command\InstallCommand + * @runTestsInSeparateProcesses + * * phpcs:disable Drupal.Commenting.FunctionComment.Missing * phpcs:disable Drupal.Commenting.DocComment.MissingShort */ @@ -28,23 +31,26 @@ class DotEnvTest extends UnitTestBase { */ protected $backupEnv; - public function setUp(): void { + protected function setUp(): void { $this->backupEnv = $GLOBALS['_ENV']; $this->backupServer = $GLOBALS['_SERVER']; parent::setUp(); } - public function tearDown(): void { + protected function tearDown(): void { $GLOBALS['_ENV'] = $this->backupEnv; $GLOBALS['_SERVER'] = $this->backupServer; } - public function testGetEnv() { + /** + * @covers ::loadDotenv + */ + public function testGetEnv(): void { $content = 'var1=val1'; $filename = $this->createFixtureEnvFile($content); - $this->assertEmpty(getenv('var1')); + $this->assertEmpty(getenv('var1'), getenv('var1')); $this->callProtectedMethod(InstallCommand::class, 'loadDotenv', [$filename]); $this->assertEquals('val1', getenv('var1')); @@ -64,8 +70,9 @@ public function testGetEnv() { /** * @dataProvider dataProviderGlobals + * @covers ::loadDotenv */ - public function testGlobals($content, $env_before, $server_before, $env_after, $server_after, $allow_override) { + public function testGlobals(string $content, array $env_before, array $server_before, array $env_after, mixed $server_after, bool $allow_override): void { $filename = $this->createFixtureEnvFile($content); $GLOBALS['_ENV'] = $env_before; @@ -80,7 +87,7 @@ public function testGlobals($content, $env_before, $server_before, $env_after, $ $this->assertTrue(TRUE); } - public static function dataProviderGlobals() { + public static function dataProviderGlobals(): array { return [ [ '', [], [], [], [], FALSE, @@ -209,7 +216,7 @@ public static function dataProviderGlobals() { ]; } - protected function createFixtureEnvFile($content) { + protected function createFixtureEnvFile($content): string|false { $filename = tempnam(sys_get_temp_dir(), '.env'); file_put_contents($filename, $content); diff --git a/.drevops/installer/tests/phpunit/unit/HelpersTest.php b/.drevops/installer/tests/phpunit/Unit/HelpersTest.php similarity index 84% rename from .drevops/installer/tests/phpunit/unit/HelpersTest.php rename to .drevops/installer/tests/phpunit/Unit/HelpersTest.php index 6fdf85202..3abf8159a 100644 --- a/.drevops/installer/tests/phpunit/unit/HelpersTest.php +++ b/.drevops/installer/tests/phpunit/Unit/HelpersTest.php @@ -9,6 +9,8 @@ * * InstallerHelpersTest fixture class. * + * @coversDefaultClass \DrevOps\Installer\Command\InstallCommand + * * phpcs:disable Drupal.Commenting.FunctionComment.Missing * phpcs:disable Drupal.Commenting.DocComment.MissingShort */ @@ -16,13 +18,14 @@ class HelpersTest extends UnitTestBase { /** * @dataProvider dataProviderToHumanName + * @covers ::toHumanName */ - public function testToHumanName($value, $expected) { + public function testToHumanName(string $value, mixed $expected): void { $actual = $this->callProtectedMethod(InstallCommand::class, 'toHumanName', [$value]); $this->assertEquals($expected, $actual); } - public static function dataProviderToHumanName() { + public static function dataProviderToHumanName(): array { return [ ['', ''], [' ', ''], @@ -42,13 +45,14 @@ public static function dataProviderToHumanName() { /** * @dataProvider dataProviderToMachineName + * @covers ::toMachineName */ - public function testToMachineName($value, $preserve, $expected) { + public function testToMachineName(string $value, array $preserve, mixed $expected): void { $actual = $this->callProtectedMethod(InstallCommand::class, 'toMachineName', [$value, $preserve]); $this->assertEquals($expected, $actual); } - public static function dataProviderToMachineName() { + public static function dataProviderToMachineName(): array { return [ ['', [], ''], [' ', [], '_'], @@ -82,13 +86,14 @@ public static function dataProviderToMachineName() { /** * @dataProvider dataProviderToCamelCase + * @covers ::toCamelCase */ - public function testToCamelCase($value, $capitalise_first, $expected) { + public function testToCamelCase(string $value, bool $capitalise_first, mixed $expected): void { $actual = $this->callProtectedMethod(InstallCommand::class, 'toCamelCase', [$value, $capitalise_first]); $this->assertEquals($expected, $actual); } - public static function dataProviderToCamelCase() { + public static function dataProviderToCamelCase(): array { return [ ['', FALSE, ''], [' ', FALSE, ''], @@ -109,13 +114,14 @@ public static function dataProviderToCamelCase() { /** * @dataProvider dataProviderIsRegex + * @covers ::isRegex */ - public function testIsRegex($value, $expected) { + public function testIsRegex(string $value, mixed $expected): void { $actual = $this->callProtectedMethod(InstallCommand::class, 'isRegex', [$value]); $this->assertEquals($expected, $actual); } - public static function dataProviderIsRegex() { + public static function dataProviderIsRegex(): array { return [ ['', FALSE], diff --git a/.drevops/installer/tests/phpunit/unit/TokenTest.php b/.drevops/installer/tests/phpunit/Unit/TokenTest.php similarity index 80% rename from .drevops/installer/tests/phpunit/unit/TokenTest.php rename to .drevops/installer/tests/phpunit/Unit/TokenTest.php index 541fe6c63..17315b811 100644 --- a/.drevops/installer/tests/phpunit/unit/TokenTest.php +++ b/.drevops/installer/tests/phpunit/Unit/TokenTest.php @@ -9,12 +9,14 @@ * * InstallerTokenTest fixture class. * + * @coversDefaultClass \DrevOps\Installer\Command\InstallCommand + * * phpcs:disable Drupal.Commenting.FunctionComment.Missing * phpcs:disable Drupal.Commenting.DocComment.MissingShort */ class TokenTest extends UnitTestBase { - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->prepareFixtureDir(); } @@ -24,7 +26,10 @@ protected function tearDown(): void { $this->cleanupFixtureDir(); } - protected function flattenFileTree($tree, $parent = '.') { + /** + * Flatten file tree. + */ + protected function flattenFileTree($tree, string $parent = '.'): array { $flatten = []; foreach ($tree as $dir => $file) { if (is_array($file)) { @@ -34,14 +39,15 @@ protected function flattenFileTree($tree, $parent = '.') { $flatten[] = $parent . DIRECTORY_SEPARATOR . $file; } } + return $flatten; } /** * @dataProvider dataProviderFileContains - * @covers \DrevOps\Installer\Command\InstallCommand::fileContains() + * @covers ::fileContains */ - public function testFileContains($string, $file, $expected) { + public function testFileContains(string $string, string $file, mixed $expected): void { $tokens_dir = $this->getFixtureDir('tokens'); $files = $this->flattenFileTree([$file], $tokens_dir); $created_files = $this->createFixtureFiles($files, $tokens_dir); @@ -52,7 +58,7 @@ public function testFileContains($string, $file, $expected) { $this->assertEquals($expected, $actual); } - public static function dataProviderFileContains() { + public static function dataProviderFileContains(): array { return [ ['FOO', 'empty.txt', FALSE], ['BAR', 'foobar_b.txt', TRUE], @@ -67,9 +73,9 @@ public static function dataProviderFileContains() { /** * @dataProvider dataProviderDirContains - * @covers \DrevOps\Installer\Command\InstallCommand::direContains() + * @covers ::dirContains */ - public function testDirContains($string, $files, $expected) { + public function testDirContains(string $string, array $files, mixed $expected): void { $tokens_dir = $this->getFixtureDir('tokens'); $files = $this->flattenFileTree($files, $tokens_dir); $this->createFixtureFiles($files, $tokens_dir); @@ -79,7 +85,7 @@ public function testDirContains($string, $files, $expected) { $this->assertEquals($expected, $actual); } - public static function dataProviderDirContains() { + public static function dataProviderDirContains(): array { return [ ['FOO', ['empty.txt'], FALSE], ['BAR', ['foobar_b.txt'], TRUE], @@ -95,9 +101,9 @@ public static function dataProviderDirContains() { /** * @dataProvider dataProviderRemoveTokenFromFile - * @covers \remove_token_with_content() + * @covers ::removeTokenFromFile */ - public function testRemoveTokenFromFile($file, $begin, $end, $with_content, $expect_exception, $expected_file) { + public function testRemoveTokenFromFile(string $file, string $begin, string $end, bool $with_content, bool $expect_exception, string $expected_file): void { $tokens_dir = $this->getFixtureDir('tokens'); $files = $this->flattenFileTree([$file], $tokens_dir); $created_files = $this->createFixtureFiles($files, $tokens_dir); @@ -114,7 +120,7 @@ public function testRemoveTokenFromFile($file, $begin, $end, $with_content, $exp $this->assertFileEquals($expected_file, $created_file); } - public static function dataProviderRemoveTokenFromFile() { + public static function dataProviderRemoveTokenFromFile(): array { return [ ['empty.txt', 'FOO', 'FOO', TRUE, FALSE, 'empty.txt'], @@ -152,16 +158,16 @@ public static function dataProviderRemoveTokenFromFile() { /** * @dataProvider dataProviderDirReplaceContent - * @covers \dir_replace_content() + * @covers ::dirReplaceContent */ - public function testDirReplaceContent($files, $expected_files) { + public function testDirReplaceContent(array $files, array $expected_files): void { $tokens_dir = $this->getFixtureDir('tokens'); $files = $this->flattenFileTree($files, $tokens_dir); $expected_files = $this->flattenFileTree($expected_files, $tokens_dir); $created_files = $this->createFixtureFiles($files, $tokens_dir); - if (count($created_files) != count($expected_files)) { - throw new \RuntimeException(sprintf('Provided files number is not equal to expected files number.')); + if (count($created_files) !== count($expected_files)) { + throw new \RuntimeException('Provided files number is not equal to expected files number.'); } $this->callProtectedMethod(InstallCommand::class, 'dirReplaceContent', ['BAR', 'FOO', $this->fixtureDir]); @@ -171,7 +177,7 @@ public function testDirReplaceContent($files, $expected_files) { } } - public static function dataProviderDirReplaceContent() { + public static function dataProviderDirReplaceContent(): array { return [ [ ['empty.txt'], @@ -190,16 +196,16 @@ public static function dataProviderDirReplaceContent() { /** * @dataProvider dataProviderReplaceStringFilename - * @covers \replace_string_filename() + * @covers ::replaceStringFilename */ - public function testReplaceStringFilename($files, $expected_files) { + public function testReplaceStringFilename(array $files, array $expected_files): void { $tokens_dir = $this->getFixtureDir('tokens'); $files = $this->flattenFileTree($files, $tokens_dir); $expected_files = $this->flattenFileTree($expected_files, $this->fixtureDir); $created_files = $this->createFixtureFiles($files, $tokens_dir, FALSE); - if (count($created_files) != count($expected_files)) { - throw new \RuntimeException(sprintf('Provided files number is not equal to expected files number.')); + if (count($created_files) !== count($expected_files)) { + throw new \RuntimeException('Provided files number is not equal to expected files number.'); } $this->callProtectedMethod(InstallCommand::class, 'replaceStringFilename', ['foo', 'bar', $this->fixtureDir]); @@ -209,7 +215,7 @@ public function testReplaceStringFilename($files, $expected_files) { } } - public static function dataProviderReplaceStringFilename() { + public static function dataProviderReplaceStringFilename(): array { return [ [ ['empty.txt'], diff --git a/.drevops/installer/tests/phpunit/unit/UnitTestBase.php b/.drevops/installer/tests/phpunit/Unit/UnitTestBase.php similarity index 84% rename from .drevops/installer/tests/phpunit/unit/UnitTestBase.php rename to .drevops/installer/tests/phpunit/Unit/UnitTestBase.php index 3f3e4a7be..be1b88ca5 100644 --- a/.drevops/installer/tests/phpunit/unit/UnitTestBase.php +++ b/.drevops/installer/tests/phpunit/Unit/UnitTestBase.php @@ -3,7 +3,7 @@ namespace Drevops\Installer\Tests\Unit; use DrevOps\Installer\Command\InstallCommand; -use Drevops\Installer\Tests\Traits\TestHelperTrait; +use Drevops\Installer\Tests\Traits\ReflectionTrait; use PHPUnit\Framework\TestCase; use Symfony\Component\Filesystem\Filesystem; @@ -12,14 +12,12 @@ * * UnitTestCase fixture class. * - * @package Drevops\Tests - * * phpcs:disable Drupal.Commenting.FunctionComment.Missing * phpcs:disable Drupal.Commenting.DocComment.MissingShort */ abstract class UnitTestBase extends TestCase { - use TestHelperTrait; + use ReflectionTrait; /** * Fixture directory. @@ -39,7 +37,7 @@ public function prepareFixtureDir(): void { /** * Cleanup fixture directory. */ - public function cleanupFixtureDir() { + public function cleanupFixtureDir(): void { $this->fileExists(); $fs = new Filesystem(); $fs->remove($this->fixtureDir); @@ -52,8 +50,8 @@ protected function createFixtureFiles($files, $basedir = NULL, $append_rand = TR $fs = new Filesystem(); $created = []; foreach ($files as $file) { - $basedir = $basedir ?? dirname($file); - $relative_dst = ltrim(str_replace($basedir, '', $file), '/') . ($append_rand ? rand(1000, 9999) : ''); + $basedir = $basedir ?? dirname((string) $file); + $relative_dst = ltrim(str_replace($basedir, '', (string) $file), '/') . ($append_rand ? rand(1000, 9999) : ''); $new_name = $this->fixtureDir . DIRECTORY_SEPARATOR . $relative_dst; $fs->copy($file, $new_name); $created[] = $new_name; @@ -73,7 +71,7 @@ protected function createFixtureFiles($files, $basedir = NULL, $append_rand = TR */ protected function getFixtureDir($name = NULL) { $parent = dirname(__FILE__); - $path = $parent . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'fixtures'; + $path = $parent . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Fixtures'; $path .= $name ? DIRECTORY_SEPARATOR . $name : ''; if (!file_exists($path)) { throw new \RuntimeException(sprintf('Unable to find fixture directory at path "%s".', $path)); diff --git a/.drevops/installer/tests/phpunit/traits/TestHelperTrait.php b/.drevops/installer/tests/phpunit/traits/TestHelperTrait.php deleted file mode 100644 index a484fb2d7..000000000 --- a/.drevops/installer/tests/phpunit/traits/TestHelperTrait.php +++ /dev/null @@ -1,138 +0,0 @@ -getMethod($method); - $method->setAccessible(TRUE); - $object = $method->isStatic() ? NULL : $object; - - return $method->invokeArgs($object, $args); - } - - /** - * Set protected property value. - * - * @param object $object - * Object to set the value on. - * @param string $property - * Property name to set the value. Property should exists in the object. - * @param mixed $value - * Value to set to the property. - */ - protected static function setProtectedValue($object, $property, $value) { - $class = new \ReflectionClass(get_class($object)); - $property = $class->getProperty($property); - $property->setAccessible(TRUE); - - $property->setValue($object, $value); - } - - /** - * Get protected value from the object. - * - * @param object $object - * Object to set the value on. - * @param string $property - * Property name to get the value. Property should exists in the object. - * - * @return mixed - * Protected property value. - */ - protected static function getProtectedValue($object, $property) { - $class = new \ReflectionClass(get_class($object)); - $property = $class->getProperty($property); - $property->setAccessible(TRUE); - - return $property->getValue($class); - } - - /** - * Helper to prepare class mock. - * - * @param string $class - * Class name to generate the mock. - * @param array $methodsMap - * Optional array of methods and values, keyed by method name. - * @param array $args - * Optional array of constructor arguments. If omitted, a constructor will - * not be called. - * - * @return object - * Mocked class. - */ - protected function prepareMock($class, array $methodsMap = [], array $args = []) { - $methods = array_keys($methodsMap); - - $reflectionClass = new \ReflectionClass($class); - - if ($reflectionClass->isAbstract()) { - $mock = $this->getMockForAbstractClass( - $class, $args, '', !empty($args), TRUE, TRUE, $methods - ); - } - else { - $mock = $this->getMockBuilder($class); - if (!empty($args)) { - $mock = $mock->enableOriginalConstructor() - ->setConstructorArgs($args); - } - else { - $mock = $mock->disableOriginalConstructor(); - } - $mock = $mock->addMethods($methods) - ->getMock(); - } - - foreach ($methodsMap as $method => $value) { - // Handle callback values differently. - if (is_object($value) && strpos(get_class($value), 'Callback') !== FALSE) { - $mock->expects($this->any()) - ->method($method) - ->will($value); - } - else { - $mock->expects($this->any()) - ->method($method) - ->willReturn($value); - } - } - - return $mock; - } - - /** - * Check if testing framework was ran with --debug option. - */ - protected function isDebug() { - return in_array('--debug', $_SERVER['argv'], TRUE); - } - -} diff --git a/.github/workflows/drevops-publish-docs.yml b/.github/workflows/drevops-publish-docs.yml index 912005cd6..7073c041a 100644 --- a/.github/workflows/drevops-publish-docs.yml +++ b/.github/workflows/drevops-publish-docs.yml @@ -1,5 +1,5 @@ # This action is used for DrevOps maintenance. It will not be used in the scaffolded project. -name: Publish DrevOps documentation +name: DrevOps - Publish documentation on: push: diff --git a/.github/workflows/drevops-publish-installer.yml b/.github/workflows/drevops-publish-installer.yml new file mode 100644 index 000000000..71377204c --- /dev/null +++ b/.github/workflows/drevops-publish-installer.yml @@ -0,0 +1,64 @@ +# This action is used for DrevOps maintenance. It will not be used in the scaffolded project. +name: DrevOps - Publish installer + +on: + push: + tags: + - '*' + branches: + - develop + - '**installer**' + +jobs: + drevops-publish-installer: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + + - name: Install dependencies + working-directory: .drevops/installer + run: composer install + + - name: Add version + working-directory: .drevops/installer + run: | + TAG=${{ github.ref_type == 'tag' && github.ref_name || '' }} + SHA=${{ github.ref_type == 'branch' && github.sha || '' }} + sed -i "s/\"git-tag-ci\": \"dev\"/\"git-tag-ci\": \"${TAG:-${SHA}}\"/g" box.json + + - name: Build installer + working-directory: .drevops/installer + run: composer build + + - name: Prepare artifact + working-directory: .drevops/installer + run: | + mkdir -p /tmp/installer/docs + cp .build/install.phar /tmp/installer/docs/index.html + echo "install.drevops.com" > /tmp/installer/docs/CNAME + + - name: Setup SSH private key + uses: webfactory/ssh-agent@v0.8.0 + with: + ssh-private-key: ${{ secrets.INSTALLER_PUBLISH_SSH_PRIVATE_KEY }} + + - name: Publish installer + run: | + git config --global user.name "Deployment robot" + git config --global user.email "deploy@drevops.com" + cd /tmp/installer + git init + git checkout -b main + git add -A + git commit -m "Automatically pushed from drevops/drevops" + git remote add origin git@github.com:drevops/installer.git + git push origin main --force diff --git a/.github/workflows/drevops-test-docs.yml b/.github/workflows/drevops-test-docs.yml index 55ba5bc50..50fc3eb45 100644 --- a/.github/workflows/drevops-test-docs.yml +++ b/.github/workflows/drevops-test-docs.yml @@ -1,5 +1,5 @@ # This action is used for DrevOps maintenance. It will not be used in the scaffolded project. -name: Test DrevOps documentation +name: DrevOps - Test documentation on: push: diff --git a/.github/workflows/drevops-test-installer.yml b/.github/workflows/drevops-test-installer.yml new file mode 100644 index 000000000..99b1c8142 --- /dev/null +++ b/.github/workflows/drevops-test-installer.yml @@ -0,0 +1,59 @@ +# This action is used for DrevOps maintenance. It will not be used in the scaffolded project. +name: DrevOps - Test installer + +on: + push: + tags: + - '*' + branches: + - '**' + +jobs: + drevops-publish-installer: + runs-on: ubuntu-latest + + strategy: + matrix: + php-versions: ['8.1', '8.2', '8.3'] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + + - name: Install dependencies + working-directory: .drevops/installer + run: composer install + + - name: Check coding standards + working-directory: .drevops/installer + run: composer lint + + - name: Run tests + working-directory: .drevops/installer + run: XDEBUG_MODE=coverage composer test + + - name: Upload coverage report as artifact + uses: actions/upload-artifact@v4 + with: + name: ${{github.job}}-code-coverage-report-${{ matrix.php-versions }} + path: .drevops/installer/.coverage-html + + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@v3 + with: + files: .drevops/installer/cobertura.xml + fail_ci_if_error: true + + # Smoke test for PHAR. + - name: Build PHAR + working-directory: .drevops/installer + run: composer build + + - name: Test PHAR + working-directory: .drevops/installer + run: ./.build/install.phar --quiet || exit 1