From ba874d4e4fa650866cf4d6f1547756e5f43e8d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 09:42:59 +0100 Subject: [PATCH 001/286] [TASK] Drop changelog file --- .dockerignore | 1 - CHANGELOG.md | 370 ---------------------------------------------- README.md | 4 - docs/changelog.md | 10 -- mkdocs.yml | 1 - 5 files changed, 386 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 docs/changelog.md diff --git a/.dockerignore b/.dockerignore index 9458972f..061084b1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,7 +7,6 @@ /.gitattributes /.gitignore /.php-cs-fixer.php -/CHANGELOG.md /codecov.yml /composer.lock /Dockerfile diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 48332fd3..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,370 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [1.5.3] - 2022-10-15 - -### Added - -- Support for `spatie/emoji` 4.x - -### Changed - -- Dependabot updates for Composer dependencies - -### Fixed - -- Replace deprecated job outputs in GitHub workflows - -## [1.5.2] - 2022-07-26 - -### Changed - -- Extract changelog entry for new releases - -## [1.5.1] - 2022-07-26 - -### Fixed - -- Fix version detection in `composer update` output - -## [1.5.0] - 2022-06-27 - -### Added - -- Support for PHP 8.1 - -### Fixed - -- Exclude packages without security advisories from security scan result - -## [1.4.1] - 2022-05-16 - -### Changed - -- Update dependencies to GitHub Actions - -## [1.4.0] - 2022-05-16 - -### Added - -- Dependabot updates for GitHub Actions - -### Fixed - -- Declare path `/docs` as "safe path" for documentation rendering - -## [1.3.0] - 2022-05-16 - -### Added - -- Build argument `PHP_VERSION` for Docker container (defaults to `7.4`) - -### Changed - -- Switch to `main` branch for tests of `composer-update-reporter` - -### Fixed - -- Respect platform requirements during update check -- Use test application variants for different PHP major versions - -## [1.2.0] - 2022-04-13 - -### Added - -- Various code quality tools and more CGL checks in CI - -### Changed - -- Rename `master` branch to `main` -- Switch to GitHub Pages for documentation - (new documentation URL: ) - -### Fixed - -- Add missing dependencies -- Compatibility with mkdocs-material 8.x - -## [1.1.3] - 2022-01-06 - -### Added - -- Support for Symfony 6 components - -## [1.1.2] - 2021-12-27 - -### Fixed - -- Various CI fixes - -## [1.1.1] - 2021-12-27 - -### Fixed - -- Various CI fixes - -## [1.1.0] - 2021-12-27 - -### Fixed - -- Various requirements for dependencies installed with `--prefer-lowest` -- Requirements for PHP 7.1 compatibility -- Requirements for PHP 8.0 compatibility - -### Added - -- Support for Composer 2.2 -- Code quality assurance with SonarCloud - -### Changed - -- Migrate project from GitLab to GitHub -- Upgrade PHP-CS-Fixer to 3.x -- Upgrade PHPStan to 1.x - -### Documentation - -- Improved README.md -- Add logo - -## [1.0.2] - 2021-10-14 - -### Fixed - -- Hostname of docs server - -## [1.0.1] - 2021-10-14 - -### Fixed - -- Autoload files from dependencies - -## [1.0.0] - 2021-04-19 - -### Added - -- Transfer objects for output style and verbosity -- Support for PHP 8.0 -- Normalization of `composer.json` - -### Changed - -- Decouple `PostUpdateCheckEvent` from command event -- Various improvements in documentation -- Use temporary directories for test applications in Unit tests -- Parallel execution of Unit tests in CI - -### Deprecated - -- Usage with Docker images (will be removed in 2.0.0) - -### Fixed - -- Remove unneeded package dependency `composer/semver` -- Render all JavaScripts in documentation - -## [0.8.2] - 2021-03-29 - -### Added - -- PHPStan for static code analysis - -### Changed - -- Use Symfony rules in PHP-CS-Fixer - -### Fixed - -- Include all installed packages and sub-dependencies in native update command - -## [0.8.1] - 2021-03-13 - -### Fixed - -- Install required dependencies for documentation rendering - -## [0.8.0] - 2021-03-13 - -### Changed - -- Replace Guzzle by more lightweight libraries - -### Fixed - -- Revert loading of Composer dependencies -- Switch to PHP as base Docker image and explicitly define PHP version - -## [0.7.3] - 2021-01-26 - -### Changed - -- Return outdated packages in sorted order -- Use `master` branch of project dependents to test their successful integration - -### Fixed - -- Include notice about conflicting requirements of `composer/semver` package to user-oriented console output -- Avoid conflicts with Composer library in test applications - -## [0.7.2] - 2021-01-18 - -### Added - -- Tests for project dependents in CI -- PHP-CS-Fixer for linting PHP - -### Changed - -- Make code PSR-2 compliant -- Collect code coverage for PHP 7.4 & Composer 2 job only - -## [0.7.1] - 2021-01-16 - -### Added - -- CI variable `$RENDER_DOCS` to manually create project documentation -- Build and deploy Docker test image on each CI build -- Run application tests in Docker containers within CI - -### Changed - -- Skip security scan if no scanned packages are outdated - -### Fixed - -- Load missing Composer dependencies in Plugin entrypoint - -## [0.7.0] - 2021-01-15 - -### Changed - -- Use Packagist API instead of Composer package to check for insecure packages - -### Fixed - -- Ensure simulated application is cleaned up properly - -## [0.6.1] - 2020-11-20 - -### Fixed - -- Handling of SSH keys in Docker containers - -## [0.6.0] - 2020-11-19 - -### Added - -- Standalone Docker image `eliashaeussler/composer-update-check` for Composer 1 and 2 - -## [0.5.0] - 2020-11-16 - -### Added - -- Support for Composer 2 - -## [0.4.3] - 2020-10-26 - -### Added - -- Add provider link (Packagist URL) property to `OutdatedPackage` - -## [0.4.0] - 2020-10-09 - -### Added - -- Project documentation - -### Changed - -- Move update check to standalone API - -## [0.3.0] - 2020-09-22 - -### Added - -- Optional security scan using the `--security-scan` option - -### Fixed - -- Support for Composer versions < 1.10.8 - -## [0.2.0] - 2020-09-21 - -### Added - -- New `--json` option for console command -- Show number of skipped packages to command success message -- Official support for PHP 7.1 - 7.4 -- Application simulation testing - -### Changed - -- Use native Composer installer for installs und updates - -### Fixed - -- Include dev-requirements in Composer installer -- Show skipped dev-requirements in user-oriented console output - -## [0.1.3] - 2020-09-17 - -### Fixed - -- Minor fixes in user-oriented console output - -## [0.1.2] - 2020-09-17 - -### Fixed - -- Hide sub-command output from user-oriented console output - -## [0.1.1] - 2020-09-17 - -### Added - -- Add emojis to user-oriented console output - -## [0.1.0] - 2020-09-16 - -Initial release - -[Unreleased]: https://github.com/eliashaeussler/composer-update-check/compare/1.5.3...main -[1.5.3]: https://github.com/eliashaeussler/composer-update-check/compare/1.5.2...1.5.3 -[1.5.2]: https://github.com/eliashaeussler/composer-update-check/compare/1.5.1...1.5.2 -[1.5.1]: https://github.com/eliashaeussler/composer-update-check/compare/1.5.0...1.5.1 -[1.5.0]: https://github.com/eliashaeussler/composer-update-check/compare/1.4.1...1.5.0 -[1.4.1]: https://github.com/eliashaeussler/composer-update-check/compare/1.4.0...1.4.1 -[1.4.0]: https://github.com/eliashaeussler/composer-update-check/compare/1.3.0...1.4.0 -[1.3.0]: https://github.com/eliashaeussler/composer-update-check/compare/1.2.0...1.3.0 -[1.2.0]: https://github.com/eliashaeussler/composer-update-check/compare/1.1.3...1.2.0 -[1.1.3]: https://github.com/eliashaeussler/composer-update-check/compare/1.1.2...1.1.3 -[1.1.2]: https://github.com/eliashaeussler/composer-update-check/compare/1.1.1...1.1.2 -[1.1.1]: https://github.com/eliashaeussler/composer-update-check/compare/1.1.0...1.1.1 -[1.1.0]: https://github.com/eliashaeussler/composer-update-check/compare/1.0.2...1.1.0 -[1.0.2]: https://github.com/eliashaeussler/composer-update-check/compare/1.0.1...1.0.2 -[1.0.1]: https://github.com/eliashaeussler/composer-update-check/compare/1.0.0...1.0.1 -[1.0.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.8.2...1.0.0 -[0.8.2]: https://github.com/eliashaeussler/composer-update-check/compare/0.8.1...0.8.2 -[0.8.1]: https://github.com/eliashaeussler/composer-update-check/compare/0.8.0...0.8.1 -[0.8.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.7.3...0.8.0 -[0.7.3]: https://github.com/eliashaeussler/composer-update-check/compare/0.7.2...0.7.3 -[0.7.2]: https://github.com/eliashaeussler/composer-update-check/compare/0.7.1...0.7.2 -[0.7.1]: https://github.com/eliashaeussler/composer-update-check/compare/0.7.0...0.7.1 -[0.7.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.6.1...0.7.0 -[0.6.1]: https://github.com/eliashaeussler/composer-update-check/compare/0.6.0...0.6.1 -[0.6.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.5.0...0.6.0 -[0.5.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.4.4...0.5.0 -[0.4.3]: https://github.com/eliashaeussler/composer-update-check/compare/0.4.0...0.4.3 -[0.4.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.3.0...0.4.0 -[0.3.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.2.0...0.3.0 -[0.2.0]: https://github.com/eliashaeussler/composer-update-check/compare/0.1.3...0.2.0 -[0.1.3]: https://github.com/eliashaeussler/composer-update-check/compare/0.1.2...0.1.3 -[0.1.2]: https://github.com/eliashaeussler/composer-update-check/compare/0.1.1...0.1.2 -[0.1.1]: https://github.com/eliashaeussler/composer-update-check/compare/0.1.0...0.1.1 -[0.1.0]: https://github.com/eliashaeussler/composer-update-check/tree/0.1.0 diff --git a/README.md b/README.md index 5267ecec..0e99cc70 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,6 @@ automated quality assurance of your projects. composer require eliashaeussler/composer-update-check ``` -## :ship: Changelog - -View all notable release notes in the [Changelog](CHANGELOG.md). - ## :gem: Credits [Business vector created by studiogstock - www.freepik.com](https://www.freepik.com/vectors/business) diff --git a/docs/changelog.md b/docs/changelog.md deleted file mode 100644 index d90f5be3..00000000 --- a/docs/changelog.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -hide: -- toc ---- - -??? info - The changelog is extracted from - [CHANGELOG.md]({{ repository.blob }}/CHANGELOG.md). - ---8<-- "CHANGELOG.md" diff --git a/mkdocs.yml b/mkdocs.yml index d993e98e..b7d98fa4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -25,7 +25,6 @@ nav: - Plugins: plugins.md - About: - Contribution: contribute.md - - Changelog: changelog.md - License: license.md # Theme configuration From f7d146aee88e4b4b4e274fadc2fb7d34d0ef23c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 09:54:11 +0100 Subject: [PATCH 002/286] [TASK] Update PHPunit and PHP-CS-Fixer --- .dockerignore | 1 - .gitattributes | 1 - composer.json | 8 +- composer.lock | 901 ++++++------------- phpunit.coverage.xml | 28 - phpunit.xml | 26 +- src/Package/UpdateCheckResult.php | 4 +- src/Security/ScanResult.php | 6 +- tests/Unit/AbstractTestCase.php | 6 +- tests/Unit/ExpectedCommandOutputTrait.php | 2 +- tests/Unit/IO/StyleTest.php | 2 +- tests/Unit/IO/VerbosityTest.php | 2 +- tests/Unit/Package/UpdateCheckResultTest.php | 14 +- tests/Unit/Security/ScanResultTest.php | 4 +- tests/Unit/Utility/InstallerTest.php | 12 +- 15 files changed, 315 insertions(+), 702 deletions(-) delete mode 100644 phpunit.coverage.xml diff --git a/.dockerignore b/.dockerignore index 061084b1..db6671a6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -13,4 +13,3 @@ /mkdocs.yml /phpstan.neon /phpunit.xml -/phpunit.coverage.xml diff --git a/.gitattributes b/.gitattributes index 235be1d1..0a291793 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,5 +16,4 @@ /mkdocs.yml export-ignore /phpstan.neon export-ignore /phpunit.xml export-ignore -/phpunit.coverage.xml export-ignore /renovate.json export-ignore diff --git a/composer.json b/composer.json index a70bef4c..1b211b5c 100644 --- a/composer.json +++ b/composer.json @@ -34,12 +34,12 @@ "composer/composer": "^1.7 || ^2.0", "composer/semver": "^1.0 || ^2.0 || ^3.0", "ergebnis/composer-normalize": "^2.8", - "friendsofphp/php-cs-fixer": ">= 2.17 < 4.0", + "friendsofphp/php-cs-fixer": "^3.39", "php-http/discovery": "^1.14", "php-http/httplug": "^2.0", "php-http/mock-client": "^1.3", "phpstan/phpstan": "^1.2", - "phpunit/phpunit": "^7.5 || ^8.5.23 || ^9.0", + "phpunit/phpunit": "^10.4", "symfony/filesystem": ">= 4.4 < 7.0" }, "autoload": { @@ -86,7 +86,7 @@ ], "sca:php": "phpstan analyse -c phpstan.neon", "simulate": "bin/simulate-application.sh", - "test": "phpunit -c phpunit.xml", - "test:coverage": "@php -d pcov.enabled=1 -d pcov.directory=src -d memory_limit=-1 vendor/bin/phpunit -c phpunit.coverage.xml" + "test": "@test:coverage --no-coverage", + "test:coverage": "phpunit -c phpunit.xml" } } diff --git a/composer.lock b/composer.lock index 167386ec..89b32d94 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "499f7dded78bd3d89d265e5435644826", + "content-hash": "8ba21e3e76b6620add8085fbdb332a43", "packages": [ { "name": "nyholm/psr7", @@ -2050,273 +2050,6 @@ ], "time": "2022-02-25T21:32:43+00:00" }, - { - "name": "doctrine/annotations", - "version": "1.14.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b", - "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^1 || ^2", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "vimeo/psalm": "^4.10" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.2" - }, - "time": "2022-12-15T06:48:22+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "shasum": "" - }, - "require": { - "php": "^7.1|^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" - }, - "time": "2022-05-02T15:47:09+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "doctrine/lexer", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^4.11 || ^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/2.1.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-12-14T08:49:07+00:00" - }, { "name": "ergebnis/composer-normalize", "version": "2.29.0", @@ -2581,52 +2314,50 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.13.1", + "version": "v3.39.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "78d2251dd86b49c609a0fd37c20dcf0a00aea5a7" + "reference": "04bf7b28fc847185b247d112cab617da941e3cca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/78d2251dd86b49c609a0fd37c20dcf0a00aea5a7", - "reference": "78d2251dd86b49c609a0fd37c20dcf0a00aea5a7", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/04bf7b28fc847185b247d112cab617da941e3cca", + "reference": "04bf7b28fc847185b247d112cab617da941e3cca", "shasum": "" }, "require": { - "composer/semver": "^3.2", + "composer/semver": "^3.3", "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^1.13", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" + "sebastian/diff": "^4.0 || ^5.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^2.0", - "mikey179/vfsstream": "^1.6.10", - "php-coveralls/php-coveralls": "^2.5.2", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", + "phpspec/prophecy": "^1.16", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.6", - "phpunitgoodpractices/traits": "^1.9.2", - "symfony/phpunit-bridge": "^6.0", - "symfony/yaml": "^5.4 || ^6.0" + "symfony/phpunit-bridge": "^6.2.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -2656,9 +2387,15 @@ } ], "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.1" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.39.0" }, "funding": [ { @@ -2666,7 +2403,7 @@ "type": "github" } ], - "time": "2022-12-18T00:47:22+00:00" + "time": "2023-11-22T11:20:09+00:00" }, { "name": "idiosyncratic/editorconfig", @@ -3537,44 +3274,44 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.19", + "version": "10.1.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + "reference": "a56a9ab2f680246adcf3db43f38ddf1765774735" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/a56a9ab2f680246adcf3db43f38ddf1765774735", + "reference": "a56a9ab2f680246adcf3db43f38ddf1765774735", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", + "nikic/php-parser": "^4.15", + "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": "^9.3" + "phpunit/phpunit": "^10.1" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "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-master": "9.2-dev" + "dev-main": "10.1-dev" } }, "autoload": { @@ -3602,7 +3339,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.9" }, "funding": [ { @@ -3610,32 +3348,32 @@ "type": "github" } ], - "time": "2022-11-18T07:47:47+00:00" + "time": "2023-11-23T12:23:20+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -3662,7 +3400,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -3670,28 +3409,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -3699,7 +3438,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -3725,7 +3464,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -3733,32 +3472,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -3784,7 +3523,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -3792,32 +3532,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -3843,7 +3583,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -3851,24 +3591,23 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "9.5.27", + "version": "10.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" + "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", + "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -3878,27 +3617,26 @@ "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", - "sebastian/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": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -3906,7 +3644,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-main": "10.4-dev" } }, "autoload": { @@ -3937,7 +3675,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.2" }, "funding": [ { @@ -3953,56 +3692,7 @@ "type": "tidelift" } ], - "time": "2022-12-09T07:31:23+00:00" - }, - { - "name": "psr/cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" - }, - "time": "2021-02-03T23:26:27+00:00" + "time": "2023-10-26T07:21:45+00:00" }, { "name": "psr/event-dispatcher", @@ -4132,28 +3822,28 @@ }, { "name": "sebastian/cli-parser", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -4176,7 +3866,7 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" }, "funding": [ { @@ -4184,32 +3874,32 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2023-02-03T06:58:15+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -4232,7 +3922,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, "funding": [ { @@ -4240,32 +3930,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -4287,7 +3977,7 @@ "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/2.0.3" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -4295,34 +3985,36 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -4361,7 +4053,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" }, "funding": [ { @@ -4369,33 +4062,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2023-08-14T13:18:12+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" + "nikic/php-parser": "^4.10", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.1-dev" } }, "autoload": { @@ -4418,7 +4111,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" }, "funding": [ { @@ -4426,33 +4120,33 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-09-28T11:50:59+00:00" }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^10.0", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -4484,7 +4178,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" }, "funding": [ { @@ -4492,27 +4187,27 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-01T07:48:21+00:00" }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -4520,7 +4215,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -4539,7 +4234,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -4547,7 +4242,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" }, "funding": [ { @@ -4555,34 +4251,34 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-04-11T05:39:26+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -4624,7 +4320,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" }, "funding": [ { @@ -4632,38 +4329,35 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2023-09-24T13:22:09+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -4688,7 +4382,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" }, "funding": [ { @@ -4696,33 +4391,33 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-07-19T07:19:23+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" + "nikic/php-parser": "^4.10", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -4745,7 +4440,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" }, "funding": [ { @@ -4753,34 +4449,34 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-08-31T09:25:50+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -4802,7 +4498,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -4810,32 +4506,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -4857,7 +4553,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -4865,32 +4561,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -4917,65 +4613,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -4983,32 +4624,32 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -5031,7 +4672,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -5039,29 +4680,29 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -5084,7 +4725,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -5092,7 +4733,7 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "seld/jsonlint", @@ -6295,5 +5936,5 @@ "composer-plugin-api": "^1.0 || ^2.0" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/phpunit.coverage.xml b/phpunit.coverage.xml deleted file mode 100644 index cedce8de..00000000 --- a/phpunit.coverage.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - tests/Unit - - - - - src - - - - - - - - - diff --git a/phpunit.xml b/phpunit.xml index bfbf9d28..93883c89 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,25 +1,27 @@ tests/Unit - - - src - - + + + + + + + - + + + + src + + diff --git a/src/Package/UpdateCheckResult.php b/src/Package/UpdateCheckResult.php index c1f312eb..870fc893 100644 --- a/src/Package/UpdateCheckResult.php +++ b/src/Package/UpdateCheckResult.php @@ -99,8 +99,8 @@ function (?OutdatedPackage $outdatedPackage) use ($allowedPackages) { public static function parseCommandOutput(string $output): ?OutdatedPackage { if ( - !preg_match(static::COMMAND_OUTPUT_PATTERN, $output, $matches) && - !preg_match(static::LEGACY_COMMAND_OUTPUT_PATTERN, $output, $matches) + !preg_match(static::COMMAND_OUTPUT_PATTERN, $output, $matches) + && !preg_match(static::LEGACY_COMMAND_OUTPUT_PATTERN, $output, $matches) ) { return null; } diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index bd51e3ba..1ab7e56e 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -55,9 +55,9 @@ public static function fromApiResult(array $apiResult): self { // Early return if no advisories were provided if ( - !array_key_exists('advisories', $apiResult) || - !is_array($apiResult['advisories']) || - [] === $apiResult['advisories'] + !array_key_exists('advisories', $apiResult) + || !is_array($apiResult['advisories']) + || [] === $apiResult['advisories'] ) { return new self([]); } diff --git a/tests/Unit/AbstractTestCase.php b/tests/Unit/AbstractTestCase.php index ca139c34..87cedf62 100644 --- a/tests/Unit/AbstractTestCase.php +++ b/tests/Unit/AbstractTestCase.php @@ -42,9 +42,9 @@ protected function tearDown(): void $reflection = new \ReflectionClass($this); foreach ($reflection->getProperties() as $property) { if ( - !$property->isStatic() && - !$property->isPrivate() && - 0 !== strpos($property->getDeclaringClass()->getName(), 'PHPUnit') + !$property->isStatic() + && !$property->isPrivate() + && 0 !== strpos($property->getDeclaringClass()->getName(), 'PHPUnit') ) { unset($this->{$property->getName()}); } diff --git a/tests/Unit/ExpectedCommandOutputTrait.php b/tests/Unit/ExpectedCommandOutputTrait.php index f5ebe740..4f00d21c 100644 --- a/tests/Unit/ExpectedCommandOutputTrait.php +++ b/tests/Unit/ExpectedCommandOutputTrait.php @@ -33,7 +33,7 @@ */ trait ExpectedCommandOutputTrait { - private function getExpectedCommandOutput(string $package = null, string $outdated = null, string $new = null): string + private static function getExpectedCommandOutput(string $package = null, string $outdated = null, string $new = null): string { $isLegacyPlatform = Composer::getMajorVersion() < 2; $output = $isLegacyPlatform ? ' - Updating' : ' - Upgrading'; diff --git a/tests/Unit/IO/StyleTest.php b/tests/Unit/IO/StyleTest.php index 6808c226..fe10a9f8 100644 --- a/tests/Unit/IO/StyleTest.php +++ b/tests/Unit/IO/StyleTest.php @@ -104,7 +104,7 @@ public function getStyleReturnsStyle(): void /** * @return \Generator */ - public function isReturnsTrueIfGivenStyleEqualsStyleDataProvider(): \Generator + public static function isReturnsTrueIfGivenStyleEqualsStyleDataProvider(): \Generator { yield 'normal style' => [Style::NORMAL]; yield 'json style' => [Style::JSON]; diff --git a/tests/Unit/IO/VerbosityTest.php b/tests/Unit/IO/VerbosityTest.php index abf6cc04..59a68e89 100644 --- a/tests/Unit/IO/VerbosityTest.php +++ b/tests/Unit/IO/VerbosityTest.php @@ -133,7 +133,7 @@ public function getLevelReturnsVerbosityLevel(): void /** * @return \Generator */ - public function isReturnsTrueIfGivenVerbosityEqualsVerbosityDataProvider(): \Generator + public static function isReturnsTrueIfGivenVerbosityEqualsVerbosityDataProvider(): \Generator { yield 'quiet level' => [Verbosity::QUIET]; yield 'normal level' => [Verbosity::NORMAL]; diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index c0961ae4..d83500c8 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -95,8 +95,8 @@ public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdate public function fromCommandOutputExcludesNonAllowedPackagesFromResult(): void { $output = implode(PHP_EOL, [ - $this->getExpectedCommandOutput('dummy/package', 'dev-master 12345', 'dev-master 67890'), - $this->getExpectedCommandOutput('foo/baz', '1.0.0', '1.0.5'), + self::getExpectedCommandOutput('dummy/package', 'dev-master 12345', 'dev-master 67890'), + self::getExpectedCommandOutput('foo/baz', '1.0.0', '1.0.5'), ]); $allowedPackages = [ 'foo/baz', @@ -124,7 +124,7 @@ public function parseCommandOutputParsesCommandOutputCorrectly(string $commandOu /** * @return \Generator}> */ - public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackagesDataProvider(): \Generator + public static function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackagesDataProvider(): \Generator { yield 'no output' => [ '', @@ -139,8 +139,8 @@ public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdate 'this is some dummy text', 'just ignore it', 'but these lines are important:', - $this->getExpectedCommandOutput('dummy/package', 'dev-master 12345', 'dev-master 67890'), - $this->getExpectedCommandOutput('foo/baz', '1.0.0', '1.0.5'), + self::getExpectedCommandOutput('dummy/package', 'dev-master 12345', 'dev-master 67890'), + self::getExpectedCommandOutput('foo/baz', '1.0.0', '1.0.5'), 'bye', ]), [ @@ -153,7 +153,7 @@ public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdate /** * @return \Generator */ - public function parseCommandOutputParsesCommandOutputCorrectlyDataProvider(): \Generator + public static function parseCommandOutputParsesCommandOutputCorrectlyDataProvider(): \Generator { yield 'no output' => [ '', @@ -164,7 +164,7 @@ public function parseCommandOutputParsesCommandOutputCorrectlyDataProvider(): \G null, ]; yield 'matching package' => [ - $this->getExpectedCommandOutput('foo/baz', '1.0.0', '1.0.5'), + self::getExpectedCommandOutput('foo/baz', '1.0.0', '1.0.5'), new OutdatedPackage('foo/baz', '1.0.0', '1.0.5'), ]; } diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index 9b81958b..48387741 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -128,7 +128,7 @@ public function isInsecureReturnsSecurityStateOfGivenPackage(OutdatedPackage $ou /** * @return \Generator */ - public function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvidedDataProvider(): \Generator + public static function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvidedDataProvider(): \Generator { yield 'empty array' => [[]]; yield 'array without advisories' => [['foo' => 'baz']]; @@ -138,7 +138,7 @@ public function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesW /** * @return \Generator */ - public function isInsecureReturnsSecurityStateOfGivenPackageDataProvider(): \Generator + public static function isInsecureReturnsSecurityStateOfGivenPackageDataProvider(): \Generator { yield 'secure package without any insecure versions' => [ new OutdatedPackage('secure/package', '1.0.0', '1.0.1'), diff --git a/tests/Unit/Utility/InstallerTest.php b/tests/Unit/Utility/InstallerTest.php index edad4d24..3bcfa75a 100644 --- a/tests/Unit/Utility/InstallerTest.php +++ b/tests/Unit/Utility/InstallerTest.php @@ -95,21 +95,21 @@ public function runUpdateExecutesDryRunUpdate(array $packages, string $expected, /** * @return \Generator */ - public function runUpdateExecutesDryRunUpdateDataProvider(): \Generator + public static function runUpdateExecutesDryRunUpdateDataProvider(): \Generator { yield 'no explicit whitelist' => [ [], - $this->getExpectedCommandOutput(), + self::getExpectedCommandOutput(), ]; yield 'symfony/console only' => [ ['symfony/console'], - $this->getExpectedCommandOutput('symfony/console'), - $this->getExpectedCommandOutput('symfony/http-kernel'), + self::getExpectedCommandOutput('symfony/console'), + self::getExpectedCommandOutput('symfony/http-kernel'), ]; yield 'symfony/http-kernel only' => [ ['symfony/http-kernel'], - $this->getExpectedCommandOutput('symfony/http-kernel'), - $this->getExpectedCommandOutput('symfony/console'), + self::getExpectedCommandOutput('symfony/http-kernel'), + self::getExpectedCommandOutput('symfony/console'), ]; } From 4a28dd0b318c2720769bc773fc51707ea234df9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 09:56:47 +0100 Subject: [PATCH 003/286] [!!!][TASK] Drop support for PHP < 8.1 --- .github/workflows/cgl.yaml | 4 +- .github/workflows/tests.yaml | 8 +- Dockerfile | 2 +- composer.json | 2 +- composer.lock | 4 +- docs/install.md | 2 +- tests/Build/test-application/v7/composer.json | 14 - tests/Build/test-application/v7/composer.lock | 3817 ----------------- 8 files changed, 9 insertions(+), 3844 deletions(-) delete mode 100644 tests/Build/test-application/v7/composer.json delete mode 100644 tests/Build/test-application/v7/composer.lock diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index d596da2e..2c98c7d5 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -4,8 +4,6 @@ on: branches: - main pull_request: - branches: - - '**' jobs: cgl: @@ -19,7 +17,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.2 tools: composer:v2, composer-require-checker, composer-unused # Validation diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 59c1850e..874c0fe2 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,8 +4,6 @@ on: branches: - main pull_request: - branches: - - '**' jobs: # Job: Run unit tests @@ -15,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["7.1", "7.2", "7.3", "7.4", "8.0", "8.1"] + php-version: ["8.1", "8.2", "8.3"] composer-version: ["1", "2"] dependencies: ["highest", "lowest"] steps: @@ -63,7 +61,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.3 tools: composer:v2 coverage: pcov @@ -103,7 +101,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["7.1", "7.2", "7.3", "7.4", "8.0", "8.1"] + php-version: ["8.1", "8.2", "8.3"] composer-version: ["1", "2"] steps: - uses: actions/checkout@v3 diff --git a/Dockerfile b/Dockerfile index d615e611..f301e1a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG PHP_VERSION=7.4 +ARG PHP_VERSION=8.1 FROM php:${PHP_VERSION}-alpine LABEL maintainer="Elias Häußler " diff --git a/composer.json b/composer.json index 1b211b5c..daefc6fd 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "rss": "https://github.com/eliashaeussler/composer-update-check/releases.atom" }, "require": { - "php": ">= 7.1 < 8.2", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "ext-json": "*", "composer-plugin-api": "^1.0 || ^2.0", "nyholm/psr7": "^1.0", diff --git a/composer.lock b/composer.lock index 89b32d94..e8f84a2e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8ba21e3e76b6620add8085fbdb332a43", + "content-hash": "13ee0f51cd1714a04f6252723ff264d7", "packages": [ { "name": "nyholm/psr7", @@ -5931,7 +5931,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">= 7.1 < 8.2", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "ext-json": "*", "composer-plugin-api": "^1.0 || ^2.0" }, diff --git a/docs/install.md b/docs/install.md index ddeb316c..f220784b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,7 +2,7 @@ ## Requirements -* PHP 7.1+ +* PHP >= 8.1 * Composer v1 or v2 ## Installation diff --git a/tests/Build/test-application/v7/composer.json b/tests/Build/test-application/v7/composer.json deleted file mode 100644 index a32c2fbd..00000000 --- a/tests/Build/test-application/v7/composer.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "require": { - "symfony/console": "^4.4", - "symfony/http-kernel": "^4.4" - }, - "require-dev": { - "codeception/codeception": "^4.1" - }, - "config": { - "allow-plugins": { - "eliashaeussler/composer-update-check": true - } - } -} diff --git a/tests/Build/test-application/v7/composer.lock b/tests/Build/test-application/v7/composer.lock deleted file mode 100644 index 394ff4cf..00000000 --- a/tests/Build/test-application/v7/composer.lock +++ /dev/null @@ -1,3817 +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": "2896851cbc2f2f05032159b969d20c2d", - "packages": [ - { - "name": "psr/container", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://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/master" - }, - "time": "2017-02-14T16:28:37+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "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/1.1.4" - }, - "time": "2021-05-03T11:20:27+00:00" - }, - { - "name": "symfony/console", - "version": "v4.4.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "326b064d804043005526f5a0494cfb49edb59bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/326b064d804043005526f5a0494cfb49edb59bb0", - "reference": "326b064d804043005526f5a0494cfb49edb59bb0", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", - "symfony/lock": "<4.4", - "symfony/process": "<3.3" - }, - "provide": { - "psr/log-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "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": "Symfony Console Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/console/tree/4.4" - }, - "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": "2020-05-30T20:06:45+00:00" - }, - { - "name": "symfony/debug", - "version": "v4.4.41", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "6637e62480b60817b9a6984154a533e8e64c6bd5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/6637e62480b60817b9a6984154a533e8e64c6bd5", - "reference": "6637e62480b60817b9a6984154a533e8e64c6bd5", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/log": "^1|^2|^3" - }, - "conflict": { - "symfony/http-kernel": "<3.4" - }, - "require-dev": { - "symfony/http-kernel": "^3.4|^4.0|^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "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 tools to ease debugging PHP code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/debug/tree/v4.4.41" - }, - "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": "2022-04-12T15:19:55+00:00" - }, - { - "name": "symfony/error-handler", - "version": "v4.4.41", - "source": { - "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "529feb0e03133dbd5fd3707200147cc4903206da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/529feb0e03133dbd5fd3707200147cc4903206da", - "reference": "529feb0e03133dbd5fd3707200147cc4903206da", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/log": "^1|^2|^3", - "symfony/debug": "^4.4.5", - "symfony/var-dumper": "^4.4|^5.0" - }, - "require-dev": { - "symfony/http-kernel": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\ErrorHandler\\": "" - }, - "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 tools to manage errors and ease debugging PHP code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/error-handler/tree/v4.4.41" - }, - "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": "2022-04-12T15:19:55+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v4.4.37", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", - "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "symfony/dependency-injection": "<3.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/error-handler": "~3.4|~4.4", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "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 tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.37" - }, - "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": "2022-01-02T09:41:36+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.12", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/1d5cd762abaa6b2a4169d3e77610193a7157129e", - "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e", - "shasum": "" - }, - "require": { - "php": ">=7.1.3" - }, - "suggest": { - "psr/event-dispatcher": "", - "symfony/event-dispatcher-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "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 dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.12" - }, - "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": "2022-01-02T09:41:36+00:00" - }, - { - "name": "symfony/http-foundation", - "version": "v4.4.41", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "27441220aebeb096b4eb8267acaaa7feb5e4266c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/27441220aebeb096b4eb8267acaaa7feb5e4266c", - "reference": "27441220aebeb096b4eb8267acaaa7feb5e4266c", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/mime": "^4.3|^5.0", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/expression-language": "^3.4|^4.0|^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "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": "Defines an object-oriented layer for the HTTP specification", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-foundation/tree/v4.4.41" - }, - "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": "2022-04-21T07:22:34+00:00" - }, - { - "name": "symfony/http-kernel", - "version": "v4.4.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/54526b598d7fc86a67850488b194a88a79ab8467", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/error-handler": "^4.4", - "symfony/event-dispatcher": "^4.4", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "symfony/browser-kit": "<4.3", - "symfony/config": "<3.4", - "symfony/console": ">=5", - "symfony/dependency-injection": "<4.3", - "symfony/translation": "<4.2", - "twig/twig": "<1.34|<2.4,>=2" - }, - "provide": { - "psr/log-implementation": "1.0" - }, - "require-dev": { - "psr/cache": "~1.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^4.3|^5.0", - "symfony/dom-crawler": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/routing": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.34|^2.4|^3.0" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "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": "Symfony HttpKernel Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-kernel/tree/v4.4.9" - }, - "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": "2020-05-31T05:25:51+00:00" - }, - { - "name": "symfony/mime", - "version": "v4.4.41", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "5b05a62a714bb7e8ba1ce7412f7442debe67c291" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/5b05a62a714bb7e8ba1ce7412f7442debe67c291", - "reference": "5b05a62a714bb7e8ba1ce7412f7442debe67c291", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "symfony/mailer": "<4.4" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", - "symfony/dependency-injection": "^3.4|^4.1|^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mime\\": "" - }, - "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 manipulating MIME messages", - "homepage": "https://symfony.com", - "keywords": [ - "mime", - "mime-type" - ], - "support": { - "source": "https://github.com/symfony/mime/tree/v4.4.41" - }, - "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": "2022-04-12T15:19:55+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-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.25.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": "2021-10-20T20:35:02+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "749045c69efb97c70d25d7463abba812e91f3a44" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44", - "reference": "749045c69efb97c70d25d7463abba812e91f3a44", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.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": "2021-09-14T14:02:44+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-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.25.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": "2021-02-19T12:13:01+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-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.25.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": "2021-11-30T18:21:41+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "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 backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.25.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": "2021-05-27T09:17:38+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "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 backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.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": "2021-06-05T21:20:04+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.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": "2022-03-04T08:16:47+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v1.1.12", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "eedb374f02031714a48848758a27812f3eca317a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/eedb374f02031714a48848758a27812f3eca317a", - "reference": "eedb374f02031714a48848758a27812f3eca317a", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/container": "^1.0" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } - }, - "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/v1.1.12" - }, - "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": "2022-03-09T13:39:03+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v4.4.41", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "58eb36075c04aaf92a7a9f38ee9a8b97e24eb481" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/58eb36075c04aaf92a7a9f38ee9a8b97e24eb481", - "reference": "58eb36075c04aaf92a7a9f38ee9a8b97e24eb481", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/console": "<3.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/process": "^4.4|^5.0", - "twig/twig": "^1.43|^2.13|^3.0.4" - }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "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 mechanisms for walking through any arbitrary PHP variable", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.41" - }, - "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": "2022-04-25T21:15:06+00:00" - } - ], - "packages-dev": [ - { - "name": "behat/gherkin", - "version": "v4.7.3", - "source": { - "type": "git", - "url": "https://github.com/Behat/Gherkin.git", - "reference": "d5ae4616aeaa91daadbfb8446d9d17aae8d43cf7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/d5ae4616aeaa91daadbfb8446d9d17aae8d43cf7", - "reference": "d5ae4616aeaa91daadbfb8446d9d17aae8d43cf7", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "cucumber/cucumber": "dev-gherkin-16.0.0", - "phpunit/phpunit": "^5.7.1|~6|~7", - "symfony/phpunit-bridge": "~2.7|~3|~4", - "symfony/yaml": "~2.3|~3|~4" - }, - "suggest": { - "symfony/yaml": "If you want to parse features, represented in YAML files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Gherkin": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Gherkin DSL parser for PHP", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "Cucumber", - "DSL", - "gherkin", - "parser" - ], - "support": { - "issues": "https://github.com/Behat/Gherkin/issues", - "source": "https://github.com/Behat/Gherkin/tree/v4.7.3" - }, - "time": "2021-02-04T12:26:47+00:00" - }, - { - "name": "codeception/codeception", - "version": "4.1.9", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "5782e342b978a3efd0b7a776b7808902840b8213" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/5782e342b978a3efd0b7a776b7808902840b8213", - "reference": "5782e342b978a3efd0b7a776b7808902840b8213", - "shasum": "" - }, - "require": { - "behat/gherkin": "^4.4.0", - "codeception/lib-asserts": "^1.0", - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0", - "codeception/stub": "^2.0 | ^3.0", - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "guzzlehttp/psr7": "~1.4", - "php": ">=5.6.0 <9.0", - "symfony/console": ">=2.7 <6.0", - "symfony/css-selector": ">=2.7 <6.0", - "symfony/event-dispatcher": ">=2.7 <6.0", - "symfony/finder": ">=2.7 <6.0", - "symfony/yaml": ">=2.7 <6.0" - }, - "require-dev": { - "codeception/module-asserts": "*@dev", - "codeception/module-cli": "*@dev", - "codeception/module-db": "*@dev", - "codeception/module-filesystem": "*@dev", - "codeception/module-phpbrowser": "*@dev", - "codeception/specify": "~0.3", - "codeception/util-universalframework": "*@dev", - "monolog/monolog": "~1.8", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": ">=2.7 <6.0", - "vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0" - }, - "suggest": { - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "hoa/console": "For interactive console functionality", - "stecman/symfony-console-completion": "For BASH autocompletion", - "symfony/phpunit-bridge": "For phpunit-bridge support" - }, - "bin": [ - "codecept" - ], - "type": "library", - "extra": { - "branch-alias": [] - }, - "autoload": { - "psr-4": { - "Codeception\\": "src/Codeception", - "Codeception\\Extension\\": "ext" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - } - ], - "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", - "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" - ], - "support": { - "issues": "https://github.com/Codeception/Codeception/issues", - "source": "https://github.com/Codeception/Codeception/tree/4.1.9" - }, - "funding": [ - { - "url": "https://opencollective.com/codeception", - "type": "open_collective" - } - ], - "time": "2020-10-23T17:59:47+00:00" - }, - { - "name": "codeception/lib-asserts", - "version": "1.13.2", - "source": { - "type": "git", - "url": "https://github.com/Codeception/lib-asserts.git", - "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/184231d5eab66bc69afd6b9429344d80c67a33b6", - "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6", - "shasum": "" - }, - "require": { - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.0.3 | ^9.0", - "ext-dom": "*", - "php": ">=5.6.0 <9.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - }, - { - "name": "Gintautas Miselis" - }, - { - "name": "Gustavo Nieves", - "homepage": "https://medium.com/@ganieves" - } - ], - "description": "Assertion methods used by Codeception core and Asserts module", - "homepage": "https://codeception.com/", - "keywords": [ - "codeception" - ], - "support": { - "issues": "https://github.com/Codeception/lib-asserts/issues", - "source": "https://github.com/Codeception/lib-asserts/tree/1.13.2" - }, - "time": "2020-10-21T16:26:20+00:00" - }, - { - "name": "codeception/phpunit-wrapper", - "version": "7.8.2", - "source": { - "type": "git", - "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "cafed18048826790c527843f9b85e8cc79b866f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/cafed18048826790c527843f9b85e8cc79b866f1", - "reference": "cafed18048826790c527843f9b85e8cc79b866f1", - "shasum": "" - }, - "require": { - "phpunit/php-code-coverage": "^6.0", - "phpunit/phpunit": "7.5.*", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0" - }, - "require-dev": { - "codeception/specify": "*", - "vlucas/phpdotenv": "^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\PHPUnit\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Davert", - "email": "davert.php@resend.cc" - } - ], - "description": "PHPUnit classes used by Codeception", - "support": { - "issues": "https://github.com/Codeception/phpunit-wrapper/issues", - "source": "https://github.com/Codeception/phpunit-wrapper/tree/7.8.2" - }, - "time": "2020-12-28T14:00:26+00:00" - }, - { - "name": "codeception/stub", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Stub.git", - "reference": "eea518711d736eab838c1274593c4568ec06b23d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Stub/zipball/eea518711d736eab838c1274593c4568ec06b23d", - "reference": "eea518711d736eab838c1274593c4568ec06b23d", - "shasum": "" - }, - "require": { - "codeception/phpunit-wrapper": "^6.6.1 | ^7.7.1 | ^8.0.3", - "phpunit/phpunit": ">=6.5 <9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", - "support": { - "issues": "https://github.com/Codeception/Stub/issues", - "source": "https://github.com/Codeception/Stub/tree/master" - }, - "time": "2019-08-10T16:20:53+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.8.5", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/337e3ad8e5716c15f9657bd214d16cc5e69df268", - "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.5" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", - "type": "tidelift" - } - ], - "time": "2022-03-20T21:51:18+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "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.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/master" - }, - "time": "2018-07-08T19:23:20+00:00" - }, - { - "name": "phar-io/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.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/master" - }, - "time": "2018-07-08T19:19:57+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", - "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master" - }, - "time": "2020-04-27T09:25:28+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpdocumentor/type-resolver": "0.4.*", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x" - }, - "time": "2019-12-28T18:55:12+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "shasum": "" - }, - "require": { - "php": "^7.1", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/0.7.2" - }, - "time": "2019-08-22T18:11:29+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, - "time": "2020-03-05T15:02:03+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "6.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-xdebug": "^2.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" - }, - "time": "2018-10-31T16:06:48+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "2.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:42:26+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "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", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "2.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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": "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/2.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:20:02+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "abandoned": true, - "time": "2021-07-26T12:15:06+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "7.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.5-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": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" - }, - "time": "2020-01-08T08:45:45+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-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/1.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:15:22+00:00" - }, - { - "name": "sebastian/comparator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:04:30+00:00" - }, - { - "name": "sebastian/diff", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-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", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:59:04+00:00" - }, - { - "name": "sebastian/environment", - "version": "4.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:53:42+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-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": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-11-11T13:51:24+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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", - "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" - }, - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-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/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:40:27+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-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/1.1.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:37:18+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:34:24+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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 a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:30:19+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "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": "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/master" - }, - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v4.4.37", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "0628e6c6d7c92f1a7bae543959bdc17347be2436" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/0628e6c6d7c92f1a7bae543959bdc17347be2436", - "reference": "0628e6c6d7c92f1a7bae543959bdc17347be2436", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Converts CSS selectors to XPath expressions", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v4.4.37" - }, - "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": "2022-01-02T09:41:36+00:00" - }, - { - "name": "symfony/finder", - "version": "v4.4.41", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "40790bdf293b462798882ef6da72bb49a4a6633a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/40790bdf293b462798882ef6da72bb49a4a6633a", - "reference": "40790bdf293b462798882ef6da72bb49a4a6633a", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "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": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v4.4.41" - }, - "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": "2022-04-14T15:36:10+00:00" - }, - { - "name": "symfony/yaml", - "version": "v4.4.37", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d7f637cc0f0cc14beb0984f2bb50da560b271311", - "reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<3.4" - }, - "require-dev": { - "symfony/console": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "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/v4.4.37" - }, - "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": "2022-01-24T20:11:01+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.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/master" - }, - "time": "2019-06-13T22:48:21+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" - }, - "time": "2020-07-08T17:02:28+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" -} From 4ffd29b81d298140e79439286482dd94c3b1cbb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 10:04:23 +0100 Subject: [PATCH 004/286] [!!!][TASK] Drop support for Composer v1 --- .github/workflows/cgl.yaml | 2 +- .github/workflows/docker.yaml | 5 ---- .github/workflows/tests.yaml | 4 +-- composer.json | 6 ++-- composer.lock | 54 ++++++++++++++++++----------------- docs/docker.md | 2 -- docs/install.md | 2 +- 7 files changed, 35 insertions(+), 40 deletions(-) diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index 2c98c7d5..8dd495db 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -26,7 +26,7 @@ jobs: # Install dependencies - name: Add required packages - run: composer require composer/composer:"^1.7 || ^2.0" composer/semver:"^1.0 || ^2.0 || ^3.0" --no-update + run: composer require composer/composer:"^2.0" composer/semver:"^3.0" --no-update - name: Install Composer dependencies uses: ramsey/composer-install@v2 with: diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 0402fb7f..0ab12b29 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -12,11 +12,6 @@ jobs: strategy: matrix: include: - - composer-version: 1 - tags: | - type=semver,pattern={{version}}-v1 - type=raw,value=v1 - latest: false - composer-version: 2 tags: | type=semver,pattern={{version}}-v2 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 874c0fe2..e03a61b5 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: php-version: ["8.1", "8.2", "8.3"] - composer-version: ["1", "2"] + composer-version: ["2"] dependencies: ["highest", "lowest"] steps: - uses: actions/checkout@v3 @@ -102,7 +102,7 @@ jobs: fail-fast: false matrix: php-version: ["8.1", "8.2", "8.3"] - composer-version: ["1", "2"] + composer-version: ["2"] steps: - uses: actions/checkout@v3 with: diff --git a/composer.json b/composer.json index daefc6fd..a5279015 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "require": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "ext-json": "*", - "composer-plugin-api": "^1.0 || ^2.0", + "composer-plugin-api": "^2.0", "nyholm/psr7": "^1.0", "psr/http-client": "^1.0", "psr/http-message": "^1.0", @@ -31,8 +31,8 @@ }, "require-dev": { "armin/editorconfig-cli": "^1.5", - "composer/composer": "^1.7 || ^2.0", - "composer/semver": "^1.0 || ^2.0 || ^3.0", + "composer/composer": "^2.0", + "composer/semver": "^3.0", "ergebnis/composer-normalize": "^2.8", "friendsofphp/php-cs-fixer": "^3.39", "php-http/discovery": "^1.14", diff --git a/composer.lock b/composer.lock index e8f84a2e..0418eba7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "13ee0f51cd1714a04f6252723ff264d7", + "content-hash": "553c5d5869e16a6fce97efd9fcd64839", "packages": [ { "name": "nyholm/psr7", @@ -1573,47 +1573,48 @@ }, { "name": "composer/composer", - "version": "2.4.4", + "version": "2.6.5", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "e8d9087229bcdbc5867594d3098091412f1130cf" + "reference": "4b0fe89db9e65b1e64df633a992e70a7a215ab33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/e8d9087229bcdbc5867594d3098091412f1130cf", - "reference": "e8d9087229bcdbc5867594d3098091412f1130cf", + "url": "https://api.github.com/repos/composer/composer/zipball/4b0fe89db9e65b1e64df633a992e70a7a215ab33", + "reference": "4b0fe89db9e65b1e64df633a992e70a7a215ab33", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/class-map-generator": "^1.0", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^2 || ^3", - "composer/semver": "^3.0", + "composer/pcre": "^2.1 || ^3.1", + "composer/semver": "^3.2.5", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", "justinrainbow/json-schema": "^5.2.11", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^2.8", + "react/promise": "^2.8 || ^3", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", - "symfony/console": "^5.4.11 || ^6.0.11", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", + "symfony/console": "^5.4.11 || ^6.0.11 || ^7", + "symfony/filesystem": "^5.4 || ^6.0 || ^7", + "symfony/finder": "^5.4 || ^6.0 || ^7", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", - "symfony/process": "^5.4 || ^6.0" + "symfony/polyfill-php81": "^1.24", + "symfony/process": "^5.4 || ^6.0 || ^7" }, "require-dev": { - "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan": "^1.9.3", "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-strict-rules": "^1", "phpstan/phpstan-symfony": "^1.2.10", - "symfony/phpunit-bridge": "^6.0" + "symfony/phpunit-bridge": "^6.0 || ^7" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -1626,7 +1627,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.6-dev" }, "phpstan": { "includes": [ @@ -1636,7 +1637,7 @@ }, "autoload": { "psr-4": { - "Composer\\": "src/Composer" + "Composer\\": "src/Composer/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1665,7 +1666,8 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.4.4" + "security": "https://github.com/composer/composer/security/policy", + "source": "https://github.com/composer/composer/tree/2.6.5" }, "funding": [ { @@ -1681,7 +1683,7 @@ "type": "tidelift" } ], - "time": "2022-10-27T12:39:29+00:00" + "time": "2023-10-06T08:11:52+00:00" }, { "name": "composer/metadata-minifier", @@ -1825,16 +1827,16 @@ }, { "name": "composer/semver", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", "shasum": "" }, "require": { @@ -1884,9 +1886,9 @@ "versioning" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" + "source": "https://github.com/composer/semver/tree/3.4.0" }, "funding": [ { @@ -1902,7 +1904,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T19:23:25+00:00" + "time": "2023-08-31T09:50:34+00:00" }, { "name": "composer/spdx-licenses", @@ -5933,7 +5935,7 @@ "platform": { "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "ext-json": "*", - "composer-plugin-api": "^1.0 || ^2.0" + "composer-plugin-api": "^2.0" }, "platform-dev": [], "plugin-api-version": "2.6.0" diff --git a/docs/docker.md b/docs/docker.md index 90817b54..6f780b64 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -18,8 +18,6 @@ Composer version you're using in your project: | `eliashaeussler/composer-update-check:latest` | v2 | latest | | `eliashaeussler/composer-update-check:-v2` | v2 | `` | | `eliashaeussler/composer-update-check:v2` | v2 | latest | -| `eliashaeussler/composer-update-check:-v1` | v1 | `` | -| `eliashaeussler/composer-update-check:v1` | v1 | latest | ## Usage diff --git a/docs/install.md b/docs/install.md index f220784b..fa26e98b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -3,7 +3,7 @@ ## Requirements * PHP >= 8.1 -* Composer v1 or v2 +* Composer v2 ## Installation From 3c174f281d965c32a4d2b3e78b3a4c4aa25af66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:12:42 +0100 Subject: [PATCH 005/286] [!!!][TASK] Drop Symfony < 5.4 --- composer.json | 4 ++-- composer.lock | 42 ++++++++++++++++++++---------------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index a5279015..0d5d0cd4 100644 --- a/composer.json +++ b/composer.json @@ -26,8 +26,8 @@ "psr/http-client": "^1.0", "psr/http-message": "^1.0", "spatie/emoji": "^2.0 || ^3.0 || ^4.0", - "symfony/console": "^4.4.11 || ^5.0.11 || ^6.0", - "symfony/http-client": "^4.4.11 || ^5.0.11 || ^6.0" + "symfony/console": "^5.4 || ^6.0", + "symfony/http-client": "^5.4 || ^6.0" }, "require-dev": { "armin/editorconfig-cli": "^1.5", diff --git a/composer.lock b/composer.lock index 0418eba7..c9de0253 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "553c5d5869e16a6fce97efd9fcd64839", + "content-hash": "82954818949b123571cb1f4c01371842", "packages": [ { "name": "nyholm/psr7", @@ -468,23 +468,23 @@ }, { "name": "symfony/console", - "version": "v6.2.2", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5a9bd5c543f00157c55face973c149957467db31" + "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5a9bd5c543f00157c55face973c149957467db31", - "reference": "5a9bd5c543f00157c55face973c149957467db31", + "url": "https://api.github.com/repos/symfony/console/zipball/0d14a9f6d04d4ac38a8cea1171f4554e325dae92", + "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/string": "^5.4|^6.0" }, "conflict": { @@ -506,12 +506,6 @@ "symfony/process": "^5.4|^6.0", "symfony/var-dumper": "^5.4|^6.0" }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, "type": "library", "autoload": { "psr-4": { @@ -539,12 +533,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.2.2" + "source": "https://github.com/symfony/console/tree/v6.3.8" }, "funding": [ { @@ -560,7 +554,7 @@ "type": "tidelift" } ], - "time": "2022-12-16T15:08:36+00:00" + "time": "2023-10-31T08:09:35+00:00" }, { "name": "symfony/deprecation-contracts", @@ -631,16 +625,16 @@ }, { "name": "symfony/http-client", - "version": "v6.2.0", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "153540b6ed72eecdcb42dc847f8d8cf2e2516e8e" + "reference": "297374a399ce6852d5905d92a1351df00bb9dd10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/153540b6ed72eecdcb42dc847f8d8cf2e2516e8e", - "reference": "153540b6ed72eecdcb42dc847f8d8cf2e2516e8e", + "url": "https://api.github.com/repos/symfony/http-client/zipball/297374a399ce6852d5905d92a1351df00bb9dd10", + "reference": "297374a399ce6852d5905d92a1351df00bb9dd10", "shasum": "" }, "require": { @@ -664,6 +658,7 @@ "guzzlehttp/promises": "^1.4", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0", @@ -695,8 +690,11 @@ ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", + "keywords": [ + "http" + ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.2.0" + "source": "https://github.com/symfony/http-client/tree/v6.2.13" }, "funding": [ { @@ -712,7 +710,7 @@ "type": "tidelift" } ], - "time": "2022-11-14T10:13:36+00:00" + "time": "2023-07-03T12:13:45+00:00" }, { "name": "symfony/http-client-contracts", From ccf9ba4b8f3b54049b889edda18ec2d477d6d4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:17:18 +0100 Subject: [PATCH 006/286] [TASK] Allow psr/http-message ^2.0 and ^3.0 --- composer.json | 11 +- composer.lock | 293 +++++++++++++++++++------------------------------- 2 files changed, 118 insertions(+), 186 deletions(-) diff --git a/composer.json b/composer.json index 0d5d0cd4..0cd3a24a 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "composer-plugin-api": "^2.0", "nyholm/psr7": "^1.0", "psr/http-client": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0 || ^2.0 || ^3.0", "spatie/emoji": "^2.0 || ^3.0 || ^4.0", "symfony/console": "^5.4 || ^6.0", "symfony/http-client": "^5.4 || ^6.0" @@ -35,9 +35,9 @@ "composer/semver": "^3.0", "ergebnis/composer-normalize": "^2.8", "friendsofphp/php-cs-fixer": "^3.39", - "php-http/discovery": "^1.14", - "php-http/httplug": "^2.0", - "php-http/mock-client": "^1.3", + "php-http/discovery": "^1.19", + "php-http/httplug": "^2.4", + "php-http/mock-client": "^1.6", "phpstan/phpstan": "^1.2", "phpunit/phpunit": "^10.4", "symfony/filesystem": ">= 4.4 < 7.0" @@ -54,7 +54,8 @@ }, "config": { "allow-plugins": { - "ergebnis/composer-normalize": true + "ergebnis/composer-normalize": true, + "php-http/discovery": true }, "sort-packages": true }, diff --git a/composer.lock b/composer.lock index c9de0253..accd32a4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,42 +4,43 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "82954818949b123571cb1f4c01371842", + "content-hash": "9c95da885f45222063490b485936c153", "packages": [ { "name": "nyholm/psr7", - "version": "1.5.1", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "f734364e38a876a23be4d906a2a089e1315be18a" + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/f734364e38a876a23be4d906a2a089e1315be18a", - "reference": "f734364e38a876a23be4d906a2a089e1315be18a", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", "shasum": "" }, "require": { - "php": ">=7.1", - "php-http/message-factory": "^1.0", + "php": ">=7.2", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.1 || ^2.0" }, "provide": { + "php-http/message-factory-implementation": "1.0", "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", "php-http/psr7-integration-tests": "^1.0", - "phpunit/phpunit": "^7.5 || 8.5 || 9.4", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", "symfony/error-handler": "^4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.8-dev" } }, "autoload": { @@ -69,7 +70,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.5.1" + "source": "https://github.com/Nyholm/psr7/tree/1.8.1" }, "funding": [ { @@ -81,61 +82,7 @@ "type": "github" } ], - "time": "2022-06-22T07:13:36+00:00" - }, - { - "name": "php-http/message-factory", - "version": "v1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-http/message-factory.git", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Factory interfaces for PSR-7 HTTP Message", - "homepage": "http://php-http.org", - "keywords": [ - "factory", - "http", - "message", - "stream", - "uri" - ], - "support": { - "issues": "https://github.com/php-http/message-factory/issues", - "source": "https://github.com/php-http/message-factory/tree/master" - }, - "time": "2015-12-19T14:08:53+00:00" + "time": "2023-11-13T09:31:12+00:00" }, { "name": "psr/container", @@ -192,21 +139,21 @@ }, { "name": "psr/http-client", - "version": "1.0.1", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -226,7 +173,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", @@ -238,27 +185,27 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "source": "https://github.com/php-fig/http-client" }, - "time": "2020-06-29T06:28:15+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { "php": ">=7.0.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -278,7 +225,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for PSR-7 HTTP message factories", @@ -293,31 +240,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" }, - "time": "2019-04-30T12:38:16+00:00" + "time": "2023-04-10T20:10:41+00:00" }, { "name": "psr/http-message", - "version": "1.0.1", + "version": "2.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -332,7 +279,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -346,9 +293,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { "name": "psr/log", @@ -2812,26 +2759,25 @@ }, { "name": "php-http/client-common", - "version": "2.6.0", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/php-http/client-common.git", - "reference": "45db684cd4e186dcdc2b9c06b22970fe123796c0" + "reference": "880509727a447474d2a71b7d7fa5d268ddd3db4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/client-common/zipball/45db684cd4e186dcdc2b9c06b22970fe123796c0", - "reference": "45db684cd4e186dcdc2b9c06b22970fe123796c0", + "url": "https://api.github.com/repos/php-http/client-common/zipball/880509727a447474d2a71b7d7fa5d268ddd3db4b", + "reference": "880509727a447474d2a71b7d7fa5d268ddd3db4b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "php-http/httplug": "^2.0", "php-http/message": "^1.6", - "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0 || ^2.0", "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0", "symfony/polyfill-php80": "^1.17" }, @@ -2841,7 +2787,7 @@ "nyholm/psr7": "^1.2", "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", "phpspec/prophecy": "^1.10.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + "phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7" }, "suggest": { "ext-json": "To detect JSON responses with the ContentTypePlugin", @@ -2851,11 +2797,6 @@ "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, "autoload": { "psr-4": { "Http\\Client\\Common\\": "src/" @@ -2881,49 +2822,59 @@ ], "support": { "issues": "https://github.com/php-http/client-common/issues", - "source": "https://github.com/php-http/client-common/tree/2.6.0" + "source": "https://github.com/php-http/client-common/tree/2.7.0" }, - "time": "2022-09-29T09:59:43+00:00" + "time": "2023-05-17T06:46:59+00:00" }, { "name": "php-http/discovery", - "version": "1.14.3", + "version": "1.19.1", "source": { "type": "git", "url": "https://github.com/php-http/discovery.git", - "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735" + "reference": "57f3de01d32085fea20865f9b16fb0e69347c39e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735", - "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735", + "url": "https://api.github.com/repos/php-http/discovery/zipball/57f3de01d32085fea20865f9b16fb0e69347c39e", + "reference": "57f3de01d32085fea20865f9b16fb0e69347c39e", "shasum": "" }, "require": { + "composer-plugin-api": "^1.0|^2.0", "php": "^7.1 || ^8.0" }, "conflict": { - "nyholm/psr7": "<1.0" + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" }, "require-dev": { + "composer/composer": "^1.0.2|^2.0", "graham-campbell/phpspec-skip-example-extension": "^5.0", "php-http/httplug": "^1.0 || ^2.0", "php-http/message-factory": "^1.0", - "phpspec/phpspec": "^5.1 || ^6.1" - }, - "suggest": { - "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories" + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" }, - "type": "library", + "type": "composer-plugin", "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true }, "autoload": { "psr-4": { "Http\\Discovery\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2935,7 +2886,7 @@ "email": "mark.sagikazar@gmail.com" } ], - "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", "homepage": "http://php-http.org", "keywords": [ "adapter", @@ -2944,44 +2895,40 @@ "factory", "http", "message", + "psr17", "psr7" ], "support": { "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.14.3" + "source": "https://github.com/php-http/discovery/tree/1.19.1" }, - "time": "2022-07-11T14:04:40+00:00" + "time": "2023-07-11T07:02:26+00:00" }, { "name": "php-http/httplug", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/php-http/httplug.git", - "reference": "f640739f80dfa1152533976e3c112477f69274eb" + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/httplug/zipball/f640739f80dfa1152533976e3c112477f69274eb", - "reference": "f640739f80dfa1152533976e3c112477f69274eb", + "url": "https://api.github.com/repos/php-http/httplug/zipball/625ad742c360c8ac580fcc647a1541d29e257f67", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "php-http/promise": "^1.1", "psr/http-client": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.1", - "phpspec/phpspec": "^5.1 || ^6.0" + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, "autoload": { "psr-4": { "Http\\Client\\": "src/" @@ -3010,29 +2957,28 @@ ], "support": { "issues": "https://github.com/php-http/httplug/issues", - "source": "https://github.com/php-http/httplug/tree/2.3.0" + "source": "https://github.com/php-http/httplug/tree/2.4.0" }, - "time": "2022-02-21T09:52:22+00:00" + "time": "2023-04-14T15:10:03+00:00" }, { "name": "php-http/message", - "version": "1.13.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/php-http/message.git", - "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361" + "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/message/zipball/7886e647a30a966a1a8d1dad1845b71ca8678361", - "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361", + "url": "https://api.github.com/repos/php-http/message/zipball/47a14338bf4ebd67d317bf1144253d7db4ab55fd", + "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd", "shasum": "" }, "require": { "clue/stream-filter": "^1.5", - "php": "^7.1 || ^8.0", - "php-http/message-factory": "^1.0.2", - "psr/http-message": "^1.0" + "php": "^7.2 || ^8.0", + "psr/http-message": "^1.1 || ^2.0" }, "provide": { "php-http/message-factory-implementation": "1.0" @@ -3040,8 +2986,9 @@ "require-dev": { "ergebnis/composer-normalize": "^2.6", "ext-zlib": "*", - "guzzlehttp/psr7": "^1.0", - "laminas/laminas-diactoros": "^2.0", + "guzzlehttp/psr7": "^1.0 || ^2.0", + "laminas/laminas-diactoros": "^2.0 || ^3.0", + "php-http/message-factory": "^1.0.2", "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", "slim/slim": "^3.0" }, @@ -3052,11 +2999,6 @@ "slim/slim": "Used with Slim Framework PSR-7 implementation" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, "autoload": { "files": [ "src/filters.php" @@ -3084,33 +3026,32 @@ ], "support": { "issues": "https://github.com/php-http/message/issues", - "source": "https://github.com/php-http/message/tree/1.13.0" + "source": "https://github.com/php-http/message/tree/1.16.0" }, - "time": "2022-02-11T13:41:14+00:00" + "time": "2023-05-17T06:43:38+00:00" }, { "name": "php-http/mock-client", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/php-http/mock-client.git", - "reference": "a797c2a9122cccafcce14773b8a24d2808a9ab44" + "reference": "ae5d717334ecd68199667bea6e9db07276e69a2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/mock-client/zipball/a797c2a9122cccafcce14773b8a24d2808a9ab44", - "reference": "a797c2a9122cccafcce14773b8a24d2808a9ab44", + "url": "https://api.github.com/repos/php-http/mock-client/zipball/ae5d717334ecd68199667bea6e9db07276e69a2b", + "reference": "ae5d717334ecd68199667bea6e9db07276e69a2b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", "php-http/client-common": "^2.0", - "php-http/discovery": "^1.0", + "php-http/discovery": "^1.16", "php-http/httplug": "^2.0", - "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-factory-implementation": "^1.0", + "psr/http-message": "^1.0 || ^2.0", "symfony/polyfill-php80": "^1.17" }, "provide": { @@ -3119,14 +3060,9 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "phpspec/phpspec": "^5.1 || ^6.0" + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { "psr-4": { "Http\\Mock\\": "src/" @@ -3152,37 +3088,32 @@ ], "support": { "issues": "https://github.com/php-http/mock-client/issues", - "source": "https://github.com/php-http/mock-client/tree/1.5.0" + "source": "https://github.com/php-http/mock-client/tree/1.6.0" }, - "time": "2021-08-25T07:01:14+00:00" + "time": "2023-05-21T08:31:38+00:00" }, { "name": "php-http/promise", - "version": "1.1.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/php-http/promise.git", - "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" + "reference": "44a67cb59f708f826f3bec35f22030b3edb90119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", - "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "url": "https://api.github.com/repos/php-http/promise/zipball/44a67cb59f708f826f3bec35f22030b3edb90119", + "reference": "44a67cb59f708f826f3bec35f22030b3edb90119", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", - "phpspec/phpspec": "^5.1.2 || ^6.2" + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, "autoload": { "psr-4": { "Http\\Promise\\": "src/" @@ -3209,9 +3140,9 @@ ], "support": { "issues": "https://github.com/php-http/promise/issues", - "source": "https://github.com/php-http/promise/tree/1.1.0" + "source": "https://github.com/php-http/promise/tree/1.2.1" }, - "time": "2020-07-07T09:29:14+00:00" + "time": "2023-11-08T12:57:08+00:00" }, { "name": "phpstan/phpstan", From 495c52508005856d0e3f8c6394bc74118d304c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:19:45 +0100 Subject: [PATCH 007/286] [TASK] Update dev-dependencies to latest stable version --- .github/workflows/cgl.yaml | 2 +- composer.json | 10 +- composer.lock | 349 ++++++++++++++++++++++++++----------- 3 files changed, 257 insertions(+), 104 deletions(-) diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index 8dd495db..1902e59e 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -26,7 +26,7 @@ jobs: # Install dependencies - name: Add required packages - run: composer require composer/composer:"^2.0" composer/semver:"^3.0" --no-update + run: composer require composer/composer:"^2.0" composer/semver:"^3.4" --no-update - name: Install Composer dependencies uses: ramsey/composer-install@v2 with: diff --git a/composer.json b/composer.json index 0cd3a24a..f6b0c5f6 100644 --- a/composer.json +++ b/composer.json @@ -30,17 +30,17 @@ "symfony/http-client": "^5.4 || ^6.0" }, "require-dev": { - "armin/editorconfig-cli": "^1.5", + "armin/editorconfig-cli": "^1.7", "composer/composer": "^2.0", - "composer/semver": "^3.0", - "ergebnis/composer-normalize": "^2.8", + "composer/semver": "^3.4", + "ergebnis/composer-normalize": "^2.39", "friendsofphp/php-cs-fixer": "^3.39", "php-http/discovery": "^1.19", "php-http/httplug": "^2.4", "php-http/mock-client": "^1.6", - "phpstan/phpstan": "^1.2", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^10.4", - "symfony/filesystem": ">= 4.4 < 7.0" + "symfony/filesystem": "^5.4 || ^6.0" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index accd32a4..8c5a455c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9c95da885f45222063490b485936c153", + "content-hash": "4542ed17b6f7be97ab1dc5214c4e4be3", "packages": [ { "name": "nyholm/psr7", @@ -1245,32 +1245,32 @@ "packages-dev": [ { "name": "armin/editorconfig-cli", - "version": "1.5.2", + "version": "1.7.4", "source": { "type": "git", "url": "https://github.com/a-r-m-i-n/editorconfig-cli.git", - "reference": "e6bc7cc8c05a24d488c077b6dac09fc587eef761" + "reference": "f16f5e723f01d385d9900178d1de856b492a5d1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/a-r-m-i-n/editorconfig-cli/zipball/e6bc7cc8c05a24d488c077b6dac09fc587eef761", - "reference": "e6bc7cc8c05a24d488c077b6dac09fc587eef761", + "url": "https://api.github.com/repos/a-r-m-i-n/editorconfig-cli/zipball/f16f5e723f01d385d9900178d1de856b492a5d1e", + "reference": "f16f5e723f01d385d9900178d1de856b492a5d1e", "shasum": "" }, "require": { "ext-iconv": "*", "ext-json": "*", "idiosyncratic/editorconfig": "^0.1.1", - "php": "^7.3 | ^8.0", + "php": "^7.4 | ^8.0", "symfony/console": "^4 || ^5 || ^6", "symfony/finder": "^4.4 || ^5 || ^6", "symfony/mime": "^4 || ^5 || ^6" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.4", - "jangregor/phpstan-prophecy": "^1.0", - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9.5", + "friendsofphp/php-cs-fixer": "3.4.0", + "jangregor/phpstan-prophecy": "1.0.0", + "phpstan/phpstan": "1.4.0", + "phpunit/phpunit": "^9.6.8 || ^10.1", "seld/phar-utils": "^1.1" }, "bin": [ @@ -1299,7 +1299,7 @@ "issues": "https://github.com/a-r-m-i-n/editorconfig-cli/issues", "source": "https://github.com/a-r-m-i-n/editorconfig-cli" }, - "time": "2022-01-17T14:19:34+00:00" + "time": "2023-10-23T18:18:44+00:00" }, { "name": "clue/stream-filter", @@ -1999,35 +1999,40 @@ }, { "name": "ergebnis/composer-normalize", - "version": "2.29.0", + "version": "2.39.0", "source": { "type": "git", "url": "https://github.com/ergebnis/composer-normalize.git", - "reference": "fad0e99b16c625817a5bfd910e4d7e31999c53b2" + "reference": "a878360bc8cb5cb440b9381f72b0aaa125f937c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/fad0e99b16c625817a5bfd910e4d7e31999c53b2", - "reference": "fad0e99b16c625817a5bfd910e4d7e31999c53b2", + "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/a878360bc8cb5cb440b9381f72b0aaa125f937c7", + "reference": "a878360bc8cb5cb440b9381f72b0aaa125f937c7", "shasum": "" }, "require": { "composer-plugin-api": "^2.0.0", - "ergebnis/json-normalizer": "~2.1.0", - "ergebnis/json-printer": "^3.3.0", + "ergebnis/json": "^1.1.0", + "ergebnis/json-normalizer": "^4.3.0", + "ergebnis/json-printer": "^3.4.0", + "ext-json": "*", "justinrainbow/json-schema": "^5.2.12", "localheinz/diff": "^1.1.1", - "php": "^8.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { - "composer/composer": "^2.4.4", - "ergebnis/license": "^2.1.0", - "ergebnis/php-cs-fixer-config": "^5.0.0", - "fakerphp/faker": "^1.20.0", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "~0.18.3", + "composer/composer": "^2.6.5", + "ergebnis/license": "^2.2.0", + "ergebnis/php-cs-fixer-config": "~6.7.0", + "ergebnis/phpunit-slow-test-detector": "^2.3.0", + "fakerphp/faker": "^1.23.0", + "infection/infection": "~0.27.4", + "phpunit/phpunit": "^10.4.1", + "psalm/plugin-phpunit": "~0.18.4", + "rector/rector": "~0.18.5", "symfony/filesystem": "^6.0.13", - "vimeo/psalm": "^5.0.0" + "vimeo/psalm": "^5.15.0" }, "type": "composer-plugin", "extra": { @@ -2035,7 +2040,8 @@ "composer-normalize": { "indent-size": 2, "indent-style": "space" - } + }, + "plugin-optional": true }, "autoload": { "psr-4": { @@ -2049,7 +2055,8 @@ "authors": [ { "name": "Andreas Möller", - "email": "am@localheinz.com" + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], "description": "Provides a composer plugin for normalizing composer.json.", @@ -2062,40 +2069,116 @@ ], "support": { "issues": "https://github.com/ergebnis/composer-normalize/issues", + "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/composer-normalize" }, - "time": "2022-12-01T11:51:19+00:00" + "time": "2023-10-10T15:43:27+00:00" + }, + { + "name": "ergebnis/json", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/json.git", + "reference": "9f2b9086c43b189d7044a5b6215a931fb6e9125d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/json/zipball/9f2b9086c43b189d7044a5b6215a931fb6e9125d", + "reference": "9f2b9086c43b189d7044a5b6215a931fb6e9125d", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.29.0", + "ergebnis/data-provider": "^3.0.0", + "ergebnis/license": "^2.2.0", + "ergebnis/php-cs-fixer-config": "^6.6.0", + "ergebnis/phpunit-slow-test-detector": "^2.3.0", + "fakerphp/faker": "^1.23.0", + "infection/infection": "~0.27.4", + "phpunit/phpunit": "^10.4.1", + "psalm/plugin-phpunit": "~0.18.4", + "rector/rector": "~0.18.5", + "vimeo/psalm": "^5.15.0" + }, + "type": "library", + "extra": { + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\Json\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" + } + ], + "description": "Provides a Json value object for representing a valid JSON string.", + "homepage": "https://github.com/ergebnis/json", + "keywords": [ + "json" + ], + "support": { + "issues": "https://github.com/ergebnis/json/issues", + "security": "https://github.com/ergebnis/json/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json" + }, + "time": "2023-10-10T07:57:48+00:00" }, { "name": "ergebnis/json-normalizer", - "version": "2.1.0", + "version": "4.3.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-normalizer.git", - "reference": "2039eb11131a243b9204bf51219baa08935e6b1d" + "reference": "716fa0a5dcc75fbcb2c1c2e0542b2f56732460bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/2039eb11131a243b9204bf51219baa08935e6b1d", - "reference": "2039eb11131a243b9204bf51219baa08935e6b1d", + "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/716fa0a5dcc75fbcb2c1c2e0542b2f56732460bd", + "reference": "716fa0a5dcc75fbcb2c1c2e0542b2f56732460bd", "shasum": "" }, "require": { - "ergebnis/json-printer": "^3.2.0", - "ergebnis/json-schema-validator": "^2.0.0", + "ergebnis/json": "^1.1.0", + "ergebnis/json-pointer": "^3.2.0", + "ergebnis/json-printer": "^3.4.0", + "ergebnis/json-schema-validator": "^4.1.0", "ext-json": "*", - "justinrainbow/json-schema": "^5.2.11", - "php": "^7.4 || ^8.0" + "justinrainbow/json-schema": "^5.2.12", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { - "ergebnis/data-provider": "^1.0.0", - "ergebnis/license": "^1.2.0", - "ergebnis/php-cs-fixer-config": "^3.4.0", - "fakerphp/faker": "^1.17.0", - "infection/infection": "~0.25.5", - "phpunit/phpunit": "^9.5.11", - "psalm/plugin-phpunit": "~0.16.1", - "vimeo/psalm": "^4.17.0" + "composer/semver": "^3.4.0", + "ergebnis/data-provider": "^3.0.0", + "ergebnis/license": "^2.2.0", + "ergebnis/php-cs-fixer-config": "~6.7.0", + "ergebnis/phpunit-slow-test-detector": "^2.3.0", + "fakerphp/faker": "^1.23.0", + "infection/infection": "~0.27.4", + "phpunit/phpunit": "^10.4.1", + "psalm/plugin-phpunit": "~0.18.4", + "rector/rector": "~0.18.5", + "symfony/filesystem": "^6.3.1", + "symfony/finder": "^6.3.5", + "vimeo/psalm": "^5.15.0" + }, + "suggest": { + "composer/semver": "If you want to use ComposerJsonNormalizer or VersionConstraintNormalizer" }, "type": "library", "autoload": { @@ -2110,7 +2193,8 @@ "authors": [ { "name": "Andreas Möller", - "email": "am@localheinz.com" + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], "description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.", @@ -2121,43 +2205,107 @@ ], "support": { "issues": "https://github.com/ergebnis/json-normalizer/issues", + "security": "https://github.com/ergebnis/json-normalizer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-normalizer" }, - "funding": [ + "time": "2023-10-10T15:15:03+00:00" + }, + { + "name": "ergebnis/json-pointer", + "version": "3.3.0", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/json-pointer.git", + "reference": "8e517faefc06b7c761eaa041febef51a9375819a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/8e517faefc06b7c761eaa041febef51a9375819a", + "reference": "8e517faefc06b7c761eaa041febef51a9375819a", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.29.0", + "ergebnis/data-provider": "^3.0.0", + "ergebnis/license": "^2.2.0", + "ergebnis/php-cs-fixer-config": "~6.7.0", + "ergebnis/phpunit-slow-test-detector": "^2.3.0", + "fakerphp/faker": "^1.23.0", + "infection/infection": "~0.27.4", + "phpunit/phpunit": "^10.4.1", + "psalm/plugin-phpunit": "~0.18.4", + "rector/rector": "~0.18.5", + "vimeo/psalm": "^5.15.0" + }, + "type": "library", + "extra": { + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\Json\\Pointer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://github.com/localheinz", - "type": "github" + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], - "time": "2022-01-04T11:19:55+00:00" + "description": "Provides JSON pointer as a value object.", + "homepage": "https://github.com/ergebnis/json-pointer", + "keywords": [ + "RFC6901", + "json", + "pointer" + ], + "support": { + "issues": "https://github.com/ergebnis/json-pointer/issues", + "security": "https://github.com/ergebnis/json-pointer/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/json-pointer" + }, + "time": "2023-10-10T14:41:06+00:00" }, { "name": "ergebnis/json-printer", - "version": "3.3.0", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-printer.git", - "reference": "18920367473b099633f644f0ca6dc8794345148f" + "reference": "05841593d72499de4f7ce4034a237c77e470558f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/18920367473b099633f644f0ca6dc8794345148f", - "reference": "18920367473b099633f644f0ca6dc8794345148f", + "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/05841593d72499de4f7ce4034a237c77e470558f", + "reference": "05841593d72499de4f7ce4034a237c77e470558f", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", - "php": "^8.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { - "ergebnis/license": "^2.0.0", - "ergebnis/php-cs-fixer-config": "^4.11.0", - "fakerphp/faker": "^1.20.0", - "infection/infection": "~0.26.6", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "~0.18.3", - "vimeo/psalm": "^4.30.0" + "ergebnis/license": "^2.2.0", + "ergebnis/php-cs-fixer-config": "^6.6.0", + "ergebnis/phpunit-slow-test-detector": "^2.3.0", + "fakerphp/faker": "^1.23.0", + "infection/infection": "~0.27.3", + "phpunit/phpunit": "^10.4.1", + "psalm/plugin-phpunit": "~0.18.4", + "rector/rector": "~0.18.5", + "vimeo/psalm": "^5.15.0" }, "type": "library", "autoload": { @@ -2172,7 +2320,8 @@ "authors": [ { "name": "Andreas Möller", - "email": "am@localheinz.com" + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], "description": "Provides a JSON printer, allowing for flexible indentation.", @@ -2184,39 +2333,44 @@ ], "support": { "issues": "https://github.com/ergebnis/json-printer/issues", + "security": "https://github.com/ergebnis/json-printer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-printer" }, - "time": "2022-11-28T10:27:43+00:00" + "time": "2023-10-10T07:42:48+00:00" }, { "name": "ergebnis/json-schema-validator", - "version": "2.0.0", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-schema-validator.git", - "reference": "dacd8a47c1cc2c426ec71e952da3609ebe901fac" + "reference": "d568ed85d1cdc2e49d650c2fc234dc2516f3f25b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/dacd8a47c1cc2c426ec71e952da3609ebe901fac", - "reference": "dacd8a47c1cc2c426ec71e952da3609ebe901fac", + "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/d568ed85d1cdc2e49d650c2fc234dc2516f3f25b", + "reference": "d568ed85d1cdc2e49d650c2fc234dc2516f3f25b", "shasum": "" }, "require": { + "ergebnis/json": "^1.0.1", + "ergebnis/json-pointer": "^3.2.0", "ext-json": "*", - "justinrainbow/json-schema": "^5.2.10", - "php": "^7.4 || ^8.0" + "justinrainbow/json-schema": "^5.2.12", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.18.0", - "ergebnis/data-provider": "^1.0.0", - "ergebnis/license": "^1.1.0", - "ergebnis/php-cs-fixer-config": "~3.4.0", - "fakerphp/faker": "^1.17.0", - "infection/infection": "~0.25.3", - "phpunit/phpunit": "~9.5.10", - "psalm/plugin-phpunit": "~0.16.1", - "vimeo/psalm": "^4.15.0" + "ergebnis/composer-normalize": "^2.21.0", + "ergebnis/data-provider": "^3.0.0", + "ergebnis/license": "^2.2.0", + "ergebnis/php-cs-fixer-config": "~6.6.0", + "ergebnis/phpunit-slow-test-detector": "^2.3.0", + "fakerphp/faker": "^1.23.0", + "infection/infection": "~0.27.4", + "phpunit/phpunit": "^10.4.1", + "psalm/plugin-phpunit": "~0.18.4", + "rector/rector": "~0.18.5", + "vimeo/psalm": "^5.15.0" }, "type": "library", "extra": { @@ -2237,7 +2391,8 @@ "authors": [ { "name": "Andreas Möller", - "email": "am@localheinz.com" + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" } ], "description": "Provides a JSON schema validator, building on top of justinrainbow/json-schema.", @@ -2249,15 +2404,10 @@ ], "support": { "issues": "https://github.com/ergebnis/json-schema-validator/issues", + "security": "https://github.com/ergebnis/json-schema-validator/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-schema-validator" }, - "funding": [ - { - "url": "https://github.com/localheinz", - "type": "github" - } - ], - "time": "2021-12-13T16:54:56+00:00" + "time": "2023-10-10T14:16:57+00:00" }, { "name": "friendsofphp/php-cs-fixer", @@ -3146,16 +3296,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.9.4", + "version": "1.10.44", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2" + "reference": "bf84367c53a23f759513985c54ffe0d0c249825b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2", - "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bf84367c53a23f759513985c54ffe0d0c249825b", + "reference": "bf84367c53a23f759513985c54ffe0d0c249825b", "shasum": "" }, "require": { @@ -3184,8 +3334,11 @@ "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", - "source": "https://github.com/phpstan/phpstan/tree/1.9.4" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -3201,7 +3354,7 @@ "type": "tidelift" } ], - "time": "2022-12-17T13:33:52+00:00" + "time": "2023-11-21T16:30:46+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5003,16 +5156,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.2.0", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "50b2523c874605cf3d4acf7a9e2b30b6a440a016" + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/50b2523c874605cf3d4acf7a9e2b30b6a440a016", - "reference": "50b2523c874605cf3d4acf7a9e2b30b6a440a016", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", "shasum": "" }, "require": { @@ -5046,7 +5199,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.0" + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" }, "funding": [ { @@ -5062,7 +5215,7 @@ "type": "tidelift" } ], - "time": "2022-11-20T13:01:27+00:00" + "time": "2023-06-01T08:30:39+00:00" }, { "name": "symfony/finder", From 8c45f7650136f3c350c137b40c51a027a25caf2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:21:22 +0100 Subject: [PATCH 008/286] [TASK] Use eliashaeussler/php-cs-fixer-config and run PHP-CS-Fixer --- .php-cs-fixer.php | 26 +- composer.json | 2 +- composer.lock | 245 ++++++++++-------- src/Capability/UpdateCheckCommandProvider.php | 19 ++ src/Command/UpdateCheckCommand.php | 29 ++- src/Event/PostUpdateCheckEvent.php | 21 +- src/IO/OutputBehavior.php | 19 ++ src/IO/Style.php | 23 +- src/IO/Verbosity.php | 22 +- src/Options.php | 19 ++ src/Package/OutdatedPackage.php | 19 ++ src/Package/UpdateCheckResult.php | 27 +- src/Plugin.php | 19 ++ src/Security/InsecurePackage.php | 19 ++ src/Security/ScanResult.php | 22 +- src/Security/SecurityScanner.php | 22 +- src/UpdateChecker.php | 24 +- src/Utility/Composer.php | 22 +- src/Utility/Installer.php | 19 ++ src/Utility/Security.php | 19 ++ tests/Unit/AbstractTestCase.php | 22 +- tests/Unit/Command/UpdateCheckCommandTest.php | 19 ++ tests/Unit/ExpectedCommandOutputTrait.php | 19 ++ tests/Unit/IO/StyleTest.php | 27 +- tests/Unit/IO/VerbosityTest.php | 27 +- tests/Unit/OptionsTest.php | 19 ++ tests/Unit/Package/OutdatedPackageTest.php | 23 +- tests/Unit/Package/UpdateCheckResultTest.php | 33 ++- tests/Unit/Security/InsecurePackageTest.php | 19 ++ tests/Unit/Security/ScanResultTest.php | 31 ++- tests/Unit/Security/SecurityScannerTest.php | 22 +- tests/Unit/TestApplicationTrait.php | 19 ++ tests/Unit/UpdateCheckerTest.php | 19 ++ tests/Unit/Utility/ComposerTest.php | 22 +- tests/Unit/Utility/InstallerTest.php | 24 +- tests/Unit/Utility/SecurityTest.php | 19 ++ 36 files changed, 849 insertions(+), 152 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index abb04433..c1f58d0b 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -5,7 +5,7 @@ /* * This file is part of the Composer package "eliashaeussler/composer-update-check". * - * Copyright (C) 2021 Elias Häußler + * Copyright (C) 2023 Elias Häußler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,20 +14,26 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -$finder = \PhpCsFixer\Finder::create() - ->in([__DIR__.'/src', __DIR__.'/tests']); +use EliasHaeussler\PhpCsFixerConfig; +use Symfony\Component\Finder; -$config = new \PhpCsFixer\Config(); +$header = PhpCsFixerConfig\Rules\Header::create( + 'eliashaeussler/composer-update-check', + PhpCsFixerConfig\Package\Type::ComposerPackage, + PhpCsFixerConfig\Package\Author::create('Elias Häußler', 'elias@haeussler.dev'), + PhpCsFixerConfig\Package\License::GPL3OrLater, +); -return $config->setRules([ - '@PSR2' => true, - '@Symfony' => true, - ]) - ->setFinder($finder); +return PhpCsFixerConfig\Config::create() + ->withRule($header) + ->withFinder( + static fn (Finder\Finder $finder) => $finder->in(__DIR__), + ) +; diff --git a/composer.json b/composer.json index f6b0c5f6..38d05dbd 100644 --- a/composer.json +++ b/composer.json @@ -33,8 +33,8 @@ "armin/editorconfig-cli": "^1.7", "composer/composer": "^2.0", "composer/semver": "^3.4", + "eliashaeussler/php-cs-fixer-config": "^1.3", "ergebnis/composer-normalize": "^2.39", - "friendsofphp/php-cs-fixer": "^3.39", "php-http/discovery": "^1.19", "php-http/httplug": "^2.4", "php-http/mock-client": "^1.6", diff --git a/composer.lock b/composer.lock index 8c5a455c..6e6089cc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4542ed17b6f7be97ab1dc5214c4e4be3", + "content-hash": "3377c804faf8951c9e6aea89fc037138", "packages": [ { "name": "nyholm/psr7", @@ -505,16 +505,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.2.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { @@ -523,7 +523,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -552,7 +552,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -568,7 +568,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/http-client", @@ -989,16 +989,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -1013,7 +1013,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1052,7 +1052,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -1068,20 +1068,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.2.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "shasum": "" }, "require": { @@ -1091,13 +1091,10 @@ "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -1137,7 +1134,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" }, "funding": [ { @@ -1153,7 +1150,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/string", @@ -1701,16 +1698,16 @@ }, { "name": "composer/pcre", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", "shasum": "" }, "require": { @@ -1752,7 +1749,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.0" + "source": "https://github.com/composer/pcre/tree/3.1.1" }, "funding": [ { @@ -1768,7 +1765,7 @@ "type": "tidelift" } ], - "time": "2022-11-17T09:50:14+00:00" + "time": "2023-10-11T07:11:09+00:00" }, { "name": "composer/semver", @@ -1997,6 +1994,58 @@ ], "time": "2022-02-25T21:32:43+00:00" }, + { + "name": "eliashaeussler/php-cs-fixer-config", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/eliashaeussler/php-cs-fixer-config.git", + "reference": "6cfffbbaa4ac2713e52b0ca1f0a9b86bbdbfffa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/eliashaeussler/php-cs-fixer-config/zipball/6cfffbbaa4ac2713e52b0ca1f0a9b86bbdbfffa8", + "reference": "6cfffbbaa4ac2713e52b0ca1f0a9b86bbdbfffa8", + "shasum": "" + }, + "require": { + "friendsofphp/php-cs-fixer": "^3.14", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "symfony/finder": "^5.4 || ^6.0" + }, + "require-dev": { + "armin/editorconfig-cli": "^1.5", + "eliashaeussler/phpstan-config": "^2.0.0", + "ergebnis/composer-normalize": "^2.29", + "phpstan/extension-installer": "^1.2", + "phpunit/phpunit": "^10.1", + "rector/rector": "^0.18.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "EliasHaeussler\\PhpCsFixerConfig\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Elias Häußler", + "email": "elias@haeussler.dev", + "homepage": "https://haeussler.dev", + "role": "Maintainer" + } + ], + "description": "My personal configuration for PHP-CS-Fixer", + "support": { + "issues": "https://github.com/eliashaeussler/php-cs-fixer-config/issues", + "source": "https://github.com/eliashaeussler/php-cs-fixer-config/tree/1.3.0" + }, + "time": "2023-10-30T21:27:50+00:00" + }, { "name": "ergebnis/composer-normalize", "version": "2.39.0", @@ -4994,24 +5043,25 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.2.2", + "version": "v6.3.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1" + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ffeb31139b49bf6ef0bc09d1db95eac053388d1", - "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^2|^3" + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", @@ -5024,13 +5074,9 @@ "symfony/error-handler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/stopwatch": "^5.4|^6.0" }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, "type": "library", "autoload": { "psr-4": { @@ -5057,7 +5103,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" }, "funding": [ { @@ -5073,33 +5119,30 @@ "type": "tidelift" } ], - "time": "2022-12-14T16:11:27+00:00" + "time": "2023-07-06T06:56:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.2.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "0782b0b52a737a05b4383d0df35a474303cabdae" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0782b0b52a737a05b4383d0df35a474303cabdae", - "reference": "0782b0b52a737a05b4383d0df35a474303cabdae", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -5136,7 +5179,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { @@ -5152,7 +5195,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/filesystem", @@ -5219,16 +5262,16 @@ }, { "name": "symfony/finder", - "version": "v6.2.0", + "version": "v6.3.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "eb2355f69519e4ef33f1835bca4c935f5d42e570" + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/eb2355f69519e4ef33f1835bca4c935f5d42e570", - "reference": "eb2355f69519e4ef33f1835bca4c935f5d42e570", + "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", "shasum": "" }, "require": { @@ -5263,7 +5306,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.2.0" + "source": "https://github.com/symfony/finder/tree/v6.3.5" }, "funding": [ { @@ -5279,7 +5322,7 @@ "type": "tidelift" } ], - "time": "2022-10-09T08:55:40+00:00" + "time": "2023-09-26T12:56:25+00:00" }, { "name": "symfony/mime", @@ -5366,21 +5409,21 @@ }, { "name": "symfony/options-resolver", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "d28f02acde71ff75e957082cd36e973df395f626" + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/d28f02acde71ff75e957082cd36e973df395f626", - "reference": "d28f02acde71ff75e957082cd36e973df395f626", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3" + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -5413,7 +5456,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.2.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" }, "funding": [ { @@ -5429,7 +5472,7 @@ "type": "tidelift" } ], - "time": "2022-11-02T09:08:04+00:00" + "time": "2023-05-12T14:21:09+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -5596,16 +5639,16 @@ }, { "name": "symfony/polyfill-php73", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", "shasum": "" }, "require": { @@ -5614,7 +5657,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5655,7 +5698,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" }, "funding": [ { @@ -5671,20 +5714,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -5693,7 +5736,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5738,7 +5781,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, "funding": [ { @@ -5754,20 +5797,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", "shasum": "" }, "require": { @@ -5776,7 +5819,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5817,7 +5860,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" }, "funding": [ { @@ -5833,20 +5876,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/process", - "version": "v6.2.0", + "version": "v6.3.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ba6e55359f8f755fe996c58a81e00eaa67a35877" + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ba6e55359f8f755fe996c58a81e00eaa67a35877", - "reference": "ba6e55359f8f755fe996c58a81e00eaa67a35877", + "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", "shasum": "" }, "require": { @@ -5878,7 +5921,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.2.0" + "source": "https://github.com/symfony/process/tree/v6.3.4" }, "funding": [ { @@ -5894,25 +5937,25 @@ "type": "tidelift" } ], - "time": "2022-11-02T09:08:04+00:00" + "time": "2023-08-07T10:39:22+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7" + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/266636bb8f3fbdccc302491df7b3a1b9a8c238a7", - "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/service-contracts": "^1|^2|^3" + "symfony/service-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -5940,7 +5983,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.2.0" + "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" }, "funding": [ { @@ -5956,7 +5999,7 @@ "type": "tidelift" } ], - "time": "2022-09-28T16:00:52+00:00" + "time": "2023-02-16T10:14:28+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/Capability/UpdateCheckCommandProvider.php b/src/Capability/UpdateCheckCommandProvider.php index 0789c78a..7e64aa8b 100644 --- a/src/Capability/UpdateCheckCommandProvider.php +++ b/src/Capability/UpdateCheckCommandProvider.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Capability; /* diff --git a/src/Command/UpdateCheckCommand.php b/src/Command/UpdateCheckCommand.php index 8df49fb4..92a96ba3 100644 --- a/src/Command/UpdateCheckCommand.php +++ b/src/Command/UpdateCheckCommand.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Command; /* @@ -65,25 +84,25 @@ protected function configure(): void 'i', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Packages to ignore when checking for available updates', - [] + [], ); $this->addOption( 'no-dev', null, InputOption::VALUE_NONE, - 'Disables update check of require-dev packages.' + 'Disables update check of require-dev packages.', ); $this->addOption( 'security-scan', 's', InputOption::VALUE_NONE, - 'Run security scan for all outdated packages' + 'Run security scan for all outdated packages', ); $this->addOption( 'json', 'j', InputOption::VALUE_NONE, - 'Format update check as JSON' + 'Format update check as JSON', ); } @@ -124,7 +143,7 @@ private function decorateResult(UpdateCheckResult $result, array $ignoredPackage $countSkipped = count($ignoredPackages); $message = sprintf( 'All packages are up to date%s.', - $countSkipped > 0 ? sprintf(' (skipped %d package%s)', $countSkipped, 1 !== $countSkipped ? 's' : '') : '' + $countSkipped > 0 ? sprintf(' (skipped %d package%s)', $countSkipped, 1 !== $countSkipped ? 's' : '') : '', ); if ($this->behavior->style->isJson()) { $this->buildJsonReport(['status' => $message], $ignoredPackages); diff --git a/src/Event/PostUpdateCheckEvent.php b/src/Event/PostUpdateCheckEvent.php index c829a29c..69d83948 100644 --- a/src/Event/PostUpdateCheckEvent.php +++ b/src/Event/PostUpdateCheckEvent.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Event; /* @@ -64,7 +83,7 @@ public function __construct( OutputBehavior $behavior, Options $options, array $args = [], - array $flags = [] + array $flags = [], ) { parent::__construct(self::NAME, $args, $flags); $this->updateCheckResult = $updateCheckResult; diff --git a/src/IO/OutputBehavior.php b/src/IO/OutputBehavior.php index 399d5c05..b4833f66 100644 --- a/src/IO/OutputBehavior.php +++ b/src/IO/OutputBehavior.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\IO; /* diff --git a/src/IO/Style.php b/src/IO/Style.php index eb4c92c6..ae44580e 100644 --- a/src/IO/Style.php +++ b/src/IO/Style.php @@ -2,8 +2,29 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\IO; +use InvalidArgumentException; + /* * This file is part of the Composer package "eliashaeussler/composer-update-check". * @@ -73,7 +94,7 @@ public function getStyle(): string private function validate(): void { if (!static::isSupported($this->style)) { - throw new \InvalidArgumentException('The given style is not supported.', 1617549657); + throw new InvalidArgumentException('The given style is not supported.', 1617549657); } } } diff --git a/src/IO/Verbosity.php b/src/IO/Verbosity.php index 298d2eaa..e7ac107a 100644 --- a/src/IO/Verbosity.php +++ b/src/IO/Verbosity.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\IO; /* @@ -23,6 +42,7 @@ * along with this program. If not, see . */ +use InvalidArgumentException; use Symfony\Component\Console\Output\OutputInterface; /** @@ -99,7 +119,7 @@ public function getLevel(): int private function validate(): void { if (!static::isSupported($this->level)) { - throw new \InvalidArgumentException('The given verbosity level is not supported.', 1617549839); + throw new InvalidArgumentException('The given verbosity level is not supported.', 1617549839); } } } diff --git a/src/Options.php b/src/Options.php index e0cde2ed..38284973 100644 --- a/src/Options.php +++ b/src/Options.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck; /* diff --git a/src/Package/OutdatedPackage.php b/src/Package/OutdatedPackage.php index f9f0bfb6..02c94452 100644 --- a/src/Package/OutdatedPackage.php +++ b/src/Package/OutdatedPackage.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Package; /* diff --git a/src/Package/UpdateCheckResult.php b/src/Package/UpdateCheckResult.php index 870fc893..bd786964 100644 --- a/src/Package/UpdateCheckResult.php +++ b/src/Package/UpdateCheckResult.php @@ -2,8 +2,29 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Package; +use InvalidArgumentException; + /* * This file is part of the Composer package "eliashaeussler/composer-update-check". * @@ -88,9 +109,9 @@ function (?OutdatedPackage $outdatedPackage) use ($allowedPackages) { } return in_array($outdatedPackage->getName(), $allowedPackages, true); - } + }, ), - SORT_REGULAR + SORT_REGULAR, ); return new self($packages); @@ -125,7 +146,7 @@ private function validateOutdatedPackages(): void { foreach ($this->outdatedPackages as $key => $outdatedPackage) { if (!($outdatedPackage instanceof OutdatedPackage)) { - throw new \InvalidArgumentException(sprintf('Outdated package #%s must be an instance of "%s".', $key, OutdatedPackage::class), 1600276584); + throw new InvalidArgumentException(sprintf('Outdated package #%s must be an instance of "%s".', $key, OutdatedPackage::class), 1600276584); } } } diff --git a/src/Plugin.php b/src/Plugin.php index 09fd2782..4743aa48 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck; /* diff --git a/src/Security/InsecurePackage.php b/src/Security/InsecurePackage.php index 06b072d9..82ad5485 100644 --- a/src/Security/InsecurePackage.php +++ b/src/Security/InsecurePackage.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Security; /* diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index 1ab7e56e..91d1fbe5 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Security; /* @@ -25,6 +44,7 @@ use Composer\Semver\Semver; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use InvalidArgumentException; /** * ScanResult. @@ -106,7 +126,7 @@ private function validateInsecurePackages(): void { foreach ($this->insecurePackages as $key => $insecurePackage) { if (!($insecurePackage instanceof InsecurePackage)) { - throw new \InvalidArgumentException(sprintf('Insecure package #%s must be an instance of "%s".', $key, InsecurePackage::class), 1610707087); + throw new InvalidArgumentException(sprintf('Insecure package #%s must be an instance of "%s".', $key, InsecurePackage::class), 1610707087); } } } diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index a5ef35f3..d142790f 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Security; /* @@ -29,6 +48,7 @@ use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; +use RuntimeException; use Symfony\Component\HttpClient\Psr18Client; /** @@ -86,7 +106,7 @@ public function scan(array $packages): ScanResult return ScanResult::fromApiResult(json_decode($apiResult, true) ?: []); } catch (ClientExceptionInterface $e) { - throw new \RuntimeException('Error while scanning security vulnerabilities.', 1610706128, $e); + throw new RuntimeException('Error while scanning security vulnerabilities.', 1610706128, $e); } } } diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 4fcf78b1..4b56eefc 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck; /* @@ -30,6 +49,7 @@ use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Utility\Installer; use EliasHaeussler\ComposerUpdateCheck\Utility\Security; +use RuntimeException; use Spatie\Emoji\Emoji; /** @@ -108,7 +128,7 @@ private function runUpdateCheck(array $packages): UpdateCheckResult // Handle installer failures if ($result > 0) { $this->behavior->io->writeError(Installer::getLastOutput()); - throw new \RuntimeException(sprintf('Error during update check. Exit code from Composer installer: %d', $result), 1600278536); + throw new RuntimeException(sprintf('Error during update check. Exit code from Composer installer: %d', $result), 1600278536); } return UpdateCheckResult::fromCommandOutput(Installer::getLastOutput(), $packages); @@ -122,7 +142,7 @@ private function installDependencies(): void // Handle installer failures if ($result > 0) { $this->behavior->io->writeError(Installer::getLastOutput()); - throw new \RuntimeException(sprintf('Error during dependency install. Exit code from Composer installer: %d', $result), 1600614218); + throw new RuntimeException(sprintf('Error during dependency install. Exit code from Composer installer: %d', $result), 1600614218); } } diff --git a/src/Utility/Composer.php b/src/Utility/Composer.php index 582e8d99..7bbb4ac2 100644 --- a/src/Utility/Composer.php +++ b/src/Utility/Composer.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Utility; /* @@ -24,6 +43,7 @@ */ use Composer\Plugin\PluginInterface; +use InvalidArgumentException; /** * Composer. @@ -50,7 +70,7 @@ public static function getPlatformVersion(int $versionType = self::VERSION_FULL) case self::VERSION_BRANCH: return $versionComponents[0].'.'.$versionComponents[1]; default: - throw new \InvalidArgumentException('The given version type is not supported.', 1603794822); + throw new InvalidArgumentException('The given version type is not supported.', 1603794822); } } diff --git a/src/Utility/Installer.php b/src/Utility/Installer.php index b0beb5a4..b2f5b07a 100644 --- a/src/Utility/Installer.php +++ b/src/Utility/Installer.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Utility; /* diff --git a/src/Utility/Security.php b/src/Utility/Security.php index 4e17d62a..63ffcadd 100644 --- a/src/Utility/Security.php +++ b/src/Utility/Security.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Utility; /* diff --git a/tests/Unit/AbstractTestCase.php b/tests/Unit/AbstractTestCase.php index 87cedf62..0ec36585 100644 --- a/tests/Unit/AbstractTestCase.php +++ b/tests/Unit/AbstractTestCase.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; /* @@ -24,6 +43,7 @@ */ use PHPUnit\Framework\TestCase; +use ReflectionClass; /** * AbstractTestCase. @@ -39,7 +59,7 @@ abstract class AbstractTestCase extends TestCase protected function tearDown(): void { - $reflection = new \ReflectionClass($this); + $reflection = new ReflectionClass($this); foreach ($reflection->getProperties() as $property) { if ( !$property->isStatic() diff --git a/tests/Unit/Command/UpdateCheckCommandTest.php b/tests/Unit/Command/UpdateCheckCommandTest.php index 3f3a49d2..1ab0b28e 100644 --- a/tests/Unit/Command/UpdateCheckCommandTest.php +++ b/tests/Unit/Command/UpdateCheckCommandTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Command; /* diff --git a/tests/Unit/ExpectedCommandOutputTrait.php b/tests/Unit/ExpectedCommandOutputTrait.php index 4f00d21c..0b07467c 100644 --- a/tests/Unit/ExpectedCommandOutputTrait.php +++ b/tests/Unit/ExpectedCommandOutputTrait.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; /* diff --git a/tests/Unit/IO/StyleTest.php b/tests/Unit/IO/StyleTest.php index fe10a9f8..59b5529e 100644 --- a/tests/Unit/IO/StyleTest.php +++ b/tests/Unit/IO/StyleTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\IO; /* @@ -25,6 +44,8 @@ use EliasHaeussler\ComposerUpdateCheck\IO\Style; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use Generator; +use InvalidArgumentException; /** * StyleTest. @@ -39,7 +60,7 @@ class StyleTest extends AbstractTestCase */ public function constructorThrowsExceptionIfGivenStyleIsNotSupported(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionCode(1617549657); new Style('foo'); @@ -102,9 +123,9 @@ public function getStyleReturnsStyle(): void } /** - * @return \Generator + * @return Generator */ - public static function isReturnsTrueIfGivenStyleEqualsStyleDataProvider(): \Generator + public static function isReturnsTrueIfGivenStyleEqualsStyleDataProvider(): Generator { yield 'normal style' => [Style::NORMAL]; yield 'json style' => [Style::JSON]; diff --git a/tests/Unit/IO/VerbosityTest.php b/tests/Unit/IO/VerbosityTest.php index 59a68e89..ba9772e3 100644 --- a/tests/Unit/IO/VerbosityTest.php +++ b/tests/Unit/IO/VerbosityTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\IO; /* @@ -25,6 +44,8 @@ use EliasHaeussler\ComposerUpdateCheck\IO\Verbosity; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use Generator; +use InvalidArgumentException; /** * VerbosityTest. @@ -39,7 +60,7 @@ class VerbosityTest extends AbstractTestCase */ public function constructorThrowsExceptionIfGivenVerbosityIsNotSupported(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionCode(1617549839); new Verbosity(-1); @@ -131,9 +152,9 @@ public function getLevelReturnsVerbosityLevel(): void } /** - * @return \Generator + * @return Generator */ - public static function isReturnsTrueIfGivenVerbosityEqualsVerbosityDataProvider(): \Generator + public static function isReturnsTrueIfGivenVerbosityEqualsVerbosityDataProvider(): Generator { yield 'quiet level' => [Verbosity::QUIET]; yield 'normal level' => [Verbosity::NORMAL]; diff --git a/tests/Unit/OptionsTest.php b/tests/Unit/OptionsTest.php index a85866e0..41d86118 100644 --- a/tests/Unit/OptionsTest.php +++ b/tests/Unit/OptionsTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; /* diff --git a/tests/Unit/Package/OutdatedPackageTest.php b/tests/Unit/Package/OutdatedPackageTest.php index 12412052..b5b93e1b 100644 --- a/tests/Unit/Package/OutdatedPackageTest.php +++ b/tests/Unit/Package/OutdatedPackageTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; /* @@ -51,13 +70,13 @@ protected function setUp(): void 'foo', '1.0.0', '1.0.5', - true + true, ); $this->subjectWithBranch = new OutdatedPackage( 'buu', 'dev-master 12345', 'dev-master 67890', - false + false, ); } diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index d83500c8..4ea4cb75 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; /* @@ -27,6 +46,8 @@ use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; +use Generator; +use InvalidArgumentException; /** * UpdateCheckResultTest. @@ -43,7 +64,7 @@ class UpdateCheckResultTest extends AbstractTestCase */ public function constructorThrowsExceptionIfOutdatedPackagesAreInvalid(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionCode(1600276584); /* @noinspection PhpParamsInspection */ @@ -73,7 +94,7 @@ public function getOutdatedPackagesReturnsListOfOutdatedPackages(): void */ public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackages( string $commandOutput, - array $expected + array $expected, ): void { $subject = UpdateCheckResult::fromCommandOutput($commandOutput, ['dummy/package', 'foo/baz']); $outdatedPackages = $subject->getOutdatedPackages(); @@ -122,9 +143,9 @@ public function parseCommandOutputParsesCommandOutputCorrectly(string $commandOu } /** - * @return \Generator}> + * @return Generator}> */ - public static function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackagesDataProvider(): \Generator + public static function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackagesDataProvider(): Generator { yield 'no output' => [ '', @@ -151,9 +172,9 @@ public static function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsed } /** - * @return \Generator + * @return Generator */ - public static function parseCommandOutputParsesCommandOutputCorrectlyDataProvider(): \Generator + public static function parseCommandOutputParsesCommandOutputCorrectlyDataProvider(): Generator { yield 'no output' => [ '', diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/Unit/Security/InsecurePackageTest.php index e1610cb9..03dbb7f5 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/Unit/Security/InsecurePackageTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; /* diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index 48387741..b4cba65b 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; /* @@ -27,6 +46,8 @@ use EliasHaeussler\ComposerUpdateCheck\Security\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use Generator; +use InvalidArgumentException; /** * ScanResultTest. @@ -41,7 +62,7 @@ class ScanResultTest extends AbstractTestCase */ public function constructorThrowsExceptionIfGivenInsecurePackagesAreInvalid(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionCode(1610707087); /* @noinspection PhpParamsInspection */ @@ -126,9 +147,9 @@ public function isInsecureReturnsSecurityStateOfGivenPackage(OutdatedPackage $ou } /** - * @return \Generator + * @return Generator */ - public static function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvidedDataProvider(): \Generator + public static function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvidedDataProvider(): Generator { yield 'empty array' => [[]]; yield 'array without advisories' => [['foo' => 'baz']]; @@ -136,9 +157,9 @@ public static function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvi } /** - * @return \Generator + * @return Generator */ - public static function isInsecureReturnsSecurityStateOfGivenPackageDataProvider(): \Generator + public static function isInsecureReturnsSecurityStateOfGivenPackageDataProvider(): Generator { yield 'secure package without any insecure versions' => [ new OutdatedPackage('secure/package', '1.0.0', '1.0.1'), diff --git a/tests/Unit/Security/SecurityScannerTest.php b/tests/Unit/Security/SecurityScannerTest.php index c575ec23..6bc98649 100644 --- a/tests/Unit/Security/SecurityScannerTest.php +++ b/tests/Unit/Security/SecurityScannerTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; /* @@ -32,6 +51,7 @@ use Http\Mock\Client; use Nyholm\Psr7\Response; use Psr\Http\Message\RequestInterface; +use RuntimeException; /** * SecurityScannerTest. @@ -145,7 +165,7 @@ public function scanThrowsExceptionIfRequestFails(): void { $this->client->addException(new TransferException()); - $this->expectException(\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionCode(1610706128); $this->subject->scan([new OutdatedPackage('foo', '1.0.0', '1.0.1')]); diff --git a/tests/Unit/TestApplicationTrait.php b/tests/Unit/TestApplicationTrait.php index fdedce94..d59a91c0 100644 --- a/tests/Unit/TestApplicationTrait.php +++ b/tests/Unit/TestApplicationTrait.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; /* diff --git a/tests/Unit/UpdateCheckerTest.php b/tests/Unit/UpdateCheckerTest.php index 0365e4fe..37f7a2ea 100644 --- a/tests/Unit/UpdateCheckerTest.php +++ b/tests/Unit/UpdateCheckerTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; /* diff --git a/tests/Unit/Utility/ComposerTest.php b/tests/Unit/Utility/ComposerTest.php index c6ac8bfe..661452b8 100644 --- a/tests/Unit/Utility/ComposerTest.php +++ b/tests/Unit/Utility/ComposerTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; /* @@ -26,6 +45,7 @@ use Composer\Plugin\PluginInterface; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; +use InvalidArgumentException; /** * ComposerTest. @@ -68,7 +88,7 @@ public function getPlatformVersionReturnsPlatformBranch(): void */ public function getPlatformVersionThrowsExceptionIfUnsupportedVersionTypeIsGiven(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionCode(1603794822); Composer::getPlatformVersion(-99); } diff --git a/tests/Unit/Utility/InstallerTest.php b/tests/Unit/Utility/InstallerTest.php index 3bcfa75a..6f984c19 100644 --- a/tests/Unit/Utility/InstallerTest.php +++ b/tests/Unit/Utility/InstallerTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; /* @@ -31,6 +50,7 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; use EliasHaeussler\ComposerUpdateCheck\Utility\Installer; +use Generator; /** * InstallerTest. @@ -93,9 +113,9 @@ public function runUpdateExecutesDryRunUpdate(array $packages, string $expected, } /** - * @return \Generator + * @return Generator */ - public static function runUpdateExecutesDryRunUpdateDataProvider(): \Generator + public static function runUpdateExecutesDryRunUpdateDataProvider(): Generator { yield 'no explicit whitelist' => [ [], diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/Unit/Utility/SecurityTest.php index e1bd7cb4..492f3116 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/Unit/Utility/SecurityTest.php @@ -2,6 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the Composer package "eliashaeussler/composer-update-check". + * + * Copyright (C) 2023 Elias Häußler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; /* From 63706e577008a96ffe6240d5f48ab69c7ea1e73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:24:01 +0100 Subject: [PATCH 009/286] [TASK] Use eliashaeussler/phpstan-config --- .dockerignore | 2 +- .gitattributes | 2 +- composer.json | 8 +- composer.lock | 202 ++++++++++++++++++++++++++++++++++++++++++++++++- phpstan.neon | 7 -- phpstan.php | 36 +++++++++ 6 files changed, 244 insertions(+), 13 deletions(-) delete mode 100644 phpstan.neon create mode 100644 phpstan.php diff --git a/.dockerignore b/.dockerignore index db6671a6..d53eb31a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,5 +11,5 @@ /composer.lock /Dockerfile /mkdocs.yml -/phpstan.neon +/phpstan.php /phpunit.xml diff --git a/.gitattributes b/.gitattributes index 0a291793..862d50ec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,6 +14,6 @@ /composer.lock export-ignore /Dockerfile export-ignore /mkdocs.yml export-ignore -/phpstan.neon export-ignore +/phpstan.php export-ignore /phpunit.xml export-ignore /renovate.json export-ignore diff --git a/composer.json b/composer.json index 38d05dbd..7f07b358 100644 --- a/composer.json +++ b/composer.json @@ -34,11 +34,12 @@ "composer/composer": "^2.0", "composer/semver": "^3.4", "eliashaeussler/php-cs-fixer-config": "^1.3", + "eliashaeussler/phpstan-config": "^2.4", "ergebnis/composer-normalize": "^2.39", "php-http/discovery": "^1.19", "php-http/httplug": "^2.4", "php-http/mock-client": "^1.6", - "phpstan/phpstan": "^1.10", + "phpstan/extension-installer": "^1.3", "phpunit/phpunit": "^10.4", "symfony/filesystem": "^5.4 || ^6.0" }, @@ -55,7 +56,8 @@ "config": { "allow-plugins": { "ergebnis/composer-normalize": true, - "php-http/discovery": true + "php-http/discovery": true, + "phpstan/extension-installer": true }, "sort-packages": true }, @@ -85,7 +87,7 @@ "sca": [ "@sca:php" ], - "sca:php": "phpstan analyse -c phpstan.neon", + "sca:php": "phpstan analyse -c phpstan.php", "simulate": "bin/simulate-application.sh", "test": "@test:coverage --no-coverage", "test:coverage": "phpunit -c phpunit.xml" diff --git a/composer.lock b/composer.lock index 6e6089cc..e68cd74f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3377c804faf8951c9e6aea89fc037138", + "content-hash": "2664979938ada1d6863991536458fdff", "packages": [ { "name": "nyholm/psr7", @@ -2046,6 +2046,65 @@ }, "time": "2023-10-30T21:27:50+00:00" }, + { + "name": "eliashaeussler/phpstan-config", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/eliashaeussler/phpstan-config.git", + "reference": "534556504f1acc54b2ebffcad4f2d35b7d830e1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/eliashaeussler/phpstan-config/zipball/534556504f1acc54b2ebffcad4f2d35b7d830e1a", + "reference": "534556504f1acc54b2ebffcad4f2d35b7d830e1a", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-strict-rules": "^1.4" + }, + "require-dev": { + "armin/editorconfig-cli": "^1.5", + "eliashaeussler/php-cs-fixer-config": "^1.2", + "eliashaeussler/rector-config": "^2.0", + "ergebnis/composer-normalize": "^2.29", + "phpunit/phpunit": "^10.1" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "phpstan-base.neon.dist" + ] + } + }, + "autoload": { + "psr-4": { + "EliasHaeussler\\PHPStanConfig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Elias Häußler", + "email": "elias@haeussler.dev", + "homepage": "https://haeussler.dev", + "role": "Maintainer" + } + ], + "description": "My personal configuration for PHPStan", + "support": { + "issues": "https://github.com/eliashaeussler/phpstan-config/issues", + "source": "https://github.com/eliashaeussler/phpstan-config/tree/2.4.0" + }, + "time": "2023-11-23T08:48:50+00:00" + }, { "name": "ergebnis/composer-normalize", "version": "2.39.0", @@ -3343,6 +3402,50 @@ }, "time": "2023-11-08T12:57:08+00:00" }, + { + "name": "phpstan/extension-installer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" + }, + "time": "2023-05-24T08:59:17+00:00" + }, { "name": "phpstan/phpstan", "version": "1.10.44", @@ -3405,6 +3508,103 @@ ], "time": "2023-11-21T16:30:46+00:00" }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa", + "reference": "089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10.3" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-php-parser": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.4" + }, + "time": "2023-08-05T09:02:04+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542", + "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10.34" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2" + }, + "time": "2023-10-30T14:35:06+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "10.1.9", diff --git a/phpstan.neon b/phpstan.neon deleted file mode 100644 index b69f3a0a..00000000 --- a/phpstan.neon +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - level: 6 - paths: - - src - - tests - excludePaths: - - tests/Build/* diff --git a/phpstan.php b/phpstan.php new file mode 100644 index 00000000..96ac18a3 --- /dev/null +++ b/phpstan.php @@ -0,0 +1,36 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +use EliasHaeussler\PHPStanConfig; + +return PHPStanConfig\Config\Config::create(__DIR__) + ->in( + 'src', + 'tests', + ) + ->not( + 'tests/Build/*', + ) + ->level(6) + ->toArray() +; From 63b69f106ebf156dc2cfe8e6ff420bd7a64d8282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:30:36 +0100 Subject: [PATCH 010/286] [BUGFIX] Remove duplicated license header --- src/Capability/UpdateCheckCommandProvider.php | 19 ------------------- src/Command/UpdateCheckCommand.php | 19 ------------------- src/Event/PostUpdateCheckEvent.php | 19 ------------------- src/IO/OutputBehavior.php | 19 ------------------- src/IO/Style.php | 19 ------------------- src/IO/Verbosity.php | 19 ------------------- src/Options.php | 19 ------------------- src/Package/OutdatedPackage.php | 19 ------------------- src/Package/UpdateCheckResult.php | 19 ------------------- src/Plugin.php | 19 ------------------- src/Security/InsecurePackage.php | 19 ------------------- src/Security/ScanResult.php | 19 ------------------- src/Security/SecurityScanner.php | 19 ------------------- src/UpdateChecker.php | 19 ------------------- src/Utility/Composer.php | 19 ------------------- src/Utility/Installer.php | 19 ------------------- src/Utility/Security.php | 19 ------------------- tests/Unit/AbstractTestCase.php | 19 ------------------- tests/Unit/Command/UpdateCheckCommandTest.php | 19 ------------------- tests/Unit/ExpectedCommandOutputTrait.php | 19 ------------------- tests/Unit/IO/StyleTest.php | 19 ------------------- tests/Unit/IO/VerbosityTest.php | 19 ------------------- tests/Unit/OptionsTest.php | 19 ------------------- tests/Unit/Package/OutdatedPackageTest.php | 19 ------------------- tests/Unit/Package/UpdateCheckResultTest.php | 19 ------------------- tests/Unit/Security/InsecurePackageTest.php | 19 ------------------- tests/Unit/Security/ScanResultTest.php | 19 ------------------- tests/Unit/Security/SecurityScannerTest.php | 19 ------------------- tests/Unit/TestApplicationTrait.php | 19 ------------------- tests/Unit/UpdateCheckerTest.php | 19 ------------------- tests/Unit/Utility/ComposerTest.php | 19 ------------------- tests/Unit/Utility/InstallerTest.php | 19 ------------------- tests/Unit/Utility/SecurityTest.php | 19 ------------------- 33 files changed, 627 deletions(-) diff --git a/src/Capability/UpdateCheckCommandProvider.php b/src/Capability/UpdateCheckCommandProvider.php index 7e64aa8b..628cae1c 100644 --- a/src/Capability/UpdateCheckCommandProvider.php +++ b/src/Capability/UpdateCheckCommandProvider.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Capability; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Plugin\Capability\CommandProvider; use EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand; diff --git a/src/Command/UpdateCheckCommand.php b/src/Command/UpdateCheckCommand.php index 92a96ba3..4be74b42 100644 --- a/src/Command/UpdateCheckCommand.php +++ b/src/Command/UpdateCheckCommand.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Command; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Command\BaseCommand; use Composer\Factory; use Composer\IO\BufferIO; diff --git a/src/Event/PostUpdateCheckEvent.php b/src/Event/PostUpdateCheckEvent.php index 69d83948..e29f51ac 100644 --- a/src/Event/PostUpdateCheckEvent.php +++ b/src/Event/PostUpdateCheckEvent.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Event; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\EventDispatcher\Event; use EliasHaeussler\ComposerUpdateCheck\IO\OutputBehavior; use EliasHaeussler\ComposerUpdateCheck\Options; diff --git a/src/IO/OutputBehavior.php b/src/IO/OutputBehavior.php index b4833f66..22e1f1b5 100644 --- a/src/IO/OutputBehavior.php +++ b/src/IO/OutputBehavior.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\IO\IOInterface; /** diff --git a/src/IO/Style.php b/src/IO/Style.php index ae44580e..4bb424be 100644 --- a/src/IO/Style.php +++ b/src/IO/Style.php @@ -25,25 +25,6 @@ use InvalidArgumentException; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - /** * Style. * diff --git a/src/IO/Verbosity.php b/src/IO/Verbosity.php index e7ac107a..628a9787 100644 --- a/src/IO/Verbosity.php +++ b/src/IO/Verbosity.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use InvalidArgumentException; use Symfony\Component\Console\Output\OutputInterface; diff --git a/src/Options.php b/src/Options.php index 38284973..8988b367 100644 --- a/src/Options.php +++ b/src/Options.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Symfony\Component\Console\Input\InputInterface; /** diff --git a/src/Package/OutdatedPackage.php b/src/Package/OutdatedPackage.php index 02c94452..2ab8604e 100644 --- a/src/Package/OutdatedPackage.php +++ b/src/Package/OutdatedPackage.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Package; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Nyholm\Psr7\Uri; use Psr\Http\Message\UriInterface; diff --git a/src/Package/UpdateCheckResult.php b/src/Package/UpdateCheckResult.php index bd786964..1ab252cc 100644 --- a/src/Package/UpdateCheckResult.php +++ b/src/Package/UpdateCheckResult.php @@ -25,25 +25,6 @@ use InvalidArgumentException; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - /** * UpdateCheckResult. * diff --git a/src/Plugin.php b/src/Plugin.php index 4743aa48..4bcb0c38 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Composer; use Composer\IO\IOInterface; use Composer\Plugin\Capability\CommandProvider; diff --git a/src/Security/InsecurePackage.php b/src/Security/InsecurePackage.php index 82ad5485..94dbb3ff 100644 --- a/src/Security/InsecurePackage.php +++ b/src/Security/InsecurePackage.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - /** * InsecurePackage. * diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index 91d1fbe5..134c776c 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Semver\Semver; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use InvalidArgumentException; diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index d142790f..42521487 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Uri; diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 4b56eefc..9890eabd 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Composer; use Composer\IO\IOInterface; use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent; diff --git a/src/Utility/Composer.php b/src/Utility/Composer.php index 7bbb4ac2..a13ba67b 100644 --- a/src/Utility/Composer.php +++ b/src/Utility/Composer.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Utility; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Plugin\PluginInterface; use InvalidArgumentException; diff --git a/src/Utility/Installer.php b/src/Utility/Installer.php index b2f5b07a..85f1efcf 100644 --- a/src/Utility/Installer.php +++ b/src/Utility/Installer.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Utility; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Composer; use Composer\DependencyResolver\Request; use Composer\Installer as ComposerInstaller; diff --git a/src/Utility/Security.php b/src/Utility/Security.php index 63ffcadd..28f81708 100644 --- a/src/Utility/Security.php +++ b/src/Utility/Security.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Utility; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; diff --git a/tests/Unit/AbstractTestCase.php b/tests/Unit/AbstractTestCase.php index 0ec36585..8a7675be 100644 --- a/tests/Unit/AbstractTestCase.php +++ b/tests/Unit/AbstractTestCase.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use PHPUnit\Framework\TestCase; use ReflectionClass; diff --git a/tests/Unit/Command/UpdateCheckCommandTest.php b/tests/Unit/Command/UpdateCheckCommandTest.php index 1ab0b28e..edc17f09 100644 --- a/tests/Unit/Command/UpdateCheckCommandTest.php +++ b/tests/Unit/Command/UpdateCheckCommandTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Command; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Composer; use Composer\Console\Application; use Composer\Json\JsonValidationException; diff --git a/tests/Unit/ExpectedCommandOutputTrait.php b/tests/Unit/ExpectedCommandOutputTrait.php index 0b07467c..6d803125 100644 --- a/tests/Unit/ExpectedCommandOutputTrait.php +++ b/tests/Unit/ExpectedCommandOutputTrait.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; /** diff --git a/tests/Unit/IO/StyleTest.php b/tests/Unit/IO/StyleTest.php index 59b5529e..72edbe41 100644 --- a/tests/Unit/IO/StyleTest.php +++ b/tests/Unit/IO/StyleTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\IO; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\IO\Style; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; diff --git a/tests/Unit/IO/VerbosityTest.php b/tests/Unit/IO/VerbosityTest.php index ba9772e3..8a7f331e 100644 --- a/tests/Unit/IO/VerbosityTest.php +++ b/tests/Unit/IO/VerbosityTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\IO; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\IO\Verbosity; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; diff --git a/tests/Unit/OptionsTest.php b/tests/Unit/OptionsTest.php index 41d86118..a9a1b722 100644 --- a/tests/Unit/OptionsTest.php +++ b/tests/Unit/OptionsTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Options; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputDefinition; diff --git a/tests/Unit/Package/OutdatedPackageTest.php b/tests/Unit/Package/OutdatedPackageTest.php index b5b93e1b..4bd5155d 100644 --- a/tests/Unit/Package/OutdatedPackageTest.php +++ b/tests/Unit/Package/OutdatedPackageTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Nyholm\Psr7\Uri; diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index 4ea4cb75..c108bd47 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/Unit/Security/InsecurePackageTest.php index 03dbb7f5..60345824 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/Unit/Security/InsecurePackageTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Security\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index b4cba65b..bfe25538 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Security\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; diff --git a/tests/Unit/Security/SecurityScannerTest.php b/tests/Unit/Security/SecurityScannerTest.php index 6bc98649..72455851 100644 --- a/tests/Unit/Security/SecurityScannerTest.php +++ b/tests/Unit/Security/SecurityScannerTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2021 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; diff --git a/tests/Unit/TestApplicationTrait.php b/tests/Unit/TestApplicationTrait.php index d59a91c0..875ab0db 100644 --- a/tests/Unit/TestApplicationTrait.php +++ b/tests/Unit/TestApplicationTrait.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Symfony\Component\Filesystem\Filesystem; /** diff --git a/tests/Unit/UpdateCheckerTest.php b/tests/Unit/UpdateCheckerTest.php index 37f7a2ea..afad8d22 100644 --- a/tests/Unit/UpdateCheckerTest.php +++ b/tests/Unit/UpdateCheckerTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Composer; use Composer\Console\Application; use Composer\IO\NullIO; diff --git a/tests/Unit/Utility/ComposerTest.php b/tests/Unit/Utility/ComposerTest.php index 661452b8..7e2da0c9 100644 --- a/tests/Unit/Utility/ComposerTest.php +++ b/tests/Unit/Utility/ComposerTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Plugin\PluginInterface; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; diff --git a/tests/Unit/Utility/InstallerTest.php b/tests/Unit/Utility/InstallerTest.php index 6f984c19..15c941fe 100644 --- a/tests/Unit/Utility/InstallerTest.php +++ b/tests/Unit/Utility/InstallerTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use Composer\Composer as BaseComposer; use Composer\Console\Application; use Composer\Json\JsonValidationException; diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/Unit/Utility/SecurityTest.php index 492f3116..f04d8f63 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/Unit/Utility/SecurityTest.php @@ -23,25 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; -/* - * This file is part of the Composer package "eliashaeussler/composer-update-check". - * - * Copyright (C) 2020 Elias Häußler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; From dce8a23b6511ac875eeb8b35ce054210fed2dfa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:38:03 +0100 Subject: [PATCH 011/286] [BUGFIX] Fix issues reported by PHPStan --- .dockerignore | 1 + .gitattributes | 1 + composer.json | 1 + composer.lock | 74 ++++++++++++++++++++- phpstan-baseline.neon | 29 ++++++++ phpstan.php | 6 ++ src/Options.php | 2 +- src/Security/SecurityScanner.php | 5 +- src/Utility/Installer.php | 28 ++------ tests/Build/phpstan/console-application.php | 29 ++++++++ 10 files changed, 148 insertions(+), 28 deletions(-) create mode 100644 phpstan-baseline.neon create mode 100644 tests/Build/phpstan/console-application.php diff --git a/.dockerignore b/.dockerignore index d53eb31a..706eb8f8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,4 +12,5 @@ /Dockerfile /mkdocs.yml /phpstan.php +/phpstan-baseline.neon /phpunit.xml diff --git a/.gitattributes b/.gitattributes index 862d50ec..784b8386 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15,5 +15,6 @@ /Dockerfile export-ignore /mkdocs.yml export-ignore /phpstan.php export-ignore +/phpstan-baseline.neon export-ignore /phpunit.xml export-ignore /renovate.json export-ignore diff --git a/composer.json b/composer.json index 7f07b358..7d85258b 100644 --- a/composer.json +++ b/composer.json @@ -40,6 +40,7 @@ "php-http/httplug": "^2.4", "php-http/mock-client": "^1.6", "phpstan/extension-installer": "^1.3", + "phpstan/phpstan-symfony": "^1.3", "phpunit/phpunit": "^10.4", "symfony/filesystem": "^5.4 || ^6.0" }, diff --git a/composer.lock b/composer.lock index e68cd74f..b5c765f6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2664979938ada1d6863991536458fdff", + "content-hash": "1db4ed18e70de4518ff66a1037ba464b", "packages": [ { "name": "nyholm/psr7", @@ -3605,6 +3605,78 @@ }, "time": "2023-10-30T14:35:06+00:00" }, + { + "name": "phpstan/phpstan-symfony", + "version": "1.3.5", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-symfony.git", + "reference": "27ff6339f83796a7e0dd963cf445cd3c456fc620" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/27ff6339f83796a7e0dd963cf445cd3c456fc620", + "reference": "27ff6339f83796a7e0dd963cf445cd3c456fc620", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10.36" + }, + "conflict": { + "symfony/framework-bundle": "<3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.3.11", + "phpstan/phpstan-strict-rules": "^1.5.1", + "phpunit/phpunit": "^8.5.29 || ^9.5", + "psr/container": "1.0 || 1.1.1", + "symfony/config": "^5.4 || ^6.1", + "symfony/console": "^5.4 || ^6.1", + "symfony/dependency-injection": "^5.4 || ^6.1", + "symfony/form": "^5.4 || ^6.1", + "symfony/framework-bundle": "^5.4 || ^6.1", + "symfony/http-foundation": "^5.4 || ^6.1", + "symfony/messenger": "^5.4", + "symfony/polyfill-php80": "^1.24", + "symfony/serializer": "^5.4", + "symfony/service-contracts": "^2.2.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukáš Unger", + "email": "looky.msc@gmail.com", + "homepage": "https://lookyman.net" + } + ], + "description": "Symfony Framework extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-symfony/issues", + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.3.5" + }, + "time": "2023-10-30T14:52:15+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "10.1.9", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 00000000..484d615b --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,29 @@ +parameters: + ignoreErrors: + - + message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\OutdatedPackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\OutdatedPackage will always evaluate to true\\.$#" + count: 1 + path: src/Package/UpdateCheckResult.php + + - + message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Security\\\\InsecurePackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Security\\\\InsecurePackage will always evaluate to true\\.$#" + count: 1 + path: src/Security/ScanResult.php + + - + message: """ + #^Call to deprecated method setRunScripts\\(\\) of class Composer\\\\Installer\\: + Use setRunScripts\\(false\\) on the EventDispatcher instance being injected instead$# + """ + count: 1 + path: src/Utility/Installer.php + + - + message: "#^Call to function method_exists\\(\\) with Composer\\\\EventDispatcher\\\\EventDispatcher and 'setRunScripts' will always evaluate to true\\.$#" + count: 1 + path: src/Utility/Installer.php + + - + message: "#^Variable property access on \\$this\\(EliasHaeussler\\\\ComposerUpdateCheck\\\\Tests\\\\Unit\\\\AbstractTestCase\\)\\.$#" + count: 1 + path: tests/Unit/AbstractTestCase.php diff --git a/phpstan.php b/phpstan.php index 96ac18a3..314b7dac 100644 --- a/phpstan.php +++ b/phpstan.php @@ -23,6 +23,10 @@ use EliasHaeussler\PHPStanConfig; +$symfonySet = PHPStanConfig\Set\SymfonySet::create() + ->withConsoleApplicationLoader('Tests/Build/phpstan/console-application.php') +; + return PHPStanConfig\Config\Config::create(__DIR__) ->in( 'src', @@ -31,6 +35,8 @@ ->not( 'tests/Build/*', ) + ->withBaseline() ->level(6) + ->withSets($symfonySet) ->toArray() ; diff --git a/src/Options.php b/src/Options.php index 8988b367..80b4f021 100644 --- a/src/Options.php +++ b/src/Options.php @@ -56,7 +56,7 @@ public static function fromInput(InputInterface $input): self $instance->setIgnorePackages($input->getOption('ignore-packages')); } if ($input->hasOption('no-dev')) { - $instance->setIncludeDevPackages(!$input->getOption('no-dev')); + $instance->setIncludeDevPackages(false === $input->getOption('no-dev')); } if ($input->hasOption('security-scan')) { $instance->setPerformSecurityScan($input->getOption('security-scan')); diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index 42521487..37fe67ad 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -24,6 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use JsonException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Uri; use Psr\Http\Client\ClientExceptionInterface; @@ -85,8 +86,8 @@ public function scan(array $packages): ScanResult $response = $this->client->sendRequest($request); $apiResult = $response->getBody()->__toString(); - return ScanResult::fromApiResult(json_decode($apiResult, true) ?: []); - } catch (ClientExceptionInterface $e) { + return ScanResult::fromApiResult(json_decode($apiResult, true, 512, JSON_THROW_ON_ERROR)); + } catch (ClientExceptionInterface|JsonException $e) { throw new RuntimeException('Error while scanning security vulnerabilities.', 1610706128, $e); } } diff --git a/src/Utility/Installer.php b/src/Utility/Installer.php index 85f1efcf..0dac316e 100644 --- a/src/Utility/Installer.php +++ b/src/Utility/Installer.php @@ -78,30 +78,10 @@ public static function runUpdate(array $packages, Composer $composer): int ->setPreferSource('source' === $preferredInstall) ->setPreferDist('dist' === $preferredInstall) ->setDevMode(true) - ->setUpdate(true); - - if (method_exists($installer, 'setUpdateAllowList')) { - // Composer >= 2.0 - $installer->setUpdateAllowList($packages); - } else { - // Composer < 2.0 - /* @noinspection PhpUndefinedMethodInspection */ - /* @phpstan-ignore-next-line */ - $installer->setUpdateWhitelist($packages); - } - - if (method_exists($installer, 'setUpdateAllowTransitiveDependencies')) { - // Composer >= 2.0 - $installer->setUpdateAllowTransitiveDependencies(Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS); - } elseif (method_exists($installer, 'setAllowListAllDependencies')) { - // Composer >= 1.10.8 - $installer->setAllowListAllDependencies(true); - } else { - // Composer < 1.10.8 - /* @noinspection PhpUndefinedMethodInspection */ - /* @phpstan-ignore-next-line */ - $installer->setWhitelistDependencies(true); - } + ->setUpdate(true) + ->setUpdateAllowList($packages) + ->setUpdateAllowTransitiveDependencies(Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS) + ; return $installer->run(); } diff --git a/tests/Build/phpstan/console-application.php b/tests/Build/phpstan/console-application.php new file mode 100644 index 00000000..21bb1b35 --- /dev/null +++ b/tests/Build/phpstan/console-application.php @@ -0,0 +1,29 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +require_once __DIR__.'/../../../vendor/autoload.php'; + +$application = new \Symfony\Component\Console\Application(); +$application->add(new \EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand()); + +return $application; From c156695e53e8beb362410f11950f6da717f0770a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:39:52 +0100 Subject: [PATCH 012/286] [TASK] Normalize composer.json in test applications --- composer.json | 7 +++++- .../test-application-empty/composer.json | 14 +++++------ .../test-application-erroneous/composer.json | 8 +++---- tests/Build/test-application/v8/composer.json | 24 +++++++++---------- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index 7d85258b..67cfb8a1 100644 --- a/composer.json +++ b/composer.json @@ -82,7 +82,12 @@ "@lint:editorconfig", "@lint:php" ], - "lint:composer": "@composer normalize", + "lint:composer": [ + "@composer normalize", + "@composer normalize tests/Build/test-application/v8/composer.json", + "@composer normalize tests/Build/test-application-empty/composer.json", + "@composer normalize tests/Build/test-application-erroneous/composer.json --no-check-lock --no-update-lock" + ], "lint:editorconfig": "ec --fix --git-only", "lint:php": "php-cs-fixer fix", "sca": [ diff --git a/tests/Build/test-application-empty/composer.json b/tests/Build/test-application-empty/composer.json index 09d488cf..d0084b07 100644 --- a/tests/Build/test-application-empty/composer.json +++ b/tests/Build/test-application-empty/composer.json @@ -1,9 +1,9 @@ { - "require": {}, - "require-dev": {}, - "config": { - "allow-plugins": { - "eliashaeussler/composer-update-check": true - } - } + "require": {}, + "require-dev": {}, + "config": { + "allow-plugins": { + "eliashaeussler/composer-update-check": true + } + } } diff --git a/tests/Build/test-application-erroneous/composer.json b/tests/Build/test-application-erroneous/composer.json index f83c9a7d..60c45717 100644 --- a/tests/Build/test-application-erroneous/composer.json +++ b/tests/Build/test-application-erroneous/composer.json @@ -1,6 +1,6 @@ { - "require": { - "composer/composer": "^1.0", - "symfony/http-kernel": "^4.4" - } + "require": { + "composer/composer": "^1.0", + "symfony/http-kernel": "^4.4" + } } diff --git a/tests/Build/test-application/v8/composer.json b/tests/Build/test-application/v8/composer.json index a32c2fbd..085f8a08 100644 --- a/tests/Build/test-application/v8/composer.json +++ b/tests/Build/test-application/v8/composer.json @@ -1,14 +1,14 @@ { - "require": { - "symfony/console": "^4.4", - "symfony/http-kernel": "^4.4" - }, - "require-dev": { - "codeception/codeception": "^4.1" - }, - "config": { - "allow-plugins": { - "eliashaeussler/composer-update-check": true - } - } + "require": { + "symfony/console": "^4.4", + "symfony/http-kernel": "^4.4" + }, + "require-dev": { + "codeception/codeception": "^4.1" + }, + "config": { + "allow-plugins": { + "eliashaeussler/composer-update-check": true + } + } } From ad227d0b5af0208f78024595403551c3244e300a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:41:56 +0100 Subject: [PATCH 013/286] [TASK] Streamline test applications --- composer.json | 2 +- .../test-application/{v8 => }/composer.json | 0 .../test-application/{v8 => }/composer.lock | 0 tests/Unit/TestApplicationTrait.php | 18 +----------------- 4 files changed, 2 insertions(+), 18 deletions(-) rename tests/Build/test-application/{v8 => }/composer.json (100%) rename tests/Build/test-application/{v8 => }/composer.lock (100%) diff --git a/composer.json b/composer.json index 67cfb8a1..ee5268c8 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ ], "lint:composer": [ "@composer normalize", - "@composer normalize tests/Build/test-application/v8/composer.json", + "@composer normalize tests/Build/test-application/composer.json", "@composer normalize tests/Build/test-application-empty/composer.json", "@composer normalize tests/Build/test-application-erroneous/composer.json --no-check-lock --no-update-lock" ], diff --git a/tests/Build/test-application/v8/composer.json b/tests/Build/test-application/composer.json similarity index 100% rename from tests/Build/test-application/v8/composer.json rename to tests/Build/test-application/composer.json diff --git a/tests/Build/test-application/v8/composer.lock b/tests/Build/test-application/composer.lock similarity index 100% rename from tests/Build/test-application/v8/composer.lock rename to tests/Build/test-application/composer.lock diff --git a/tests/Unit/TestApplicationTrait.php b/tests/Unit/TestApplicationTrait.php index 875ab0db..4e23e508 100644 --- a/tests/Unit/TestApplicationTrait.php +++ b/tests/Unit/TestApplicationTrait.php @@ -48,30 +48,14 @@ protected function goToTestDirectory(string $applicationPath = AbstractTestCase: $this->initialDirectory = getcwd(); $this->temporaryDirectory = tempnam(sys_get_temp_dir(), str_replace('\\', '', strtolower(static::class))); - $applicationVariant = $this->getApplicationVariant($applicationPath); - if (null !== $applicationVariant) { - $applicationVariant = '/'.$applicationVariant; - } - $filesystem = new Filesystem(); $filesystem->remove($this->temporaryDirectory); - $filesystem->mirror(dirname(__DIR__, 2).'/'.$applicationPath.$applicationVariant, $this->temporaryDirectory); + $filesystem->mirror(dirname(__DIR__, 2).'/'.$applicationPath, $this->temporaryDirectory); chdir($this->temporaryDirectory); $this->cleanUpComposerEnvironment(); } - protected function getApplicationVariant(string $applicationPath): ?string - { - switch ($applicationPath) { - case AbstractTestCase::TEST_APPLICATION_NORMAL: - return 'v'.PHP_MAJOR_VERSION; - - default: - return null; - } - } - protected function goBackToInitialDirectory(): void { if (is_string($this->initialDirectory)) { From 2e85b480baee58dcc1fdd58c03bdd0a9d9b23e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 11:45:07 +0100 Subject: [PATCH 014/286] [TASK] Streamline Composer scripts --- .github/workflows/cgl.yaml | 6 +++--- composer.json | 22 +++++++++++++++------- docs/contribute.md | 17 +++++++++++++++-- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index 1902e59e..cbc3a94e 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -44,11 +44,11 @@ jobs: # Linting - name: Lint composer.json - run: composer lint:composer -- --dry-run + run: composer lint:composer - name: Lint .editorconfig - run: vendor/bin/ec --git-only + run: composer lint:editorconfig - name: Lint PHP - run: composer lint:php -- --dry-run + run: composer lint:php # SCA - name: SCA PHP diff --git a/composer.json b/composer.json index ee5268c8..006d416c 100644 --- a/composer.json +++ b/composer.json @@ -77,19 +77,27 @@ "docs:open": "open http://$(docker-compose -f docs/build/docker-compose.yaml port docs 8000)", "docs:start": "@docs:exec up -d", "docs:stop": "@docs:exec down", - "lint": [ - "@lint:composer", - "@lint:editorconfig", - "@lint:php" + "fix": [ + "@fix:composer", + "@fix:editorconfig", + "@fix:php" ], - "lint:composer": [ + "fix:composer": [ "@composer normalize", "@composer normalize tests/Build/test-application/composer.json", "@composer normalize tests/Build/test-application-empty/composer.json", "@composer normalize tests/Build/test-application-erroneous/composer.json --no-check-lock --no-update-lock" ], - "lint:editorconfig": "ec --fix --git-only", - "lint:php": "php-cs-fixer fix", + "fix:editorconfig": "@lint:editorconfig --fix", + "fix:php": "php-cs-fixer fix", + "lint": [ + "@lint:composer", + "@lint:editorconfig", + "@lint:php" + ], + "lint:composer": "@fix:composer --dry-run", + "lint:editorconfig": "ec --git-only", + "lint:php": "@fix:php --dry-run", "sca": [ "@sca:php" ], diff --git a/docs/contribute.md b/docs/contribute.md index 00ac0859..6ba44c94 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -22,13 +22,26 @@ composer install Code quality can be checked by running the following commands: ```bash -# Run linters +# All linters composer lint + +# Specific linters composer lint:composer +composer lint:editorconfig composer lint:php -# Run static code analysis +# Fix all CGL issues +composer fix + +# Fix specific CGL issues +composer fix:composer +composer fix:editorconfig +composer fix:php + +# All static code analyzers composer sca + +# Specific static code analyzers composer sca:php ``` From 61d03c1268761587fe6204c716635e92690d4769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 24 Nov 2023 12:05:44 +0100 Subject: [PATCH 015/286] [TASK] Perform automatic code migration with Rector --- .github/workflows/cgl.yaml | 4 + composer.json | 5 + composer.lock | 118 ++++++++++++++- rector.php | 57 +++++++ src/Capability/UpdateCheckCommandProvider.php | 2 +- src/Command/UpdateCheckCommand.php | 12 +- src/Event/PostUpdateCheckEvent.php | 26 +--- src/IO/OutputBehavior.php | 28 +--- src/IO/Style.php | 13 +- src/IO/Verbosity.php | 13 +- src/Options.php | 16 +- src/Package/OutdatedPackage.php | 39 +---- src/Package/UpdateCheckResult.php | 36 +++-- src/Plugin.php | 24 +-- src/Security/InsecurePackage.php | 21 +-- src/Security/ScanResult.php | 13 +- src/Security/SecurityScanner.php | 14 +- src/UpdateChecker.php | 30 +--- src/Utility/Composer.php | 16 +- src/Utility/Installer.php | 5 +- src/Utility/Security.php | 4 +- tests/Unit/AbstractTestCase.php | 8 +- tests/Unit/Command/UpdateCheckCommandTest.php | 141 +++++++---------- tests/Unit/IO/StyleTest.php | 53 +++---- tests/Unit/IO/VerbosityTest.php | 69 ++++----- tests/Unit/OptionsTest.php | 44 +++--- tests/Unit/Package/OutdatedPackageTest.php | 93 +++++------- tests/Unit/Package/UpdateCheckResultTest.php | 52 +++---- tests/Unit/Security/InsecurePackageTest.php | 32 ++-- tests/Unit/Security/ScanResultTest.php | 47 +++--- tests/Unit/Security/SecurityScannerTest.php | 47 +++--- tests/Unit/TestApplicationTrait.php | 11 +- tests/Unit/UpdateCheckerTest.php | 143 +++++++----------- tests/Unit/Utility/ComposerTest.php | 31 ++-- tests/Unit/Utility/InstallerTest.php | 30 ++-- tests/Unit/Utility/SecurityTest.php | 19 +-- 36 files changed, 584 insertions(+), 732 deletions(-) create mode 100644 rector.php diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index cbc3a94e..47acf98f 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -53,3 +53,7 @@ jobs: # SCA - name: SCA PHP run: composer sca:php -- --error-format github + + # Migration + - name: Run Rector migration + run: composer migration:rector -- --dry-run diff --git a/composer.json b/composer.json index 006d416c..5f8ad60c 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,7 @@ "composer/semver": "^3.4", "eliashaeussler/php-cs-fixer-config": "^1.3", "eliashaeussler/phpstan-config": "^2.4", + "eliashaeussler/rector-config": "^2.0", "ergebnis/composer-normalize": "^2.39", "php-http/discovery": "^1.19", "php-http/httplug": "^2.4", @@ -98,6 +99,10 @@ "lint:composer": "@fix:composer --dry-run", "lint:editorconfig": "ec --git-only", "lint:php": "@fix:php --dry-run", + "migration": [ + "@migration:rector" + ], + "migration:rector": "rector process -c rector.php", "sca": [ "@sca:php" ], diff --git a/composer.lock b/composer.lock index b5c765f6..d52f7091 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1db4ed18e70de4518ff66a1037ba464b", + "content-hash": "589ea1dd2476547caa86af42ebbe561e", "packages": [ { "name": "nyholm/psr7", @@ -2105,6 +2105,66 @@ }, "time": "2023-11-23T08:48:50+00:00" }, + { + "name": "eliashaeussler/rector-config", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/eliashaeussler/rector-config.git", + "reference": "2eaed22ddc5e893a1b3c415b06863a87d79e7769" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/eliashaeussler/rector-config/zipball/2eaed22ddc5e893a1b3c415b06863a87d79e7769", + "reference": "2eaed22ddc5e893a1b3c415b06863a87d79e7769", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "rector/rector": "^0.15.21 || ^0.16.0 || ^0.17.0 || ^0.18.0" + }, + "require-dev": { + "armin/editorconfig-cli": "^1.5", + "composer/composer": "^2.0", + "eliashaeussler/php-cs-fixer-config": "^1.1", + "eliashaeussler/phpstan-config": "^2.0", + "ergebnis/composer-normalize": "^2.30", + "phpstan/extension-installer": "^1.2", + "phpunit/phpunit": "^10.1", + "ssch/typo3-rector": "^1.2", + "symfony/config": "^5.4 || ^6.0", + "symfony/dependency-injection": "^5.4 || ^6.0", + "typo3/cms-core": "^12.4" + }, + "suggest": { + "ssch/typo3-rector": "Configures additional Rector rules for TYPO3 CMS projects" + }, + "type": "library", + "autoload": { + "psr-4": { + "EliasHaeussler\\RectorConfig\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Elias Häußler", + "email": "elias@haeussler.dev", + "homepage": "https://haeussler.dev", + "role": "Maintainer" + } + ], + "description": "My personal configuration for Rector", + "support": { + "issues": "https://github.com/eliashaeussler/rector-config/issues", + "source": "https://github.com/eliashaeussler/rector-config/tree/2.0.0" + }, + "time": "2023-11-17T16:20:45+00:00" + }, { "name": "ergebnis/composer-normalize", "version": "2.39.0", @@ -4225,6 +4285,62 @@ ], "time": "2022-02-11T10:27:51+00:00" }, + { + "name": "rector/rector", + "version": "0.18.10", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "f36bc0a707fd8af301df5108740ce41f9db8eded" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/f36bc0a707fd8af301df5108740ce41f9db8eded", + "reference": "f36bc0a707fd8af301df5108740ce41f9db8eded", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.35" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.18.10" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-11-16T19:42:21+00:00" + }, { "name": "sebastian/cli-parser", "version": "2.0.0", diff --git a/rector.php b/rector.php new file mode 100644 index 00000000..df0361b6 --- /dev/null +++ b/rector.php @@ -0,0 +1,57 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +use EliasHaeussler\RectorConfig\Config\Config; +use Rector\Config\RectorConfig; +use Rector\Core\ValueObject\PhpVersion; +use Rector\Php80\Rector\Class_\AnnotationToAttributeRector; +use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector; + +return static function (RectorConfig $rectorConfig): void { + Config::create($rectorConfig, PhpVersion::PHP_81) + ->in( + __DIR__.'/src', + __DIR__.'/tests', + ) + ->withPHPUnit() + ->skip( + AnnotationToAttributeRector::class, + [ + __DIR__.'/src/Capability/UpdateCheckCommandProvider.php', + __DIR__.'/src/Event/PostUpdateCheckEvent.php', + __DIR__.'/src/Plugin.php', + ], + ) +// ->skip( +// FinalizeClassesWithoutChildrenRector::class, +// [ +// __DIR__.'/src/Sitemap/Sitemap.php', +// __DIR__.'/src/Sitemap/Url.php', +// // For some reason Rector does not recognize child classes +// // of this fixture class, therefore we need to skip it here +// __DIR__.'/tests/src/Fixtures/Classes/DummyCrawler.php', +// ], +// ) + ->apply() + ; +}; diff --git a/src/Capability/UpdateCheckCommandProvider.php b/src/Capability/UpdateCheckCommandProvider.php index 628cae1c..53d3a889 100644 --- a/src/Capability/UpdateCheckCommandProvider.php +++ b/src/Capability/UpdateCheckCommandProvider.php @@ -34,7 +34,7 @@ * * @codeCoverageIgnore */ -class UpdateCheckCommandProvider implements CommandProvider +final class UpdateCheckCommandProvider implements CommandProvider { public function getCommands(): array { diff --git a/src/Command/UpdateCheckCommand.php b/src/Command/UpdateCheckCommand.php index 4be74b42..847b2ab3 100644 --- a/src/Command/UpdateCheckCommand.php +++ b/src/Command/UpdateCheckCommand.php @@ -43,17 +43,11 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class UpdateCheckCommand extends BaseCommand +final class UpdateCheckCommand extends BaseCommand { - /** - * @var SymfonyStyle - */ - private $symfonyStyle; + private ?SymfonyStyle $symfonyStyle = null; - /** - * @var OutputBehavior - */ - private $behavior; + private ?OutputBehavior $behavior = null; protected function configure(): void { diff --git a/src/Event/PostUpdateCheckEvent.php b/src/Event/PostUpdateCheckEvent.php index e29f51ac..71fb1140 100644 --- a/src/Event/PostUpdateCheckEvent.php +++ b/src/Event/PostUpdateCheckEvent.php @@ -36,40 +36,22 @@ * * @codeCoverageIgnore */ -class PostUpdateCheckEvent extends Event +final class PostUpdateCheckEvent extends Event { public const NAME = 'post-update-check'; - /** - * @var UpdateCheckResult - */ - private $updateCheckResult; - - /** - * @var OutputBehavior - */ - private $behavior; - - /** - * @var Options - */ - private $options; - /** * @param string[] $args * @param string[] $flags */ public function __construct( - UpdateCheckResult $updateCheckResult, - OutputBehavior $behavior, - Options $options, + private readonly UpdateCheckResult $updateCheckResult, + private readonly OutputBehavior $behavior, + private readonly Options $options, array $args = [], array $flags = [], ) { parent::__construct(self::NAME, $args, $flags); - $this->updateCheckResult = $updateCheckResult; - $this->behavior = $behavior; - $this->options = $options; } public function getUpdateCheckResult(): UpdateCheckResult diff --git a/src/IO/OutputBehavior.php b/src/IO/OutputBehavior.php index 22e1f1b5..dab8d150 100644 --- a/src/IO/OutputBehavior.php +++ b/src/IO/OutputBehavior.php @@ -31,27 +31,11 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class OutputBehavior +final class OutputBehavior { - /** - * @var Style - */ - public $style; - - /** - * @var Verbosity - */ - public $verbosity; - - /** - * @var IOInterface - */ - public $io; - - public function __construct(Style $style, Verbosity $verbosity, IOInterface $io) - { - $this->style = $style; - $this->verbosity = $verbosity; - $this->io = $io; - } + public function __construct( + public readonly Style $style, + public readonly Verbosity $verbosity, + public readonly IOInterface $io, + ) {} } diff --git a/src/IO/Style.php b/src/IO/Style.php index 4bb424be..4649f941 100644 --- a/src/IO/Style.php +++ b/src/IO/Style.php @@ -31,19 +31,14 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class Style +final class Style { public const NORMAL = 'normal'; public const JSON = 'json'; - /** - * @var string - */ - private $style; - - public function __construct(string $style = self::NORMAL) - { - $this->style = $style; + public function __construct( + private readonly string $style = self::NORMAL, + ) { $this->validate(); } diff --git a/src/IO/Verbosity.php b/src/IO/Verbosity.php index 628a9787..00f35dcf 100644 --- a/src/IO/Verbosity.php +++ b/src/IO/Verbosity.php @@ -32,7 +32,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class Verbosity +final class Verbosity { public const QUIET = OutputInterface::VERBOSITY_QUIET; public const NORMAL = OutputInterface::VERBOSITY_NORMAL; @@ -40,14 +40,9 @@ class Verbosity public const VERY_VERBOSE = OutputInterface::VERBOSITY_VERY_VERBOSE; public const DEBUG = OutputInterface::VERBOSITY_DEBUG; - /** - * @var int - */ - private $level; - - public function __construct(int $level = OutputInterface::VERBOSITY_NORMAL) - { - $this->level = $level; + public function __construct( + private readonly int $level = OutputInterface::VERBOSITY_NORMAL, + ) { $this->validate(); } diff --git a/src/Options.php b/src/Options.php index 80b4f021..c03d9d87 100644 --- a/src/Options.php +++ b/src/Options.php @@ -31,22 +31,14 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class Options +final class Options { /** * @var string[] */ - private $ignorePackages = []; - - /** - * @var bool - */ - private $includeDevPackages = true; - - /** - * @var bool - */ - private $performSecurityScan = false; + private array $ignorePackages = []; + private bool $includeDevPackages = true; + private bool $performSecurityScan = false; public static function fromInput(InputInterface $input): self { diff --git a/src/Package/OutdatedPackage.php b/src/Package/OutdatedPackage.php index 2ab8604e..7c14c510 100644 --- a/src/Package/OutdatedPackage.php +++ b/src/Package/OutdatedPackage.php @@ -32,41 +32,18 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class OutdatedPackage +final class OutdatedPackage { private const PROVIDER_LINK_PATTERN = 'https://packagist.org/packages/%s#%s'; - /** - * @var string - */ - private $name; + private UriInterface $providerLink; - /** - * @var string - */ - private $outdatedVersion; - - /** - * @var string - */ - private $newVersion; - - /** - * @var bool - */ - private $insecure; - - /** - * @var UriInterface - */ - private $providerLink; - - public function __construct(string $name, string $outdatedVersion, string $newVersion, bool $insecure = false) - { - $this->name = $name; - $this->outdatedVersion = $outdatedVersion; - $this->newVersion = $newVersion; - $this->insecure = $insecure; + public function __construct( + private string $name, + private string $outdatedVersion, + private string $newVersion, + private bool $insecure = false, + ) { $this->providerLink = $this->generateProviderLink(); } diff --git a/src/Package/UpdateCheckResult.php b/src/Package/UpdateCheckResult.php index 1ab252cc..59f547ef 100644 --- a/src/Package/UpdateCheckResult.php +++ b/src/Package/UpdateCheckResult.php @@ -31,9 +31,9 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class UpdateCheckResult +final class UpdateCheckResult { - protected const COMMAND_OUTPUT_PATTERN = + private const COMMAND_OUTPUT_PATTERN = '#^'. '\\s*- Upgrading '. '(?P\\S+) \\('. @@ -42,7 +42,7 @@ class UpdateCheckResult '(?Pdev-\S+ \S+|(?!dev-)\S+)'. '\\)'. '$#'; - protected const LEGACY_COMMAND_OUTPUT_PATTERN = + private const LEGACY_COMMAND_OUTPUT_PATTERN = '#^'. '\\s*- Updating '. '(?Pdev-\\S+ \\S+|(?!dev-)\\S+) \\('. @@ -55,16 +55,15 @@ class UpdateCheckResult /** * @var OutdatedPackage[] */ - private $outdatedPackages; + private readonly array $outdatedPackages; /** * @param OutdatedPackage[] $outdatedPackages */ public function __construct(array $outdatedPackages) { - $this->outdatedPackages = $outdatedPackages; - $this->validateOutdatedPackages(); - $this->sortPackages($this->outdatedPackages); + $this->validateOutdatedPackages($outdatedPackages); + $this->outdatedPackages = $this->sortPackages($outdatedPackages); } /** @@ -83,7 +82,7 @@ public static function fromCommandOutput(string $output, array $allowedPackages) $outputParts = explode(PHP_EOL, $output); $packages = array_unique( array_filter( - array_map([static::class, 'parseCommandOutput'], $outputParts), + array_map([self::class, 'parseCommandOutput'], $outputParts), function (?OutdatedPackage $outdatedPackage) use ($allowedPackages) { if (null === $outdatedPackage) { return false; @@ -101,8 +100,8 @@ function (?OutdatedPackage $outdatedPackage) use ($allowedPackages) { public static function parseCommandOutput(string $output): ?OutdatedPackage { if ( - !preg_match(static::COMMAND_OUTPUT_PATTERN, $output, $matches) - && !preg_match(static::LEGACY_COMMAND_OUTPUT_PATTERN, $output, $matches) + !preg_match(self::COMMAND_OUTPUT_PATTERN, $output, $matches) + && !preg_match(self::LEGACY_COMMAND_OUTPUT_PATTERN, $output, $matches) ) { return null; } @@ -115,17 +114,22 @@ public static function parseCommandOutput(string $output): ?OutdatedPackage /** * @param OutdatedPackage[] $outdatedPackages + * + * @return OutdatedPackage[] */ - private function sortPackages(array &$outdatedPackages): void + private function sortPackages(array $outdatedPackages): array { - usort($outdatedPackages, function (OutdatedPackage $a, OutdatedPackage $b) { - return strcmp($a->getName(), $b->getName()); - }); + usort($outdatedPackages, fn (OutdatedPackage $a, OutdatedPackage $b) => strcmp($a->getName(), $b->getName())); + + return $outdatedPackages; } - private function validateOutdatedPackages(): void + /** + * @param OutdatedPackage[] $outdatedPackages + */ + private function validateOutdatedPackages(array $outdatedPackages): void { - foreach ($this->outdatedPackages as $key => $outdatedPackage) { + foreach ($outdatedPackages as $key => $outdatedPackage) { if (!($outdatedPackage instanceof OutdatedPackage)) { throw new InvalidArgumentException(sprintf('Outdated package #%s must be an instance of "%s".', $key, OutdatedPackage::class), 1600276584); } diff --git a/src/Plugin.php b/src/Plugin.php index 4bcb0c38..2688d6e0 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -38,11 +38,11 @@ * * @codeCoverageIgnore */ -class Plugin implements PluginInterface, Capable +final class Plugin implements PluginInterface, Capable { public function activate(Composer $composer, IOInterface $io): void { - $this->autoloadFunctions($composer); + // Nothing to do here. Just go ahead :) } public function deactivate(Composer $composer, IOInterface $io): void @@ -61,24 +61,4 @@ public function getCapabilities(): array CommandProvider::class => UpdateCheckCommandProvider::class, ]; } - - /** - * Workaround to ensure required functions from dependencies are auto-loaded. - * - * @see https://github.com/composer/composer/issues/4764#issuecomment-379619265 - */ - protected function autoloadFunctions(Composer $composer): void - { - $vendor = $composer->getConfig()->get('vendor-dir'); - - $this->loadFailsafe($vendor.'/symfony/polyfill-php73/bootstrap.php'); - $this->loadFailsafe($vendor.'/symfony/polyfill-php80/bootstrap.php'); - } - - protected function loadFailsafe(string $vendorFile): void - { - if (file_exists($vendorFile)) { - require_once $vendorFile; - } - } } diff --git a/src/Security/InsecurePackage.php b/src/Security/InsecurePackage.php index 94dbb3ff..0e513941 100644 --- a/src/Security/InsecurePackage.php +++ b/src/Security/InsecurePackage.php @@ -29,26 +29,15 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class InsecurePackage +final class InsecurePackage { - /** - * @var string - */ - private $name; - - /** - * @var string[] - */ - private $affectedVersions; - /** * @param string[] $affectedVersions */ - public function __construct(string $name, array $affectedVersions) - { - $this->name = $name; - $this->affectedVersions = $affectedVersions; - } + public function __construct( + private string $name, + private array $affectedVersions, + ) {} public function getName(): string { diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index 134c776c..4f4b7589 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -33,19 +33,14 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class ScanResult +final class ScanResult { - /** - * @var InsecurePackage[] - */ - private $insecurePackages; - /** * @param InsecurePackage[] $insecurePackages */ - public function __construct(array $insecurePackages) - { - $this->insecurePackages = $insecurePackages; + public function __construct( + private readonly array $insecurePackages, + ) { $this->validateInsecurePackages(); } diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index 37fe67ad..48f8110b 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -29,7 +29,6 @@ use Nyholm\Psr7\Uri; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; -use Psr\Http\Message\RequestFactoryInterface; use RuntimeException; use Symfony\Component\HttpClient\Psr18Client; @@ -39,19 +38,12 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class SecurityScanner +final class SecurityScanner { public const API_ENDPOINT = 'https://packagist.org/api/security-advisories'; - /** - * @var RequestFactoryInterface - */ - private $requestFactory; - - /** - * @var ClientInterface - */ - private $client; + private readonly Psr17Factory $requestFactory; + private readonly ClientInterface $client; public function __construct(ClientInterface $client = null) { diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 9890eabd..07bdd41c 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -39,34 +39,18 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class UpdateChecker +final class UpdateChecker { - /** - * @var Composer - */ - private $composer; - - /** - * @var OutputBehavior - */ - private $behavior; - - /** - * @var Options - */ - private $options; - /** * @var string[] */ - private $packageBlacklist = []; + private array $packageBlacklist = []; - public function __construct(Composer $composer, OutputBehavior $behavior, Options $options) - { - $this->composer = $composer; - $this->behavior = $behavior; - $this->options = $options; - } + public function __construct( + private readonly Composer $composer, + private readonly OutputBehavior $behavior, + private readonly Options $options, + ) {} public function run(): UpdateCheckResult { diff --git a/src/Utility/Composer.php b/src/Utility/Composer.php index a13ba67b..e88090d5 100644 --- a/src/Utility/Composer.php +++ b/src/Utility/Composer.php @@ -43,16 +43,12 @@ public static function getPlatformVersion(int $versionType = self::VERSION_FULL) $platformVersion = PluginInterface::PLUGIN_API_VERSION; $versionComponents = explode('.', $platformVersion); - switch ($versionType) { - case self::VERSION_FULL: - return $platformVersion; - case self::VERSION_MAJOR: - return $versionComponents[0]; - case self::VERSION_BRANCH: - return $versionComponents[0].'.'.$versionComponents[1]; - default: - throw new InvalidArgumentException('The given version type is not supported.', 1603794822); - } + return match ($versionType) { + self::VERSION_FULL => $platformVersion, + self::VERSION_MAJOR => $versionComponents[0], + self::VERSION_BRANCH => $versionComponents[0].'.'.$versionComponents[1], + default => throw new InvalidArgumentException('The given version type is not supported.', 1603794822), + }; } public static function getMajorVersion(): int diff --git a/src/Utility/Installer.php b/src/Utility/Installer.php index 0dac316e..1aa0757d 100644 --- a/src/Utility/Installer.php +++ b/src/Utility/Installer.php @@ -38,10 +38,7 @@ */ final class Installer { - /** - * @var BufferIO|null - */ - private static $io; + private static ?BufferIO $io = null; public static function runInstall(Composer $composer): int { diff --git a/src/Utility/Security.php b/src/Utility/Security.php index 28f81708..1337adf1 100644 --- a/src/Utility/Security.php +++ b/src/Utility/Security.php @@ -34,7 +34,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class Security +final class Security { /** * @param OutdatedPackage[] $outdatedPackages @@ -49,7 +49,7 @@ public static function scan(array $outdatedPackages): ScanResult public static function scanAndOverlayResult(UpdateCheckResult $result): UpdateCheckResult { $outdatedPackages = $result->getOutdatedPackages(); - $scanResult = static::scan($outdatedPackages); + $scanResult = self::scan($outdatedPackages); foreach ($outdatedPackages as $outdatedPackage) { if ($scanResult->isInsecure($outdatedPackage)) { $outdatedPackage->setInsecure(true); diff --git a/tests/Unit/AbstractTestCase.php b/tests/Unit/AbstractTestCase.php index 8a7675be..b4fc7102 100644 --- a/tests/Unit/AbstractTestCase.php +++ b/tests/Unit/AbstractTestCase.php @@ -34,9 +34,9 @@ */ abstract class AbstractTestCase extends TestCase { - public const TEST_APPLICATION_NORMAL = 'tests/Build/test-application'; - public const TEST_APPLICATION_EMPTY = 'tests/Build/test-application-empty'; - public const TEST_APPLICATION_ERRONEOUS = 'tests/Build/test-application-erroneous'; + final public const TEST_APPLICATION_NORMAL = 'tests/Build/test-application'; + final public const TEST_APPLICATION_EMPTY = 'tests/Build/test-application-empty'; + final public const TEST_APPLICATION_ERRONEOUS = 'tests/Build/test-application-erroneous'; protected function tearDown(): void { @@ -45,7 +45,7 @@ protected function tearDown(): void if ( !$property->isStatic() && !$property->isPrivate() - && 0 !== strpos($property->getDeclaringClass()->getName(), 'PHPUnit') + && !str_starts_with($property->getDeclaringClass()->getName(), 'PHPUnit') ) { unset($this->{$property->getName()}); } diff --git a/tests/Unit/Command/UpdateCheckCommandTest.php b/tests/Unit/Command/UpdateCheckCommandTest.php index edc17f09..09aa61bf 100644 --- a/tests/Unit/Command/UpdateCheckCommandTest.php +++ b/tests/Unit/Command/UpdateCheckCommandTest.php @@ -23,12 +23,11 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Command; -use Composer\Composer; use Composer\Console\Application; -use Composer\Json\JsonValidationException; use EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; +use PHPUnit\Framework\Attributes\Test; use Symfony\Component\Console\Tester\CommandTester; /** @@ -37,41 +36,23 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class UpdateCheckCommandTest extends AbstractTestCase +final class UpdateCheckCommandTest extends AbstractTestCase { use TestApplicationTrait; - /** - * @var Application - */ - protected $application; + private CommandTester $commandTester; - /** - * @var Composer - */ - protected $composer; - - /** - * @var CommandTester - */ - protected $commandTester; - - /** - * @throws JsonValidationException - */ protected function setUp(): void { $this->goToTestDirectory(); - $this->application = new Application(); - $this->application->add(new UpdateCheckCommand()); - $this->composer = $this->application->getComposer(); - $this->commandTester = new CommandTester($this->application->find('update-check')); + $application = new Application(); + $application->add(new UpdateCheckCommand()); + + $this->commandTester = new CommandTester($application->find('update-check')); } - /** - * @test - */ + #[Test] public function executePrintsNoOutdatedPackagesMessageIfNoPackagesAreRequired(): void { $this->goToTestDirectory(self::TEST_APPLICATION_EMPTY); @@ -79,12 +60,10 @@ public function executePrintsNoOutdatedPackagesMessageIfNoPackagesAreRequired(): $this->commandTester->execute(['--json' => true]); $expected = json_encode(['status' => 'All packages are up to date.']); - static::assertJsonStringEqualsJsonString($expected, $this->commandTester->getDisplay()); + self::assertJsonStringEqualsJsonString($expected, $this->commandTester->getDisplay()); } - /** - * @test - */ + #[Test] public function executePrintsNoOutdatedPackagesMessageIfOutdatedPackagesAreSkipped(): void { $this->commandTester->execute(['--json' => true, '--ignore-packages' => ['symfony/*'], '--no-dev' => true]); @@ -93,12 +72,10 @@ public function executePrintsNoOutdatedPackagesMessageIfOutdatedPackagesAreSkipp 'status' => 'All packages are up to date (skipped 3 packages).', 'skipped' => ['codeception/codeception', 'symfony/console', 'symfony/http-kernel'], ]); - static::assertJsonStringEqualsJsonString($expected, $this->commandTester->getDisplay()); + self::assertJsonStringEqualsJsonString($expected, $this->commandTester->getDisplay()); } - /** - * @test - */ + #[Test] public function executePrintsListOfOutdatedPackagesWithoutDevRequirements(): void { $this->commandTester->execute(['--json' => true, '--no-dev' => true]); @@ -106,21 +83,19 @@ public function executePrintsListOfOutdatedPackagesWithoutDevRequirements(): voi $actualJson = json_decode($this->commandTester->getDisplay(), true); $expectedStatus = '2 packages are outdated.'; - static::assertSame($expectedStatus, $actualJson['status']); - static::assertCount(2, $actualJson['result']); + self::assertSame($expectedStatus, $actualJson['status']); + self::assertCount(2, $actualJson['result']); - static::assertSame('symfony/console', $actualJson['result'][0]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][0]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][0]['New version']); + self::assertSame('symfony/console', $actualJson['result'][0]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][0]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][0]['New version']); - static::assertSame('symfony/http-kernel', $actualJson['result'][1]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); + self::assertSame('symfony/http-kernel', $actualJson['result'][1]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); } - /** - * @test - */ + #[Test] public function executePrintsListOfOutdatedPackagesWithoutSkippedPackages(): void { $this->commandTester->execute(['--json' => true, '--ignore-packages' => ['symfony/console']]); @@ -128,21 +103,19 @@ public function executePrintsListOfOutdatedPackagesWithoutSkippedPackages(): voi $actualJson = json_decode($this->commandTester->getDisplay(), true); $expectedStatus = '2 packages are outdated.'; - static::assertSame($expectedStatus, $actualJson['status']); - static::assertCount(2, $actualJson['result']); + self::assertSame($expectedStatus, $actualJson['status']); + self::assertCount(2, $actualJson['result']); - static::assertSame('codeception/codeception', $actualJson['result'][0]['Package']); - static::assertSame('4.1.9', $actualJson['result'][0]['Outdated version']); - static::assertNotSame('4.1.9', $actualJson['result'][0]['New version']); + self::assertSame('codeception/codeception', $actualJson['result'][0]['Package']); + self::assertSame('4.1.9', $actualJson['result'][0]['Outdated version']); + self::assertNotSame('4.1.9', $actualJson['result'][0]['New version']); - static::assertSame('symfony/http-kernel', $actualJson['result'][1]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); + self::assertSame('symfony/http-kernel', $actualJson['result'][1]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); } - /** - * @test - */ + #[Test] public function executePrintsListOfOutdatedPackages(): void { $this->commandTester->execute(['--json' => true]); @@ -150,25 +123,23 @@ public function executePrintsListOfOutdatedPackages(): void $actualJson = json_decode($this->commandTester->getDisplay(), true); $expectedStatus = '3 packages are outdated.'; - static::assertSame($expectedStatus, $actualJson['status']); - static::assertCount(3, $actualJson['result']); + self::assertSame($expectedStatus, $actualJson['status']); + self::assertCount(3, $actualJson['result']); - static::assertSame('codeception/codeception', $actualJson['result'][0]['Package']); - static::assertSame('4.1.9', $actualJson['result'][0]['Outdated version']); - static::assertNotSame('4.1.9', $actualJson['result'][0]['New version']); + self::assertSame('codeception/codeception', $actualJson['result'][0]['Package']); + self::assertSame('4.1.9', $actualJson['result'][0]['Outdated version']); + self::assertNotSame('4.1.9', $actualJson['result'][0]['New version']); - static::assertSame('symfony/console', $actualJson['result'][1]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); + self::assertSame('symfony/console', $actualJson['result'][1]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); - static::assertSame('symfony/http-kernel', $actualJson['result'][2]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][2]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][2]['New version']); + self::assertSame('symfony/http-kernel', $actualJson['result'][2]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][2]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][2]['New version']); } - /** - * @test - */ + #[Test] public function executePrintsListOfOutdatedPackagesAndFlagsInsecurePackages(): void { $this->commandTester->execute(['--json' => true, '--security-scan' => true]); @@ -176,23 +147,23 @@ public function executePrintsListOfOutdatedPackagesAndFlagsInsecurePackages(): v $actualJson = json_decode($this->commandTester->getDisplay(), true); $expectedStatus = '3 packages are outdated.'; - static::assertSame($expectedStatus, $actualJson['status']); - static::assertCount(3, $actualJson['result']); + self::assertSame($expectedStatus, $actualJson['status']); + self::assertCount(3, $actualJson['result']); - static::assertSame('codeception/codeception', $actualJson['result'][0]['Package']); - static::assertSame('4.1.9', $actualJson['result'][0]['Outdated version']); - static::assertNotSame('4.1.9', $actualJson['result'][0]['New version']); - static::assertTrue($actualJson['result'][0]['Insecure']); + self::assertSame('codeception/codeception', $actualJson['result'][0]['Package']); + self::assertSame('4.1.9', $actualJson['result'][0]['Outdated version']); + self::assertNotSame('4.1.9', $actualJson['result'][0]['New version']); + self::assertTrue($actualJson['result'][0]['Insecure']); - static::assertSame('symfony/console', $actualJson['result'][1]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); - static::assertFalse($actualJson['result'][1]['Insecure']); + self::assertSame('symfony/console', $actualJson['result'][1]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][1]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][1]['New version']); + self::assertFalse($actualJson['result'][1]['Insecure']); - static::assertSame('symfony/http-kernel', $actualJson['result'][2]['Package']); - static::assertSame('v4.4.9', $actualJson['result'][2]['Outdated version']); - static::assertNotSame('v4.4.9', $actualJson['result'][2]['New version']); - static::assertTrue($actualJson['result'][2]['Insecure']); + self::assertSame('symfony/http-kernel', $actualJson['result'][2]['Package']); + self::assertSame('v4.4.9', $actualJson['result'][2]['Outdated version']); + self::assertNotSame('v4.4.9', $actualJson['result'][2]['New version']); + self::assertTrue($actualJson['result'][2]['Insecure']); } protected function tearDown(): void diff --git a/tests/Unit/IO/StyleTest.php b/tests/Unit/IO/StyleTest.php index 72edbe41..844e5760 100644 --- a/tests/Unit/IO/StyleTest.php +++ b/tests/Unit/IO/StyleTest.php @@ -27,6 +27,8 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * StyleTest. @@ -34,11 +36,9 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class StyleTest extends AbstractTestCase +final class StyleTest extends AbstractTestCase { - /** - * @test - */ + #[Test] public function constructorThrowsExceptionIfGivenStyleIsNotSupported(): void { $this->expectException(InvalidArgumentException::class); @@ -47,60 +47,49 @@ public function constructorThrowsExceptionIfGivenStyleIsNotSupported(): void new Style('foo'); } - /** - * @test - */ + #[Test] public function isSupportedReturnsTrueIfGivenStyleIsSupported(): void { - static::assertTrue(Style::isSupported(Style::NORMAL)); - static::assertTrue(Style::isSupported(Style::JSON)); - static::assertFalse(Style::isSupported('foo')); + self::assertTrue(Style::isSupported(Style::NORMAL)); + self::assertTrue(Style::isSupported(Style::JSON)); + self::assertFalse(Style::isSupported('foo')); } - /** - * @test - */ + #[Test] public function isNormalReturnsTrueIfStyleIsNormal(): void { $subject = new Style(Style::NORMAL); - static::assertTrue($subject->isNormal()); - static::assertFalse($subject->isJson()); - static::assertFalse($subject->is('foo')); + self::assertTrue($subject->isNormal()); + self::assertFalse($subject->isJson()); + self::assertFalse($subject->is('foo')); } - /** - * @test - */ + #[Test] public function isJsonReturnsTrueIfStyleIsJson(): void { $subject = new Style(Style::JSON); - static::assertTrue($subject->isJson()); - static::assertFalse($subject->isNormal()); - static::assertFalse($subject->is('foo')); + self::assertTrue($subject->isJson()); + self::assertFalse($subject->isNormal()); + self::assertFalse($subject->is('foo')); } - /** - * @dataProvider isReturnsTrueIfGivenStyleEqualsStyleDataProvider - * - * @test - */ + #[Test] + #[DataProvider('isReturnsTrueIfGivenStyleEqualsStyleDataProvider')] public function isReturnsTrueIfGivenStyleEqualsStyle(string $style): void { $subject = new Style($style); - static::assertTrue($subject->is($style)); + self::assertTrue($subject->is($style)); } - /** - * @test - */ + #[Test] public function getStyleReturnsStyle(): void { $subject = new Style(Style::JSON); - static::assertSame(Style::JSON, $subject->getStyle()); + self::assertSame(Style::JSON, $subject->getStyle()); } /** diff --git a/tests/Unit/IO/VerbosityTest.php b/tests/Unit/IO/VerbosityTest.php index 8a7f331e..3efceb17 100644 --- a/tests/Unit/IO/VerbosityTest.php +++ b/tests/Unit/IO/VerbosityTest.php @@ -27,6 +27,8 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * VerbosityTest. @@ -34,11 +36,9 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class VerbosityTest extends AbstractTestCase +final class VerbosityTest extends AbstractTestCase { - /** - * @test - */ + #[Test] public function constructorThrowsExceptionIfGivenVerbosityIsNotSupported(): void { $this->expectException(InvalidArgumentException::class); @@ -47,89 +47,72 @@ public function constructorThrowsExceptionIfGivenVerbosityIsNotSupported(): void new Verbosity(-1); } - /** - * @test - */ + #[Test] public function isSupportedReturnsTrueIfVerbosityLevelIsSupported(): void { - static::assertTrue(Verbosity::isSupported(Verbosity::QUIET)); - static::assertTrue(Verbosity::isSupported(Verbosity::NORMAL)); - static::assertTrue(Verbosity::isSupported(Verbosity::VERBOSE)); - static::assertTrue(Verbosity::isSupported(Verbosity::VERY_VERBOSE)); - static::assertTrue(Verbosity::isSupported(Verbosity::DEBUG)); - static::assertFalse(Verbosity::isSupported(-1)); + self::assertTrue(Verbosity::isSupported(Verbosity::QUIET)); + self::assertTrue(Verbosity::isSupported(Verbosity::NORMAL)); + self::assertTrue(Verbosity::isSupported(Verbosity::VERBOSE)); + self::assertTrue(Verbosity::isSupported(Verbosity::VERY_VERBOSE)); + self::assertTrue(Verbosity::isSupported(Verbosity::DEBUG)); + self::assertFalse(Verbosity::isSupported(-1)); } - /** - * @test - */ + #[Test] public function isQuietReturnsTrueIfVerbosityLevelIsQuiet(): void { $subject = new Verbosity(Verbosity::QUIET); - static::assertTrue($subject->isQuiet()); + self::assertTrue($subject->isQuiet()); } - /** - * @test - */ + #[Test] public function isNormalReturnsTrueIfVerbosityLevelIsNormal(): void { $subject = new Verbosity(Verbosity::NORMAL); - static::assertTrue($subject->isNormal()); + self::assertTrue($subject->isNormal()); } - /** - * @test - */ + #[Test] public function isVerboseReturnsTrueIfVerbosityLevelIsVerbose(): void { $subject = new Verbosity(Verbosity::VERBOSE); - static::assertTrue($subject->isVerbose()); + self::assertTrue($subject->isVerbose()); } - /** - * @test - */ + #[Test] public function isVeryVerboseReturnsTrueIfVerbosityLevelIsVeryVerbose(): void { $subject = new Verbosity(Verbosity::VERY_VERBOSE); - static::assertTrue($subject->isVeryVerbose()); + self::assertTrue($subject->isVeryVerbose()); } - /** - * @test - */ + #[Test] public function isDebugReturnsTrueIfVerbosityLevelIsDebug(): void { $subject = new Verbosity(Verbosity::DEBUG); - static::assertTrue($subject->isDebug()); + self::assertTrue($subject->isDebug()); } - /** - * @dataProvider isReturnsTrueIfGivenVerbosityEqualsVerbosityDataProvider - * - * @test - */ + #[Test] + #[DataProvider('isReturnsTrueIfGivenVerbosityEqualsVerbosityDataProvider')] public function isReturnsTrueIfGivenVerbosityEqualsVerbosity(int $verbosity): void { $subject = new Verbosity($verbosity); - static::assertTrue($subject->is($verbosity)); + self::assertTrue($subject->is($verbosity)); } - /** - * @test - */ + #[Test] public function getLevelReturnsVerbosityLevel(): void { $subject = new Verbosity(Verbosity::VERBOSE); - static::assertSame(Verbosity::VERBOSE, $subject->getLevel()); + self::assertSame(Verbosity::VERBOSE, $subject->getLevel()); } /** diff --git a/tests/Unit/OptionsTest.php b/tests/Unit/OptionsTest.php index a9a1b722..389c902a 100644 --- a/tests/Unit/OptionsTest.php +++ b/tests/Unit/OptionsTest.php @@ -24,6 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; use EliasHaeussler\ComposerUpdateCheck\Options; +use PHPUnit\Framework\Attributes\Test; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; @@ -34,21 +35,16 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class OptionsTest extends AbstractTestCase +final class OptionsTest extends AbstractTestCase { - /** - * @var Options - */ - protected $subject; + private Options $subject; protected function setUp(): void { $this->subject = new Options(); } - /** - * @test - */ + #[Test] public function fromInputReadsInputOptionsCorrectly(): void { $definition = new InputDefinition([ @@ -64,50 +60,44 @@ public function fromInputReadsInputOptionsCorrectly(): void $subject = Options::fromInput($input); - static::assertSame(['foo/baz'], $subject->getIgnorePackages()); - static::assertFalse($subject->isIncludingDevPackages()); - static::assertTrue($subject->isPerformingSecurityScan()); + self::assertSame(['foo/baz'], $subject->getIgnorePackages()); + self::assertFalse($subject->isIncludingDevPackages()); + self::assertTrue($subject->isPerformingSecurityScan()); } - /** - * @test - */ + #[Test] public function getIgnorePackagesReturnsIgnoredPackages(): void { $this->subject->setIgnorePackages(['foo/*', 'baz/*']); - static::assertSame(['foo/*', 'baz/*'], $this->subject->getIgnorePackages()); + self::assertSame(['foo/*', 'baz/*'], $this->subject->getIgnorePackages()); } - /** - * @test - */ + #[Test] public function isIncludingDevPackagesReturnsCorrectStateOfNoDevOption(): void { - static::assertTrue($this->subject->isIncludingDevPackages()); + self::assertTrue($this->subject->isIncludingDevPackages()); $this->subject->setIncludeDevPackages(false); - static::assertFalse($this->subject->isIncludingDevPackages()); + self::assertFalse($this->subject->isIncludingDevPackages()); $this->subject->setIncludeDevPackages(true); - static::assertTrue($this->subject->isIncludingDevPackages()); + self::assertTrue($this->subject->isIncludingDevPackages()); } - /** - * @test - */ + #[Test] public function isPerformingSecurityScanReturnsCorrectStateOfSecurityScanOption(): void { - static::assertFalse($this->subject->isPerformingSecurityScan()); + self::assertFalse($this->subject->isPerformingSecurityScan()); $this->subject->setPerformSecurityScan(true); - static::assertTrue($this->subject->isPerformingSecurityScan()); + self::assertTrue($this->subject->isPerformingSecurityScan()); $this->subject->setPerformSecurityScan(false); - static::assertFalse($this->subject->isPerformingSecurityScan()); + self::assertFalse($this->subject->isPerformingSecurityScan()); } } diff --git a/tests/Unit/Package/OutdatedPackageTest.php b/tests/Unit/Package/OutdatedPackageTest.php index 4bd5155d..3d255a55 100644 --- a/tests/Unit/Package/OutdatedPackageTest.php +++ b/tests/Unit/Package/OutdatedPackageTest.php @@ -26,6 +26,7 @@ use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Nyholm\Psr7\Uri; +use PHPUnit\Framework\Attributes\Test; /** * OutdatedPackageTest. @@ -33,17 +34,11 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class OutdatedPackageTest extends AbstractTestCase +final class OutdatedPackageTest extends AbstractTestCase { - /** - * @var OutdatedPackage - */ - protected $subjectWithVersion; + private OutdatedPackage $subjectWithVersion; - /** - * @var OutdatedPackage - */ - protected $subjectWithBranch; + private OutdatedPackage $subjectWithBranch; protected function setUp(): void { @@ -61,107 +56,87 @@ protected function setUp(): void ); } - /** - * @test - */ + #[Test] public function getNameReturnsOutdatedPackageName(): void { - static::assertSame('foo', $this->subjectWithVersion->getName()); - static::assertSame('buu', $this->subjectWithBranch->getName()); + self::assertSame('foo', $this->subjectWithVersion->getName()); + self::assertSame('buu', $this->subjectWithBranch->getName()); } - /** - * @test - */ + #[Test] public function setNameSetsNameOfOutdatedPackage(): void { $this->subjectWithVersion->setName('baz'); - static::assertSame('baz', $this->subjectWithVersion->getName()); + self::assertSame('baz', $this->subjectWithVersion->getName()); $this->subjectWithBranch->setName('baz'); - static::assertSame('baz', $this->subjectWithBranch->getName()); + self::assertSame('baz', $this->subjectWithBranch->getName()); } - /** - * @test - */ + #[Test] public function getOutdatedVersionReturnsOutdatedPackageVersion(): void { - static::assertSame('1.0.0', $this->subjectWithVersion->getOutdatedVersion()); - static::assertSame('dev-master 12345', $this->subjectWithBranch->getOutdatedVersion()); + self::assertSame('1.0.0', $this->subjectWithVersion->getOutdatedVersion()); + self::assertSame('dev-master 12345', $this->subjectWithBranch->getOutdatedVersion()); } - /** - * @test - */ + #[Test] public function setOutdatedVersionSetsOutdatedPackageVersionOfOutdatedPackage(): void { $this->subjectWithVersion->setOutdatedVersion('1.0.4'); - static::assertSame('1.0.4', $this->subjectWithVersion->getOutdatedVersion()); + self::assertSame('1.0.4', $this->subjectWithVersion->getOutdatedVersion()); $this->subjectWithBranch->setOutdatedVersion('dev-master 54321'); - static::assertSame('dev-master 54321', $this->subjectWithBranch->getOutdatedVersion()); + self::assertSame('dev-master 54321', $this->subjectWithBranch->getOutdatedVersion()); } - /** - * @test - */ + #[Test] public function getNewVersionReturnsNewPackageVersionOfOutdatedPackage(): void { - static::assertSame('1.0.5', $this->subjectWithVersion->getNewVersion()); - static::assertSame('dev-master 67890', $this->subjectWithBranch->getNewVersion()); + self::assertSame('1.0.5', $this->subjectWithVersion->getNewVersion()); + self::assertSame('dev-master 67890', $this->subjectWithBranch->getNewVersion()); } - /** - * @test - */ + #[Test] public function setNewVersionSetsNewPackageVersionOfOutdatedPackage(): void { $this->subjectWithVersion->setNewVersion('1.1.0'); - static::assertSame('1.1.0', $this->subjectWithVersion->getNewVersion()); + self::assertSame('1.1.0', $this->subjectWithVersion->getNewVersion()); $this->subjectWithBranch->setNewVersion('dev-master 09876'); - static::assertSame('dev-master 09876', $this->subjectWithBranch->getNewVersion()); + self::assertSame('dev-master 09876', $this->subjectWithBranch->getNewVersion()); } - /** - * @test - */ + #[Test] public function isInsecureReturnsSecurityStateOfOutdatedPackage(): void { - static::assertTrue($this->subjectWithVersion->isInsecure()); - static::assertFalse($this->subjectWithBranch->isInsecure()); + self::assertTrue($this->subjectWithVersion->isInsecure()); + self::assertFalse($this->subjectWithBranch->isInsecure()); } - /** - * @test - */ + #[Test] public function setInsecureSetsSecurityStateOfOutdatedPackage(): void { $this->subjectWithVersion->setInsecure(false); - static::assertFalse($this->subjectWithVersion->isInsecure()); + self::assertFalse($this->subjectWithVersion->isInsecure()); $this->subjectWithBranch->setInsecure(true); - static::assertTrue($this->subjectWithBranch->isInsecure()); + self::assertTrue($this->subjectWithBranch->isInsecure()); } - /** - * @test - */ + #[Test] public function getProviderLinkReturnsProviderLinkOfOutdatedPackage(): void { $expected = new Uri('https://packagist.org/packages/foo#1.0.5'); - static::assertEquals($expected, $this->subjectWithVersion->getProviderLink()); + self::assertEquals($expected, $this->subjectWithVersion->getProviderLink()); $expected = new Uri('https://packagist.org/packages/buu#dev-master'); - static::assertEquals($expected, $this->subjectWithBranch->getProviderLink()); + self::assertEquals($expected, $this->subjectWithBranch->getProviderLink()); } - /** - * @test - */ + #[Test] public function setProviderLinkSetsProviderLinkOfOutdatedPackage(): void { $uri = new Uri('https://example.org/foo'); $this->subjectWithVersion->setProviderLink($uri); - static::assertSame($uri, $this->subjectWithVersion->getProviderLink()); + self::assertSame($uri, $this->subjectWithVersion->getProviderLink()); $uri = new Uri('https://example.org/buu'); $this->subjectWithBranch->setProviderLink($uri); - static::assertSame($uri, $this->subjectWithBranch->getProviderLink()); + self::assertSame($uri, $this->subjectWithBranch->getProviderLink()); } } diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index c108bd47..b7079a66 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -29,6 +29,8 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; use Generator; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * UpdateCheckResultTest. @@ -36,13 +38,11 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class UpdateCheckResultTest extends AbstractTestCase +final class UpdateCheckResultTest extends AbstractTestCase { use ExpectedCommandOutputTrait; - /** - * @test - */ + #[Test] public function constructorThrowsExceptionIfOutdatedPackagesAreInvalid(): void { $this->expectException(InvalidArgumentException::class); @@ -53,26 +53,22 @@ public function constructorThrowsExceptionIfOutdatedPackagesAreInvalid(): void new UpdateCheckResult(['foo']); } - /** - * @test - */ + #[Test] public function getOutdatedPackagesReturnsListOfOutdatedPackages(): void { $outdatedPackage1 = new OutdatedPackage('foo', '1.0.0', '1.0.5'); $outdatedPackage2 = new OutdatedPackage('baz', '2.0.1', '2.1.2'); $subject = new UpdateCheckResult([$outdatedPackage1, $outdatedPackage2]); - static::assertCount(2, $subject->getOutdatedPackages()); - static::assertSame([$outdatedPackage2, $outdatedPackage1], $subject->getOutdatedPackages()); + self::assertCount(2, $subject->getOutdatedPackages()); + self::assertSame([$outdatedPackage2, $outdatedPackage1], $subject->getOutdatedPackages()); } /** - * @test - * - * @dataProvider fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackagesDataProvider - * * @param OutdatedPackage[] $expected */ + #[Test] + #[DataProvider('fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackagesDataProvider')] public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdatedPackages( string $commandOutput, array $expected, @@ -80,20 +76,17 @@ public function fromCommandOutputReturnsInstanceWithListOfCorrectlyParsedOutdate $subject = UpdateCheckResult::fromCommandOutput($commandOutput, ['dummy/package', 'foo/baz']); $outdatedPackages = $subject->getOutdatedPackages(); - static::assertCount(count($expected), $outdatedPackages); + self::assertCount(count($expected), $outdatedPackages); - reset($outdatedPackages); foreach ($expected as $expectedOutdatedPackage) { - static::assertSame($expectedOutdatedPackage->getName(), current($outdatedPackages)->getName()); - static::assertSame($expectedOutdatedPackage->getOutdatedVersion(), current($outdatedPackages)->getOutdatedVersion()); - static::assertSame($expectedOutdatedPackage->getNewVersion(), current($outdatedPackages)->getNewVersion()); + self::assertSame($expectedOutdatedPackage->getName(), current($outdatedPackages)->getName()); + self::assertSame($expectedOutdatedPackage->getOutdatedVersion(), current($outdatedPackages)->getOutdatedVersion()); + self::assertSame($expectedOutdatedPackage->getNewVersion(), current($outdatedPackages)->getNewVersion()); next($outdatedPackages); } } - /** - * @test - */ + #[Test] public function fromCommandOutputExcludesNonAllowedPackagesFromResult(): void { $output = implode(PHP_EOL, [ @@ -107,20 +100,17 @@ public function fromCommandOutputExcludesNonAllowedPackagesFromResult(): void $subject = UpdateCheckResult::fromCommandOutput($output, $allowedPackages); $outdatedPackages = $subject->getOutdatedPackages(); - static::assertCount(1, $outdatedPackages); - static::assertSame('foo/baz', reset($outdatedPackages)->getName()); - static::assertSame('1.0.0', reset($outdatedPackages)->getOutdatedVersion()); - static::assertSame('1.0.5', reset($outdatedPackages)->getNewVersion()); + self::assertCount(1, $outdatedPackages); + self::assertSame('foo/baz', reset($outdatedPackages)->getName()); + self::assertSame('1.0.0', reset($outdatedPackages)->getOutdatedVersion()); + self::assertSame('1.0.5', reset($outdatedPackages)->getNewVersion()); } - /** - * @test - * - * @dataProvider parseCommandOutputParsesCommandOutputCorrectlyDataProvider - */ + #[Test] + #[DataProvider('parseCommandOutputParsesCommandOutputCorrectlyDataProvider')] public function parseCommandOutputParsesCommandOutputCorrectly(string $commandOutput, ?OutdatedPackage $expected): void { - static::assertEquals($expected, UpdateCheckResult::parseCommandOutput($commandOutput)); + self::assertEquals($expected, UpdateCheckResult::parseCommandOutput($commandOutput)); } /** diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/Unit/Security/InsecurePackageTest.php index 60345824..531fb07b 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/Unit/Security/InsecurePackageTest.php @@ -25,6 +25,7 @@ use EliasHaeussler\ComposerUpdateCheck\Security\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use PHPUnit\Framework\Attributes\Test; /** * InsecurePackageTest. @@ -32,49 +33,38 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class InsecurePackageTest extends AbstractTestCase +final class InsecurePackageTest extends AbstractTestCase { - /** - * @var InsecurePackage - */ - protected $subject; + private InsecurePackage $subject; protected function setUp(): void { $this->subject = new InsecurePackage('foo', ['>=1.0.0,<1.0.5', '>=2.5.0,<2.6.0']); } - /** - * @test - */ + #[Test] public function getNameReturnsInsecurePackageName(): void { - static::assertSame('foo', $this->subject->getName()); + self::assertSame('foo', $this->subject->getName()); } - /** - * @test - */ + #[Test] public function getNameSetsNameOfInsecurePackage(): void { $this->subject->setName('baz'); - static::assertSame('baz', $this->subject->getName()); + self::assertSame('baz', $this->subject->getName()); } - /** - * @test - */ + #[Test] public function getAffectedVersionsReturnsAffectedVersionsOfInsecurePackage(): void { - static::assertSame(['>=1.0.0,<1.0.5', '>=2.5.0,<2.6.0'], $this->subject->getAffectedVersions()); + self::assertSame(['>=1.0.0,<1.0.5', '>=2.5.0,<2.6.0'], $this->subject->getAffectedVersions()); } - /** - * @test - */ + #[Test] public function setAffectedVersionsSetsAffectedVersionsOfInsecurePackage(): void { $this->subject->setAffectedVersions(['3.0.0']); - static::assertSame(['3.0.0'], $this->subject->getAffectedVersions()); + self::assertSame(['3.0.0'], $this->subject->getAffectedVersions()); } } diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index bfe25538..b0973924 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -29,6 +29,8 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * ScanResultTest. @@ -36,11 +38,9 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class ScanResultTest extends AbstractTestCase +final class ScanResultTest extends AbstractTestCase { - /** - * @test - */ + #[Test] public function constructorThrowsExceptionIfGivenInsecurePackagesAreInvalid(): void { $this->expectException(InvalidArgumentException::class); @@ -52,20 +52,16 @@ public function constructorThrowsExceptionIfGivenInsecurePackagesAreInvalid(): v } /** - * @test - * - * @dataProvider fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvidedDataProvider - * * @param array $apiResult */ + #[Test] + #[DataProvider('fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvidedDataProvider')] public function fromApiResultReturnsEmptyScanResultObjectIfNoSecurityAdvisoriesWereProvided(array $apiResult): void { - static::assertSame([], ScanResult::fromApiResult($apiResult)->getInsecurePackages()); + self::assertSame([], ScanResult::fromApiResult($apiResult)->getInsecurePackages()); } - /** - * @test - */ + #[Test] public function fromApiResultReturnsScanResultObjectWithInsecurePackages(): void { $apiResult = [ @@ -89,16 +85,14 @@ public function fromApiResultReturnsScanResultObjectWithInsecurePackages(): void $subject = ScanResult::fromApiResult($apiResult); $insecurePackages = $subject->getInsecurePackages(); - static::assertCount(2, $insecurePackages); - static::assertSame('foo', $insecurePackages[0]->getName()); - static::assertSame(['>=1.0.0,<1.1.0', '2.0.0'], $insecurePackages[0]->getAffectedVersions()); - static::assertSame('baz', $insecurePackages[1]->getName()); - static::assertSame(['1.0.0-alpha-1'], $insecurePackages[1]->getAffectedVersions()); + self::assertCount(2, $insecurePackages); + self::assertSame('foo', $insecurePackages[0]->getName()); + self::assertSame(['>=1.0.0,<1.1.0', '2.0.0'], $insecurePackages[0]->getAffectedVersions()); + self::assertSame('baz', $insecurePackages[1]->getName()); + self::assertSame(['1.0.0-alpha-1'], $insecurePackages[1]->getAffectedVersions()); } - /** - * @test - */ + #[Test] public function getInsecurePackagesReturnsInsecurePackagesFromScanResult(): void { $insecurePackages = [ @@ -107,15 +101,12 @@ public function getInsecurePackagesReturnsInsecurePackagesFromScanResult(): void ]; $subject = new ScanResult($insecurePackages); - static::assertCount(2, $subject->getInsecurePackages()); - static::assertSame($insecurePackages, $subject->getInsecurePackages()); + self::assertCount(2, $subject->getInsecurePackages()); + self::assertSame($insecurePackages, $subject->getInsecurePackages()); } - /** - * @test - * - * @dataProvider isInsecureReturnsSecurityStateOfGivenPackageDataProvider - */ + #[Test] + #[DataProvider('isInsecureReturnsSecurityStateOfGivenPackageDataProvider')] public function isInsecureReturnsSecurityStateOfGivenPackage(OutdatedPackage $outdatedPackage, bool $expected): void { $insecurePackages = [ @@ -124,7 +115,7 @@ public function isInsecureReturnsSecurityStateOfGivenPackage(OutdatedPackage $ou ]; $subject = new ScanResult($insecurePackages); - static::assertSame($expected, $subject->isInsecure($outdatedPackage)); + self::assertSame($expected, $subject->isInsecure($outdatedPackage)); } /** diff --git a/tests/Unit/Security/SecurityScannerTest.php b/tests/Unit/Security/SecurityScannerTest.php index 72455851..22a2d737 100644 --- a/tests/Unit/Security/SecurityScannerTest.php +++ b/tests/Unit/Security/SecurityScannerTest.php @@ -31,6 +31,7 @@ use Http\Message\RequestMatcher\CallbackRequestMatcher; use Http\Mock\Client; use Nyholm\Psr7\Response; +use PHPUnit\Framework\Attributes\Test; use Psr\Http\Message\RequestInterface; use RuntimeException; @@ -40,17 +41,11 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class SecurityScannerTest extends AbstractTestCase +final class SecurityScannerTest extends AbstractTestCase { - /** - * @var SecurityScanner - */ - protected $subject; + private SecurityScanner $subject; - /** - * @var Client - */ - protected $client; + private Client $client; protected function setUp(): void { @@ -58,9 +53,7 @@ protected function setUp(): void $this->subject = new SecurityScanner($this->client); } - /** - * @test - */ + #[Test] public function scanReturnsScanResult(): void { $packages = [ @@ -88,23 +81,19 @@ public function scanReturnsScanResult(): void $scanResult = $this->subject->scan($packages); - static::assertInstanceOf(ScanResult::class, $scanResult); - static::assertCount(1, $scanResult->getInsecurePackages()); - static::assertSame('foo', $scanResult->getInsecurePackages()[0]->getName()); - static::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getInsecurePackages()[0]->getAffectedVersions()); + self::assertInstanceOf(ScanResult::class, $scanResult); + self::assertCount(1, $scanResult->getInsecurePackages()); + self::assertSame('foo', $scanResult->getInsecurePackages()[0]->getName()); + self::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getInsecurePackages()[0]->getAffectedVersions()); } - /** - * @test - */ + #[Test] public function scanReturnsEmptyScanResultIfNoPackagesAreRequestedToBeScanned(): void { - static::assertSame([], $this->subject->scan([])->getInsecurePackages()); + self::assertSame([], $this->subject->scan([])->getInsecurePackages()); } - /** - * @test - */ + #[Test] public function scanExcludesPackagesWithoutAffectedVersions(): void { $packages = [ @@ -133,15 +122,13 @@ public function scanExcludesPackagesWithoutAffectedVersions(): void $scanResult = $this->subject->scan($packages); - static::assertInstanceOf(ScanResult::class, $scanResult); - static::assertCount(1, $scanResult->getInsecurePackages()); - static::assertSame('foo', $scanResult->getInsecurePackages()[0]->getName()); - static::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getInsecurePackages()[0]->getAffectedVersions()); + self::assertInstanceOf(ScanResult::class, $scanResult); + self::assertCount(1, $scanResult->getInsecurePackages()); + self::assertSame('foo', $scanResult->getInsecurePackages()[0]->getName()); + self::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getInsecurePackages()[0]->getAffectedVersions()); } - /** - * @test - */ + #[Test] public function scanThrowsExceptionIfRequestFails(): void { $this->client->addException(new TransferException()); diff --git a/tests/Unit/TestApplicationTrait.php b/tests/Unit/TestApplicationTrait.php index 4e23e508..7db738ae 100644 --- a/tests/Unit/TestApplicationTrait.php +++ b/tests/Unit/TestApplicationTrait.php @@ -33,15 +33,8 @@ */ trait TestApplicationTrait { - /** - * @var string|null - */ - protected $initialDirectory; - - /** - * @var string|null - */ - protected $temporaryDirectory; + protected ?string $initialDirectory = null; + protected ?string $temporaryDirectory = null; protected function goToTestDirectory(string $applicationPath = AbstractTestCase::TEST_APPLICATION_NORMAL): void { diff --git a/tests/Unit/UpdateCheckerTest.php b/tests/Unit/UpdateCheckerTest.php index afad8d22..6303249f 100644 --- a/tests/Unit/UpdateCheckerTest.php +++ b/tests/Unit/UpdateCheckerTest.php @@ -34,6 +34,7 @@ use EliasHaeussler\ComposerUpdateCheck\Options; use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\UpdateChecker; +use PHPUnit\Framework\Attributes\Test; /** * UpdateCheckerTest. @@ -41,29 +42,14 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class UpdateCheckerTest extends AbstractTestCase +final class UpdateCheckerTest extends AbstractTestCase { use TestApplicationTrait; - /** - * @var Composer - */ - protected $composer; - - /** - * @var OutputBehavior - */ - protected $behavior; - - /** - * @var Options - */ - protected $options; - - /** - * @var UpdateChecker - */ - protected $subject; + private Composer $composer; + private OutputBehavior $behavior; + private Options $options; + private UpdateChecker $subject; /** * @throws JsonValidationException @@ -79,10 +65,9 @@ protected function setUp(): void } /** - * @test - * * @throws JsonValidationException */ + #[Test] public function runReturnsEmptyUpdateCheckResultIfNoPackagesAreRequired(): void { $this->goToTestDirectory(self::TEST_APPLICATION_EMPTY); @@ -90,24 +75,20 @@ public function runReturnsEmptyUpdateCheckResultIfNoPackagesAreRequired(): void $subject = new UpdateChecker($this->getComposer(), $this->behavior, $this->options); $expected = new UpdateCheckResult([]); - static::assertEquals($expected, $subject->run()); + self::assertEquals($expected, $subject->run()); } - /** - * @test - */ + #[Test] public function runReturnsEmptyUpdateCheckResultIfOutdatedPackagesAreSkipped(): void { $this->options->setIgnorePackages(['symfony/*']); $this->options->setIncludeDevPackages(false); $expected = new UpdateCheckResult([]); - static::assertEquals($expected, $this->subject->run()); + self::assertEquals($expected, $this->subject->run()); } - /** - * @test - */ + #[Test] public function runReturnsUpdateCheckResultWithoutDevRequirements(): void { $this->options->setIncludeDevPackages(false); @@ -116,20 +97,18 @@ public function runReturnsUpdateCheckResultWithoutDevRequirements(): void $firstOutdatedPackage = reset($outdatedPackages); $secondOutdatedPackage = next($outdatedPackages); - static::assertCount(2, $outdatedPackages); + self::assertCount(2, $outdatedPackages); - static::assertSame('symfony/console', $firstOutdatedPackage->getName()); - static::assertSame('v4.4.9', $firstOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $firstOutdatedPackage->getNewVersion()); + self::assertSame('symfony/console', $firstOutdatedPackage->getName()); + self::assertSame('v4.4.9', $firstOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $firstOutdatedPackage->getNewVersion()); - static::assertSame('symfony/http-kernel', $secondOutdatedPackage->getName()); - static::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); + self::assertSame('symfony/http-kernel', $secondOutdatedPackage->getName()); + self::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); } - /** - * @test - */ + #[Test] public function runReturnsUpdateCheckResultWithoutSkippedPackages(): void { $this->options->setIgnorePackages(['symfony/console']); @@ -138,20 +117,18 @@ public function runReturnsUpdateCheckResultWithoutSkippedPackages(): void $firstOutdatedPackage = reset($outdatedPackages); $secondOutdatedPackage = next($outdatedPackages); - static::assertCount(2, $outdatedPackages); + self::assertCount(2, $outdatedPackages); - static::assertSame('codeception/codeception', $firstOutdatedPackage->getName()); - static::assertSame('4.1.9', $firstOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('4.1.9', $firstOutdatedPackage->getNewVersion()); + self::assertSame('codeception/codeception', $firstOutdatedPackage->getName()); + self::assertSame('4.1.9', $firstOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('4.1.9', $firstOutdatedPackage->getNewVersion()); - static::assertSame('symfony/http-kernel', $secondOutdatedPackage->getName()); - static::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); + self::assertSame('symfony/http-kernel', $secondOutdatedPackage->getName()); + self::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); } - /** - * @test - */ + #[Test] public function runReturnsUpdateCheckResultListOfOutdatedPackages(): void { $outdatedPackages = $this->subject->run()->getOutdatedPackages(); @@ -159,24 +136,22 @@ public function runReturnsUpdateCheckResultListOfOutdatedPackages(): void $secondOutdatedPackage = next($outdatedPackages); $thirdOutdatedPackage = next($outdatedPackages); - static::assertCount(3, $outdatedPackages); + self::assertCount(3, $outdatedPackages); - static::assertSame('codeception/codeception', $firstOutdatedPackage->getName()); - static::assertSame('4.1.9', $firstOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('4.1.9', $firstOutdatedPackage->getNewVersion()); + self::assertSame('codeception/codeception', $firstOutdatedPackage->getName()); + self::assertSame('4.1.9', $firstOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('4.1.9', $firstOutdatedPackage->getNewVersion()); - static::assertSame('symfony/console', $secondOutdatedPackage->getName()); - static::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); + self::assertSame('symfony/console', $secondOutdatedPackage->getName()); + self::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); - static::assertSame('symfony/http-kernel', $thirdOutdatedPackage->getName()); - static::assertSame('v4.4.9', $thirdOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $thirdOutdatedPackage->getNewVersion()); + self::assertSame('symfony/http-kernel', $thirdOutdatedPackage->getName()); + self::assertSame('v4.4.9', $thirdOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $thirdOutdatedPackage->getNewVersion()); } - /** - * @test - */ + #[Test] public function runReturnsUpdateCheckResultListOfOutdatedPackagesAndFlagsInsecurePackages(): void { $this->options->setPerformSecurityScan(true); @@ -186,41 +161,39 @@ public function runReturnsUpdateCheckResultListOfOutdatedPackagesAndFlagsInsecur $secondOutdatedPackage = next($outdatedPackages); $thirdOutdatedPackage = next($outdatedPackages); - static::assertCount(3, $outdatedPackages); + self::assertCount(3, $outdatedPackages); - static::assertSame('codeception/codeception', $firstOutdatedPackage->getName()); - static::assertSame('4.1.9', $firstOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('4.1.9', $firstOutdatedPackage->getNewVersion()); - static::assertTrue($firstOutdatedPackage->isInsecure()); + self::assertSame('codeception/codeception', $firstOutdatedPackage->getName()); + self::assertSame('4.1.9', $firstOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('4.1.9', $firstOutdatedPackage->getNewVersion()); + self::assertTrue($firstOutdatedPackage->isInsecure()); - static::assertSame('symfony/console', $secondOutdatedPackage->getName()); - static::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); - static::assertFalse($secondOutdatedPackage->isInsecure()); + self::assertSame('symfony/console', $secondOutdatedPackage->getName()); + self::assertSame('v4.4.9', $secondOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $secondOutdatedPackage->getNewVersion()); + self::assertFalse($secondOutdatedPackage->isInsecure()); - static::assertSame('symfony/http-kernel', $thirdOutdatedPackage->getName()); - static::assertSame('v4.4.9', $thirdOutdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $thirdOutdatedPackage->getNewVersion()); - static::assertTrue($thirdOutdatedPackage->isInsecure()); + self::assertSame('symfony/http-kernel', $thirdOutdatedPackage->getName()); + self::assertSame('v4.4.9', $thirdOutdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $thirdOutdatedPackage->getNewVersion()); + self::assertTrue($thirdOutdatedPackage->isInsecure()); } - /** - * @test - */ + #[Test] public function runDispatchesPostUpdateCheckEvent(): void { $listener = function (PostUpdateCheckEvent $event) { $outdatedPackages = $event->getUpdateCheckResult()->getOutdatedPackages(); - static::assertSame($this->behavior, $event->getBehavior()); - static::assertSame($this->options, $event->getOptions()); + self::assertSame($this->behavior, $event->getBehavior()); + self::assertSame($this->options, $event->getOptions()); $outdatedPackage = reset($outdatedPackages); - static::assertCount(1, $outdatedPackages); - static::assertSame('symfony/http-kernel', $outdatedPackage->getName()); - static::assertSame('v4.4.9', $outdatedPackage->getOutdatedVersion()); - static::assertNotSame('v4.4.9', $outdatedPackage->getNewVersion()); + self::assertCount(1, $outdatedPackages); + self::assertSame('symfony/http-kernel', $outdatedPackage->getName()); + self::assertSame('v4.4.9', $outdatedPackage->getOutdatedVersion()); + self::assertNotSame('v4.4.9', $outdatedPackage->getNewVersion()); }; $this->options->setIgnorePackages(['symfony/console']); diff --git a/tests/Unit/Utility/ComposerTest.php b/tests/Unit/Utility/ComposerTest.php index 7e2da0c9..b8382068 100644 --- a/tests/Unit/Utility/ComposerTest.php +++ b/tests/Unit/Utility/ComposerTest.php @@ -27,6 +27,7 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\Test; /** * ComposerTest. @@ -34,39 +35,31 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class ComposerTest extends AbstractTestCase +final class ComposerTest extends AbstractTestCase { - /** - * @test - */ + #[Test] public function getPlatformVersionReturnsFullPlatformVersion(): void { $expected = PluginInterface::PLUGIN_API_VERSION; - static::assertSame($expected, Composer::getPlatformVersion(Composer::VERSION_FULL)); + self::assertSame($expected, Composer::getPlatformVersion(Composer::VERSION_FULL)); } - /** - * @test - */ + #[Test] public function getPlatformVersionReturnsMajorPlatformVersion(): void { [$expected] = explode('.', PluginInterface::PLUGIN_API_VERSION); - static::assertSame($expected, Composer::getPlatformVersion(Composer::VERSION_MAJOR)); + self::assertSame($expected, Composer::getPlatformVersion(Composer::VERSION_MAJOR)); } - /** - * @test - */ + #[Test] public function getPlatformVersionReturnsPlatformBranch(): void { [$major, $minor] = explode('.', PluginInterface::PLUGIN_API_VERSION); $expected = $major.'.'.$minor; - static::assertSame($expected, Composer::getPlatformVersion(Composer::VERSION_BRANCH)); + self::assertSame($expected, Composer::getPlatformVersion(Composer::VERSION_BRANCH)); } - /** - * @test - */ + #[Test] public function getPlatformVersionThrowsExceptionIfUnsupportedVersionTypeIsGiven(): void { $this->expectException(InvalidArgumentException::class); @@ -74,12 +67,10 @@ public function getPlatformVersionThrowsExceptionIfUnsupportedVersionTypeIsGiven Composer::getPlatformVersion(-99); } - /** - * @test - */ + #[Test] public function getMajorVersionReturnsMajorPlatformVersion(): void { [$expected] = explode('.', PluginInterface::PLUGIN_API_VERSION); - static::assertSame((int) $expected, Composer::getMajorVersion()); + self::assertSame((int) $expected, Composer::getMajorVersion()); } } diff --git a/tests/Unit/Utility/InstallerTest.php b/tests/Unit/Utility/InstallerTest.php index 15c941fe..ca325019 100644 --- a/tests/Unit/Utility/InstallerTest.php +++ b/tests/Unit/Utility/InstallerTest.php @@ -23,7 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; -use Composer\Composer as BaseComposer; use Composer\Console\Application; use Composer\Json\JsonValidationException; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; @@ -32,6 +31,8 @@ use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; use EliasHaeussler\ComposerUpdateCheck\Utility\Installer; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; /** * InstallerTest. @@ -39,15 +40,12 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class InstallerTest extends AbstractTestCase +final class InstallerTest extends AbstractTestCase { use ExpectedCommandOutputTrait; use TestApplicationTrait; - /** - * @var BaseComposer - */ - protected $composer; + private ?\Composer\Composer $composer = null; /** * @throws JsonValidationException @@ -60,9 +58,7 @@ protected function setUp(): void $this->composer = $application->getComposer(); } - /** - * @test - */ + #[Test] public function runInstallInstallsComposerDependencies(): void { $expected = 'Installing dependencies from lock file (including require-dev)'; @@ -70,26 +66,24 @@ public function runInstallInstallsComposerDependencies(): void $expected = 'Installing dependencies (including require-dev) from lock file'; } - static::assertSame(0, Installer::runInstall($this->composer)); - static::assertStringContainsString($expected, Installer::getLastOutput()); + self::assertSame(0, Installer::runInstall($this->composer)); + self::assertStringContainsString($expected, Installer::getLastOutput()); } /** - * @test - * - * @dataProvider runUpdateExecutesDryRunUpdateDataProvider - * * @param string[] $packages */ + #[Test] + #[DataProvider('runUpdateExecutesDryRunUpdateDataProvider')] public function runUpdateExecutesDryRunUpdate(array $packages, string $expected, string $notExpected = null): void { // Ensure dependencies are installed Installer::runInstall($this->composer); - static::assertSame(0, Installer::runUpdate($packages, $this->composer)); - static::assertStringContainsString($expected, Installer::getLastOutput()); + self::assertSame(0, Installer::runUpdate($packages, $this->composer)); + self::assertStringContainsString($expected, Installer::getLastOutput()); if (null !== $notExpected) { - static::assertStringNotContainsString($notExpected, Installer::getLastOutput()); + self::assertStringNotContainsString($notExpected, Installer::getLastOutput()); } } diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/Unit/Utility/SecurityTest.php index f04d8f63..fd9f2847 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/Unit/Utility/SecurityTest.php @@ -28,6 +28,7 @@ use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; use EliasHaeussler\ComposerUpdateCheck\Utility\Security; +use PHPUnit\Framework\Attributes\Test; /** * SecurityTest. @@ -35,7 +36,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -class SecurityTest extends AbstractTestCase +final class SecurityTest extends AbstractTestCase { use TestApplicationTrait; @@ -44,9 +45,7 @@ protected function setUp(): void $this->goToTestDirectory(); } - /** - * @test - */ + #[Test] public function scanReturnsSecurityVulnerabilities(): void { $securePackage = new OutdatedPackage('symfony/console', '4.4.0', '4.4.18'); @@ -54,13 +53,11 @@ public function scanReturnsSecurityVulnerabilities(): void $scan = Security::scan([$securePackage, $insecurePackage]); - static::assertFalse($scan->isInsecure($securePackage)); - static::assertTrue($scan->isInsecure($insecurePackage)); + self::assertFalse($scan->isInsecure($securePackage)); + self::assertTrue($scan->isInsecure($insecurePackage)); } - /** - * @test - */ + #[Test] public function scanAndOverlayResultsAppliesInsecureFlagsToInsecureOutdatedPackages(): void { $securePackage = new OutdatedPackage('symfony/console', '4.4.0', '4.4.18'); @@ -69,8 +66,8 @@ public function scanAndOverlayResultsAppliesInsecureFlagsToInsecureOutdatedPacka Security::scanAndOverlayResult($result); - static::assertFalse($securePackage->isInsecure()); - static::assertTrue($insecurePackage->isInsecure()); + self::assertFalse($securePackage->isInsecure()); + self::assertTrue($insecurePackage->isInsecure()); } protected function tearDown(): void From 153f9a83c55f36a0046a5da8253fa6b2f968599b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Mon, 27 Nov 2023 21:10:35 +0100 Subject: [PATCH 016/286] [TASK] Remove dependency to spatie/emoji --- composer.json | 1 - composer.lock | 70 ++----------------------------------------- src/UpdateChecker.php | 11 ++++--- 3 files changed, 7 insertions(+), 75 deletions(-) diff --git a/composer.json b/composer.json index 5f8ad60c..4ea8d592 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "nyholm/psr7": "^1.0", "psr/http-client": "^1.0", "psr/http-message": "^1.0 || ^2.0 || ^3.0", - "spatie/emoji": "^2.0 || ^3.0 || ^4.0", "symfony/console": "^5.4 || ^6.0", "symfony/http-client": "^5.4 || ^6.0" }, diff --git a/composer.lock b/composer.lock index d52f7091..881d9ef6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "589ea1dd2476547caa86af42ebbe561e", + "content-hash": "8ba30970b992bf163ef5c442b8fea10f", "packages": [ { "name": "nyholm/psr7", @@ -347,72 +347,6 @@ }, "time": "2021-07-14T16:46:02+00:00" }, - { - "name": "spatie/emoji", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/emoji.git", - "reference": "aa9b01775ad3ff825914dab77f10fb8aa9aa297e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/emoji/zipball/aa9b01775ad3ff825914dab77f10fb8aa9aa297e", - "reference": "aa9b01775ad3ff825914dab77f10fb8aa9aa297e", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^7.2|^8.0" - }, - "require-dev": { - "ext-iconv": "*", - "ext-json": "*", - "guzzlehttp/guzzle": "^7.0", - "phpunit/phpunit": "^9.4", - "symfony/console": "^4.2", - "twig/twig": "^2.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Emoji\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Display emoji characters", - "homepage": "https://github.com/spatie/emoji", - "keywords": [ - "emoji", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/emoji/issues", - "source": "https://github.com/spatie/emoji/tree/4.0.0" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2022-09-22T07:46:11+00:00" - }, { "name": "symfony/console", "version": "v6.3.8", @@ -6451,5 +6385,5 @@ "composer-plugin-api": "^2.0" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 07bdd41c..08391ebd 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -31,7 +31,6 @@ use EliasHaeussler\ComposerUpdateCheck\Utility\Installer; use EliasHaeussler\ComposerUpdateCheck\Utility\Security; use RuntimeException; -use Spatie\Emoji\Emoji; /** * UpdateChecker. @@ -55,7 +54,7 @@ public function __construct( public function run(): UpdateCheckResult { // Resolve packages to be checked - $this->behavior->io->write(Emoji::package().' Resolving packages...', true, IOInterface::VERBOSE); + $this->behavior->io->write('📦 Resolving packages...', true, IOInterface::VERBOSE); $packages = $this->resolvePackagesForUpdateCheck(); // Run update check @@ -63,7 +62,7 @@ public function run(): UpdateCheckResult // Overlay security scan if ($this->options->isPerformingSecurityScan() && [] !== $result->getOutdatedPackages()) { - $this->behavior->io->write(Emoji::policeCarLight().' Checking for insecure packages...', true, IOInterface::VERBOSE); + $this->behavior->io->write('🚨 Checking for insecure packages...', true, IOInterface::VERBOSE); $result = Security::scanAndOverlayResult($result); } @@ -87,7 +86,7 @@ private function runUpdateCheck(array $packages): UpdateCheckResult $this->installDependencies(); // Run Composer installer - $this->behavior->io->write(Emoji::hourglassNotDone().' Checking for outdated packages...', true, IOInterface::VERBOSE); + $this->behavior->io->write('⏳ Checking for outdated packages...', true, IOInterface::VERBOSE); $result = Installer::runUpdate($packages, $this->composer); // Handle installer failures @@ -125,7 +124,7 @@ private function resolvePackagesForUpdateCheck(): array $requiredPackages = array_merge($requiredPackages, $requiredDevPackages); } else { $this->packageBlacklist = array_merge($this->packageBlacklist, $requiredDevPackages); - $this->behavior->io->write(Emoji::prohibited().' Skipped dev-requirements', true, IOInterface::VERBOSE); + $this->behavior->io->write('🚫 Skipped dev-requirements', true, IOInterface::VERBOSE); } // Remove blacklisted packages @@ -147,7 +146,7 @@ private function removeByIgnorePattern(string $pattern, array $packages): array if (!fnmatch($pattern, $package)) { return true; } - $this->behavior->io->write(sprintf('%s Skipped "%s"', Emoji::prohibited(), $package), true, IOInterface::VERBOSE); + $this->behavior->io->write(sprintf('🚫 Skipped "%s"', $package), true, IOInterface::VERBOSE); $this->packageBlacklist[] = $package; return false; From 528045638f44351884c33c1065fb21b6db75a52b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 28 Nov 2023 21:35:08 +0100 Subject: [PATCH 017/286] [TASK] Migrate Plugin class to CommandProvider --- rector.php | 1 - src/Capability/UpdateCheckCommandProvider.php | 45 ------------------- src/Plugin.php | 12 +++-- 3 files changed, 9 insertions(+), 49 deletions(-) delete mode 100644 src/Capability/UpdateCheckCommandProvider.php diff --git a/rector.php b/rector.php index df0361b6..f59a6006 100644 --- a/rector.php +++ b/rector.php @@ -37,7 +37,6 @@ ->skip( AnnotationToAttributeRector::class, [ - __DIR__.'/src/Capability/UpdateCheckCommandProvider.php', __DIR__.'/src/Event/PostUpdateCheckEvent.php', __DIR__.'/src/Plugin.php', ], diff --git a/src/Capability/UpdateCheckCommandProvider.php b/src/Capability/UpdateCheckCommandProvider.php deleted file mode 100644 index 53d3a889..00000000 --- a/src/Capability/UpdateCheckCommandProvider.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -namespace EliasHaeussler\ComposerUpdateCheck\Capability; - -use Composer\Plugin\Capability\CommandProvider; -use EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand; - -/** - * UpdateCheckCommandProvider. - * - * @author Elias Häußler - * @license GPL-3.0-or-later - * - * @codeCoverageIgnore - */ -final class UpdateCheckCommandProvider implements CommandProvider -{ - public function getCommands(): array - { - return [ - new UpdateCheckCommand(), - ]; - } -} diff --git a/src/Plugin.php b/src/Plugin.php index 2688d6e0..7ed3f39e 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -28,7 +28,6 @@ use Composer\Plugin\Capability\CommandProvider; use Composer\Plugin\Capable; use Composer\Plugin\PluginInterface; -use EliasHaeussler\ComposerUpdateCheck\Capability\UpdateCheckCommandProvider; /** * Plugin. @@ -38,7 +37,7 @@ * * @codeCoverageIgnore */ -final class Plugin implements PluginInterface, Capable +final class Plugin implements PluginInterface, Capable, CommandProvider { public function activate(Composer $composer, IOInterface $io): void { @@ -58,7 +57,14 @@ public function uninstall(Composer $composer, IOInterface $io): void public function getCapabilities(): array { return [ - CommandProvider::class => UpdateCheckCommandProvider::class, + CommandProvider::class => self::class, + ]; + } + + public function getCommands(): array + { + return [ + new Command\UpdateCheckCommand(), ]; } } From 9c43a5e92c50ae2fd088d676c5a06e791b353e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 28 Nov 2023 21:36:48 +0100 Subject: [PATCH 018/286] [BUGFIX] Correct application path in simulate-application.sh --- bin/simulate-application.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/simulate-application.sh b/bin/simulate-application.sh index 4799456b..b1b8b940 100755 --- a/bin/simulate-application.sh +++ b/bin/simulate-application.sh @@ -3,8 +3,7 @@ set -e # Resolve variables ROOT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)" -PHP_VERSION="$(php -r 'echo PHP_MAJOR_VERSION;')" -APP_PATH="${ROOT_PATH}/tests/Build/test-application/v${PHP_VERSION}" +APP_PATH="${ROOT_PATH}/tests/Build/test-application" TEMP_DIR="/tmp" # Check if temp directory is writeable From ea2754e70ed0cbd6b98e3a501053d18dcde6f2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 30 Nov 2023 20:48:44 +0100 Subject: [PATCH 019/286] [TASK] Rearrange classes, introduces config files, add formatter and DI --- .github/workflows/cgl.yaml | 2 +- .github/workflows/tests.yaml | 4 +- composer.json | 16 +- composer.lock | 1031 +++-- config/services.yaml | 32 + docs/install.md | 4 +- phpstan-baseline.neon | 20 +- rector.php | 2 +- src/Command/UpdateCheckCommand.php | 150 +- .../ComposerInstaller.php} | 69 +- .../Adapter/ChainedConfigAdapter.php | 73 + .../Adapter/CommandInputConfigAdapter.php | 79 + .../Adapter/ConfigAdapter.php} | 14 +- .../Adapter/ConfigAdapterFactory.php | 51 + .../Adapter/FileBasedConfigAdapter.php | 77 + .../Adapter/JsonConfigAdapter.php | 48 + .../Adapter/PhpConfigAdapter.php | 46 + .../Adapter/YamlConfigAdapter.php | 58 + .../ComposerUpdateCheckConfig.php | 125 + .../Options/PackageExcludePattern.php} | 50 +- src/DependencyInjection/ContainerFactory.php | 107 + src/Event/PostUpdateCheckEvent.php | 24 +- src/Exception/ComposerInstallFailed.php | 43 + src/Exception/ComposerUpdateFailed.php | 43 + src/Exception/ConfigFileIsInvalid.php | 43 + src/Exception/ConfigFileIsNotSupported.php | 43 + src/Exception/Exception.php | 32 + src/Exception/FileDoesNotExist.php | 43 + src/Exception/FormatterIsNotSupported.php | 43 + src/IO/Formatter/Formatter.php | 43 + src/IO/Formatter/FormatterFactory.php | 69 + src/IO/Formatter/GitHubActionsFormatter.php | 108 + src/IO/Formatter/JsonFormatter.php | 195 + src/IO/Formatter/TextFormatter.php | 136 + src/IO/Verbosity.php | 101 - src/Options.php | 101 - src/{Security => Package}/InsecurePackage.php | 33 +- src/Package/OutdatedPackage.php | 59 +- src/Package/Package.php | 41 + .../Style.php => Package/RequiredPackage.php} | 52 +- src/Package/UpdateCheckResult.php | 138 - src/Plugin.php | 10 +- src/Security/ScanResult.php | 5 +- src/Security/SecurityScanner.php | 15 +- src/UpdateCheckResult.php | 134 + src/UpdateChecker.php | 159 +- src/Utility/Security.php | 61 - tests/Build/phpstan/console-application.php | 14 +- tests/Build/test-application/composer.json | 5 +- tests/Build/test-application/composer.lock | 3539 +++-------------- tests/Unit/ExpectedCommandOutputTrait.php | 5 +- tests/Unit/Package/UpdateCheckResultTest.php | 2 +- tests/Unit/Security/InsecurePackageTest.php | 2 +- tests/Unit/Security/ScanResultTest.php | 2 +- tests/Unit/UpdateCheckerTest.php | 2 +- tests/Unit/Utility/InstallerTest.php | 18 +- tests/Unit/Utility/SecurityTest.php | 2 +- 57 files changed, 3379 insertions(+), 4044 deletions(-) create mode 100644 config/services.yaml rename src/{Utility/Installer.php => Composer/ComposerInstaller.php} (52%) create mode 100644 src/Configuration/Adapter/ChainedConfigAdapter.php create mode 100644 src/Configuration/Adapter/CommandInputConfigAdapter.php rename src/{IO/OutputBehavior.php => Configuration/Adapter/ConfigAdapter.php} (76%) create mode 100644 src/Configuration/Adapter/ConfigAdapterFactory.php create mode 100644 src/Configuration/Adapter/FileBasedConfigAdapter.php create mode 100644 src/Configuration/Adapter/JsonConfigAdapter.php create mode 100644 src/Configuration/Adapter/PhpConfigAdapter.php create mode 100644 src/Configuration/Adapter/YamlConfigAdapter.php create mode 100644 src/Configuration/ComposerUpdateCheckConfig.php rename src/{Utility/Composer.php => Configuration/Options/PackageExcludePattern.php} (50%) create mode 100644 src/DependencyInjection/ContainerFactory.php create mode 100644 src/Exception/ComposerInstallFailed.php create mode 100644 src/Exception/ComposerUpdateFailed.php create mode 100644 src/Exception/ConfigFileIsInvalid.php create mode 100644 src/Exception/ConfigFileIsNotSupported.php create mode 100644 src/Exception/Exception.php create mode 100644 src/Exception/FileDoesNotExist.php create mode 100644 src/Exception/FormatterIsNotSupported.php create mode 100644 src/IO/Formatter/Formatter.php create mode 100644 src/IO/Formatter/FormatterFactory.php create mode 100644 src/IO/Formatter/GitHubActionsFormatter.php create mode 100644 src/IO/Formatter/JsonFormatter.php create mode 100644 src/IO/Formatter/TextFormatter.php delete mode 100644 src/IO/Verbosity.php delete mode 100644 src/Options.php rename src/{Security => Package}/InsecurePackage.php (68%) create mode 100644 src/Package/Package.php rename src/{IO/Style.php => Package/RequiredPackage.php} (51%) delete mode 100644 src/Package/UpdateCheckResult.php create mode 100644 src/UpdateCheckResult.php delete mode 100644 src/Utility/Security.php diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index 47acf98f..6aab3526 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -26,7 +26,7 @@ jobs: # Install dependencies - name: Add required packages - run: composer require composer/composer:"^2.0" composer/semver:"^3.4" --no-update + run: composer require composer/composer:"^2.1" composer/semver:"^3.4" --no-update - name: Install Composer dependencies uses: ramsey/composer-install@v2 with: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e03a61b5..67f0ca57 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.1", "8.2", "8.3"] + php-version: ["8.2", "8.3"] composer-version: ["2"] dependencies: ["highest", "lowest"] steps: @@ -101,7 +101,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.1", "8.2", "8.3"] + php-version: ["8.2", "8.3"] composer-version: ["2"] steps: - uses: actions/checkout@v3 diff --git a/composer.json b/composer.json index 4ea8d592..5f4be423 100644 --- a/composer.json +++ b/composer.json @@ -19,18 +19,23 @@ "rss": "https://github.com/eliashaeussler/composer-update-check/releases.atom" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.2.0 || ~8.3.0", "ext-json": "*", - "composer-plugin-api": "^2.0", + "composer-plugin-api": "^2.1", + "cuyz/valinor": "^1.7", "nyholm/psr7": "^1.0", "psr/http-client": "^1.0", "psr/http-message": "^1.0 || ^2.0 || ^3.0", + "symfony/config": "^5.4 || ^6.0", "symfony/console": "^5.4 || ^6.0", - "symfony/http-client": "^5.4 || ^6.0" + "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/http-client": "^5.4 || ^6.0", + "symfony/yaml": "^5.4 || ^6.0" }, "require-dev": { "armin/editorconfig-cli": "^1.7", - "composer/composer": "^2.0", + "composer/composer": "^2.1", "composer/semver": "^3.4", "eliashaeussler/php-cs-fixer-config": "^1.3", "eliashaeussler/phpstan-config": "^2.4", @@ -41,8 +46,7 @@ "php-http/mock-client": "^1.6", "phpstan/extension-installer": "^1.3", "phpstan/phpstan-symfony": "^1.3", - "phpunit/phpunit": "^10.4", - "symfony/filesystem": "^5.4 || ^6.0" + "phpunit/phpunit": "^10.4" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 881d9ef6..fab7564c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,81 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8ba30970b992bf163ef5c442b8fea10f", + "content-hash": "4da8728231f9d71bd5def17381cad08a", "packages": [ + { + "name": "cuyz/valinor", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/CuyZ/Valinor.git", + "reference": "e384ad6d6801c3d4a03b444d267dbfec91ee23da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/e384ad6d6801c3d4a03b444d267dbfec91ee23da", + "reference": "e384ad6d6801c3d4a03b444d267dbfec91ee23da", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.4", + "infection/infection": "^0.26", + "marcocesarato/php-conventional-changelog": "^1.12", + "mikey179/vfsstream": "^1.6.10", + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "rector/rector": "~0.17.0", + "vimeo/psalm": "^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "CuyZ\\Valinor\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Romain Canon", + "email": "romain.hydrocanon@gmail.com", + "homepage": "https://github.com/romm" + } + ], + "description": "Library that helps to map any input into a strongly-typed value object structure.", + "homepage": "https://github.com/CuyZ/Valinor", + "keywords": [ + "array", + "conversion", + "hydrator", + "json", + "mapper", + "mapping", + "object", + "tree", + "yaml" + ], + "support": { + "issues": "https://github.com/CuyZ/Valinor/issues", + "source": "https://github.com/CuyZ/Valinor/tree/1.7.0" + }, + "funding": [ + { + "url": "https://github.com/romm", + "type": "github" + } + ], + "time": "2023-10-23T11:05:23+00:00" + }, { "name": "nyholm/psr7", "version": "1.8.1", @@ -347,18 +420,144 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "symfony/config", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "5d33e0fb707d603330e0edfd4691803a1253572e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/5d33e0fb707d603330e0edfd4691803a1253572e", + "reference": "5d33e0fb707d603330e0edfd4691803a1253572e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^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/v6.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-11-09T08:28:32+00:00" + }, { "name": "symfony/console", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92" + "reference": "cd9864b47c367450e14ab32f78fdbf98c44c26b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d14a9f6d04d4ac38a8cea1171f4554e325dae92", - "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92", + "url": "https://api.github.com/repos/symfony/console/zipball/cd9864b47c367450e14ab32f78fdbf98c44c26b6", + "reference": "cd9864b47c367450e14ab32f78fdbf98c44c26b6", "shasum": "" }, "require": { @@ -366,7 +565,7 @@ "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0" + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { "symfony/dependency-injection": "<5.4", @@ -380,12 +579,16 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" + "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": { @@ -419,7 +622,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.8" + "source": "https://github.com/symfony/console/tree/v6.4.0" }, "funding": [ { @@ -435,7 +638,88 @@ "type": "tidelift" } ], - "time": "2023-10-31T08:09:35+00:00" + "time": "2023-11-20T16:41:16+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "5dc8ad5f2bbba7046f5947682bf7d868ce80d4e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5dc8ad5f2bbba7046f5947682bf7d868ce80d4e8", + "reference": "5dc8ad5f2bbba7046f5947682bf7d868ce80d4e8", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.2.10|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.1", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<6.3", + "symfony/yaml": "<5.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.1|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^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/v6.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-10-31T08:40:20+00:00" }, { "name": "symfony/deprecation-contracts", @@ -504,26 +788,93 @@ ], "time": "2023-05-23T14:45:45+00:00" }, + { + "name": "symfony/filesystem", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "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/v6.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-07-26T17:27:13+00:00" + }, { "name": "symfony/http-client", - "version": "v6.2.13", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "297374a399ce6852d5905d92a1351df00bb9dd10" + "reference": "5c584530b77aa10ae216989ffc48b4bedc9c0b29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/297374a399ce6852d5905d92a1351df00bb9dd10", - "reference": "297374a399ce6852d5905d92a1351df00bb9dd10", + "url": "https://api.github.com/repos/symfony/http-client/zipball/5c584530b77aa10ae216989ffc48b4bedc9c0b29", + "reference": "5c584530b77aa10ae216989ffc48b4bedc9c0b29", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-client-contracts": "^3", - "symfony/service-contracts": "^1.0|^2|^3" + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.3" }, "provide": { "php-http/async-client-implementation": "*", @@ -539,12 +890,12 @@ "guzzlehttp/promises": "^1.4", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", - "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0" + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^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" }, "type": "library", "autoload": { @@ -575,7 +926,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.2.13" + "source": "https://github.com/symfony/http-client/tree/v6.4.0" }, "funding": [ { @@ -591,32 +942,29 @@ "type": "tidelift" } ], - "time": "2023-07-03T12:13:45+00:00" + "time": "2023-11-28T20:55:58+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.1.1", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800" + "reference": "1ee70e699b41909c209a0c930f11034b93578654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/fd038f08c623ab5d22b26e9ba35afe8c79071800", - "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654", + "reference": "1ee70e699b41909c209a0c930f11034b93578654", "shasum": "" }, "require": { "php": ">=8.1" }, - "suggest": { - "symfony/http-client-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -656,7 +1004,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0" }, "funding": [ { @@ -672,20 +1020,20 @@ "type": "tidelift" } ], - "time": "2022-04-22T07:30:54+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -700,7 +1048,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -738,7 +1086,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -754,20 +1102,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -779,7 +1127,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -819,7 +1167,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -835,20 +1183,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -860,7 +1208,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -903,7 +1251,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -919,7 +1267,7 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1088,34 +1436,34 @@ }, { "name": "symfony/string", - "version": "v6.2.2", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "863219fd713fa41cbcd285a79723f94672faff4d" + "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d", - "reference": "863219fd713fa41cbcd285a79723f94672faff4d", + "url": "https://api.github.com/repos/symfony/string/zipball/92bd2bfbba476d4a1838e5e12168bef2fd1e6620", + "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620", "shasum": "" }, "require": { - "php": ">=8.1", + "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.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "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": { @@ -1154,7 +1502,153 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.2.2" + "source": "https://github.com/symfony/string/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-29T08:40:23+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "d97726e8d254a2d5512b2b4ba204735d84e7167d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d97726e8d254a2d5512b2b4ba204735d84e7167d", + "reference": "d97726e8d254a2d5512b2b4ba204735d84e7167d", + "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.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-29T08:40:23+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^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/v6.4.0" }, "funding": [ { @@ -1170,7 +1664,7 @@ "type": "tidelift" } ], - "time": "2022-12-14T16:11:27+00:00" + "time": "2023-11-06T11:00:25+00:00" } ], "packages-dev": [ @@ -1300,16 +1794,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.3.4", + "version": "1.3.7", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5" + "reference": "76e46335014860eec1aa5a724799a00a2e47cc85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/69098eca243998b53eed7a48d82dedd28b447cd5", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/76e46335014860eec1aa5a724799a00a2e47cc85", + "reference": "76e46335014860eec1aa5a724799a00a2e47cc85", "shasum": "" }, "require": { @@ -1356,7 +1850,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.4" + "source": "https://github.com/composer/ca-bundle/tree/1.3.7" }, "funding": [ { @@ -1372,26 +1866,26 @@ "type": "tidelift" } ], - "time": "2022-10-12T12:08:29+00:00" + "time": "2023-08-30T09:31:38+00:00" }, { "name": "composer/class-map-generator", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/composer/class-map-generator.git", - "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + "reference": "953cc4ea32e0c31f2185549c7d216d7921f03da9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", - "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/953cc4ea32e0c31f2185549c7d216d7921f03da9", + "reference": "953cc4ea32e0c31f2185549c7d216d7921f03da9", "shasum": "" }, "require": { - "composer/pcre": "^2 || ^3", + "composer/pcre": "^2.1 || ^3.1", "php": "^7.2 || ^8.0", - "symfony/finder": "^4.4 || ^5.3 || ^6" + "symfony/finder": "^4.4 || ^5.3 || ^6 || ^7" }, "require-dev": { "phpstan/phpstan": "^1.6", @@ -1429,7 +1923,7 @@ ], "support": { "issues": "https://github.com/composer/class-map-generator/issues", - "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + "source": "https://github.com/composer/class-map-generator/tree/1.1.0" }, "funding": [ { @@ -1445,7 +1939,7 @@ "type": "tidelift" } ], - "time": "2022-06-19T11:31:27+00:00" + "time": "2023-06-30T13:58:57+00:00" }, { "name": "composer/composer", @@ -1784,16 +2278,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.7", + "version": "1.5.8", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "c848241796da2abf65837d51dce1fae55a960149" + "reference": "560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/c848241796da2abf65837d51dce1fae55a960149", - "reference": "c848241796da2abf65837d51dce1fae55a960149", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a", + "reference": "560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a", "shasum": "" }, "require": { @@ -1842,9 +2336,9 @@ "validator" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/spdx-licenses/issues", - "source": "https://github.com/composer/spdx-licenses/tree/1.5.7" + "source": "https://github.com/composer/spdx-licenses/tree/1.5.8" }, "funding": [ { @@ -1860,7 +2354,7 @@ "type": "tidelift" } ], - "time": "2022-05-23T07:37:50+00:00" + "time": "2023-11-20T07:44:33+00:00" }, { "name": "composer/xdebug-handler", @@ -2513,20 +3007,20 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.39.0", + "version": "v3.40.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "04bf7b28fc847185b247d112cab617da941e3cca" + "reference": "27d2b3265b5d550ec411b4319967ae7cfddfb2e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/04bf7b28fc847185b247d112cab617da941e3cca", - "reference": "04bf7b28fc847185b247d112cab617da941e3cca", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/27d2b3265b5d550ec411b4319967ae7cfddfb2e0", + "reference": "27d2b3265b5d550ec411b4319967ae7cfddfb2e0", "shasum": "" }, "require": { - "composer/semver": "^3.3", + "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", "ext-json": "*", "ext-tokenizer": "*", @@ -2537,25 +3031,25 @@ "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", "symfony/finder": "^5.4 || ^6.0 || ^7.0", "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", - "symfony/polyfill-mbstring": "^1.27", - "symfony/polyfill-php80": "^1.27", - "symfony/polyfill-php81": "^1.27", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", "symfony/process": "^5.4 || ^6.0 || ^7.0", "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { "facile-it/paraunit": "^1.3 || ^2.0", "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.0", + "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.5.3", + "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.16", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpspec/prophecy": "^1.17", "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "symfony/phpunit-bridge": "^6.2.3 || ^7.0", + "phpunit/phpunit": "^9.6", + "symfony/phpunit-bridge": "^6.3.8 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { @@ -2594,7 +3088,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.39.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.40.0" }, "funding": [ { @@ -2602,7 +3096,7 @@ "type": "github" } ], - "time": "2023-11-22T11:20:09+00:00" + "time": "2023-11-26T09:25:53+00:00" }, { "name": "idiosyncratic/editorconfig", @@ -2655,16 +3149,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.2.12", + "version": "v5.2.13", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, "require": { @@ -2719,9 +3213,9 @@ ], "support": { "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" + "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" }, - "time": "2022-04-13T08:02:27+00:00" + "time": "2023-09-26T02:20:38+00:00" }, { "name": "localheinz/diff", @@ -2785,16 +3279,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -2832,7 +3326,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -2840,20 +3334,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.2", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -2894,9 +3388,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2022-11-12T15:38:23+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "phar-io/manifest", @@ -3442,16 +3936,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.44", + "version": "1.10.46", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "bf84367c53a23f759513985c54ffe0d0c249825b" + "reference": "90d3d25c5b98b8068916bbf08ce42d5cb6c54e70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bf84367c53a23f759513985c54ffe0d0c249825b", - "reference": "bf84367c53a23f759513985c54ffe0d0c249825b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/90d3d25c5b98b8068916bbf08ce42d5cb6c54e70", + "reference": "90d3d25c5b98b8068916bbf08ce42d5cb6c54e70", "shasum": "" }, "require": { @@ -3500,7 +3994,7 @@ "type": "tidelift" } ], - "time": "2023-11-21T16:30:46+00:00" + "time": "2023-11-28T14:57:26+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -4145,23 +4639,24 @@ }, { "name": "react/promise", - "version": "v2.9.0", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + "reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "url": "https://api.github.com/repos/reactphp/promise/zipball/e563d55d1641de1dea9f5e84f3cccc66d2bfe02c", + "reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" }, "type": "library", "autoload": { @@ -4205,32 +4700,28 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.9.0" + "source": "https://github.com/reactphp/promise/tree/v3.1.0" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-02-11T10:27:51+00:00" + "time": "2023-11-16T16:21:57+00:00" }, { "name": "rector/rector", - "version": "0.18.10", + "version": "0.18.11", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "f36bc0a707fd8af301df5108740ce41f9db8eded" + "reference": "9621124c860066f56a4ab841349cb7c284edfaee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/f36bc0a707fd8af301df5108740ce41f9db8eded", - "reference": "f36bc0a707fd8af301df5108740ce41f9db8eded", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/9621124c860066f56a4ab841349cb7c284edfaee", + "reference": "9621124c860066f56a4ab841349cb7c284edfaee", "shasum": "" }, "require": { @@ -4265,7 +4756,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/0.18.10" + "source": "https://github.com/rectorphp/rector/tree/0.18.11" }, "funding": [ { @@ -4273,7 +4764,7 @@ "type": "github" } ], - "time": "2023-11-16T19:42:21+00:00" + "time": "2023-11-27T13:27:43+00:00" }, { "name": "sebastian/cli-parser", @@ -5192,16 +5683,16 @@ }, { "name": "seld/jsonlint", - "version": "1.9.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/594fd6462aad8ecee0b45ca5045acea4776667f1", + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1", "shasum": "" }, "require": { @@ -5240,7 +5731,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + "source": "https://github.com/Seldaek/jsonlint/tree/1.10.0" }, "funding": [ { @@ -5252,7 +5743,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T13:37:23+00:00" + "time": "2023-05-11T13:16:46+00:00" }, { "name": "seld/phar-utils", @@ -5304,16 +5795,16 @@ }, { "name": "seld/signal-handler", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/Seldaek/signal-handler.git", - "reference": "f69d119511dc0360440cdbdaa71829c149b7be75" + "reference": "04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/f69d119511dc0360440cdbdaa71829c149b7be75", - "reference": "f69d119511dc0360440cdbdaa71829c149b7be75", + "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98", + "reference": "04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98", "shasum": "" }, "require": { @@ -5359,30 +5850,30 @@ ], "support": { "issues": "https://github.com/Seldaek/signal-handler/issues", - "source": "https://github.com/Seldaek/signal-handler/tree/2.0.1" + "source": "https://github.com/Seldaek/signal-handler/tree/2.0.2" }, - "time": "2022-07-20T18:31:45+00:00" + "time": "2023-09-03T09:24:00+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.3.2", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" + "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", - "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c459b40ffe67c49af6fd392aac374c9edf8a027e", + "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4", + "symfony/dependency-injection": "<6.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -5391,13 +5882,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0" + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5425,7 +5916,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.0" }, "funding": [ { @@ -5441,7 +5932,7 @@ "type": "tidelift" } ], - "time": "2023-07-06T06:56:43+00:00" + "time": "2023-07-27T16:29:09+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -5519,88 +6010,25 @@ ], "time": "2023-05-23T14:45:45+00:00" }, - { - "name": "symfony/filesystem", - "version": "v6.3.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", - "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "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/v6.3.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-06-01T08:30:39+00:00" - }, { "name": "symfony/finder", - "version": "v6.3.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", - "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", + "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", "shasum": "" }, "require": { "php": ">=8.1" }, "require-dev": { - "symfony/filesystem": "^6.0" + "symfony/filesystem": "^6.0|^7.0" }, "type": "library", "autoload": { @@ -5628,7 +6056,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.3.5" + "source": "https://github.com/symfony/finder/tree/v6.4.0" }, "funding": [ { @@ -5644,24 +6072,25 @@ "type": "tidelift" } ], - "time": "2023-09-26T12:56:25+00:00" + "time": "2023-10-31T17:30:12+00:00" }, { "name": "symfony/mime", - "version": "v6.2.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "4b7b349f67d15cd0639955c8179a76c89f6fd610" + "reference": "ca4f58b2ef4baa8f6cecbeca2573f88cd577d205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/4b7b349f67d15cd0639955c8179a76c89f6fd610", - "reference": "4b7b349f67d15cd0639955c8179a76c89f6fd610", + "url": "https://api.github.com/repos/symfony/mime/zipball/ca4f58b2ef4baa8f6cecbeca2573f88cd577d205", + "reference": "ca4f58b2ef4baa8f6cecbeca2573f88cd577d205", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -5670,16 +6099,16 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/mailer": "<5.4", - "symfony/serializer": "<6.2" + "symfony/serializer": "<6.3.2" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/serializer": "^6.2" + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3.2|^7.0" }, "type": "library", "autoload": { @@ -5711,7 +6140,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.2.5" + "source": "https://github.com/symfony/mime/tree/v6.4.0" }, "funding": [ { @@ -5727,20 +6156,20 @@ "type": "tidelift" } ], - "time": "2023-01-10T18:53:53+00:00" + "time": "2023-10-17T11:49:05+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.3.0", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" + "reference": "22301f0e7fdeaacc14318928612dee79be99860e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e", "shasum": "" }, "require": { @@ -5778,7 +6207,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.4.0" }, "funding": [ { @@ -5794,20 +6223,20 @@ "type": "tidelift" } ], - "time": "2023-05-12T14:21:09+00:00" + "time": "2023-08-08T10:16:24+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", + "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", "shasum": "" }, "require": { @@ -5821,7 +6250,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5865,7 +6294,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" }, "funding": [ { @@ -5881,20 +6310,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:30:37+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", + "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", "shasum": "" }, "require": { @@ -5903,7 +6332,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5941,7 +6370,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" }, "funding": [ { @@ -5957,7 +6386,7 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php73", @@ -6202,20 +6631,20 @@ }, { "name": "symfony/process", - "version": "v6.3.4", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" + "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", - "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", + "url": "https://api.github.com/repos/symfony/process/zipball/13bdb1670c7f510494e04fcb2bfa29af63db9c0d", + "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -6243,7 +6672,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.3.4" + "source": "https://github.com/symfony/process/tree/v7.0.0" }, "funding": [ { @@ -6259,24 +6688,24 @@ "type": "tidelift" } ], - "time": "2023-08-07T10:39:22+00:00" + "time": "2023-11-20T16:43:42+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -6305,7 +6734,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.0.0" }, "funding": [ { @@ -6321,20 +6750,20 @@ "type": "tidelift" } ], - "time": "2023-02-16T10:14:28+00:00" + "time": "2023-07-05T13:06:06+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -6363,7 +6792,7 @@ "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.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -6371,7 +6800,7 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" } ], "aliases": [], @@ -6380,9 +6809,9 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.2.0 || ~8.3.0", "ext-json": "*", - "composer-plugin-api": "^2.0" + "composer-plugin-api": "^2.1" }, "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 00000000..91b315c2 --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,32 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + EliasHaeussler\ComposerUpdateCheck\: + resource: '../src/*' + exclude: + - '../src/DependencyInjection/*' + - '../src/Event/*' + - '../src/Exception/*' + - '../src/Package/*' + - '../src/Plugin.php' + - '../src/UpdateCheckResult.php' + + _instanceof: + EliasHaeussler\ComposerUpdateCheck\IO\Formatter\Formatter: + tags: ['io.formatter'] + + EliasHaeussler\ComposerUpdateCheck\IO\Formatter\FormatterFactory: + arguments: + $formatters: !tagged_locator { tag: 'io.formatter', default_index_method: 'getFormat' } + + EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand: + public: true + + # Synthetic services (set when the container is built on runtime) + Composer\Composer: + synthetic: true + Composer\IO\IOInterface: + synthetic: true diff --git a/docs/install.md b/docs/install.md index fa26e98b..56a00e8b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,8 +2,8 @@ ## Requirements -* PHP >= 8.1 -* Composer v2 +* PHP >= 8.2 +* Composer >= 2.1 ## Installation diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 484d615b..d96a8f17 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,28 +1,10 @@ parameters: ignoreErrors: - - message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\OutdatedPackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\OutdatedPackage will always evaluate to true\\.$#" - count: 1 - path: src/Package/UpdateCheckResult.php - - - - message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Security\\\\InsecurePackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Security\\\\InsecurePackage will always evaluate to true\\.$#" + message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\InsecurePackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\InsecurePackage will always evaluate to true\\.$#" count: 1 path: src/Security/ScanResult.php - - - message: """ - #^Call to deprecated method setRunScripts\\(\\) of class Composer\\\\Installer\\: - Use setRunScripts\\(false\\) on the EventDispatcher instance being injected instead$# - """ - count: 1 - path: src/Utility/Installer.php - - - - message: "#^Call to function method_exists\\(\\) with Composer\\\\EventDispatcher\\\\EventDispatcher and 'setRunScripts' will always evaluate to true\\.$#" - count: 1 - path: src/Utility/Installer.php - - message: "#^Variable property access on \\$this\\(EliasHaeussler\\\\ComposerUpdateCheck\\\\Tests\\\\Unit\\\\AbstractTestCase\\)\\.$#" count: 1 diff --git a/rector.php b/rector.php index f59a6006..2ef3c2fe 100644 --- a/rector.php +++ b/rector.php @@ -28,7 +28,7 @@ use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector; return static function (RectorConfig $rectorConfig): void { - Config::create($rectorConfig, PhpVersion::PHP_81) + Config::create($rectorConfig, PhpVersion::PHP_82) ->in( __DIR__.'/src', __DIR__.'/tests', diff --git a/src/Command/UpdateCheckCommand.php b/src/Command/UpdateCheckCommand.php index 847b2ab3..88b88deb 100644 --- a/src/Command/UpdateCheckCommand.php +++ b/src/Command/UpdateCheckCommand.php @@ -24,14 +24,13 @@ namespace EliasHaeussler\ComposerUpdateCheck\Command; use Composer\Command\BaseCommand; -use Composer\Factory; -use Composer\IO\BufferIO; -use EliasHaeussler\ComposerUpdateCheck\IO\OutputBehavior; -use EliasHaeussler\ComposerUpdateCheck\IO\Style; -use EliasHaeussler\ComposerUpdateCheck\IO\Verbosity; -use EliasHaeussler\ComposerUpdateCheck\Options; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\ChainedConfigAdapter; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\CommandInputConfigAdapter; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\ConfigAdapterFactory; +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\IO\Formatter\FormatterFactory; use EliasHaeussler\ComposerUpdateCheck\UpdateChecker; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -45,21 +44,28 @@ */ final class UpdateCheckCommand extends BaseCommand { - private ?SymfonyStyle $symfonyStyle = null; - - private ?OutputBehavior $behavior = null; + public function __construct( + private readonly FormatterFactory $formatterFactory, + private readonly UpdateChecker $updateChecker, + ) { + parent::__construct('update-check'); + } protected function configure(): void { - $this->setName('update-check'); $this->setDescription('Checks your root requirements for available updates.'); + $this->addOption( + 'config', + 'c', + InputOption::VALUE_REQUIRED, + 'Path to configuration file, can be in JSON, PHP oder YAML format', + ); $this->addOption( 'ignore-packages', 'i', - InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Packages to ignore when checking for available updates', - [], ); $this->addOption( 'no-dev', @@ -74,112 +80,42 @@ protected function configure(): void 'Run security scan for all outdated packages', ); $this->addOption( - 'json', - 'j', - InputOption::VALUE_NONE, - 'Format update check as JSON', + 'format', + 'f', + InputOption::VALUE_REQUIRED, + 'Format to display update check results', ); } - protected function execute(InputInterface $input, OutputInterface $output): int + protected function initialize(InputInterface $input, OutputInterface $output): void { - $this->symfonyStyle = new SymfonyStyle($input, $output); - - // Prepare command options - $json = $input->getOption('json'); - $securityScan = $input->getOption('security-scan'); - - // Initialize IO - $style = new Style($json ? Style::JSON : Style::NORMAL); - $verbosity = new Verbosity($style->isJson() ? OutputInterface::VERBOSITY_NORMAL : OutputInterface::VERBOSITY_VERBOSE); - $this->behavior = new OutputBehavior($style, $verbosity, $this->getIO()); - $output->setVerbosity($verbosity->getLevel()); - - // Run update check - $composer = Factory::create(new BufferIO()); - $updateChecker = new UpdateChecker($composer, $this->behavior, Options::fromInput($input)); - $result = $updateChecker->run(); - - // Decorate update check result - $this->decorateResult($result, $updateChecker->getPackageBlacklist(), $securityScan); - - return 0; + $this->formatterFactory->setIO(new SymfonyStyle($input, $output)); } - /** - * @param string[] $ignoredPackages - */ - private function decorateResult(UpdateCheckResult $result, array $ignoredPackages, bool $flagInsecurePackages = false): void + protected function execute(InputInterface $input, OutputInterface $output): int { - $outdatedPackages = $result->getOutdatedPackages(); - - // Print message if no packages are outdated - if ([] === $outdatedPackages) { - $countSkipped = count($ignoredPackages); - $message = sprintf( - 'All packages are up to date%s.', - $countSkipped > 0 ? sprintf(' (skipped %d package%s)', $countSkipped, 1 !== $countSkipped ? 's' : '') : '', - ); - if ($this->behavior->style->isJson()) { - $this->buildJsonReport(['status' => $message], $ignoredPackages); - } else { - $this->symfonyStyle->success($message); - } - - return; - } + $config = $this->resolveConfiguration($input); + $result = $this->updateChecker->run($config); - // Print header - $statusLabel = 1 === count($outdatedPackages) - ? '1 package is outdated.' - : sprintf('%d packages are outdated.', count($outdatedPackages)); - if (!$this->behavior->style->isJson()) { - $this->symfonyStyle->warning($statusLabel); - } - - // Parse table rows - $tableRows = []; - foreach ($outdatedPackages as $outdatedPackage) { - $report = [ - $outdatedPackage->getName(), - $outdatedPackage->getOutdatedVersion(), - $outdatedPackage->getNewVersion(), - ]; - if ($flagInsecurePackages) { - if (!$this->behavior->style->isJson() && $outdatedPackage->isInsecure()) { - $report[1] .= ' insecure'; - } elseif ($this->behavior->style->isJson()) { - $report[] = $outdatedPackage->isInsecure(); - } - } - $tableRows[] = $report; - } + $formatter = $this->formatterFactory->make($config->getFormat()); + $formatter->formatResult($result); - // Print table - $tableHeader = ['Package', 'Outdated version', 'New version']; - if (!$this->behavior->style->isJson()) { - $this->symfonyStyle->table($tableHeader, $tableRows); - } else { - $result = []; - if ($flagInsecurePackages) { - $tableHeader[] = 'Insecure'; - } - foreach ($tableRows as $tableRow) { - $result[] = array_combine($tableHeader, $tableRow); - } - $this->buildJsonReport(['status' => $statusLabel, 'result' => $result], $ignoredPackages); - } + return Command::SUCCESS; } - /** - * @param array{status: string, result?: array>} $report - * @param string[] $ignoredPackages - */ - private function buildJsonReport(array $report, array $ignoredPackages = []): void + private function resolveConfiguration(InputInterface $input): ComposerUpdateCheckConfig { - if ([] !== $ignoredPackages) { - $report['skipped'] = $ignoredPackages; + $filename = $input->getOption('config'); + $configAdapter = new CommandInputConfigAdapter($input); + + if (null !== $filename && '' !== $filename) { + $configAdapterFactory = new ConfigAdapterFactory(); + $configAdapter = new ChainedConfigAdapter([ + $configAdapterFactory->make($filename), + $configAdapter, + ]); } - $this->symfonyStyle->writeln(json_encode($report)); + + return $configAdapter->resolve(); } } diff --git a/src/Utility/Installer.php b/src/Composer/ComposerInstaller.php similarity index 52% rename from src/Utility/Installer.php rename to src/Composer/ComposerInstaller.php index 1aa0757d..76b15c4e 100644 --- a/src/Utility/Installer.php +++ b/src/Composer/ComposerInstaller.php @@ -21,74 +21,71 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Utility; +namespace EliasHaeussler\ComposerUpdateCheck\Composer; use Composer\Composer; use Composer\DependencyResolver\Request; -use Composer\Installer as ComposerInstaller; -use Composer\IO\BufferIO; +use Composer\Installer; +use Composer\IO\IOInterface; +use EliasHaeussler\ComposerUpdateCheck\Package\Package; + +use function array_map; /** - * Installer. + * ComposerInstaller. * * @author Elias Häußler * @license GPL-3.0-or-later * * @internal */ -final class Installer +final readonly class ComposerInstaller { - private static ?BufferIO $io = null; + public function __construct( + private Composer $composer, + private IOInterface $io, + ) {} - public static function runInstall(Composer $composer): int + public function runInstall(IOInterface $io = null): int { - self::$io = new BufferIO(); - $preferredInstall = $composer->getConfig()->get('preferred-install'); - $eventDispatcher = $composer->getEventDispatcher(); + $io ??= $this->io; - $installer = ComposerInstaller::create(self::$io, $composer) + $preferredInstall = $this->composer->getConfig()->get('preferred-install'); + $installer = Installer::create($io, $this->composer) ->setPreferSource('source' === $preferredInstall) ->setPreferDist('dist' === $preferredInstall) - ->setDevMode(true); + ->setDevMode() + ; - if (method_exists($eventDispatcher, 'setRunScripts')) { - // Composer >= 2.1.2 - $eventDispatcher->setRunScripts(false); - } else { - // Composer < 2.1.2 - $installer->setRunScripts(false); - } + $eventDispatcher = $this->composer->getEventDispatcher(); + $eventDispatcher->setRunScripts(false); return $installer->run(); } /** - * @param string[] $packages + * @param list $packages */ - public static function runUpdate(array $packages, Composer $composer): int + public function runUpdate(array $packages, IOInterface $io = null): int { - self::$io = new BufferIO(); - $preferredInstall = $composer->getConfig()->get('preferred-install'); + $io ??= $this->io; - $installer = ComposerInstaller::create(self::$io, $composer) - ->setDryRun(true) + $preferredInstall = $this->composer->getConfig()->get('preferred-install'); + $installer = Installer::create($io, $this->composer) + ->setDryRun() ->setPreferSource('source' === $preferredInstall) ->setPreferDist('dist' === $preferredInstall) - ->setDevMode(true) + ->setDevMode() ->setUpdate(true) - ->setUpdateAllowList($packages) + ->setUpdateAllowList( + array_map( + static fn (Package $package) => $package->getName(), + $packages, + ), + ) ->setUpdateAllowTransitiveDependencies(Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS) ; return $installer->run(); } - - public static function getLastOutput(): ?string - { - if (self::$io instanceof BufferIO) { - return self::$io->getOutput(); - } - - return null; - } } diff --git a/src/Configuration/Adapter/ChainedConfigAdapter.php b/src/Configuration/Adapter/ChainedConfigAdapter.php new file mode 100644 index 00000000..96fb63f1 --- /dev/null +++ b/src/Configuration/Adapter/ChainedConfigAdapter.php @@ -0,0 +1,73 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\IO\Formatter\TextFormatter; + +/** + * ChainedConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class ChainedConfigAdapter implements ConfigAdapter +{ + /** + * @param list $adapters + */ + public function __construct( + private array $adapters, + ) {} + + public function resolve(): ComposerUpdateCheckConfig + { + $config = new ComposerUpdateCheckConfig(); + + foreach ($this->adapters as $adapter) { + $this->mergeConfigs($config, $adapter->resolve()); + } + + return $config; + } + + private function mergeConfigs(ComposerUpdateCheckConfig $config, ComposerUpdateCheckConfig $other): void + { + foreach ($other->getExcludePatterns() as $excludePattern) { + $config->excludePackageByPattern($excludePattern); + } + + if (!$other->areDevPackagesIncluded()) { + $config->excludeDevPackages(); + } + + if ($other->shouldPerformSecurityScan()) { + $config->performSecurityScan(); + } + + if (TextFormatter::FORMAT !== $other->getFormat()) { + $config->setFormat($other->getFormat()); + } + } +} diff --git a/src/Configuration/Adapter/CommandInputConfigAdapter.php b/src/Configuration/Adapter/CommandInputConfigAdapter.php new file mode 100644 index 00000000..55ff1d0e --- /dev/null +++ b/src/Configuration/Adapter/CommandInputConfigAdapter.php @@ -0,0 +1,79 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Options\PackageExcludePattern; +use Symfony\Component\Console\Input\InputInterface; + +use function is_string; +use function str_starts_with; + +/** + * CommandInputConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class CommandInputConfigAdapter implements ConfigAdapter +{ + public function __construct( + private InputInterface $input, + ) {} + + public function resolve(): ComposerUpdateCheckConfig + { + $config = new ComposerUpdateCheckConfig(); + + if ($this->input->hasOption('ignore-packages')) { + foreach ($this->input->getOption('ignore-packages') as $pattern) { + $excludePattern = $this->resolveExcludePattern($pattern); + $config->excludePackageByPattern($excludePattern); + } + } + + if ($this->input->hasOption('no-dev') && true === $this->input->getOption('no-dev')) { + $config->excludeDevPackages(); + } + + if ($this->input->hasOption('security-scan') && true === $this->input->getOption('security-scan')) { + $config->performSecurityScan(); + } + + if ($this->input->hasOption('format') && is_string($this->input->getOption('format'))) { + $config->setFormat($this->input->getOption('format')); + } + + return $config; + } + + private function resolveExcludePattern(string $pattern): PackageExcludePattern + { + if (str_starts_with($pattern, '/') || str_starts_with($pattern, '#')) { + return PackageExcludePattern::regex($pattern); + } + + return PackageExcludePattern::name($pattern); + } +} diff --git a/src/IO/OutputBehavior.php b/src/Configuration/Adapter/ConfigAdapter.php similarity index 76% rename from src/IO/OutputBehavior.php rename to src/Configuration/Adapter/ConfigAdapter.php index dab8d150..8531b95c 100644 --- a/src/IO/OutputBehavior.php +++ b/src/Configuration/Adapter/ConfigAdapter.php @@ -21,21 +21,17 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\IO; +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; -use Composer\IO\IOInterface; +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; /** - * OutputBehavior. + * ConfigAdapter. * * @author Elias Häußler * @license GPL-3.0-or-later */ -final class OutputBehavior +interface ConfigAdapter { - public function __construct( - public readonly Style $style, - public readonly Verbosity $verbosity, - public readonly IOInterface $io, - ) {} + public function resolve(): ComposerUpdateCheckConfig; } diff --git a/src/Configuration/Adapter/ConfigAdapterFactory.php b/src/Configuration/Adapter/ConfigAdapterFactory.php new file mode 100644 index 00000000..84e464ff --- /dev/null +++ b/src/Configuration/Adapter/ConfigAdapterFactory.php @@ -0,0 +1,51 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileIsNotSupported; +use EliasHaeussler\ComposerUpdateCheck\Exception\FileDoesNotExist; +use Symfony\Component\Filesystem\Path; + +/** + * ConfigAdapterFactory. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class ConfigAdapterFactory +{ + /** + * @throws ConfigFileIsNotSupported + * @throws FileDoesNotExist + */ + public function make(string $filename): ConfigAdapter + { + return match (Path::getExtension($filename, true)) { + 'json' => new JsonConfigAdapter($filename), + 'php' => new PhpConfigAdapter($filename), + 'yaml', 'yml' => new YamlConfigAdapter($filename), + default => throw new ConfigFileIsNotSupported($filename), + }; + } +} diff --git a/src/Configuration/Adapter/FileBasedConfigAdapter.php b/src/Configuration/Adapter/FileBasedConfigAdapter.php new file mode 100644 index 00000000..123ffe11 --- /dev/null +++ b/src/Configuration/Adapter/FileBasedConfigAdapter.php @@ -0,0 +1,77 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use CuyZ\Valinor\Mapper\TreeMapper; +use CuyZ\Valinor\MapperBuilder; +use EliasHaeussler\ComposerUpdateCheck\Exception\FileDoesNotExist; +use Symfony\Component\Filesystem\Path; + +use function file_exists; +use function getcwd; + +/** + * FileBasedConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +abstract readonly class FileBasedConfigAdapter implements ConfigAdapter +{ + protected string $filename; + protected TreeMapper $mapper; + + /** + * @throws FileDoesNotExist + */ + public function __construct(string $filename) + { + $this->filename = $this->resolveFilename($filename); + $this->mapper = $this->createMapper(); + } + + /** + * @throws FileDoesNotExist + */ + private function resolveFilename(string $filename): string + { + if (!Path::isAbsolute($filename)) { + $currentWorkingDirectory = (string) getcwd(); + $filename = Path::join($currentWorkingDirectory, $filename); + } + + if (!file_exists($filename)) { + throw new FileDoesNotExist($filename); + } + + return $filename; + } + + private function createMapper(): TreeMapper + { + return (new MapperBuilder()) + ->mapper() + ; + } +} diff --git a/src/Configuration/Adapter/JsonConfigAdapter.php b/src/Configuration/Adapter/JsonConfigAdapter.php new file mode 100644 index 00000000..d3a1ded4 --- /dev/null +++ b/src/Configuration/Adapter/JsonConfigAdapter.php @@ -0,0 +1,48 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use CuyZ\Valinor\Mapper\MappingError; +use CuyZ\Valinor\Mapper\Source\Source; +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use SplFileObject; + +/** + * JsonConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class JsonConfigAdapter extends FileBasedConfigAdapter +{ + /** + * @throws MappingError + */ + public function resolve(): ComposerUpdateCheckConfig + { + $source = Source::file(new SplFileObject($this->filename)); + + return $this->mapper->map(ComposerUpdateCheckConfig::class, $source); + } +} diff --git a/src/Configuration/Adapter/PhpConfigAdapter.php b/src/Configuration/Adapter/PhpConfigAdapter.php new file mode 100644 index 00000000..9d0e11ff --- /dev/null +++ b/src/Configuration/Adapter/PhpConfigAdapter.php @@ -0,0 +1,46 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; + +/** + * PhpConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class PhpConfigAdapter extends FileBasedConfigAdapter +{ + public function resolve(): ComposerUpdateCheckConfig + { + $config = new ComposerUpdateCheckConfig(); + $closure = require $this->filename; + + // Call closure with config object + $closure($config); + + return $config; + } +} diff --git a/src/Configuration/Adapter/YamlConfigAdapter.php b/src/Configuration/Adapter/YamlConfigAdapter.php new file mode 100644 index 00000000..c693c212 --- /dev/null +++ b/src/Configuration/Adapter/YamlConfigAdapter.php @@ -0,0 +1,58 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use CuyZ\Valinor\Mapper\MappingError; +use CuyZ\Valinor\Mapper\Source\Source; +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileIsInvalid; +use Symfony\Component\Yaml\Yaml; + +use function is_iterable; + +/** + * YamlConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class YamlConfigAdapter extends FileBasedConfigAdapter +{ + /** + * @throws ConfigFileIsInvalid + * @throws MappingError + */ + public function resolve(): ComposerUpdateCheckConfig + { + $yaml = Yaml::parseFile($this->filename); + + if (!is_iterable($yaml)) { + throw new ConfigFileIsInvalid($this->filename); + } + + $source = Source::iterable($yaml); + + return $this->mapper->map(ComposerUpdateCheckConfig::class, $source); + } +} diff --git a/src/Configuration/ComposerUpdateCheckConfig.php b/src/Configuration/ComposerUpdateCheckConfig.php new file mode 100644 index 00000000..7fc4a83f --- /dev/null +++ b/src/Configuration/ComposerUpdateCheckConfig.php @@ -0,0 +1,125 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration; + +use EliasHaeussler\ComposerUpdateCheck\Configuration\Options\PackageExcludePattern; +use EliasHaeussler\ComposerUpdateCheck\IO\Formatter\TextFormatter; + +/** + * ComposerUpdateCheckConfig. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ComposerUpdateCheckConfig +{ + /** + * @param list $excludePatterns + */ + public function __construct( + private array $excludePatterns = [], + private bool $includeDevPackages = true, + private bool $performSecurityScan = false, + private string $format = TextFormatter::FORMAT, + ) {} + + public function excludePackageByName(string $name): self + { + $this->excludePatterns[] = PackageExcludePattern::name($name); + + return $this; + } + + public function excludePackageByRegex(string $regex): self + { + $this->excludePatterns[] = PackageExcludePattern::regex($regex); + + return $this; + } + + public function excludePackageByPattern(PackageExcludePattern $excludePattern): self + { + $this->excludePatterns[] = $excludePattern; + + return $this; + } + + /** + * @return list + */ + public function getExcludePatterns(): array + { + return $this->excludePatterns; + } + + public function includeDevPackages(): self + { + $this->includeDevPackages = true; + + return $this; + } + + public function excludeDevPackages(): self + { + $this->includeDevPackages = false; + + return $this; + } + + public function areDevPackagesIncluded(): bool + { + return $this->includeDevPackages; + } + + public function performSecurityScan(): self + { + $this->performSecurityScan = true; + + return $this; + } + + public function skipSecurityScan(): self + { + $this->performSecurityScan = false; + + return $this; + } + + public function shouldPerformSecurityScan(): bool + { + return $this->performSecurityScan; + } + + public function setFormat(string $format): self + { + $this->format = $format; + + return $this; + } + + public function getFormat(): string + { + return $this->format; + } +} diff --git a/src/Utility/Composer.php b/src/Configuration/Options/PackageExcludePattern.php similarity index 50% rename from src/Utility/Composer.php rename to src/Configuration/Options/PackageExcludePattern.php index e88090d5..6548ae38 100644 --- a/src/Utility/Composer.php +++ b/src/Configuration/Options/PackageExcludePattern.php @@ -21,38 +21,48 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Utility; +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Options; -use Composer\Plugin\PluginInterface; -use InvalidArgumentException; +use function fnmatch; +use function preg_match; /** - * Composer. + * PackageExcludePattern. * * @author Elias Häußler * @license GPL-3.0-or-later */ -final class Composer +final class PackageExcludePattern { - public const VERSION_FULL = 0; - public const VERSION_MAJOR = 1; - public const VERSION_BRANCH = 2; + /** + * @var callable(string): bool + */ + private $matchFunction; - public static function getPlatformVersion(int $versionType = self::VERSION_FULL): string + /** + * @param callable(string): bool $matchFunction + */ + private function __construct(callable $matchFunction) { - $platformVersion = PluginInterface::PLUGIN_API_VERSION; - $versionComponents = explode('.', $platformVersion); - - return match ($versionType) { - self::VERSION_FULL => $platformVersion, - self::VERSION_MAJOR => $versionComponents[0], - self::VERSION_BRANCH => $versionComponents[0].'.'.$versionComponents[1], - default => throw new InvalidArgumentException('The given version type is not supported.', 1603794822), - }; + $this->matchFunction = $matchFunction; } - public static function getMajorVersion(): int + public static function name(string $name): self { - return (int) self::getPlatformVersion(self::VERSION_MAJOR); + return new self( + static fn (string $packageName) => fnmatch($name, $packageName), + ); + } + + public static function regex(string $regex): self + { + return new self( + static fn (string $packageName) => 1 === preg_match($regex, $packageName), + ); + } + + public function matches(string $packageName): bool + { + return ($this->matchFunction)($packageName); } } diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php new file mode 100644 index 00000000..6aaff613 --- /dev/null +++ b/src/DependencyInjection/ContainerFactory.php @@ -0,0 +1,107 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\DependencyInjection; + +use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileIsNotSupported; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\Filesystem\Path; + +use function dirname; +use function in_array; + +/** + * ContainerFactory. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + * + * @internal + */ +final readonly class ContainerFactory +{ + /** + * @var list + */ + private array $configs; + + /** + * @param list $configs + */ + public function __construct(array $configs = []) + { + $defaultConfigurationFile = $this->getDefaultConfigurationFile(); + + if (!in_array($defaultConfigurationFile, $configs, true)) { + $this->configs = [ + $defaultConfigurationFile, + ...$configs, + ]; + } else { + $this->configs = $configs; + } + } + + /** + * @throws ConfigFileIsNotSupported + */ + public function make(): ContainerInterface + { + $container = new ContainerBuilder(); + + foreach ($this->configs as $config) { + $loader = $this->createLoader($config, $container); + $loader->load($config); + } + + $container->compile(); + + return $container; + } + + /** + * @throws ConfigFileIsNotSupported + */ + private function createLoader(string $filename, ContainerBuilder $container): LoaderInterface + { + $locator = new FileLocator($filename); + + return match (Path::getExtension($filename, true)) { + 'php' => new PhpFileLoader($container, $locator), + 'yaml', 'yml' => new YamlFileLoader($container, $locator), + 'xml' => new XmlFileLoader($container, $locator), + default => throw new ConfigFileIsNotSupported($filename), + }; + } + + private function getDefaultConfigurationFile(): string + { + return dirname(__DIR__, 2).'/config/services.yaml'; + } +} diff --git a/src/Event/PostUpdateCheckEvent.php b/src/Event/PostUpdateCheckEvent.php index 71fb1140..9fa3ba50 100644 --- a/src/Event/PostUpdateCheckEvent.php +++ b/src/Event/PostUpdateCheckEvent.php @@ -24,9 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Event; use Composer\EventDispatcher\Event; -use EliasHaeussler\ComposerUpdateCheck\IO\OutputBehavior; -use EliasHaeussler\ComposerUpdateCheck\Options; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; /** * PostUpdateCheckEvent. @@ -40,32 +38,14 @@ final class PostUpdateCheckEvent extends Event { public const NAME = 'post-update-check'; - /** - * @param string[] $args - * @param string[] $flags - */ public function __construct( private readonly UpdateCheckResult $updateCheckResult, - private readonly OutputBehavior $behavior, - private readonly Options $options, - array $args = [], - array $flags = [], ) { - parent::__construct(self::NAME, $args, $flags); + parent::__construct(self::NAME); } public function getUpdateCheckResult(): UpdateCheckResult { return $this->updateCheckResult; } - - public function getBehavior(): OutputBehavior - { - return $this->behavior; - } - - public function getOptions(): Options - { - return $this->options; - } } diff --git a/src/Exception/ComposerInstallFailed.php b/src/Exception/ComposerInstallFailed.php new file mode 100644 index 00000000..c0180c22 --- /dev/null +++ b/src/Exception/ComposerInstallFailed.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * ComposerInstallFailed. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ComposerInstallFailed extends Exception +{ + public function __construct(int $exitCode) + { + parent::__construct( + sprintf('Error during dependency install. Exit code from Composer installer: %d', $exitCode), + 1600614218, + ); + } +} diff --git a/src/Exception/ComposerUpdateFailed.php b/src/Exception/ComposerUpdateFailed.php new file mode 100644 index 00000000..80b3daf7 --- /dev/null +++ b/src/Exception/ComposerUpdateFailed.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * ComposerUpdateFailed. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ComposerUpdateFailed extends Exception +{ + public function __construct(int $exitCode) + { + parent::__construct( + sprintf('Error during update check. Exit code from Composer installer: %d', $exitCode), + 1600278536, + ); + } +} diff --git a/src/Exception/ConfigFileIsInvalid.php b/src/Exception/ConfigFileIsInvalid.php new file mode 100644 index 00000000..56a4f720 --- /dev/null +++ b/src/Exception/ConfigFileIsInvalid.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * ConfigFileIsInvalid. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ConfigFileIsInvalid extends Exception +{ + public function __construct(string $filename) + { + parent::__construct( + sprintf('The file "%s" does not contain valid configuration.', $filename), + 1701204777, + ); + } +} diff --git a/src/Exception/ConfigFileIsNotSupported.php b/src/Exception/ConfigFileIsNotSupported.php new file mode 100644 index 00000000..9e9c707d --- /dev/null +++ b/src/Exception/ConfigFileIsNotSupported.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * ConfigFileIsNotSupported. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ConfigFileIsNotSupported extends Exception +{ + public function __construct(string $filename) + { + parent::__construct( + sprintf('The file "%s" is not a supported config file.', $filename), + 1701117985, + ); + } +} diff --git a/src/Exception/Exception.php b/src/Exception/Exception.php new file mode 100644 index 00000000..e6d116b1 --- /dev/null +++ b/src/Exception/Exception.php @@ -0,0 +1,32 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +/** + * Exception. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +abstract class Exception extends \Exception {} diff --git a/src/Exception/FileDoesNotExist.php b/src/Exception/FileDoesNotExist.php new file mode 100644 index 00000000..4a36b263 --- /dev/null +++ b/src/Exception/FileDoesNotExist.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * FileDoesNotExist. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class FileDoesNotExist extends Exception +{ + public function __construct(string $filename) + { + parent::__construct( + sprintf('The file "%s" does not exist.', $filename), + 1701204856, + ); + } +} diff --git a/src/Exception/FormatterIsNotSupported.php b/src/Exception/FormatterIsNotSupported.php new file mode 100644 index 00000000..ab082a84 --- /dev/null +++ b/src/Exception/FormatterIsNotSupported.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * FormatterIsNotSupported. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class FormatterIsNotSupported extends Exception +{ + public function __construct(string $format) + { + parent::__construct( + sprintf('The formatter "%s" is not supported.', $format), + 1701117262, + ); + } +} diff --git a/src/IO/Formatter/Formatter.php b/src/IO/Formatter/Formatter.php new file mode 100644 index 00000000..e0481792 --- /dev/null +++ b/src/IO/Formatter/Formatter.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; + +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\StyleInterface; + +/** + * Formatter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +interface Formatter +{ + public function formatResult(UpdateCheckResult $result): void; + + public function setIO(OutputInterface&StyleInterface $io): void; + + public static function getFormat(): string; +} diff --git a/src/IO/Formatter/FormatterFactory.php b/src/IO/Formatter/FormatterFactory.php new file mode 100644 index 00000000..33cf9b5a --- /dev/null +++ b/src/IO/Formatter/FormatterFactory.php @@ -0,0 +1,69 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; + +use EliasHaeussler\ComposerUpdateCheck\Exception\FormatterIsNotSupported; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\DependencyInjection\ServiceLocator; + +/** + * FormatterFactory. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class FormatterFactory +{ + /** + * @param ServiceLocator $formatters + */ + public function __construct( + private readonly ServiceLocator $formatters, + private (OutputInterface&StyleInterface)|null $io = null, + ) {} + + /** + * @throws FormatterIsNotSupported + */ + public function make(string $format): Formatter + { + if (!$this->formatters->has($format)) { + throw new FormatterIsNotSupported($format); + } + + $formatter = $this->formatters->get($format); + + if (null !== $this->io) { + $formatter->setIO($this->io); + } + + return $formatter; + } + + public function setIO(OutputInterface&StyleInterface $io): void + { + $this->io = $io; + } +} diff --git a/src/IO/Formatter/GitHubActionsFormatter.php b/src/IO/Formatter/GitHubActionsFormatter.php new file mode 100644 index 00000000..1d4cc7ad --- /dev/null +++ b/src/IO/Formatter/GitHubActionsFormatter.php @@ -0,0 +1,108 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; + +use Composer\Factory; +use Composer\Util\Platform; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\Filesystem\Path; + +use function realpath; +use function sprintf; + +/** + * GitHubActionsFormatter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class GitHubActionsFormatter implements Formatter +{ + public const FORMAT = 'github-actions'; + + public function __construct( + private (OutputInterface&StyleInterface)|null $io = null, + ) {} + + public function formatResult(UpdateCheckResult $result): void + { + // Early return if IO is missing + if (null === $this->io) { + return; + } + + // Resolve path to composer.json file + $composerFile = Path::makeRelative( + realpath(Factory::getComposerFile()), + Platform::getCwd(), + ); + + $outdatedPackages = $result->getOutdatedPackages(); + $excludedPackages = $result->getExcludedPackages(); + + foreach ($outdatedPackages as $outdatedPackage) { + $this->writePackageToOutput( + $composerFile, + sprintf('Package %s is outdated', $outdatedPackage->getName()), + sprintf( + // %0A is an encoded newline + 'Outdated version: %s%%0ANew version: %s%s', + $outdatedPackage->getOutdatedVersion(), + $outdatedPackage->getNewVersion(), + $outdatedPackage->isInsecure() ? '%0APackage is insecure' : '', + ), + 'warning', + ); + } + + foreach ($excludedPackages as $excludedPackage) { + $this->writePackageToOutput( + $composerFile, + sprintf('Package %s was excluded', $excludedPackage->getName()), + 'Package was excluded due to a configured exclude pattern.', + 'notice', + ); + } + } + + private function writePackageToOutput(string $composerFile, string $title, string $message, string $severity): void + { + $this->io?->writeln( + // https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions + sprintf('::%s file=%s,title=%s::%s', $severity, $composerFile, $title, $message), + ); + } + + public function setIO(OutputInterface&StyleInterface $io): void + { + $this->io = $io; + } + + public static function getFormat(): string + { + return self::FORMAT; + } +} diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php new file mode 100644 index 00000000..8475ab06 --- /dev/null +++ b/src/IO/Formatter/JsonFormatter.php @@ -0,0 +1,195 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; + +use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\StyleInterface; + +use function count; +use function json_encode; +use function sprintf; + +/** + * JsonFormatter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class JsonFormatter implements Formatter +{ + public const FORMAT = 'json'; + + public function __construct( + private (OutputInterface&StyleInterface)|null $io = null, + ) {} + + public function formatResult(UpdateCheckResult $result): void + { + // Early return if IO is missing + if (null === $this->io) { + return; + } + + $outdatedPackages = $result->getOutdatedPackages(); + $excludedPackages = $result->getExcludedPackages(); + + // Print message if no packages are outdated + if ([] === $outdatedPackages) { + $this->renderUpToDateMessage($excludedPackages); + + return; + } + + $this->renderTable($outdatedPackages, $excludedPackages); + } + + /** + * @param list $excludedPackages + */ + private function renderUpToDateMessage(array $excludedPackages): void + { + $numberOfExcludedPackages = count($excludedPackages); + + if ($numberOfExcludedPackages > 0) { + $additionalInformation = sprintf( + ' (skipped %d package%s)', + $numberOfExcludedPackages, + 1 !== $numberOfExcludedPackages ? 's' : '', + ); + } else { + $additionalInformation = ''; + } + + $json = [ + 'status' => sprintf('All packages are up to date%s.', $additionalInformation), + ]; + + if ([] !== $excludedPackages) { + $json['excludedPackages'] = $excludedPackages; + } + + $this->renderJson($json); + } + + /** + * @param list $outdatedPackages + * @param list $excludedPackages + */ + private function renderTable(array $outdatedPackages, array $excludedPackages): void + { + $numberOfOutdatedPackages = count($outdatedPackages); + $hasInsecurePackages = false; + + // Create status label + if (1 === $numberOfOutdatedPackages) { + $statusLabel = '1 package is outdated.'; + } else { + $statusLabel = sprintf('%d packages are outdated.', $numberOfOutdatedPackages); + } + + // Print table + $tableHeader = ['name', 'outdatedVersion', 'newVersion']; + $tableRows = $this->parseTableRows($outdatedPackages, $hasInsecurePackages); + $result = []; + + if ($hasInsecurePackages) { + $tableHeader[] = 'insecure'; + } + + foreach ($tableRows as $tableRow) { + $result[] = array_combine($tableHeader, $tableRow); + } + + $json = [ + 'status' => $statusLabel, + 'outdatedPackages' => $result, + ]; + + if ([] !== $excludedPackages) { + $json['excludedPackages'] = $excludedPackages; + } + + $this->renderJson($json); + } + + /** + * @param list $outdatedPackages + * + * @return list + */ + private function parseTableRows(array $outdatedPackages, bool &$hasInsecurePackages = false): array + { + $tableRows = []; + + foreach ($outdatedPackages as $outdatedPackage) { + $report = [ + $outdatedPackage->getName(), + $outdatedPackage->getOutdatedVersion(), + $outdatedPackage->getNewVersion(), + ]; + + if ($outdatedPackage->isInsecure()) { + $report[] = $outdatedPackage->isInsecure(); + $hasInsecurePackages = true; + } + + $tableRows[] = $report; + } + + return $tableRows; + } + + /** + * @param array $json + */ + private function renderJson(array $json): void + { + // Early return if output is quiet + if ($this->io->isQuiet()) { + return; + } + + $flags = JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR; + + // Pretty-print JSON on verbose output + if ($this->io->isVerbose()) { + $flags |= JSON_PRETTY_PRINT; + } + + $this->io->writeln(json_encode($json, $flags)); + } + + public function setIO(OutputInterface&StyleInterface $io): void + { + $this->io = $io; + } + + public static function getFormat(): string + { + return self::FORMAT; + } +} diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php new file mode 100644 index 00000000..3c897e57 --- /dev/null +++ b/src/IO/Formatter/TextFormatter.php @@ -0,0 +1,136 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; + +use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\StyleInterface; + +use function count; +use function sprintf; + +/** + * TextFormatter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class TextFormatter implements Formatter +{ + public const FORMAT = 'text'; + + public function __construct( + private (OutputInterface&StyleInterface)|null $io = null, + ) {} + + public function formatResult(UpdateCheckResult $result): void + { + // Early return if IO is missing + if (null === $this->io) { + return; + } + + $outdatedPackages = $result->getOutdatedPackages(); + $excludedPackages = $result->getExcludedPackages(); + $numberOfOutdatedPackages = count($outdatedPackages); + + // Print message if no packages are outdated + if ([] === $outdatedPackages) { + $this->renderUpToDateMessage($excludedPackages); + + return; + } + + // Print header + if (1 === $numberOfOutdatedPackages) { + $this->io->warning('1 package is outdated.'); + } else { + $this->io->warning( + sprintf('%d packages are outdated.', $numberOfOutdatedPackages), + ); + } + + $this->renderTable($outdatedPackages); + } + + /** + * @param list $excludedPackages + */ + private function renderUpToDateMessage(array $excludedPackages): void + { + $numberOfExcludedPackages = count($excludedPackages); + + if ($numberOfExcludedPackages > 0) { + $additionalInformation = sprintf( + ' (skipped %d package%s)', + $numberOfExcludedPackages, + 1 !== $numberOfExcludedPackages ? 's' : '', + ); + } else { + $additionalInformation = ''; + } + + $this->io->success( + sprintf('All packages are up to date%s.', $additionalInformation), + ); + } + + /** + * @param list $outdatedPackages + */ + private function renderTable(array $outdatedPackages): void + { + $tableRows = []; + + // Parse table rows + foreach ($outdatedPackages as $outdatedPackage) { + $report = [ + $outdatedPackage->getName(), + $outdatedPackage->getOutdatedVersion(), + $outdatedPackage->getNewVersion(), + ]; + + if ($outdatedPackage->isInsecure()) { + $report[1] .= ' insecure'; + } + + $tableRows[] = $report; + } + + // Print table + $this->io->table(['Package', 'Outdated version', 'New version'], $tableRows); + } + + public function setIO(OutputInterface&StyleInterface $io): void + { + $this->io = $io; + } + + public static function getFormat(): string + { + return self::FORMAT; + } +} diff --git a/src/IO/Verbosity.php b/src/IO/Verbosity.php deleted file mode 100644 index 00f35dcf..00000000 --- a/src/IO/Verbosity.php +++ /dev/null @@ -1,101 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -namespace EliasHaeussler\ComposerUpdateCheck\IO; - -use InvalidArgumentException; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Verbosity. - * - * @author Elias Häußler - * @license GPL-3.0-or-later - */ -final class Verbosity -{ - public const QUIET = OutputInterface::VERBOSITY_QUIET; - public const NORMAL = OutputInterface::VERBOSITY_NORMAL; - public const VERBOSE = OutputInterface::VERBOSITY_VERBOSE; - public const VERY_VERBOSE = OutputInterface::VERBOSITY_VERY_VERBOSE; - public const DEBUG = OutputInterface::VERBOSITY_DEBUG; - - public function __construct( - private readonly int $level = OutputInterface::VERBOSITY_NORMAL, - ) { - $this->validate(); - } - - public static function isSupported(int $level): bool - { - return in_array($level, [ - self::QUIET, - self::NORMAL, - self::VERBOSE, - self::VERY_VERBOSE, - self::DEBUG, - ], true); - } - - public function isQuiet(): bool - { - return $this->is(self::QUIET); - } - - public function isNormal(): bool - { - return $this->is(self::NORMAL); - } - - public function isVerbose(): bool - { - return $this->is(self::VERBOSE); - } - - public function isVeryVerbose(): bool - { - return $this->is(self::VERY_VERBOSE); - } - - public function isDebug(): bool - { - return $this->is(self::DEBUG); - } - - public function is(int $level): bool - { - return $this->level === $level; - } - - public function getLevel(): int - { - return $this->level; - } - - private function validate(): void - { - if (!static::isSupported($this->level)) { - throw new InvalidArgumentException('The given verbosity level is not supported.', 1617549839); - } - } -} diff --git a/src/Options.php b/src/Options.php deleted file mode 100644 index c03d9d87..00000000 --- a/src/Options.php +++ /dev/null @@ -1,101 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -namespace EliasHaeussler\ComposerUpdateCheck; - -use Symfony\Component\Console\Input\InputInterface; - -/** - * Options. - * - * @author Elias Häußler - * @license GPL-3.0-or-later - */ -final class Options -{ - /** - * @var string[] - */ - private array $ignorePackages = []; - private bool $includeDevPackages = true; - private bool $performSecurityScan = false; - - public static function fromInput(InputInterface $input): self - { - $instance = new self(); - - if ($input->hasOption('ignore-packages')) { - $instance->setIgnorePackages($input->getOption('ignore-packages')); - } - if ($input->hasOption('no-dev')) { - $instance->setIncludeDevPackages(false === $input->getOption('no-dev')); - } - if ($input->hasOption('security-scan')) { - $instance->setPerformSecurityScan($input->getOption('security-scan')); - } - - return $instance; - } - - /** - * @return string[] - */ - public function getIgnorePackages(): array - { - return $this->ignorePackages; - } - - /** - * @param string[] $ignorePackages - */ - public function setIgnorePackages(array $ignorePackages): self - { - $this->ignorePackages = $ignorePackages; - - return $this; - } - - public function isIncludingDevPackages(): bool - { - return $this->includeDevPackages; - } - - public function setIncludeDevPackages(bool $includeDevPackages): self - { - $this->includeDevPackages = $includeDevPackages; - - return $this; - } - - public function isPerformingSecurityScan(): bool - { - return $this->performSecurityScan; - } - - public function setPerformSecurityScan(bool $performSecurityScan): self - { - $this->performSecurityScan = $performSecurityScan; - - return $this; - } -} diff --git a/src/Security/InsecurePackage.php b/src/Package/InsecurePackage.php similarity index 68% rename from src/Security/InsecurePackage.php rename to src/Package/InsecurePackage.php index 0e513941..7142d1a0 100644 --- a/src/Security/InsecurePackage.php +++ b/src/Package/InsecurePackage.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Security; +namespace EliasHaeussler\ComposerUpdateCheck\Package; /** * InsecurePackage. @@ -29,10 +29,11 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final class InsecurePackage +final readonly class InsecurePackage implements Package { /** - * @param string[] $affectedVersions + * @param non-empty-string $name + * @param list $affectedVersions */ public function __construct( private string $name, @@ -44,15 +45,8 @@ public function getName(): string return $this->name; } - public function setName(string $name): self - { - $this->name = $name; - - return $this; - } - /** - * @return string[] + * @return list */ public function getAffectedVersions(): array { @@ -60,12 +54,21 @@ public function getAffectedVersions(): array } /** - * @param string[] $affectedVersions + * @return array{ + * name: non-empty-string, + * affectedVersions: list, + * } */ - public function setAffectedVersions(array $affectedVersions): self + public function jsonSerialize(): array { - $this->affectedVersions = $affectedVersions; + return [ + 'name' => $this->name, + 'affectedVersions' => $this->affectedVersions, + ]; + } - return $this; + public function __toString(): string + { + return $this->name; } } diff --git a/src/Package/OutdatedPackage.php b/src/Package/OutdatedPackage.php index 7c14c510..0bd6c602 100644 --- a/src/Package/OutdatedPackage.php +++ b/src/Package/OutdatedPackage.php @@ -32,16 +32,19 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final class OutdatedPackage +final class OutdatedPackage implements Package { private const PROVIDER_LINK_PATTERN = 'https://packagist.org/packages/%s#%s'; private UriInterface $providerLink; + /** + * @param non-empty-string $name + */ public function __construct( - private string $name, - private string $outdatedVersion, - private string $newVersion, + private readonly string $name, + private readonly string $outdatedVersion, + private readonly string $newVersion, private bool $insecure = false, ) { $this->providerLink = $this->generateProviderLink(); @@ -52,37 +55,16 @@ public function getName(): string return $this->name; } - public function setName(string $name): self - { - $this->name = $name; - - return $this; - } - public function getOutdatedVersion(): string { return $this->outdatedVersion; } - public function setOutdatedVersion(string $outdatedVersion): self - { - $this->outdatedVersion = $outdatedVersion; - - return $this; - } - public function getNewVersion(): string { return $this->newVersion; } - public function setNewVersion(string $newVersion): self - { - $this->newVersion = $newVersion; - - return $this; - } - public function isInsecure(): bool { return $this->insecure; @@ -100,13 +82,38 @@ public function getProviderLink(): UriInterface return $this->providerLink; } - public function setProviderLink(Uri $providerLink): self + public function setProviderLink(UriInterface $providerLink): self { $this->providerLink = $providerLink; return $this; } + /** + * @return array{ + * name: non-empty-string, + * outdatedVersion: string, + * newVersion: string, + * insecure: bool, + * providerLink: string, + * } + */ + public function jsonSerialize(): array + { + return [ + 'name' => $this->name, + 'outdatedVersion' => $this->outdatedVersion, + 'newVersion' => $this->newVersion, + 'insecure' => $this->insecure, + 'providerLink' => (string) $this->providerLink, + ]; + } + + public function __toString(): string + { + return $this->name; + } + private function generateProviderLink(): UriInterface { $versionHash = explode(' ', $this->newVersion, 2)[0]; diff --git a/src/Package/Package.php b/src/Package/Package.php new file mode 100644 index 00000000..626a77f4 --- /dev/null +++ b/src/Package/Package.php @@ -0,0 +1,41 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Package; + +use JsonSerializable; +use Stringable; + +/** + * Package. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +interface Package extends JsonSerializable, Stringable +{ + /** + * @return non-empty-string + */ + public function getName(): string; +} diff --git a/src/IO/Style.php b/src/Package/RequiredPackage.php similarity index 51% rename from src/IO/Style.php rename to src/Package/RequiredPackage.php index 4649f941..476604e0 100644 --- a/src/IO/Style.php +++ b/src/Package/RequiredPackage.php @@ -21,56 +21,38 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\IO; - -use InvalidArgumentException; +namespace EliasHaeussler\ComposerUpdateCheck\Package; /** - * Style. + * RequiredPackage. * * @author Elias Häußler * @license GPL-3.0-or-later */ -final class Style +final readonly class RequiredPackage implements Package { - public const NORMAL = 'normal'; - public const JSON = 'json'; - + /** + * @param non-empty-string $name + */ public function __construct( - private readonly string $style = self::NORMAL, - ) { - $this->validate(); - } - - public static function isSupported(string $style): bool - { - return in_array($style, [self::NORMAL, self::JSON], true); - } - - public function isNormal(): bool - { - return $this->is(self::NORMAL); - } - - public function isJson(): bool - { - return $this->is(self::JSON); - } + private string $name, + ) {} - public function is(string $style): bool + public function getName(): string { - return $this->style === $style; + return $this->name; } - public function getStyle(): string + /** + * @return non-empty-string + */ + public function jsonSerialize(): string { - return $this->style; + return $this->name; } - private function validate(): void + public function __toString(): string { - if (!static::isSupported($this->style)) { - throw new InvalidArgumentException('The given style is not supported.', 1617549657); - } + return $this->name; } } diff --git a/src/Package/UpdateCheckResult.php b/src/Package/UpdateCheckResult.php deleted file mode 100644 index 59f547ef..00000000 --- a/src/Package/UpdateCheckResult.php +++ /dev/null @@ -1,138 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -namespace EliasHaeussler\ComposerUpdateCheck\Package; - -use InvalidArgumentException; - -/** - * UpdateCheckResult. - * - * @author Elias Häußler - * @license GPL-3.0-or-later - */ -final class UpdateCheckResult -{ - private const COMMAND_OUTPUT_PATTERN = - '#^'. - '\\s*- Upgrading '. - '(?P\\S+) \\('. - '(?Pdev-\\S+ \\S+|(?!dev-)\\S+)'. - ' => '. - '(?Pdev-\S+ \S+|(?!dev-)\S+)'. - '\\)'. - '$#'; - private const LEGACY_COMMAND_OUTPUT_PATTERN = - '#^'. - '\\s*- Updating '. - '(?Pdev-\\S+ \\S+|(?!dev-)\\S+) \\('. - '(?Pdev-\S+ \S+|(?!dev-)\S+)'. - '\\) to \\S+ \\('. - '(?Pdev-\S+ \S+|(?!dev-)\S+)'. - '\\)'. - '$#'; - - /** - * @var OutdatedPackage[] - */ - private readonly array $outdatedPackages; - - /** - * @param OutdatedPackage[] $outdatedPackages - */ - public function __construct(array $outdatedPackages) - { - $this->validateOutdatedPackages($outdatedPackages); - $this->outdatedPackages = $this->sortPackages($outdatedPackages); - } - - /** - * @return OutdatedPackage[] - */ - public function getOutdatedPackages(): array - { - return $this->outdatedPackages; - } - - /** - * @param string[] $allowedPackages - */ - public static function fromCommandOutput(string $output, array $allowedPackages): self - { - $outputParts = explode(PHP_EOL, $output); - $packages = array_unique( - array_filter( - array_map([self::class, 'parseCommandOutput'], $outputParts), - function (?OutdatedPackage $outdatedPackage) use ($allowedPackages) { - if (null === $outdatedPackage) { - return false; - } - - return in_array($outdatedPackage->getName(), $allowedPackages, true); - }, - ), - SORT_REGULAR, - ); - - return new self($packages); - } - - public static function parseCommandOutput(string $output): ?OutdatedPackage - { - if ( - !preg_match(self::COMMAND_OUTPUT_PATTERN, $output, $matches) - && !preg_match(self::LEGACY_COMMAND_OUTPUT_PATTERN, $output, $matches) - ) { - return null; - } - $packageName = $matches['name']; - $outdatedVersion = $matches['outdated']; - $newVersion = $matches['new']; - - return new OutdatedPackage($packageName, $outdatedVersion, $newVersion); - } - - /** - * @param OutdatedPackage[] $outdatedPackages - * - * @return OutdatedPackage[] - */ - private function sortPackages(array $outdatedPackages): array - { - usort($outdatedPackages, fn (OutdatedPackage $a, OutdatedPackage $b) => strcmp($a->getName(), $b->getName())); - - return $outdatedPackages; - } - - /** - * @param OutdatedPackage[] $outdatedPackages - */ - private function validateOutdatedPackages(array $outdatedPackages): void - { - foreach ($outdatedPackages as $key => $outdatedPackage) { - if (!($outdatedPackage instanceof OutdatedPackage)) { - throw new InvalidArgumentException(sprintf('Outdated package #%s must be an instance of "%s".', $key, OutdatedPackage::class), 1600276584); - } - } - } -} diff --git a/src/Plugin.php b/src/Plugin.php index 7ed3f39e..bf3da953 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -28,6 +28,8 @@ use Composer\Plugin\Capability\CommandProvider; use Composer\Plugin\Capable; use Composer\Plugin\PluginInterface; +use EliasHaeussler\ComposerUpdateCheck\DependencyInjection\ContainerFactory; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Plugin. @@ -39,9 +41,13 @@ */ final class Plugin implements PluginInterface, Capable, CommandProvider { + private static ?ContainerInterface $container = null; + public function activate(Composer $composer, IOInterface $io): void { - // Nothing to do here. Just go ahead :) + self::$container = (new ContainerFactory())->make(); + self::$container->set(Composer::class, $composer); + self::$container->set(IOInterface::class, $io); } public function deactivate(Composer $composer, IOInterface $io): void @@ -64,7 +70,7 @@ public function getCapabilities(): array public function getCommands(): array { return [ - new Command\UpdateCheckCommand(), + self::$container->get(Command\UpdateCheckCommand::class), ]; } } diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index 4f4b7589..b49a6444 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -24,6 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; use Composer\Semver\Semver; +use EliasHaeussler\ComposerUpdateCheck\Package\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; use InvalidArgumentException; @@ -33,13 +34,13 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final class ScanResult +final readonly class ScanResult { /** * @param InsecurePackage[] $insecurePackages */ public function __construct( - private readonly array $insecurePackages, + private array $insecurePackages, ) { $this->validateInsecurePackages(); } diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index 48f8110b..8733c1cd 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -24,6 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use JsonException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Uri; @@ -52,7 +53,7 @@ public function __construct(ClientInterface $client = null) } /** - * @param OutdatedPackage[] $packages + * @param list $packages */ public function scan(array $packages): ScanResult { @@ -83,4 +84,16 @@ public function scan(array $packages): ScanResult throw new RuntimeException('Error while scanning security vulnerabilities.', 1610706128, $e); } } + + public function scanAndOverlayResult(UpdateCheckResult $result): void + { + $outdatedPackages = $result->getOutdatedPackages(); + $scanResult = $this->scan($outdatedPackages); + + foreach ($outdatedPackages as $outdatedPackage) { + if ($scanResult->isInsecure($outdatedPackage)) { + $outdatedPackage->setInsecure(true); + } + } + } } diff --git a/src/UpdateCheckResult.php b/src/UpdateCheckResult.php new file mode 100644 index 00000000..6d549b3b --- /dev/null +++ b/src/UpdateCheckResult.php @@ -0,0 +1,134 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck; + +/** + * UpdateCheckResult. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class UpdateCheckResult +{ + private const COMMAND_OUTPUT_PATTERN = + '#^'. + '\\s*- Upgrading '. + '(?P\\S+) \\('. + '(?Pdev-\\S+ \\S+|(?!dev-)\\S+)'. + ' => '. + '(?Pdev-\S+ \S+|(?!dev-)\S+)'. + '\\)'. + '$#'; + + /** + * @var list + */ + private readonly array $outdatedPackages; + + /** + * @var list + */ + private readonly array $excludedPackages; + + /** + * @param list $outdatedPackages + * @param list $excludedPackages + */ + public function __construct(array $outdatedPackages, array $excludedPackages = []) + { + $this->outdatedPackages = $this->sortPackages($outdatedPackages); + $this->excludedPackages = $this->sortPackages($excludedPackages); + } + + /** + * @param list $allowedPackages + * @param list $excludedPackages + */ + public static function fromCommandOutput( + string $output, + array $allowedPackages, + array $excludedPackages = [], + ): self { + $allowedPackageNames = array_map( + static fn (Package\Package $package) => $package->getName(), + $allowedPackages, + ); + + $outputParts = explode(PHP_EOL, $output); + $outdatedPackages = array_unique( + array_filter( + array_map(self::parseCommandOutput(...), $outputParts), + static function (?Package\OutdatedPackage $outdatedPackage) use ($allowedPackageNames) { + if (null === $outdatedPackage) { + return false; + } + + return in_array($outdatedPackage->getName(), $allowedPackageNames, true); + }, + ), + SORT_REGULAR, + ); + + return new self($outdatedPackages, $excludedPackages); + } + + /** + * @return list + */ + public function getOutdatedPackages(): array + { + return $this->outdatedPackages; + } + + /** + * @return list + */ + public function getExcludedPackages(): array + { + return $this->excludedPackages; + } + + private static function parseCommandOutput(string $output): ?Package\OutdatedPackage + { + if (1 !== preg_match(self::COMMAND_OUTPUT_PATTERN, $output, $matches)) { + return null; + } + + return new Package\OutdatedPackage($matches['name'], $matches['outdated'], $matches['new']); + } + + /** + * @template T of Package\Package + * + * @param list $packages + * + * @return list + */ + private function sortPackages(array $packages): array + { + usort($packages, static fn (Package\Package $a, Package\Package $b) => strcmp($a->getName(), $b->getName())); + + return $packages; + } +} diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 08391ebd..077935ef 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -24,13 +24,20 @@ namespace EliasHaeussler\ComposerUpdateCheck; use Composer\Composer; +use Composer\IO\BufferIO; use Composer\IO\IOInterface; +use EliasHaeussler\ComposerUpdateCheck\Composer\ComposerInstaller; +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Options\PackageExcludePattern; use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent; -use EliasHaeussler\ComposerUpdateCheck\IO\OutputBehavior; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; -use EliasHaeussler\ComposerUpdateCheck\Utility\Installer; -use EliasHaeussler\ComposerUpdateCheck\Utility\Security; -use RuntimeException; +use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerInstallFailed; +use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerUpdateFailed; +use EliasHaeussler\ComposerUpdateCheck\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Package\RequiredPackage; +use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; + +use function array_map; +use function array_merge; /** * UpdateChecker. @@ -38,32 +45,24 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final class UpdateChecker +final readonly class UpdateChecker { - /** - * @var string[] - */ - private array $packageBlacklist = []; - public function __construct( - private readonly Composer $composer, - private readonly OutputBehavior $behavior, - private readonly Options $options, + private Composer $composer, + private ComposerInstaller $installer, + private IOInterface $io, + private SecurityScanner $securityScanner, ) {} - public function run(): UpdateCheckResult + public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult { - // Resolve packages to be checked - $this->behavior->io->write('📦 Resolving packages...', true, IOInterface::VERBOSE); - $packages = $this->resolvePackagesForUpdateCheck(); - - // Run update check - $result = $this->runUpdateCheck($packages); + [$packages, $excludedPackages] = $this->resolvePackagesForUpdateCheck($config); + $result = $this->runUpdateCheck($packages, $excludedPackages); // Overlay security scan - if ($this->options->isPerformingSecurityScan() && [] !== $result->getOutdatedPackages()) { - $this->behavior->io->write('🚨 Checking for insecure packages...', true, IOInterface::VERBOSE); - $result = Security::scanAndOverlayResult($result); + if ($config->shouldPerformSecurityScan() && [] !== $result->getOutdatedPackages()) { + $this->io->writeError('🚨 Checking for insecure packages...', true, IOInterface::VERBOSE); + $this->securityScanner->scanAndOverlayResult($result); } // Dispatch event @@ -73,9 +72,13 @@ public function run(): UpdateCheckResult } /** - * @param string[] $packages + * @param list $packages + * @param list $excludedPackages + * + * @throws ComposerInstallFailed + * @throws ComposerUpdateFailed */ - private function runUpdateCheck(array $packages): UpdateCheckResult + private function runUpdateCheck(array $packages, array $excludedPackages): UpdateCheckResult { // Early return if no packages are listed for update check if ([] === $packages) { @@ -85,85 +88,117 @@ private function runUpdateCheck(array $packages): UpdateCheckResult // Ensure dependencies are installed $this->installDependencies(); + // Show progress + $this->io->writeError('⏳ Checking for outdated packages...', true, IOInterface::VERBOSE); + // Run Composer installer - $this->behavior->io->write('⏳ Checking for outdated packages...', true, IOInterface::VERBOSE); - $result = Installer::runUpdate($packages, $this->composer); + $io = new BufferIO(); + $exitCode = $this->installer->runUpdate($packages, $io); // Handle installer failures - if ($result > 0) { - $this->behavior->io->writeError(Installer::getLastOutput()); - throw new RuntimeException(sprintf('Error during update check. Exit code from Composer installer: %d', $result), 1600278536); + if ($exitCode > 0) { + $this->io->writeError($io->getOutput()); + + throw new ComposerUpdateFailed($exitCode); } - return UpdateCheckResult::fromCommandOutput(Installer::getLastOutput(), $packages); + return UpdateCheckResult::fromCommandOutput($io->getOutput(), $packages, $excludedPackages); } + /** + * @throws ComposerInstallFailed + */ private function installDependencies(): void { // Run Composer installer - $result = Installer::runInstall($this->composer); + $io = new BufferIO(); + $exitCode = $this->installer->runInstall($io); // Handle installer failures - if ($result > 0) { - $this->behavior->io->writeError(Installer::getLastOutput()); - throw new RuntimeException(sprintf('Error during dependency install. Exit code from Composer installer: %d', $result), 1600614218); + if ($exitCode > 0) { + $this->io->writeError($io->getOutput()); + + throw new ComposerInstallFailed($exitCode); } } /** - * @return string[] + * @return array{list, list} */ - private function resolvePackagesForUpdateCheck(): array + private function resolvePackagesForUpdateCheck(ComposerUpdateCheckConfig $config): array { + $this->io->writeError('📦 Resolving packages...', true, IOInterface::VERBOSE); + $rootPackage = $this->composer->getPackage(); $requiredPackages = array_keys($rootPackage->getRequires()); $requiredDevPackages = array_keys($rootPackage->getDevRequires()); + $excludedPackages = []; // Handle dev-packages - if ($this->options->isIncludingDevPackages()) { + if ($config->areDevPackagesIncluded()) { $requiredPackages = array_merge($requiredPackages, $requiredDevPackages); } else { - $this->packageBlacklist = array_merge($this->packageBlacklist, $requiredDevPackages); - $this->behavior->io->write('🚫 Skipped dev-requirements', true, IOInterface::VERBOSE); - } + $excludedPackages = $requiredDevPackages; - // Remove blacklisted packages - foreach ($this->options->getIgnorePackages() as $ignoredPackage) { - $requiredPackages = $this->removeByIgnorePattern($ignoredPackage, $requiredPackages); + $this->io->writeError('🚫 Skipped dev-requirements', true, IOInterface::VERBOSE); } - return $requiredPackages; + // Remove packages by exclude patterns + $excludedPackages = array_merge( + $excludedPackages, + $this->removeByExcludePatterns($requiredPackages, $config->getExcludePatterns()), + ); + + return [ + $this->mapPackageNamesToPackage($requiredPackages), + $this->mapPackageNamesToPackage($excludedPackages), + ]; } /** - * @param string[] $packages + * @param string[] $packages + * @param list $excludePatterns * * @return string[] */ - private function removeByIgnorePattern(string $pattern, array $packages): array + private function removeByExcludePatterns(array &$packages, array $excludePatterns): array { - return array_filter($packages, function (string $package) use ($pattern) { - if (!fnmatch($pattern, $package)) { - return true; + $excludedPackages = []; + + $packages = array_filter($packages, function (string $package) use (&$excludedPackages, $excludePatterns) { + foreach ($excludePatterns as $excludePattern) { + if ($excludePattern->matches($package)) { + $excludedPackages[] = $package; + + $this->io->writeError(sprintf('🚫 Skipped "%s"', $package), true, IOInterface::VERBOSE); + + return false; + } } - $this->behavior->io->write(sprintf('🚫 Skipped "%s"', $package), true, IOInterface::VERBOSE); - $this->packageBlacklist[] = $package; - return false; + return true; }); - } - private function dispatchPostUpdateCheckEvent(UpdateCheckResult $result): void - { - $commandEvent = new PostUpdateCheckEvent($result, $this->behavior, $this->options); - $this->composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); + return $excludedPackages; } /** - * @return string[] + * @param array $packageNames + * + * @return array */ - public function getPackageBlacklist(): array + private function mapPackageNamesToPackage(array $packageNames): array { - return $this->packageBlacklist; + return array_map( + static fn (string $packageName) => new RequiredPackage($packageName), + $packageNames, + ); + } + + private function dispatchPostUpdateCheckEvent(UpdateCheckResult $result): void + { + $event = new PostUpdateCheckEvent($result); + + $this->composer->getEventDispatcher()->dispatch($event->getName(), $event); } } diff --git a/src/Utility/Security.php b/src/Utility/Security.php deleted file mode 100644 index 1337adf1..00000000 --- a/src/Utility/Security.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -namespace EliasHaeussler\ComposerUpdateCheck\Utility; - -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; -use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; -use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; - -/** - * Security. - * - * @author Elias Häußler - * @license GPL-3.0-or-later - */ -final class Security -{ - /** - * @param OutdatedPackage[] $outdatedPackages - */ - public static function scan(array $outdatedPackages): ScanResult - { - $securityChecker = new SecurityScanner(); - - return $securityChecker->scan($outdatedPackages); - } - - public static function scanAndOverlayResult(UpdateCheckResult $result): UpdateCheckResult - { - $outdatedPackages = $result->getOutdatedPackages(); - $scanResult = self::scan($outdatedPackages); - foreach ($outdatedPackages as $outdatedPackage) { - if ($scanResult->isInsecure($outdatedPackage)) { - $outdatedPackage->setInsecure(true); - } - } - - return $result; - } -} diff --git a/tests/Build/phpstan/console-application.php b/tests/Build/phpstan/console-application.php index 21bb1b35..86d9af2e 100644 --- a/tests/Build/phpstan/console-application.php +++ b/tests/Build/phpstan/console-application.php @@ -21,9 +21,19 @@ * along with this program. If not, see . */ +namespace EliasHaeussler\ComposerUpdateCheck; + +use Composer\Composer; +use Composer\IO; +use Symfony\Component\Console; + require_once __DIR__.'/../../../vendor/autoload.php'; -$application = new \Symfony\Component\Console\Application(); -$application->add(new \EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand()); +$container = (new DependencyInjection\ContainerFactory())->make(); +$container->set(Composer::class, new Composer()); +$container->set(IO\IOInterface::class, new IO\NullIO()); + +$application = new Console\Application(); +$application->add($container->get(Command\UpdateCheckCommand::class)); return $application; diff --git a/tests/Build/test-application/composer.json b/tests/Build/test-application/composer.json index 085f8a08..13bd0e1b 100644 --- a/tests/Build/test-application/composer.json +++ b/tests/Build/test-application/composer.json @@ -1,10 +1,9 @@ { "require": { - "symfony/console": "^4.4", - "symfony/http-kernel": "^4.4" + "symfony/http-kernel": "^5.4" }, "require-dev": { - "codeception/codeception": "^4.1" + "doctrine/dbal": "^3.1" }, "config": { "allow-plugins": { diff --git a/tests/Build/test-application/composer.lock b/tests/Build/test-application/composer.lock index 5e13429e..6c3acb94 100644 --- a/tests/Build/test-application/composer.lock +++ b/tests/Build/test-application/composer.lock @@ -4,71 +4,24 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2896851cbc2f2f05032159b969d20c2d", + "content-hash": "1461553a0cfcd2458fa996129ce84828", "packages": [ { - "name": "paragonie/random_compat", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "a1d9f267eb8b8ad560e54e397a5ed1e3b78097d1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a1d9f267eb8b8ad560e54e397a5ed1e3b78097d1", - "reference": "a1d9f267eb8b8ad560e54e397a5ed1e3b78097d1", - "shasum": "" - }, - "require": { - "php": ">=5.2.0" - }, - "type": "library", - "autoload": { - "files": [ - "lib/random.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "time": "2015-09-07T01:49:23+00:00" - }, - { - "name": "psr/container", + "name": "psr/event-dispatcher", "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", "extra": { @@ -78,7 +31,7 @@ }, "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "Psr\\EventDispatcher\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -91,39 +44,44 @@ "homepage": "http://www.php-fig.org/" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", + "description": "Standard interfaces for event handling.", "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" + "events", + "psr", + "psr-14" ], "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" }, - "time": "2017-02-14T16:28:37+00:00" + "time": "2019-01-08T18:20:26+00:00" }, { "name": "psr/log", - "version": "1.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", "shasum": "" }, + "require": { + "php": ">=8.0.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -133,152 +91,51 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "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": { - "issues": "https://github.com/php-fig/log/issues", - "source": "https://github.com/php-fig/log/tree/1.0.0" + "source": "https://github.com/php-fig/log/tree/2.0.0" }, - "time": "2012-12-21T11:40:51+00:00" + "time": "2021-07-14T16:41:46+00:00" }, { - "name": "symfony/console", - "version": "v4.4.9", + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "326b064d804043005526f5a0494cfb49edb59bb0" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/326b064d804043005526f5a0494cfb49edb59bb0", - "reference": "326b064d804043005526f5a0494cfb49edb59bb0", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", - "symfony/lock": "<4.4", - "symfony/process": "<3.3" - }, - "provide": { - "psr/log-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "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": "Symfony Console Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/console/tree/4.4" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" + "dev-main": "3.4-dev" }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-05-30T20:06:45+00:00" - }, - { - "name": "symfony/debug", - "version": "v4.4.9", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/28f92d08bb6d1fddf8158e02c194ad43870007e6", - "reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "symfony/http-kernel": "<3.4" - }, - "require-dev": { - "symfony/http-kernel": "^3.4|^4.0|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -287,18 +144,18 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug/tree/4.4" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -314,40 +171,39 @@ "type": "tidelift" } ], - "abandoned": "symfony/error-handler", - "time": "2020-05-24T08:33:35+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/error-handler", - "version": "v4.4.9", + "version": "v6.3.5", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "0df9a23c0f9eddbb6682479fee6fd58b88add75b" + "reference": "1f69476b64fb47105c06beef757766c376b548c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/0df9a23c0f9eddbb6682479fee6fd58b88add75b", - "reference": "0df9a23c0f9eddbb6682479fee6fd58b88add75b", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/1f69476b64fb47105c06beef757766c376b548c4", + "reference": "1f69476b64fb47105c06beef757766c376b548c4", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/debug": "^4.4.5", - "symfony/polyfill-php80": "^1.15", - "symfony/var-dumper": "^4.4|^5.0" + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5" }, "require-dev": { - "symfony/http-kernel": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\ErrorHandler\\": "" @@ -370,10 +226,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony ErrorHandler Component", + "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/4.4" + "source": "https://github.com/symfony/error-handler/tree/v6.3.5" }, "funding": [ { @@ -389,52 +245,45 @@ "type": "tidelift" } ], - "time": "2020-05-28T10:39:14+00:00" + "time": "2023-09-12T06:57:20+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.9", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a5370aaa7807c7a439b21386661ffccf3dff2866" + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5370aaa7807c7a439b21386661ffccf3dff2866", - "reference": "a5370aaa7807c7a439b21386661ffccf3dff2866", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d76d2632cfc2206eecb5ad2b26cd5934082941b6", + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<3.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" @@ -457,10 +306,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/4.4" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.0" }, "funding": [ { @@ -476,33 +325,30 @@ "type": "tidelift" } ], - "time": "2020-05-20T08:37:50+00:00" + "time": "2023-07-27T06:52:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.9", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { - "php": ">=7.1.3" - }, - "suggest": { - "psr/event-dispatcher": "", - "symfony/event-dispatcher-implementation": "" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -539,7 +385,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.9" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { @@ -555,37 +401,42 @@ "type": "tidelift" } ], - "time": "2020-07-06T13:19:58+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.4.9", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3adfbd7098c850b02d107330b7b9deacf2581578" + "reference": "44a6d39a9cc11e154547d882d5aac1e014440771" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3adfbd7098c850b02d107330b7b9deacf2581578", - "reference": "3adfbd7098c850b02d107330b7b9deacf2581578", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/44a6d39a9cc11e154547d882d5aac1e014440771", + "reference": "44a6d39a9cc11e154547d882d5aac1e014440771", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/mime": "^4.3|^5.0", - "symfony/polyfill-mbstring": "~1.1" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "symfony/cache": "<6.3" }, "require-dev": { - "predis/predis": "~1.0", - "symfony/expression-language": "^3.4|^4.0|^5.0" + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" @@ -608,10 +459,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpFoundation Component", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/4.4" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.0" }, "funding": [ { @@ -627,60 +478,69 @@ "type": "tidelift" } ], - "time": "2020-05-23T09:11:46+00:00" + "time": "2023-11-20T16:41:16+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.9", + "version": "v5.4.19", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467" + "reference": "ee371cd7718c938d1bffdf868b665003aeeae69c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/54526b598d7fc86a67850488b194a88a79ab8467", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ee371cd7718c938d1bffdf868b665003aeeae69c", + "reference": "ee371cd7718c938d1bffdf868b665003aeeae69c", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/error-handler": "^4.4", - "symfony/event-dispatcher": "^4.4", - "symfony/http-foundation": "^4.4|^5.0", + "php": ">=7.2.5", + "psr/log": "^1|^2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^5.0|^6.0", + "symfony/http-foundation": "^5.3.7|^6.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { - "symfony/browser-kit": "<4.3", - "symfony/config": "<3.4", - "symfony/console": ">=5", - "symfony/dependency-injection": "<4.3", - "symfony/translation": "<4.2", - "twig/twig": "<1.34|<2.4,>=2" + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.0", + "symfony/config": "<5.0", + "symfony/console": "<4.4", + "symfony/dependency-injection": "<5.3", + "symfony/doctrine-bridge": "<5.0", + "symfony/form": "<5.0", + "symfony/http-client": "<5.0", + "symfony/mailer": "<5.0", + "symfony/messenger": "<5.0", + "symfony/translation": "<5.0", + "symfony/twig-bridge": "<5.0", + "symfony/validator": "<5.0", + "twig/twig": "<2.13" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/cache": "~1.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^4.3|^5.0", - "symfony/dom-crawler": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/routing": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.34|^2.4|^3.0" + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^5.0|^6.0", + "symfony/console": "^4.4|^5.0|^6.0", + "symfony/css-selector": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.3|^6.0", + "symfony/dom-crawler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/routing": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0", + "symfony/translation": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^2.13|^3.0.4" }, "suggest": { "symfony/browser-kit": "", @@ -689,11 +549,6 @@ "symfony/dependency-injection": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\HttpKernel\\": "" @@ -716,10 +571,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpKernel Component", + "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v4.4.9" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.19" }, "funding": [ { @@ -735,47 +590,48 @@ "type": "tidelift" } ], - "time": "2020-05-31T05:25:51+00:00" + "time": "2023-01-24T13:37:42+00:00" }, { - "name": "symfony/mime", - "version": "v4.4.9", + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "2adc53069becd0de3ea2748438646610ad0968db" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/2adc53069becd0de3ea2748438646610ad0968db", - "reference": "2adc53069becd0de3ea2748438646610ad0968db", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" + "php": ">=7.1" }, - "conflict": { - "symfony/mailer": "<4.4" + "provide": { + "ext-ctype": "*" }, - "require-dev": { - "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "^3.4|^4.1|^5.0" + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Mime\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -783,22 +639,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "A library to manipulate MIME messages", + "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", "keywords": [ - "mime", - "mime-type" + "compatibility", + "ctype", + "polyfill", + "portable" ], "support": { - "source": "https://github.com/symfony/mime/tree/v4.4.9" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -814,29 +672,39 @@ "type": "tidelift" } ], - "time": "2020-05-25T05:42:33+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.8.0", + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -844,7 +712,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" + "Symfony\\Polyfill\\Mbstring\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -853,54 +721,63 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "ctype", + "mbstring", "polyfill", - "portable" + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/master" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, - "time": "2018-04-30T19:57:29+00:00" + "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/polyfill-intl-idn", - "version": "v1.18.0", + "name": "symfony/polyfill-php73", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "bc6549d068d0160e0f10f7a5a23c7d1406b95ebe" + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/bc6549d068d0160e0f10f7a5a23c7d1406b95ebe", - "reference": "bc6549d068d0160e0f10f7a5a23c7d1406b95ebe", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php70": "^1.10", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -912,8 +789,11 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -921,30 +801,24 @@ ], "authors": [ { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "idn", - "intl", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/master" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" }, "funding": [ { @@ -960,32 +834,33 @@ "type": "tidelift" } ], - "time": "2020-07-14T12:35:20+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.10.0", + "name": "symfony/polyfill-php80", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "f8ed52909fc049b42a772c64ec1e6b31792abad6" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/f8ed52909fc049b42a772c64ec1e6b31792abad6", - "reference": "f8ed52909fc049b42a772c64ec1e6b31792abad6", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -993,7 +868,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + "Symfony\\Polyfill\\Php80\\": "" }, "classmap": [ "Resources/stubs" @@ -1004,6 +879,10 @@ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -1013,105 +892,59 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "intl", - "normalizer", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/master" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, - "time": "2018-09-21T06:26:08+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "1289d16209491b584839022f29257ad859b8532d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", - "reference": "1289d16209491b584839022f29257ad859b8532d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "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/master" - }, - "time": "2016-01-20T09:13:37+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { - "name": "symfony/polyfill-php70", - "version": "v1.10.0", + "name": "symfony/polyfill-php83", + "version": "v1.28.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", - "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", "shasum": "" }, "require": { - "paragonie/random_compat": "~1.0|~2.0|~9.99", - "php": ">=5.3.3" + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -1119,7 +952,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" + "Symfony\\Polyfill\\Php83\\": "" }, "classmap": [ "Resources/stubs" @@ -1139,7 +972,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -1148,40 +981,69 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php70/tree/master" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.0" }, - "time": "2018-09-21T06:26:08+00:00" + "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-08-16T06:22:46+00:00" }, { - "name": "symfony/polyfill-php72", - "version": "v1.10.0", + "name": "symfony/var-dumper", + "version": "v6.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c40f7d17e91d8b407582ed51a2bbf83c52c367f6", + "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } + "conflict": { + "symfony/console": "<5.4" }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "twig/twig": "^2.13|^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", "autoload": { "files": [ - "bootstrap.php" + "Resources/functions/dump.php" ], "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1197,48 +1059,69 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "debug", + "dump" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/master" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.0" }, - "time": "2018-09-21T13:07:52+00:00" - }, + "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:28:32+00:00" + } + ], + "packages-dev": [ { - "name": "symfony/polyfill-php73", - "version": "v1.9.0", + "name": "composer/package-versions-deprecated", + "version": "1.11.99.5", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "990ca8fa94736211d2b305178c3fb2527e1fbce1" + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/990ca8fa94736211d2b305178c3fb2527e1fbce1", - "reference": "990ca8fa94736211d2b305178c3fb2527e1fbce1", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", "shasum": "" }, "require": { - "php": ">=5.3.3" + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" }, - "type": "library", + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", "extra": { + "class": "PackageVersions\\Installer", "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.x-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" + "PackageVersions\\": "src/PackageVersions" } }, "notification-url": "https://packagist.org/downloads/", @@ -1247,60 +1130,68 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" } ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.9.0" + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" }, - "time": "2018-08-06T14:22:27+00:00" + "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-01-17T14:14:24+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "v1.15.0", + "name": "doctrine/cache", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "8854dc880784d2ae32908b75824754339b5c0555" + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/8854dc880784d2ae32908b75824754339b5c0555", - "reference": "8854dc880784d2ae32908b75824754339b5c0555", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { - "php": ">=7.0.8" + "php": "~7.1 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, + "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1308,79 +1199,102 @@ ], "authors": [ { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/master" + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", "type": "tidelift" } ], - "time": "2020-03-03T16:59:03+00:00" + "time": "2022-05-20T20:07:39+00:00" }, { - "name": "symfony/service-contracts", - "version": "v1.1.9", + "name": "doctrine/dbal", + "version": "3.1.3", "source": { "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26" + "url": "https://github.com/doctrine/dbal.git", + "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26", - "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/96b0053775a544b4a6ab47654dac0621be8b4cf8", + "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/container": "^1.0" + "composer/package-versions-deprecated": "^1.11.99", + "doctrine/cache": "^1.0|^2.0", + "doctrine/deprecations": "^0.5.3", + "doctrine/event-manager": "^1.0", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "9.0.0", + "jetbrains/phpstorm-stubs": "2021.1", + "phpstan/phpstan": "0.12.99", + "phpstan/phpstan-strict-rules": "^0.12.11", + "phpunit/phpunit": "9.5.10", + "psalm/plugin-phpunit": "0.16.1", + "squizlabs/php_codesniffer": "3.6.0", + "symfony/cache": "^5.2|^6.0", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0", + "vimeo/psalm": "4.10.0" }, "suggest": { - "symfony/service-implementation": "" + "symfony/console": "For helpful console commands such as SQL execution and import of files." }, + "bin": [ + "bin/doctrine-dbal" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, "autoload": { "psr-4": { - "Symfony\\Contracts\\Service\\": "" + "Doctrine\\DBAL\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1389,262 +1303,138 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" } ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v1.1.9" + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.1.3" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", "type": "tidelift" } ], - "time": "2020-07-06T13:19:58+00:00" + "time": "2021-10-02T16:15:05+00:00" }, { - "name": "symfony/var-dumper", - "version": "v4.4.9", + "name": "doctrine/deprecations", + "version": "v0.5.3", "source": { "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "56b3aa5eab0ac6720dcd559fd1d590ce301594ac" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/56b3aa5eab0ac6720dcd559fd1d590ce301594ac", - "reference": "56b3aa5eab0ac6720dcd559fd1d590ce301594ac", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/console": "<3.4" + "php": "^7.1|^8.0" }, "require-dev": { - "ext-iconv": "*", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/process": "^4.4|^5.0", - "twig/twig": "^1.34|^2.4|^3.0" + "doctrine/coding-standard": "^6.0|^7.0|^8.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "psr/log": "^1.0" }, "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" }, - "bin": [ - "Resources/bin/var-dump-server" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { - "files": [ - "Resources/functions/dump.php" - ], "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } }, "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 mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.9" - }, - "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": "2020-05-30T20:06:45+00:00" - } - ], - "packages-dev": [ - { - "name": "behat/gherkin", - "version": "v4.4.0", - "source": { - "type": "git", - "url": "https://github.com/Behat/Gherkin.git", - "reference": "6b3f8cf3560dc4909c4cddd4f1af3e1f6e9d80af" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/6b3f8cf3560dc4909c4cddd4f1af3e1f6e9d80af", - "reference": "6b3f8cf3560dc4909c4cddd4f1af3e1f6e9d80af", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "symfony/yaml": "~2.1" - }, - "suggest": { - "symfony/yaml": "If you want to parse features, represented in YAML files" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-0": { - "Behat\\Gherkin": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - } - ], - "description": "Gherkin DSL parser for PHP 5.3", - "homepage": "http://behat.org/", - "keywords": [ - "BDD", - "Behat", - "Cucumber", - "DSL", - "gherkin", - "parser" - ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", "support": { - "issues": "https://github.com/Behat/Gherkin/issues", - "source": "https://github.com/Behat/Gherkin/tree/v4.4.0" + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v0.5.3" }, - "time": "2015-09-29T13:41:19+00:00" + "time": "2021-03-21T12:59:47+00:00" }, { - "name": "codeception/codeception", - "version": "4.1.9", + "name": "doctrine/event-manager", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "5782e342b978a3efd0b7a776b7808902840b8213" + "url": "https://github.com/doctrine/event-manager.git", + "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/5782e342b978a3efd0b7a776b7808902840b8213", - "reference": "5782e342b978a3efd0b7a776b7808902840b8213", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520", + "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520", "shasum": "" }, "require": { - "behat/gherkin": "^4.4.0", - "codeception/lib-asserts": "^1.0", - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0", - "codeception/stub": "^2.0 | ^3.0", - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "guzzlehttp/psr7": "~1.4", - "php": ">=5.6.0 <9.0", - "symfony/console": ">=2.7 <6.0", - "symfony/css-selector": ">=2.7 <6.0", - "symfony/event-dispatcher": ">=2.7 <6.0", - "symfony/finder": ">=2.7 <6.0", - "symfony/yaml": ">=2.7 <6.0" + "doctrine/deprecations": "^0.5.3 || ^1", + "php": "^7.1 || ^8.0" }, - "require-dev": { - "codeception/module-asserts": "*@dev", - "codeception/module-cli": "*@dev", - "codeception/module-db": "*@dev", - "codeception/module-filesystem": "*@dev", - "codeception/module-phpbrowser": "*@dev", - "codeception/specify": "~0.3", - "codeception/util-universalframework": "*@dev", - "monolog/monolog": "~1.8", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": ">=2.7 <6.0", - "vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0" + "conflict": { + "doctrine/common": "<2.9" }, - "suggest": { - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "hoa/console": "For interactive console functionality", - "stecman/symfony-console-completion": "For BASH autocompletion", - "symfony/phpunit-bridge": "For phpunit-bridge support" + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.8", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.24" }, - "bin": [ - "codecept" - ], "type": "library", - "extra": { - "branch-alias": [] - }, "autoload": { "psr-4": { - "Codeception\\": "src/Codeception", - "Codeception\\Extension\\": "ext" + "Doctrine\\Common\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1653,231 +1443,42 @@ ], "authors": [ { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - } - ], - "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", - "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" - ], - "support": { - "issues": "https://github.com/Codeception/Codeception/issues", - "source": "https://github.com/Codeception/Codeception/tree/4.1.9" - }, - "funding": [ - { - "url": "https://opencollective.com/codeception", - "type": "open_collective" - } - ], - "time": "2020-10-23T17:59:47+00:00" - }, - { - "name": "codeception/lib-asserts", - "version": "1.13.2", - "source": { - "type": "git", - "url": "https://github.com/Codeception/lib-asserts.git", - "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/184231d5eab66bc69afd6b9429344d80c67a33b6", - "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6", - "shasum": "" - }, - "require": { - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.0.3 | ^9.0", - "ext-dom": "*", - "php": ">=5.6.0 <9.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Gintautas Miselis" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { - "name": "Gustavo Nieves", - "homepage": "https://medium.com/@ganieves" - } - ], - "description": "Assertion methods used by Codeception core and Asserts module", - "homepage": "https://codeception.com/", - "keywords": [ - "codeception" - ], - "support": { - "issues": "https://github.com/Codeception/lib-asserts/issues", - "source": "https://github.com/Codeception/lib-asserts/tree/1.13.2" - }, - "time": "2020-10-21T16:26:20+00:00" - }, - { - "name": "codeception/phpunit-wrapper", - "version": "8.1.1", - "source": { - "type": "git", - "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "f1370a15e5fe60e7347b1c60642479b923a7ceef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/f1370a15e5fe60e7347b1c60642479b923a7ceef", - "reference": "f1370a15e5fe60e7347b1c60642479b923a7ceef", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "phpunit/php-code-coverage": "^7.0", - "phpunit/phpunit": "^8.0", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0" - }, - "require-dev": { - "codeception/specify": "*", - "vlucas/phpdotenv": "^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\PHPUnit\\": "src\\" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, { - "name": "Davert", - "email": "davert.php@resend.cc" - } - ], - "description": "PHPUnit classes used by Codeception", - "support": { - "issues": "https://github.com/Codeception/phpunit-wrapper/issues", - "source": "https://github.com/Codeception/phpunit-wrapper/tree/8.0" - }, - "time": "2019-12-21T16:08:14+00:00" - }, - { - "name": "codeception/stub", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Stub.git", - "reference": "000766b85dcf854cd172b01d3bcdc1ce35f146c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Stub/zipball/000766b85dcf854cd172b01d3bcdc1ce35f146c2", - "reference": "000766b85dcf854cd172b01d3bcdc1ce35f146c2", - "shasum": "" - }, - "require": { - "phpunit/phpunit-mock-objects": ">2.3 <7.0" - }, - "conflict": { - "codeception/codeception": "<2.4" - }, - "require-dev": { - "phpunit/phpunit": ">=4.8 <8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", - "support": { - "issues": "https://github.com/Codeception/Stub/issues", - "source": "https://github.com/Codeception/Stub/tree/master" - }, - "time": "2018-05-18T14:20:06+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, { "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "email": "ocramius@gmail.com" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ - "constructor", - "instantiate" + "event", + "event dispatcher", + "event manager", + "event system", + "events" ], "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.3.x" + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/1.2.0" }, "funding": [ { @@ -1889,1978 +1490,18 @@ "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", "type": "tidelift" } ], - "time": "2020-05-29T17:27:14+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "04a6d1a00ea5da0727ee94309a9f0d3dbaecb569" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/04a6d1a00ea5da0727ee94309a9f0d3dbaecb569", - "reference": "04a6d1a00ea5da0727ee94309a9f0d3dbaecb569", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/master" - }, - "time": "2017-02-21T01:20:32+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "5796d127b0c4ff505b77455148ea9d5269d99758" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5796d127b0c4ff505b77455148ea9d5269d99758", - "reference": "5796d127b0c4ff505b77455148ea9d5269d99758", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "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.x" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2020-06-28T07:02:41+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "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/master" - }, - "time": "2020-06-27T14:33:11+00:00" - }, - { - "name": "phar-io/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", - "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", - "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/master" - }, - "time": "2020-06-27T14:39:04+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "3170448f5769fe19f456173d833734e0ff1b84df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/3170448f5769fe19f456173d833734e0ff1b84df", - "reference": "3170448f5769fe19f456173d833734e0ff1b84df", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" - }, - "time": "2020-07-20T20:05:34+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.x" - }, - "time": "2020-06-27T10:12:23+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.14.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" - }, - "time": "2021-09-10T09:02:12+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "7.0.13", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ad0dcd7b184e76f7198a1fe07685bfbec3ae911a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ad0dcd7b184e76f7198a1fe07685bfbec3ae911a", - "reference": "ad0dcd7b184e76f7198a1fe07685bfbec3ae911a", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": ">=7.2", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.1.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^4.2.2", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1.3" - }, - "require-dev": { - "phpunit/phpunit": "^8.2.2" - }, - "suggest": { - "ext-xdebug": "^2.7.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.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 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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.13" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:35:22+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:25:21+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "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", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "2.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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": "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/2.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:20:02+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "abandoned": true, - "time": "2020-11-30T08:38:46+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "8.5.12", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f40cf5be80a7d177494592ad1b2db3f64ea1dee3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f40cf5be80a7d177494592ad1b2db3f64ea1dee3", - "reference": "f40cf5be80a7d177494592ad1b2db3f64ea1dee3", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.0", - "phar-io/manifest": "^2.0.1", - "phar-io/version": "^3.0.2", - "php": ">=7.2", - "phpspec/prophecy": "^1.10.3", - "phpunit/php-code-coverage": "^7.0.12", - "phpunit/php-file-iterator": "^2.0.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1.2", - "sebastian/comparator": "^3.0.2", - "sebastian/diff": "^3.0.2", - "sebastian/environment": "^4.2.3", - "sebastian/exporter": "^3.1.2", - "sebastian/global-state": "^3.0.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0.1", - "sebastian/type": "^1.1.3", - "sebastian/version": "^2.0.1" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0.0" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "8.5-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": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.12" - }, - "funding": [ - { - "url": "https://phpunit.de/donate.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T12:23:30+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "74ffb87f527f24616f72460e54b595f508dccb5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c", - "reference": "74ffb87f527f24616f72460e54b595f508dccb5c", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", - "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/2.3.1" - }, - "abandoned": true, - "time": "2015-04-02T05:36:41+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "issues": "https://github.com/php-fig/http-message/issues", - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2015-05-04T20:22:00+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-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/1.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:15:22+00:00" - }, - { - "name": "sebastian/comparator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T08:04:30+00:00" - }, - { - "name": "sebastian/diff", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-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", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:59:04+00:00" - }, - { - "name": "sebastian/environment", - "version": "4.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:53:42+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-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": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:47:53+00:00" - }, - { - "name": "sebastian/global-state", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b", - "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^8.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:43:24+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-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/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:40:27+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-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/1.1.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:37:18+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:34:24+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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 a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:30:19+00:00" - }, - { - "name": "sebastian/type", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4", - "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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": "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/1.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-30T07:25:11+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "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": "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/master" - }, - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v2.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092", - "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v2.7.3" - }, - "time": "2015-05-15T13:33:16+00:00" - }, - { - "name": "symfony/finder", - "version": "v2.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "ccb8ed8339cf24824f2ef35dacec30d92ff44368" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/ccb8ed8339cf24824f2ef35dacec30d92ff44368", - "reference": "ccb8ed8339cf24824f2ef35dacec30d92ff44368", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - } - }, - "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": "Symfony Finder Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/Finder/tree/2.7" - }, - "time": "2015-05-15T14:02:48+00:00" - }, - { - "name": "symfony/yaml", - "version": "v2.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/4a29a5248aed4fb45f626a7bbbd330291492f5c3", - "reference": "4a29a5248aed4fb45f626a7bbbd330291492f5c3", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "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": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/Yaml/tree/2.7" - }, - "time": "2015-05-02T15:21:08+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", - "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/master" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2020-07-12T23:59:07+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" - }, - "time": "2020-07-08T17:02:28+00:00" + "time": "2022-10-12T20:51:15+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, - "prefer-lowest": true, + "prefer-lowest": false, "platform": [], "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/tests/Unit/ExpectedCommandOutputTrait.php b/tests/Unit/ExpectedCommandOutputTrait.php index 6d803125..9b1d7d5d 100644 --- a/tests/Unit/ExpectedCommandOutputTrait.php +++ b/tests/Unit/ExpectedCommandOutputTrait.php @@ -23,8 +23,6 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; -use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; - /** * ExpectedCommandOutputTrait. * @@ -35,8 +33,7 @@ trait ExpectedCommandOutputTrait { private static function getExpectedCommandOutput(string $package = null, string $outdated = null, string $new = null): string { - $isLegacyPlatform = Composer::getMajorVersion() < 2; - $output = $isLegacyPlatform ? ' - Updating' : ' - Upgrading'; + $output = ' - Upgrading'; // Early return if no package is specified if (null === $package) { diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index b7079a66..e3d30221 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -24,9 +24,9 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use Generator; use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/Unit/Security/InsecurePackageTest.php index 531fb07b..8143f154 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/Unit/Security/InsecurePackageTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -use EliasHaeussler\ComposerUpdateCheck\Security\InsecurePackage; +use EliasHaeussler\ComposerUpdateCheck\Package\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index b0973924..a5c2b5e8 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -23,8 +23,8 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; +use EliasHaeussler\ComposerUpdateCheck\Package\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Security\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; diff --git a/tests/Unit/UpdateCheckerTest.php b/tests/Unit/UpdateCheckerTest.php index 6303249f..4c40daf9 100644 --- a/tests/Unit/UpdateCheckerTest.php +++ b/tests/Unit/UpdateCheckerTest.php @@ -32,8 +32,8 @@ use EliasHaeussler\ComposerUpdateCheck\IO\Style; use EliasHaeussler\ComposerUpdateCheck\IO\Verbosity; use EliasHaeussler\ComposerUpdateCheck\Options; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\UpdateChecker; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use PHPUnit\Framework\Attributes\Test; /** diff --git a/tests/Unit/Utility/InstallerTest.php b/tests/Unit/Utility/InstallerTest.php index ca325019..657a3e26 100644 --- a/tests/Unit/Utility/InstallerTest.php +++ b/tests/Unit/Utility/InstallerTest.php @@ -25,11 +25,10 @@ use Composer\Console\Application; use Composer\Json\JsonValidationException; +use EliasHaeussler\ComposerUpdateCheck\Composer\ComposerInstaller; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; -use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; -use EliasHaeussler\ComposerUpdateCheck\Utility\Installer; use Generator; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; @@ -62,12 +61,9 @@ protected function setUp(): void public function runInstallInstallsComposerDependencies(): void { $expected = 'Installing dependencies from lock file (including require-dev)'; - if (Composer::getMajorVersion() < 2) { - $expected = 'Installing dependencies (including require-dev) from lock file'; - } - self::assertSame(0, Installer::runInstall($this->composer)); - self::assertStringContainsString($expected, Installer::getLastOutput()); + self::assertSame(0, ComposerInstaller::runInstall()); + self::assertStringContainsString($expected, ComposerInstaller::getLastOutput()); } /** @@ -78,12 +74,12 @@ public function runInstallInstallsComposerDependencies(): void public function runUpdateExecutesDryRunUpdate(array $packages, string $expected, string $notExpected = null): void { // Ensure dependencies are installed - Installer::runInstall($this->composer); + ComposerInstaller::runInstall(); - self::assertSame(0, Installer::runUpdate($packages, $this->composer)); - self::assertStringContainsString($expected, Installer::getLastOutput()); + self::assertSame(0, ComposerInstaller::runUpdate($packages)); + self::assertStringContainsString($expected, ComposerInstaller::getLastOutput()); if (null !== $notExpected) { - self::assertStringNotContainsString($notExpected, Installer::getLastOutput()); + self::assertStringNotContainsString($notExpected, ComposerInstaller::getLastOutput()); } } diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/Unit/Utility/SecurityTest.php index fd9f2847..6ab552ee 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/Unit/Utility/SecurityTest.php @@ -24,9 +24,9 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Package\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; +use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Utility\Security; use PHPUnit\Framework\Attributes\Test; From 0949a914df1ed72acc7dbacd37b13c58456edcbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 30 Nov 2023 21:16:48 +0100 Subject: [PATCH 020/286] [TASK] Properly handle configuration file mapping errors --- bin/simulate-application.sh | 1 + src/Command/UpdateCheckCommand.php | 40 ++++++++++++++-- .../Adapter/JsonConfigAdapter.php | 9 +++- .../Adapter/YamlConfigAdapter.php | 9 +++- src/Exception/ConfigFileHasErrors.php | 47 +++++++++++++++++++ 5 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 src/Exception/ConfigFileHasErrors.php diff --git a/bin/simulate-application.sh b/bin/simulate-application.sh index b1b8b940..0cd445de 100755 --- a/bin/simulate-application.sh +++ b/bin/simulate-application.sh @@ -21,6 +21,7 @@ function cleanup() { trap cleanup INT ERR EXIT # Prepare temporary application +rm -rf "${TEMP_PATH}" cp -r "${APP_PATH}" "${TEMP_PATH}" rm -rf "${TEMP_PATH}/vendor" composer config --working-dir "${TEMP_PATH}" repositories.local path "${ROOT_PATH}" diff --git a/src/Command/UpdateCheckCommand.php b/src/Command/UpdateCheckCommand.php index 88b88deb..78410848 100644 --- a/src/Command/UpdateCheckCommand.php +++ b/src/Command/UpdateCheckCommand.php @@ -24,18 +24,23 @@ namespace EliasHaeussler\ComposerUpdateCheck\Command; use Composer\Command\BaseCommand; +use CuyZ\Valinor\Mapper\Tree\Message\Messages; +use CuyZ\Valinor\Mapper\Tree\Message\NodeMessage; use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\ChainedConfigAdapter; use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\CommandInputConfigAdapter; use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\ConfigAdapterFactory; use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileHasErrors; use EliasHaeussler\ComposerUpdateCheck\IO\Formatter\FormatterFactory; use EliasHaeussler\ComposerUpdateCheck\UpdateChecker; -use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use function array_map; +use function sprintf; + /** * UpdateCheckCommand. * @@ -44,6 +49,8 @@ */ final class UpdateCheckCommand extends BaseCommand { + private SymfonyStyle $io; + public function __construct( private readonly FormatterFactory $formatterFactory, private readonly UpdateChecker $updateChecker, @@ -89,18 +96,25 @@ protected function configure(): void protected function initialize(InputInterface $input, OutputInterface $output): void { - $this->formatterFactory->setIO(new SymfonyStyle($input, $output)); + $this->io = new SymfonyStyle($input, $output); + $this->formatterFactory->setIO($this->io); } protected function execute(InputInterface $input, OutputInterface $output): int { - $config = $this->resolveConfiguration($input); - $result = $this->updateChecker->run($config); + try { + $config = $this->resolveConfiguration($input); + } catch (ConfigFileHasErrors $exception) { + $this->displayMappingErrors($exception); + + return self::FAILURE; + } $formatter = $this->formatterFactory->make($config->getFormat()); + $result = $this->updateChecker->run($config); $formatter->formatResult($result); - return Command::SUCCESS; + return self::SUCCESS; } private function resolveConfiguration(InputInterface $input): ComposerUpdateCheckConfig @@ -118,4 +132,20 @@ private function resolveConfiguration(InputInterface $input): ComposerUpdateChec return $configAdapter->resolve(); } + + private function displayMappingErrors(ConfigFileHasErrors $exception): void + { + $errors = Messages::flattenFromNode($exception->error->node())->errors(); + + $this->io->error($exception->getMessage()); + $this->io->writeln('The following errors occurred:'); + $this->io->listing( + array_map($this->formatErrorMessage(...), $errors->toArray()), + ); + } + + private function formatErrorMessage(NodeMessage $message): string + { + return sprintf('%s: %s', $message->node()->path(), $message->toString()); + } } diff --git a/src/Configuration/Adapter/JsonConfigAdapter.php b/src/Configuration/Adapter/JsonConfigAdapter.php index d3a1ded4..f4a3853f 100644 --- a/src/Configuration/Adapter/JsonConfigAdapter.php +++ b/src/Configuration/Adapter/JsonConfigAdapter.php @@ -26,6 +26,7 @@ use CuyZ\Valinor\Mapper\MappingError; use CuyZ\Valinor\Mapper\Source\Source; use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileHasErrors; use SplFileObject; /** @@ -37,12 +38,16 @@ final readonly class JsonConfigAdapter extends FileBasedConfigAdapter { /** - * @throws MappingError + * @throws ConfigFileHasErrors */ public function resolve(): ComposerUpdateCheckConfig { $source = Source::file(new SplFileObject($this->filename)); - return $this->mapper->map(ComposerUpdateCheckConfig::class, $source); + try { + return $this->mapper->map(ComposerUpdateCheckConfig::class, $source); + } catch (MappingError $error) { + throw new ConfigFileHasErrors($this->filename, $error); + } } } diff --git a/src/Configuration/Adapter/YamlConfigAdapter.php b/src/Configuration/Adapter/YamlConfigAdapter.php index c693c212..266e550a 100644 --- a/src/Configuration/Adapter/YamlConfigAdapter.php +++ b/src/Configuration/Adapter/YamlConfigAdapter.php @@ -26,6 +26,7 @@ use CuyZ\Valinor\Mapper\MappingError; use CuyZ\Valinor\Mapper\Source\Source; use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileHasErrors; use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileIsInvalid; use Symfony\Component\Yaml\Yaml; @@ -40,8 +41,8 @@ final readonly class YamlConfigAdapter extends FileBasedConfigAdapter { /** + * @throws ConfigFileHasErrors * @throws ConfigFileIsInvalid - * @throws MappingError */ public function resolve(): ComposerUpdateCheckConfig { @@ -53,6 +54,10 @@ public function resolve(): ComposerUpdateCheckConfig $source = Source::iterable($yaml); - return $this->mapper->map(ComposerUpdateCheckConfig::class, $source); + try { + return $this->mapper->map(ComposerUpdateCheckConfig::class, $source); + } catch (MappingError $error) { + throw new ConfigFileHasErrors($this->filename, $error); + } } } diff --git a/src/Exception/ConfigFileHasErrors.php b/src/Exception/ConfigFileHasErrors.php new file mode 100644 index 00000000..e6c0e789 --- /dev/null +++ b/src/Exception/ConfigFileHasErrors.php @@ -0,0 +1,47 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use CuyZ\Valinor\Mapper\MappingError; + +use function sprintf; + +/** + * ConfigFileIsInvalid. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ConfigFileHasErrors extends Exception +{ + public function __construct( + string $filename, + public readonly MappingError $error, + ) { + parent::__construct( + sprintf('The file "%s" has errors and cannot be mapped.', $filename), + 1701204777, + ); + } +} From fba8a7f76e10cc22c255056e6c2b310b984457a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 30 Nov 2023 21:50:59 +0100 Subject: [PATCH 021/286] [TASK] Rename RequiredPackage -> InstalledPackage --- src/Package/{RequiredPackage.php => InstalledPackage.php} | 4 ++-- src/UpdateChecker.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/Package/{RequiredPackage.php => InstalledPackage.php} (94%) diff --git a/src/Package/RequiredPackage.php b/src/Package/InstalledPackage.php similarity index 94% rename from src/Package/RequiredPackage.php rename to src/Package/InstalledPackage.php index 476604e0..a8c6f200 100644 --- a/src/Package/RequiredPackage.php +++ b/src/Package/InstalledPackage.php @@ -24,12 +24,12 @@ namespace EliasHaeussler\ComposerUpdateCheck\Package; /** - * RequiredPackage. + * InstalledPackage. * * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class RequiredPackage implements Package +final readonly class InstalledPackage implements Package { /** * @param non-empty-string $name diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 077935ef..38243017 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -33,7 +33,7 @@ use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerInstallFailed; use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerUpdateFailed; use EliasHaeussler\ComposerUpdateCheck\Package\Package; -use EliasHaeussler\ComposerUpdateCheck\Package\RequiredPackage; +use EliasHaeussler\ComposerUpdateCheck\Package\InstalledPackage; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; use function array_map; @@ -190,7 +190,7 @@ private function removeByExcludePatterns(array &$packages, array $excludePattern private function mapPackageNamesToPackage(array $packageNames): array { return array_map( - static fn (string $packageName) => new RequiredPackage($packageName), + static fn (string $packageName) => new InstalledPackage($packageName), $packageNames, ); } From 8375c895277c1a8711eb9be3f23e2cbe7cc6894a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 30 Nov 2023 21:58:56 +0100 Subject: [PATCH 022/286] [TASK] Rename GitHubActionsFormatter -> GitHubFormatter --- .../{GitHubActionsFormatter.php => GitHubFormatter.php} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/IO/Formatter/{GitHubActionsFormatter.php => GitHubFormatter.php} (96%) diff --git a/src/IO/Formatter/GitHubActionsFormatter.php b/src/IO/Formatter/GitHubFormatter.php similarity index 96% rename from src/IO/Formatter/GitHubActionsFormatter.php rename to src/IO/Formatter/GitHubFormatter.php index 1d4cc7ad..8127fea6 100644 --- a/src/IO/Formatter/GitHubActionsFormatter.php +++ b/src/IO/Formatter/GitHubFormatter.php @@ -34,14 +34,14 @@ use function sprintf; /** - * GitHubActionsFormatter. + * GitHubFormatter. * * @author Elias Häußler * @license GPL-3.0-or-later */ -final class GitHubActionsFormatter implements Formatter +final class GitHubFormatter implements Formatter { - public const FORMAT = 'github-actions'; + public const FORMAT = 'github'; public function __construct( private (OutputInterface&StyleInterface)|null $io = null, From 79d1681e7e3b36f94af137872a13dec75b0c820c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 30 Nov 2023 22:10:57 +0100 Subject: [PATCH 023/286] [TASK] Introduce Version entity --- src/IO/Formatter/JsonFormatter.php | 4 +-- src/IO/Formatter/TextFormatter.php | 4 +-- src/Package/OutdatedPackage.php | 14 ++++----- src/Package/Version.php | 49 ++++++++++++++++++++++++++++++ src/Security/ScanResult.php | 2 +- src/UpdateCheckResult.php | 6 +++- 6 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 src/Package/Version.php diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index 8475ab06..8c260ede 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -148,8 +148,8 @@ private function parseTableRows(array $outdatedPackages, bool &$hasInsecurePacka foreach ($outdatedPackages as $outdatedPackage) { $report = [ $outdatedPackage->getName(), - $outdatedPackage->getOutdatedVersion(), - $outdatedPackage->getNewVersion(), + $outdatedPackage->getOutdatedVersion()->get(), + $outdatedPackage->getNewVersion()->get(), ]; if ($outdatedPackage->isInsecure()) { diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php index 3c897e57..94f7965e 100644 --- a/src/IO/Formatter/TextFormatter.php +++ b/src/IO/Formatter/TextFormatter.php @@ -109,8 +109,8 @@ private function renderTable(array $outdatedPackages): void foreach ($outdatedPackages as $outdatedPackage) { $report = [ $outdatedPackage->getName(), - $outdatedPackage->getOutdatedVersion(), - $outdatedPackage->getNewVersion(), + $outdatedPackage->getOutdatedVersion()->get(), + $outdatedPackage->getNewVersion()->get(), ]; if ($outdatedPackage->isInsecure()) { diff --git a/src/Package/OutdatedPackage.php b/src/Package/OutdatedPackage.php index 0bd6c602..539bfbeb 100644 --- a/src/Package/OutdatedPackage.php +++ b/src/Package/OutdatedPackage.php @@ -43,8 +43,8 @@ final class OutdatedPackage implements Package */ public function __construct( private readonly string $name, - private readonly string $outdatedVersion, - private readonly string $newVersion, + private readonly Version $outdatedVersion, + private readonly Version $newVersion, private bool $insecure = false, ) { $this->providerLink = $this->generateProviderLink(); @@ -55,12 +55,12 @@ public function getName(): string return $this->name; } - public function getOutdatedVersion(): string + public function getOutdatedVersion(): Version { return $this->outdatedVersion; } - public function getNewVersion(): string + public function getNewVersion(): Version { return $this->newVersion; } @@ -102,8 +102,8 @@ public function jsonSerialize(): array { return [ 'name' => $this->name, - 'outdatedVersion' => $this->outdatedVersion, - 'newVersion' => $this->newVersion, + 'outdatedVersion' => (string) $this->outdatedVersion, + 'newVersion' => (string) $this->newVersion, 'insecure' => $this->insecure, 'providerLink' => (string) $this->providerLink, ]; @@ -116,7 +116,7 @@ public function __toString(): string private function generateProviderLink(): UriInterface { - $versionHash = explode(' ', $this->newVersion, 2)[0]; + $versionHash = explode(' ', $this->newVersion->get(), 2)[0]; $uri = sprintf(self::PROVIDER_LINK_PATTERN, $this->name, $versionHash); return new Uri($uri); diff --git a/src/Package/Version.php b/src/Package/Version.php new file mode 100644 index 00000000..685fc076 --- /dev/null +++ b/src/Package/Version.php @@ -0,0 +1,49 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Package; + +use Stringable; + +/** + * Version. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class Version implements Stringable +{ + public function __construct( + private string $version, + ) {} + + public function get(): string + { + return $this->version; + } + + public function __toString(): string + { + return $this->version; + } +} diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index b49a6444..9ddee031 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -92,7 +92,7 @@ public function isInsecure(OutdatedPackage $outdatedPackage): bool if ($insecurePackage->getName() === $outdatedPackage->getName()) { $insecureVersions = implode('|', $insecurePackage->getAffectedVersions()); - return Semver::satisfies($outdatedPackage->getOutdatedVersion(), $insecureVersions); + return Semver::satisfies($outdatedPackage->getOutdatedVersion()->get(), $insecureVersions); } } diff --git a/src/UpdateCheckResult.php b/src/UpdateCheckResult.php index 6d549b3b..d4a96363 100644 --- a/src/UpdateCheckResult.php +++ b/src/UpdateCheckResult.php @@ -115,7 +115,11 @@ private static function parseCommandOutput(string $output): ?Package\OutdatedPac return null; } - return new Package\OutdatedPackage($matches['name'], $matches['outdated'], $matches['new']); + return new Package\OutdatedPackage( + $matches['name'], + new Package\Version($matches['outdated']), + new Package\Version($matches['new']), + ); } /** From 03d22f26e5afe469a189fd3e32157a337767a7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 30 Nov 2023 22:16:25 +0100 Subject: [PATCH 024/286] [TASK] Move entities to dedicated namespace --- src/Composer/ComposerInstaller.php | 2 +- src/{ => Entity}/Package/InsecurePackage.php | 2 +- src/{ => Entity}/Package/InstalledPackage.php | 2 +- src/{ => Entity}/Package/OutdatedPackage.php | 3 +- src/{ => Entity}/Package/Package.php | 2 +- src/{Package => Entity}/Version.php | 2 +- src/IO/Formatter/JsonFormatter.php | 4 +-- src/IO/Formatter/TextFormatter.php | 4 +-- src/Security/ScanResult.php | 4 +-- src/Security/SecurityScanner.php | 2 +- src/UpdateCheckResult.php | 32 +++++++++---------- src/UpdateChecker.php | 4 +-- tests/Unit/Package/OutdatedPackageTest.php | 2 +- tests/Unit/Package/UpdateCheckResultTest.php | 2 +- tests/Unit/Security/InsecurePackageTest.php | 2 +- tests/Unit/Security/ScanResultTest.php | 4 +-- tests/Unit/Security/SecurityScannerTest.php | 2 +- tests/Unit/Utility/SecurityTest.php | 2 +- 18 files changed, 39 insertions(+), 38 deletions(-) rename src/{ => Entity}/Package/InsecurePackage.php (96%) rename src/{ => Entity}/Package/InstalledPackage.php (95%) rename src/{ => Entity}/Package/OutdatedPackage.php (96%) rename src/{ => Entity}/Package/Package.php (94%) rename src/{Package => Entity}/Version.php (95%) diff --git a/src/Composer/ComposerInstaller.php b/src/Composer/ComposerInstaller.php index 76b15c4e..614c59d9 100644 --- a/src/Composer/ComposerInstaller.php +++ b/src/Composer/ComposerInstaller.php @@ -27,7 +27,7 @@ use Composer\DependencyResolver\Request; use Composer\Installer; use Composer\IO\IOInterface; -use EliasHaeussler\ComposerUpdateCheck\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use function array_map; diff --git a/src/Package/InsecurePackage.php b/src/Entity/Package/InsecurePackage.php similarity index 96% rename from src/Package/InsecurePackage.php rename to src/Entity/Package/InsecurePackage.php index 7142d1a0..1c618801 100644 --- a/src/Package/InsecurePackage.php +++ b/src/Entity/Package/InsecurePackage.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Package; /** * InsecurePackage. diff --git a/src/Package/InstalledPackage.php b/src/Entity/Package/InstalledPackage.php similarity index 95% rename from src/Package/InstalledPackage.php rename to src/Entity/Package/InstalledPackage.php index a8c6f200..397d8a04 100644 --- a/src/Package/InstalledPackage.php +++ b/src/Entity/Package/InstalledPackage.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Package; /** * InstalledPackage. diff --git a/src/Package/OutdatedPackage.php b/src/Entity/Package/OutdatedPackage.php similarity index 96% rename from src/Package/OutdatedPackage.php rename to src/Entity/Package/OutdatedPackage.php index 539bfbeb..8bcf10fb 100644 --- a/src/Package/OutdatedPackage.php +++ b/src/Entity/Package/OutdatedPackage.php @@ -21,8 +21,9 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Version; use Nyholm\Psr7\Uri; use Psr\Http\Message\UriInterface; diff --git a/src/Package/Package.php b/src/Entity/Package/Package.php similarity index 94% rename from src/Package/Package.php rename to src/Entity/Package/Package.php index 626a77f4..acbdcf34 100644 --- a/src/Package/Package.php +++ b/src/Entity/Package/Package.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Package; use JsonSerializable; use Stringable; diff --git a/src/Package/Version.php b/src/Entity/Version.php similarity index 95% rename from src/Package/Version.php rename to src/Entity/Version.php index 685fc076..9fdbfd10 100644 --- a/src/Package/Version.php +++ b/src/Entity/Version.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Entity; use Stringable; diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index 8c260ede..8b4770b1 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -23,8 +23,8 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\StyleInterface; diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php index 94f7965e..a9a27cb5 100644 --- a/src/IO/Formatter/TextFormatter.php +++ b/src/IO/Formatter/TextFormatter.php @@ -23,8 +23,8 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\StyleInterface; diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php index 9ddee031..ba7c76a7 100644 --- a/src/Security/ScanResult.php +++ b/src/Security/ScanResult.php @@ -24,8 +24,8 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; use Composer\Semver\Semver; -use EliasHaeussler\ComposerUpdateCheck\Package\InsecurePackage; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InsecurePackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use InvalidArgumentException; /** diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index 8733c1cd..a0adbf30 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use JsonException; use Nyholm\Psr7\Factory\Psr17Factory; diff --git a/src/UpdateCheckResult.php b/src/UpdateCheckResult.php index d4a96363..38cb7f22 100644 --- a/src/UpdateCheckResult.php +++ b/src/UpdateCheckResult.php @@ -42,18 +42,18 @@ final class UpdateCheckResult '$#'; /** - * @var list + * @var list */ private readonly array $outdatedPackages; /** - * @var list + * @var list */ private readonly array $excludedPackages; /** - * @param list $outdatedPackages - * @param list $excludedPackages + * @param list $outdatedPackages + * @param list $excludedPackages */ public function __construct(array $outdatedPackages, array $excludedPackages = []) { @@ -62,8 +62,8 @@ public function __construct(array $outdatedPackages, array $excludedPackages = [ } /** - * @param list $allowedPackages - * @param list $excludedPackages + * @param list $allowedPackages + * @param list $excludedPackages */ public static function fromCommandOutput( string $output, @@ -71,7 +71,7 @@ public static function fromCommandOutput( array $excludedPackages = [], ): self { $allowedPackageNames = array_map( - static fn (Package\Package $package) => $package->getName(), + static fn (Entity\Package\Package $package) => $package->getName(), $allowedPackages, ); @@ -79,7 +79,7 @@ public static function fromCommandOutput( $outdatedPackages = array_unique( array_filter( array_map(self::parseCommandOutput(...), $outputParts), - static function (?Package\OutdatedPackage $outdatedPackage) use ($allowedPackageNames) { + static function (?Entity\Package\OutdatedPackage $outdatedPackage) use ($allowedPackageNames) { if (null === $outdatedPackage) { return false; } @@ -94,7 +94,7 @@ static function (?Package\OutdatedPackage $outdatedPackage) use ($allowedPackage } /** - * @return list + * @return list */ public function getOutdatedPackages(): array { @@ -102,28 +102,28 @@ public function getOutdatedPackages(): array } /** - * @return list + * @return list */ public function getExcludedPackages(): array { return $this->excludedPackages; } - private static function parseCommandOutput(string $output): ?Package\OutdatedPackage + private static function parseCommandOutput(string $output): ?Entity\Package\OutdatedPackage { if (1 !== preg_match(self::COMMAND_OUTPUT_PATTERN, $output, $matches)) { return null; } - return new Package\OutdatedPackage( + return new Entity\Package\OutdatedPackage( $matches['name'], - new Package\Version($matches['outdated']), - new Package\Version($matches['new']), + new Entity\Version($matches['outdated']), + new Entity\Version($matches['new']), ); } /** - * @template T of Package\Package + * @template T of Entity\Package\Package * * @param list $packages * @@ -131,7 +131,7 @@ private static function parseCommandOutput(string $output): ?Package\OutdatedPac */ private function sortPackages(array $packages): array { - usort($packages, static fn (Package\Package $a, Package\Package $b) => strcmp($a->getName(), $b->getName())); + usort($packages, static fn (Entity\Package\Package $a, Entity\Package\Package $b) => strcmp($a->getName(), $b->getName())); return $packages; } diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 38243017..02e1df53 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -32,8 +32,8 @@ use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent; use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerInstallFailed; use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerUpdateFailed; -use EliasHaeussler\ComposerUpdateCheck\Package\Package; -use EliasHaeussler\ComposerUpdateCheck\Package\InstalledPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InstalledPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; use function array_map; diff --git a/tests/Unit/Package/OutdatedPackageTest.php b/tests/Unit/Package/OutdatedPackageTest.php index 3d255a55..a6f4617e 100644 --- a/tests/Unit/Package/OutdatedPackageTest.php +++ b/tests/Unit/Package/OutdatedPackageTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Nyholm\Psr7\Uri; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index e3d30221..8ddba8cb 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/Unit/Security/InsecurePackageTest.php index 8143f154..cde03b92 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/Unit/Security/InsecurePackageTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -use EliasHaeussler\ComposerUpdateCheck\Package\InsecurePackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index a5c2b5e8..353bc5a1 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -23,8 +23,8 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -use EliasHaeussler\ComposerUpdateCheck\Package\InsecurePackage; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InsecurePackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; diff --git a/tests/Unit/Security/SecurityScannerTest.php b/tests/Unit/Security/SecurityScannerTest.php index 22a2d737..acc40601 100644 --- a/tests/Unit/Security/SecurityScannerTest.php +++ b/tests/Unit/Security/SecurityScannerTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/Unit/Utility/SecurityTest.php index 6ab552ee..14df69dd 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/Unit/Utility/SecurityTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; -use EliasHaeussler\ComposerUpdateCheck\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; From 99083c645ff1f72756939d2bba58b59c4aae6eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Mon, 4 Dec 2023 22:47:33 +0100 Subject: [PATCH 025/286] [TASK] Skip auditing during composer install and update --- phpstan-baseline.neon | 5 +++++ src/Composer/ComposerInstaller.php | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d96a8f17..b66820e5 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,5 +1,10 @@ parameters: ignoreErrors: + - + message: "#^Call to function method_exists\\(\\) with Composer\\\\Installer and 'setAudit' will always evaluate to true\\.$#" + count: 2 + path: src/Composer/ComposerInstaller.php + - message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\InsecurePackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\InsecurePackage will always evaluate to true\\.$#" count: 1 diff --git a/src/Composer/ComposerInstaller.php b/src/Composer/ComposerInstaller.php index 614c59d9..f40c9d83 100644 --- a/src/Composer/ComposerInstaller.php +++ b/src/Composer/ComposerInstaller.php @@ -30,6 +30,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use function array_map; +use function method_exists; /** * ComposerInstaller. @@ -57,6 +58,10 @@ public function runInstall(IOInterface $io = null): int ->setDevMode() ; + if (method_exists($installer, 'setAudit')) { + $installer->setAudit(false); + } + $eventDispatcher = $this->composer->getEventDispatcher(); $eventDispatcher->setRunScripts(false); @@ -86,6 +91,10 @@ public function runUpdate(array $packages, IOInterface $io = null): int ->setUpdateAllowTransitiveDependencies(Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS) ; + if (method_exists($installer, 'setAudit')) { + $installer->setAudit(false); + } + return $installer->run(); } } From 6dfda8161340ee3065eb71f49c8140045596e91a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Mon, 4 Dec 2023 22:50:51 +0100 Subject: [PATCH 026/286] [FEATURE] Rewrite handling and determination of insecure packages --- composer.json | 4 +- composer.lock | 586 ++++++++++++++---- config/services.yaml | 5 + phpstan-baseline.neon | 5 - src/Entity/Package/OutdatedPackage.php | 31 +- .../ScanResult.php} | 42 +- src/{ => Entity/Result}/UpdateCheckResult.php | 41 +- src/Entity/Security/SecurityAdvisory.php | 114 ++++ src/Event/PostUpdateCheckEvent.php | 2 +- src/Exception/PackagistResponseHasErrors.php | 44 ++ .../UnableToFetchSecurityAdvisories.php | 56 ++ src/IO/Formatter/Formatter.php | 2 +- src/IO/Formatter/GitHubFormatter.php | 2 +- src/IO/Formatter/JsonFormatter.php | 2 +- src/IO/Formatter/TextFormatter.php | 2 +- src/Security/ScanResult.php | 110 ---- src/Security/SecurityScanner.php | 81 ++- src/UpdateChecker.php | 5 +- tests/Unit/Package/UpdateCheckResultTest.php | 2 +- tests/Unit/Security/InsecurePackageTest.php | 10 +- tests/Unit/Security/ScanResultTest.php | 16 +- tests/Unit/Security/SecurityScannerTest.php | 16 +- tests/Unit/UpdateCheckerTest.php | 2 +- tests/Unit/Utility/SecurityTest.php | 2 +- 24 files changed, 840 insertions(+), 342 deletions(-) rename src/Entity/{Package/InsecurePackage.php => Result/ScanResult.php} (55%) rename src/{ => Entity/Result}/UpdateCheckResult.php (74%) create mode 100644 src/Entity/Security/SecurityAdvisory.php create mode 100644 src/Exception/PackagistResponseHasErrors.php create mode 100644 src/Exception/UnableToFetchSecurityAdvisories.php delete mode 100644 src/Security/ScanResult.php diff --git a/composer.json b/composer.json index 5f4be423..b2cbf0ba 100644 --- a/composer.json +++ b/composer.json @@ -23,9 +23,11 @@ "ext-json": "*", "composer-plugin-api": "^2.1", "cuyz/valinor": "^1.7", - "nyholm/psr7": "^1.0", + "guzzlehttp/guzzle": "^7.0", + "guzzlehttp/psr7": "^2.0", "psr/http-client": "^1.0", "psr/http-message": "^1.0 || ^2.0 || ^3.0", + "spatie/packagist-api": "^2.1", "symfony/config": "^5.4 || ^6.0", "symfony/console": "^5.4 || ^6.0", "symfony/dependency-injection": "^5.4 || ^6.0", diff --git a/composer.lock b/composer.lock index fab7564c..fe4ef84c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,89 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4da8728231f9d71bd5def17381cad08a", + "content-hash": "ce257b5bca8fdd484ee8e146d22c7300", "packages": [ + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.0" + }, + "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-08-31T09:50:34+00:00" + }, { "name": "cuyz/valinor", "version": "1.7.0", @@ -80,45 +161,256 @@ "time": "2023-10-23T11:05:23+00:00" }, { - "name": "nyholm/psr7", - "version": "1.8.1", + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:35:24+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:19:20+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", "source": { "type": "git", - "url": "https://github.com/Nyholm/psr7.git", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { - "php": ">=7.2", + "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0" + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" }, "provide": { - "php-http/message-factory-implementation": "1.0", "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "^0.9", - "php-http/message-factory": "^1.0", - "php-http/psr7-integration-tests": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", - "symfony/error-handler": "^4.4" + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.8-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { "psr-4": { - "Nyholm\\Psr7\\": "src/" + "GuzzleHttp\\Psr7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -126,36 +418,72 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, { "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com" + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" }, { - "name": "Martijn van der Ven", - "email": "martijn@vanderven.se" + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], - "description": "A fast PHP7 implementation of PSR-7", - "homepage": "https://tnyholm.se", + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ - "psr-17", - "psr-7" + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" ], "support": { - "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" }, "funding": [ { - "url": "https://github.com/Zegnat", + "url": "https://github.com/GrahamCampbell", "type": "github" }, { - "url": "https://github.com/nyholm", + "url": "https://github.com/Nyholm", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" } ], - "time": "2023-11-13T09:31:12+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { "name": "psr/container", @@ -471,6 +799,125 @@ }, "time": "2021-10-29T13:26:27+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "spatie/packagist-api", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/packagist-api.git", + "reference": "4d125fec1c937ba8485a5b7e026532508314fc32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/packagist-api/zipball/4d125fec1c937ba8485a5b7e026532508314fc32", + "reference": "4d125fec1c937ba8485a5b7e026532508314fc32", + "shasum": "" + }, + "require": { + "composer/semver": "^1.0|^2.0|^3.0", + "ext-json": "*", + "guzzlehttp/guzzle": "^7.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.4", + "spatie/phpunit-snapshot-assertions": "^4.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Packagist\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Jolita Grazyte", + "email": "jolita@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Mark Walet", + "homepage": "https://markwalet.me", + "role": "Developer" + } + ], + "description": "Fetch package info from Packagist", + "homepage": "https://github.com/spatie/packagist-api", + "keywords": [ + "api", + "packagist", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/packagist-api/tree/2.1.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-08-01T10:13:17+00:00" + }, { "name": "symfony/config", "version": "v6.4.0", @@ -2195,87 +2642,6 @@ ], "time": "2023-10-11T07:11:09+00:00" }, - { - "name": "composer/semver", - "version": "3.4.0", - "source": { - "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" - }, - "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-08-31T09:50:34+00:00" - }, { "name": "composer/spdx-licenses", "version": "1.5.8", diff --git a/config/services.yaml b/config/services.yaml index 91b315c2..f29d7250 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -30,3 +30,8 @@ services: synthetic: true Composer\IO\IOInterface: synthetic: true + + # External services + GuzzleHttp\Client: + Spatie\Packagist\PackagistClient: + Spatie\Packagist\PackagistUrlGenerator: diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b66820e5..757016aa 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,11 +5,6 @@ parameters: count: 2 path: src/Composer/ComposerInstaller.php - - - message: "#^Instanceof between EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\InsecurePackage and EliasHaeussler\\\\ComposerUpdateCheck\\\\Package\\\\InsecurePackage will always evaluate to true\\.$#" - count: 1 - path: src/Security/ScanResult.php - - message: "#^Variable property access on \\$this\\(EliasHaeussler\\\\ComposerUpdateCheck\\\\Tests\\\\Unit\\\\AbstractTestCase\\)\\.$#" count: 1 diff --git a/src/Entity/Package/OutdatedPackage.php b/src/Entity/Package/OutdatedPackage.php index 8bcf10fb..06ac3d3d 100644 --- a/src/Entity/Package/OutdatedPackage.php +++ b/src/Entity/Package/OutdatedPackage.php @@ -23,8 +23,9 @@ namespace EliasHaeussler\ComposerUpdateCheck\Entity\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; use EliasHaeussler\ComposerUpdateCheck\Entity\Version; -use Nyholm\Psr7\Uri; +use GuzzleHttp\Psr7\Uri; use Psr\Http\Message\UriInterface; /** @@ -40,13 +41,14 @@ final class OutdatedPackage implements Package private UriInterface $providerLink; /** - * @param non-empty-string $name + * @param non-empty-string $name + * @param list $securityAdvisories */ public function __construct( private readonly string $name, private readonly Version $outdatedVersion, private readonly Version $newVersion, - private bool $insecure = false, + private array $securityAdvisories = [], ) { $this->providerLink = $this->generateProviderLink(); } @@ -66,18 +68,29 @@ public function getNewVersion(): Version return $this->newVersion; } - public function isInsecure(): bool + /** + * @return list + */ + public function getSecurityAdvisories(): array { - return $this->insecure; + return $this->securityAdvisories; } - public function setInsecure(bool $insecure): self + /** + * @param list $securityAdvisories + */ + public function setSecurityAdvisories(array $securityAdvisories): self { - $this->insecure = $insecure; + $this->securityAdvisories = $securityAdvisories; return $this; } + public function isInsecure(): bool + { + return [] !== $this->securityAdvisories; + } + public function getProviderLink(): UriInterface { return $this->providerLink; @@ -95,7 +108,7 @@ public function setProviderLink(UriInterface $providerLink): self * name: non-empty-string, * outdatedVersion: string, * newVersion: string, - * insecure: bool, + * securityAdvisories: list, * providerLink: string, * } */ @@ -105,7 +118,7 @@ public function jsonSerialize(): array 'name' => $this->name, 'outdatedVersion' => (string) $this->outdatedVersion, 'newVersion' => (string) $this->newVersion, - 'insecure' => $this->insecure, + 'securityAdvisories' => $this->securityAdvisories, 'providerLink' => (string) $this->providerLink, ]; } diff --git a/src/Entity/Package/InsecurePackage.php b/src/Entity/Result/ScanResult.php similarity index 55% rename from src/Entity/Package/InsecurePackage.php rename to src/Entity/Result/ScanResult.php index 1c618801..fd57022a 100644 --- a/src/Entity/Package/InsecurePackage.php +++ b/src/Entity/Result/ScanResult.php @@ -21,54 +21,44 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Entity\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Result; + +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; /** - * InsecurePackage. + * ScanResult. * * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class InsecurePackage implements Package +final readonly class ScanResult { /** - * @param non-empty-string $name - * @param list $affectedVersions + * @param array> $securityAdvisories */ public function __construct( - private string $name, - private array $affectedVersions, + private array $securityAdvisories, ) {} - public function getName(): string - { - return $this->name; - } - /** - * @return list + * @return array> */ - public function getAffectedVersions(): array + public function getSecurityAdvisories(): array { - return $this->affectedVersions; + return $this->securityAdvisories; } /** - * @return array{ - * name: non-empty-string, - * affectedVersions: list, - * } + * @return list */ - public function jsonSerialize(): array + public function getSecurityAdvisoriesForPackage(Package $package): array { - return [ - 'name' => $this->name, - 'affectedVersions' => $this->affectedVersions, - ]; + return $this->securityAdvisories[$package->getName()] ?? []; } - public function __toString(): string + public function isInsecure(Package $package): bool { - return $this->name; + return [] !== $this->getSecurityAdvisoriesForPackage($package); } } diff --git a/src/UpdateCheckResult.php b/src/Entity/Result/UpdateCheckResult.php similarity index 74% rename from src/UpdateCheckResult.php rename to src/Entity/Result/UpdateCheckResult.php index 38cb7f22..91276795 100644 --- a/src/UpdateCheckResult.php +++ b/src/Entity/Result/UpdateCheckResult.php @@ -21,7 +21,11 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Result; + +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Version; /** * UpdateCheckResult. @@ -42,18 +46,18 @@ final class UpdateCheckResult '$#'; /** - * @var list + * @var list */ private readonly array $outdatedPackages; /** - * @var list + * @var list */ private readonly array $excludedPackages; /** - * @param list $outdatedPackages - * @param list $excludedPackages + * @param list $outdatedPackages + * @param list $excludedPackages */ public function __construct(array $outdatedPackages, array $excludedPackages = []) { @@ -62,8 +66,8 @@ public function __construct(array $outdatedPackages, array $excludedPackages = [ } /** - * @param list $allowedPackages - * @param list $excludedPackages + * @param list $allowedPackages + * @param list $excludedPackages */ public static function fromCommandOutput( string $output, @@ -71,7 +75,7 @@ public static function fromCommandOutput( array $excludedPackages = [], ): self { $allowedPackageNames = array_map( - static fn (Entity\Package\Package $package) => $package->getName(), + static fn (Package $package) => $package->getName(), $allowedPackages, ); @@ -79,7 +83,7 @@ public static function fromCommandOutput( $outdatedPackages = array_unique( array_filter( array_map(self::parseCommandOutput(...), $outputParts), - static function (?Entity\Package\OutdatedPackage $outdatedPackage) use ($allowedPackageNames) { + static function (?OutdatedPackage $outdatedPackage) use ($allowedPackageNames) { if (null === $outdatedPackage) { return false; } @@ -94,7 +98,7 @@ static function (?Entity\Package\OutdatedPackage $outdatedPackage) use ($allowed } /** - * @return list + * @return list */ public function getOutdatedPackages(): array { @@ -102,28 +106,28 @@ public function getOutdatedPackages(): array } /** - * @return list + * @return list */ public function getExcludedPackages(): array { return $this->excludedPackages; } - private static function parseCommandOutput(string $output): ?Entity\Package\OutdatedPackage + private static function parseCommandOutput(string $output): ?OutdatedPackage { if (1 !== preg_match(self::COMMAND_OUTPUT_PATTERN, $output, $matches)) { return null; } - return new Entity\Package\OutdatedPackage( + return new OutdatedPackage( $matches['name'], - new Entity\Version($matches['outdated']), - new Entity\Version($matches['new']), + new Version($matches['outdated']), + new Version($matches['new']), ); } /** - * @template T of Entity\Package\Package + * @template T of Package * * @param list $packages * @@ -131,7 +135,10 @@ private static function parseCommandOutput(string $output): ?Entity\Package\Outd */ private function sortPackages(array $packages): array { - usort($packages, static fn (Entity\Package\Package $a, Entity\Package\Package $b) => strcmp($a->getName(), $b->getName())); + usort( + $packages, + static fn (Package $a, Package $b) => strcmp($a->getName(), $b->getName()), + ); return $packages; } diff --git a/src/Entity/Security/SecurityAdvisory.php b/src/Entity/Security/SecurityAdvisory.php new file mode 100644 index 00000000..1789caf3 --- /dev/null +++ b/src/Entity/Security/SecurityAdvisory.php @@ -0,0 +1,114 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Security; + +use DateTimeImmutable; +use JsonSerializable; +use Psr\Http\Message\UriInterface; + +/** + * SecurityAdvisory. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final readonly class SecurityAdvisory implements JsonSerializable +{ + public function __construct( + private string $packageName, + private string $advisoryId, + private string $affectedVersions, + private string $title, + private DateTimeImmutable $reportedAt, + private string $severity, + private ?string $cve = null, + private ?UriInterface $link = null, + ) {} + + public function getPackageName(): string + { + return $this->packageName; + } + + public function getAdvisoryId(): string + { + return $this->advisoryId; + } + + public function getAffectedVersions(): string + { + return $this->affectedVersions; + } + + public function getTitle(): string + { + return $this->title; + } + + public function getReportedAt(): DateTimeImmutable + { + return $this->reportedAt; + } + + public function getSeverity(): string + { + return $this->severity; + } + + public function getCVE(): ?string + { + return $this->cve; + } + + public function getLink(): ?UriInterface + { + return $this->link; + } + + /** + * @return array{ + * packageName: string, + * advisoryId: string, + * affectedVersions: string, + * title: string, + * reportedAt: DateTimeImmutable, + * severity: string, + * cve: string|null, + * link: string|null, + * } + */ + public function jsonSerialize(): array + { + return [ + 'packageName' => $this->packageName, + 'advisoryId' => $this->advisoryId, + 'affectedVersions' => $this->affectedVersions, + 'title' => $this->title, + 'reportedAt' => $this->reportedAt, + 'severity' => $this->severity, + 'cve' => $this->cve, + 'link' => null !== $this->link ? (string) $this->link : null, + ]; + } +} diff --git a/src/Event/PostUpdateCheckEvent.php b/src/Event/PostUpdateCheckEvent.php index 9fa3ba50..e65c34a7 100644 --- a/src/Event/PostUpdateCheckEvent.php +++ b/src/Event/PostUpdateCheckEvent.php @@ -24,7 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Event; use Composer\EventDispatcher\Event; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; /** * PostUpdateCheckEvent. diff --git a/src/Exception/PackagistResponseHasErrors.php b/src/Exception/PackagistResponseHasErrors.php new file mode 100644 index 00000000..c236ee89 --- /dev/null +++ b/src/Exception/PackagistResponseHasErrors.php @@ -0,0 +1,44 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use CuyZ\Valinor\Mapper\MappingError; + +/** + * PackagistResponseHasErrors. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class PackagistResponseHasErrors extends Exception +{ + public function __construct( + public readonly MappingError $error, + ) { + parent::__construct( + 'Packagist API response with security advisories is invalid and cannot be mapped.', + 1701723100, + ); + } +} diff --git a/src/Exception/UnableToFetchSecurityAdvisories.php b/src/Exception/UnableToFetchSecurityAdvisories.php new file mode 100644 index 00000000..234bebde --- /dev/null +++ b/src/Exception/UnableToFetchSecurityAdvisories.php @@ -0,0 +1,56 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Exception\RequestException; + +use function sprintf; + +/** + * UnableToFetchSecurityAdvisories. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class UnableToFetchSecurityAdvisories extends Exception +{ + public function __construct(GuzzleException $exception) + { + if ($exception instanceof RequestException && ($response = $exception->getResponse()) !== null) { + $message = (string) $response->getBody(); + } else { + $message = $exception->getMessage(); + } + + parent::__construct( + sprintf( + 'There was an error while fetching security advisories from Packagist API: %s', + $message, + ), + 1610706128, + $exception, + ); + } +} diff --git a/src/IO/Formatter/Formatter.php b/src/IO/Formatter/Formatter.php index e0481792..20c955ef 100644 --- a/src/IO/Formatter/Formatter.php +++ b/src/IO/Formatter/Formatter.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\StyleInterface; diff --git a/src/IO/Formatter/GitHubFormatter.php b/src/IO/Formatter/GitHubFormatter.php index 8127fea6..b23a5a95 100644 --- a/src/IO/Formatter/GitHubFormatter.php +++ b/src/IO/Formatter/GitHubFormatter.php @@ -25,7 +25,7 @@ use Composer\Factory; use Composer\Util\Platform; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\StyleInterface; use Symfony\Component\Filesystem\Path; diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index 8b4770b1..03bb3470 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -25,7 +25,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\StyleInterface; diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php index a9a27cb5..b94b63bd 100644 --- a/src/IO/Formatter/TextFormatter.php +++ b/src/IO/Formatter/TextFormatter.php @@ -25,7 +25,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\StyleInterface; diff --git a/src/Security/ScanResult.php b/src/Security/ScanResult.php deleted file mode 100644 index ba7c76a7..00000000 --- a/src/Security/ScanResult.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -namespace EliasHaeussler\ComposerUpdateCheck\Security; - -use Composer\Semver\Semver; -use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InsecurePackage; -use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; -use InvalidArgumentException; - -/** - * ScanResult. - * - * @author Elias Häußler - * @license GPL-3.0-or-later - */ -final readonly class ScanResult -{ - /** - * @param InsecurePackage[] $insecurePackages - */ - public function __construct( - private array $insecurePackages, - ) { - $this->validateInsecurePackages(); - } - - /** - * @param array $apiResult - */ - public static function fromApiResult(array $apiResult): self - { - // Early return if no advisories were provided - if ( - !array_key_exists('advisories', $apiResult) - || !is_array($apiResult['advisories']) - || [] === $apiResult['advisories'] - ) { - return new self([]); - } - - // Parse security advisories - $insecurePackages = []; - $advisories = $apiResult['advisories']; - - foreach ($advisories as $packageName => $packageAdvisories) { - $affectedVersions = []; - - foreach ($packageAdvisories as $packageAdvisory) { - $affectedVersions[] = $packageAdvisory['affectedVersions']; - } - - if ([] !== $affectedVersions) { - $insecurePackages[] = new InsecurePackage($packageName, $affectedVersions); - } - } - - return new self($insecurePackages); - } - - /** - * @return InsecurePackage[] - */ - public function getInsecurePackages(): array - { - return $this->insecurePackages; - } - - public function isInsecure(OutdatedPackage $outdatedPackage): bool - { - foreach ($this->insecurePackages as $insecurePackage) { - if ($insecurePackage->getName() === $outdatedPackage->getName()) { - $insecureVersions = implode('|', $insecurePackage->getAffectedVersions()); - - return Semver::satisfies($outdatedPackage->getOutdatedVersion()->get(), $insecureVersions); - } - } - - return false; - } - - private function validateInsecurePackages(): void - { - foreach ($this->insecurePackages as $key => $insecurePackage) { - if (!($insecurePackage instanceof InsecurePackage)) { - throw new InvalidArgumentException(sprintf('Insecure package #%s must be an instance of "%s".', $key, InsecurePackage::class), 1610707087); - } - } - } -} diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index a0adbf30..0a8f7efb 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -23,15 +23,19 @@ namespace EliasHaeussler\ComposerUpdateCheck\Security; +use CuyZ\Valinor\Mapper\MappingError; +use CuyZ\Valinor\Mapper\Source\Source; +use CuyZ\Valinor\Mapper\TreeMapper; +use CuyZ\Valinor\MapperBuilder; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; -use JsonException; -use Nyholm\Psr7\Factory\Psr17Factory; -use Nyholm\Psr7\Uri; -use Psr\Http\Client\ClientExceptionInterface; -use Psr\Http\Client\ClientInterface; -use RuntimeException; -use Symfony\Component\HttpClient\Psr18Client; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\ScanResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Exception\PackagistResponseHasErrors; +use EliasHaeussler\ComposerUpdateCheck\Exception\UnableToFetchSecurityAdvisories; +use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Psr7\Uri; +use Psr\Http\Message\UriInterface; +use Spatie\Packagist\PackagistClient; /** * SecurityScanner. @@ -39,52 +43,51 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final class SecurityScanner +final readonly class SecurityScanner { - public const API_ENDPOINT = 'https://packagist.org/api/security-advisories'; + private TreeMapper $mapper; - private readonly Psr17Factory $requestFactory; - private readonly ClientInterface $client; - - public function __construct(ClientInterface $client = null) - { - $this->requestFactory = new Psr17Factory(); - $this->client = $client ?? new Psr18Client(); + public function __construct( + private PackagistClient $client, + ) { + $this->mapper = $this->createMapper(); } /** * @param list $packages + * + * @throws PackagistResponseHasErrors + * @throws UnableToFetchSecurityAdvisories */ public function scan(array $packages): ScanResult { + $packagesToScan = []; + // Early return if no packages are requested to be scanned if ([] === $packages) { return new ScanResult([]); } - // Parse package names - $packagesToScan = []; foreach ($packages as $package) { - $packagesToScan[] = $package->getName(); + $packagesToScan[$package->getName()] = $package->getOutdatedVersion()->get(); } - // Build API request - $query = http_build_query(['packages' => $packagesToScan]); - $requestUri = new Uri(self::API_ENDPOINT); - $requestUri = $requestUri->withQuery($query); - $request = $this->requestFactory->createRequest('GET', $requestUri)->withHeader('Accept', 'application/json'); - - // Send API request and evaluate response try { - $response = $this->client->sendRequest($request); - $apiResult = $response->getBody()->__toString(); + $advisories = $this->client->getAdvisoriesAffectingVersions($packagesToScan); + $source = Source::array(['securityAdvisories' => $advisories]); - return ScanResult::fromApiResult(json_decode($apiResult, true, 512, JSON_THROW_ON_ERROR)); - } catch (ClientExceptionInterface|JsonException $e) { - throw new RuntimeException('Error while scanning security vulnerabilities.', 1610706128, $e); + return $this->mapper->map(ScanResult::class, $source); + } catch (GuzzleException $exception) { + throw new UnableToFetchSecurityAdvisories($exception); + } catch (MappingError $error) { + throw new PackagistResponseHasErrors($error); } } + /** + * @throws PackagistResponseHasErrors + * @throws UnableToFetchSecurityAdvisories + */ public function scanAndOverlayResult(UpdateCheckResult $result): void { $outdatedPackages = $result->getOutdatedPackages(); @@ -92,8 +95,20 @@ public function scanAndOverlayResult(UpdateCheckResult $result): void foreach ($outdatedPackages as $outdatedPackage) { if ($scanResult->isInsecure($outdatedPackage)) { - $outdatedPackage->setInsecure(true); + $outdatedPackage->setSecurityAdvisories( + $scanResult->getSecurityAdvisoriesForPackage($outdatedPackage), + ); } } } + + private function createMapper(): TreeMapper + { + return (new MapperBuilder()) + ->allowSuperfluousKeys() + ->infer(UriInterface::class, static fn () => Uri::class) + ->supportDateFormats('Y-m-d H:i:s') + ->mapper() + ; + } } diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 02e1df53..a42b8011 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -29,11 +29,12 @@ use EliasHaeussler\ComposerUpdateCheck\Composer\ComposerInstaller; use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; use EliasHaeussler\ComposerUpdateCheck\Configuration\Options\PackageExcludePattern; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InstalledPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent; use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerInstallFailed; use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerUpdateFailed; -use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InstalledPackage; -use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; use function array_map; diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/Unit/Package/UpdateCheckResultTest.php index 8ddba8cb..9e4d8c57 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/Unit/Package/UpdateCheckResultTest.php @@ -24,9 +24,9 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use Generator; use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/Unit/Security/InsecurePackageTest.php index cde03b92..ef06d2ff 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/Unit/Security/InsecurePackageTest.php @@ -23,7 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InsecurePackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use PHPUnit\Framework\Attributes\Test; @@ -35,24 +35,24 @@ */ final class InsecurePackageTest extends AbstractTestCase { - private InsecurePackage $subject; + private SecurityAdvisory $subject; protected function setUp(): void { - $this->subject = new InsecurePackage('foo', ['>=1.0.0,<1.0.5', '>=2.5.0,<2.6.0']); + $this->subject = new SecurityAdvisory('foo', ['>=1.0.0,<1.0.5', '>=2.5.0,<2.6.0']); } #[Test] public function getNameReturnsInsecurePackageName(): void { - self::assertSame('foo', $this->subject->getName()); + self::assertSame('foo', $this->subject->getPackageName()); } #[Test] public function getNameSetsNameOfInsecurePackage(): void { $this->subject->setName('baz'); - self::assertSame('baz', $this->subject->getName()); + self::assertSame('baz', $this->subject->getPackageName()); } #[Test] diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/Unit/Security/ScanResultTest.php index 353bc5a1..904cad71 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/Unit/Security/ScanResultTest.php @@ -23,9 +23,9 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; -use EliasHaeussler\ComposerUpdateCheck\Entity\Package\InsecurePackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\ScanResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Generator; use InvalidArgumentException; @@ -96,13 +96,13 @@ public function fromApiResultReturnsScanResultObjectWithInsecurePackages(): void public function getInsecurePackagesReturnsInsecurePackagesFromScanResult(): void { $insecurePackages = [ - new InsecurePackage('foo', ['1.0.0']), - new InsecurePackage('baz', ['2.0.0']), + new SecurityAdvisory('foo', ['1.0.0']), + new SecurityAdvisory('baz', ['2.0.0']), ]; $subject = new ScanResult($insecurePackages); - self::assertCount(2, $subject->getInsecurePackages()); - self::assertSame($insecurePackages, $subject->getInsecurePackages()); + self::assertCount(2, $subject->getSecurityAdvisories()); + self::assertSame($insecurePackages, $subject->getSecurityAdvisories()); } #[Test] @@ -110,8 +110,8 @@ public function getInsecurePackagesReturnsInsecurePackagesFromScanResult(): void public function isInsecureReturnsSecurityStateOfGivenPackage(OutdatedPackage $outdatedPackage, bool $expected): void { $insecurePackages = [ - new InsecurePackage('foo', ['>=1.0.0,<1.5.0', '2.0.0']), - new InsecurePackage('baz', ['1.0.0-alpha-1']), + new SecurityAdvisory('foo', ['>=1.0.0,<1.5.0', '2.0.0']), + new SecurityAdvisory('baz', ['1.0.0-alpha-1']), ]; $subject = new ScanResult($insecurePackages); diff --git a/tests/Unit/Security/SecurityScannerTest.php b/tests/Unit/Security/SecurityScannerTest.php index acc40601..6e3005b9 100644 --- a/tests/Unit/Security/SecurityScannerTest.php +++ b/tests/Unit/Security/SecurityScannerTest.php @@ -24,7 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Security\ScanResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use Http\Client\Exception\TransferException; @@ -82,15 +82,15 @@ public function scanReturnsScanResult(): void $scanResult = $this->subject->scan($packages); self::assertInstanceOf(ScanResult::class, $scanResult); - self::assertCount(1, $scanResult->getInsecurePackages()); - self::assertSame('foo', $scanResult->getInsecurePackages()[0]->getName()); - self::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getInsecurePackages()[0]->getAffectedVersions()); + self::assertCount(1, $scanResult->getSecurityAdvisories()); + self::assertSame('foo', $scanResult->getSecurityAdvisories()[0]->getName()); + self::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getSecurityAdvisories()[0]->getAffectedVersions()); } #[Test] public function scanReturnsEmptyScanResultIfNoPackagesAreRequestedToBeScanned(): void { - self::assertSame([], $this->subject->scan([])->getInsecurePackages()); + self::assertSame([], $this->subject->scan([])->getSecurityAdvisories()); } #[Test] @@ -123,9 +123,9 @@ public function scanExcludesPackagesWithoutAffectedVersions(): void $scanResult = $this->subject->scan($packages); self::assertInstanceOf(ScanResult::class, $scanResult); - self::assertCount(1, $scanResult->getInsecurePackages()); - self::assertSame('foo', $scanResult->getInsecurePackages()[0]->getName()); - self::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getInsecurePackages()[0]->getAffectedVersions()); + self::assertCount(1, $scanResult->getSecurityAdvisories()); + self::assertSame('foo', $scanResult->getSecurityAdvisories()[0]->getName()); + self::assertSame(['>=1.0.0,<2.0.0'], $scanResult->getSecurityAdvisories()[0]->getAffectedVersions()); } #[Test] diff --git a/tests/Unit/UpdateCheckerTest.php b/tests/Unit/UpdateCheckerTest.php index 4c40daf9..0f262118 100644 --- a/tests/Unit/UpdateCheckerTest.php +++ b/tests/Unit/UpdateCheckerTest.php @@ -27,13 +27,13 @@ use Composer\Console\Application; use Composer\IO\NullIO; use Composer\Json\JsonValidationException; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent; use EliasHaeussler\ComposerUpdateCheck\IO\OutputBehavior; use EliasHaeussler\ComposerUpdateCheck\IO\Style; use EliasHaeussler\ComposerUpdateCheck\IO\Verbosity; use EliasHaeussler\ComposerUpdateCheck\Options; use EliasHaeussler\ComposerUpdateCheck\UpdateChecker; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use PHPUnit\Framework\Attributes\Test; /** diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/Unit/Utility/SecurityTest.php index 14df69dd..f5dc57dc 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/Unit/Utility/SecurityTest.php @@ -24,9 +24,9 @@ namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; -use EliasHaeussler\ComposerUpdateCheck\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Utility\Security; use PHPUnit\Framework\Attributes\Test; From 01dbcd79ff89826aac52365c163f386d09e147dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 5 Dec 2023 21:35:56 +0100 Subject: [PATCH 027/286] [TASK] Use SymfonyStyle in formatters and re-add support for PHP 8.1 --- .github/workflows/cgl.yaml | 2 +- .github/workflows/tests.yaml | 4 ++-- composer.json | 2 +- composer.lock | 4 ++-- docs/install.md | 2 +- rector.php | 2 +- src/Composer/ComposerInstaller.php | 6 +++--- .../Adapter/ChainedConfigAdapter.php | 4 ++-- .../Adapter/CommandInputConfigAdapter.php | 4 ++-- .../Adapter/ConfigAdapterFactory.php | 2 +- .../Adapter/FileBasedConfigAdapter.php | 6 +++--- .../Adapter/JsonConfigAdapter.php | 2 +- src/Configuration/Adapter/PhpConfigAdapter.php | 2 +- .../Adapter/YamlConfigAdapter.php | 2 +- src/DependencyInjection/ContainerFactory.php | 4 ++-- src/Entity/Package/InstalledPackage.php | 4 ++-- src/Entity/Result/ScanResult.php | 4 ++-- src/Entity/Security/SecurityAdvisory.php | 18 +++++++++--------- src/Entity/Version.php | 4 ++-- src/IO/Formatter/Formatter.php | 5 ++--- src/IO/Formatter/FormatterFactory.php | 7 +++---- src/IO/Formatter/GitHubFormatter.php | 7 +++---- src/IO/Formatter/JsonFormatter.php | 7 +++---- src/IO/Formatter/TextFormatter.php | 7 +++---- src/Security/SecurityScanner.php | 6 +++--- src/UpdateChecker.php | 10 +++++----- 26 files changed, 61 insertions(+), 66 deletions(-) diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index 6aab3526..72071fff 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -17,7 +17,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 tools: composer:v2, composer-require-checker, composer-unused # Validation diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 67f0ca57..e03a61b5 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.2", "8.3"] + php-version: ["8.1", "8.2", "8.3"] composer-version: ["2"] dependencies: ["highest", "lowest"] steps: @@ -101,7 +101,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["8.2", "8.3"] + php-version: ["8.1", "8.2", "8.3"] composer-version: ["2"] steps: - uses: actions/checkout@v3 diff --git a/composer.json b/composer.json index b2cbf0ba..4e3fa0fb 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "rss": "https://github.com/eliashaeussler/composer-update-check/releases.atom" }, "require": { - "php": "~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "ext-json": "*", "composer-plugin-api": "^2.1", "cuyz/valinor": "^1.7", diff --git a/composer.lock b/composer.lock index fe4ef84c..52614d08 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ce257b5bca8fdd484ee8e146d22c7300", + "content-hash": "67b7e817c9b9d2c99f17defb884b077a", "packages": [ { "name": "composer/semver", @@ -7175,7 +7175,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0", "ext-json": "*", "composer-plugin-api": "^2.1" }, diff --git a/docs/install.md b/docs/install.md index 56a00e8b..a7c82a0e 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,7 +2,7 @@ ## Requirements -* PHP >= 8.2 +* PHP >= 8.1 * Composer >= 2.1 ## Installation diff --git a/rector.php b/rector.php index 2ef3c2fe..f59a6006 100644 --- a/rector.php +++ b/rector.php @@ -28,7 +28,7 @@ use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector; return static function (RectorConfig $rectorConfig): void { - Config::create($rectorConfig, PhpVersion::PHP_82) + Config::create($rectorConfig, PhpVersion::PHP_81) ->in( __DIR__.'/src', __DIR__.'/tests', diff --git a/src/Composer/ComposerInstaller.php b/src/Composer/ComposerInstaller.php index f40c9d83..8a1aea97 100644 --- a/src/Composer/ComposerInstaller.php +++ b/src/Composer/ComposerInstaller.php @@ -40,11 +40,11 @@ * * @internal */ -final readonly class ComposerInstaller +final class ComposerInstaller { public function __construct( - private Composer $composer, - private IOInterface $io, + private readonly Composer $composer, + private readonly IOInterface $io, ) {} public function runInstall(IOInterface $io = null): int diff --git a/src/Configuration/Adapter/ChainedConfigAdapter.php b/src/Configuration/Adapter/ChainedConfigAdapter.php index 96fb63f1..dd57c54c 100644 --- a/src/Configuration/Adapter/ChainedConfigAdapter.php +++ b/src/Configuration/Adapter/ChainedConfigAdapter.php @@ -32,13 +32,13 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class ChainedConfigAdapter implements ConfigAdapter +final class ChainedConfigAdapter implements ConfigAdapter { /** * @param list $adapters */ public function __construct( - private array $adapters, + private readonly array $adapters, ) {} public function resolve(): ComposerUpdateCheckConfig diff --git a/src/Configuration/Adapter/CommandInputConfigAdapter.php b/src/Configuration/Adapter/CommandInputConfigAdapter.php index 55ff1d0e..b03aaefb 100644 --- a/src/Configuration/Adapter/CommandInputConfigAdapter.php +++ b/src/Configuration/Adapter/CommandInputConfigAdapter.php @@ -36,10 +36,10 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class CommandInputConfigAdapter implements ConfigAdapter +final class CommandInputConfigAdapter implements ConfigAdapter { public function __construct( - private InputInterface $input, + private readonly InputInterface $input, ) {} public function resolve(): ComposerUpdateCheckConfig diff --git a/src/Configuration/Adapter/ConfigAdapterFactory.php b/src/Configuration/Adapter/ConfigAdapterFactory.php index 84e464ff..9ebf54d4 100644 --- a/src/Configuration/Adapter/ConfigAdapterFactory.php +++ b/src/Configuration/Adapter/ConfigAdapterFactory.php @@ -33,7 +33,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class ConfigAdapterFactory +final class ConfigAdapterFactory { /** * @throws ConfigFileIsNotSupported diff --git a/src/Configuration/Adapter/FileBasedConfigAdapter.php b/src/Configuration/Adapter/FileBasedConfigAdapter.php index 123ffe11..199f7aea 100644 --- a/src/Configuration/Adapter/FileBasedConfigAdapter.php +++ b/src/Configuration/Adapter/FileBasedConfigAdapter.php @@ -37,10 +37,10 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -abstract readonly class FileBasedConfigAdapter implements ConfigAdapter +abstract class FileBasedConfigAdapter implements ConfigAdapter { - protected string $filename; - protected TreeMapper $mapper; + protected readonly string $filename; + protected readonly TreeMapper $mapper; /** * @throws FileDoesNotExist diff --git a/src/Configuration/Adapter/JsonConfigAdapter.php b/src/Configuration/Adapter/JsonConfigAdapter.php index f4a3853f..31d39a0e 100644 --- a/src/Configuration/Adapter/JsonConfigAdapter.php +++ b/src/Configuration/Adapter/JsonConfigAdapter.php @@ -35,7 +35,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class JsonConfigAdapter extends FileBasedConfigAdapter +final class JsonConfigAdapter extends FileBasedConfigAdapter { /** * @throws ConfigFileHasErrors diff --git a/src/Configuration/Adapter/PhpConfigAdapter.php b/src/Configuration/Adapter/PhpConfigAdapter.php index 9d0e11ff..531c7f1f 100644 --- a/src/Configuration/Adapter/PhpConfigAdapter.php +++ b/src/Configuration/Adapter/PhpConfigAdapter.php @@ -31,7 +31,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class PhpConfigAdapter extends FileBasedConfigAdapter +final class PhpConfigAdapter extends FileBasedConfigAdapter { public function resolve(): ComposerUpdateCheckConfig { diff --git a/src/Configuration/Adapter/YamlConfigAdapter.php b/src/Configuration/Adapter/YamlConfigAdapter.php index 266e550a..ffb95cf3 100644 --- a/src/Configuration/Adapter/YamlConfigAdapter.php +++ b/src/Configuration/Adapter/YamlConfigAdapter.php @@ -38,7 +38,7 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class YamlConfigAdapter extends FileBasedConfigAdapter +final class YamlConfigAdapter extends FileBasedConfigAdapter { /** * @throws ConfigFileHasErrors diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index 6aaff613..73d1c125 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -44,12 +44,12 @@ * * @internal */ -final readonly class ContainerFactory +final class ContainerFactory { /** * @var list */ - private array $configs; + private readonly array $configs; /** * @param list $configs diff --git a/src/Entity/Package/InstalledPackage.php b/src/Entity/Package/InstalledPackage.php index 397d8a04..1b4ac88d 100644 --- a/src/Entity/Package/InstalledPackage.php +++ b/src/Entity/Package/InstalledPackage.php @@ -29,13 +29,13 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class InstalledPackage implements Package +final class InstalledPackage implements Package { /** * @param non-empty-string $name */ public function __construct( - private string $name, + private readonly string $name, ) {} public function getName(): string diff --git a/src/Entity/Result/ScanResult.php b/src/Entity/Result/ScanResult.php index fd57022a..02a69562 100644 --- a/src/Entity/Result/ScanResult.php +++ b/src/Entity/Result/ScanResult.php @@ -32,13 +32,13 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class ScanResult +final class ScanResult { /** * @param array> $securityAdvisories */ public function __construct( - private array $securityAdvisories, + private readonly array $securityAdvisories, ) {} /** diff --git a/src/Entity/Security/SecurityAdvisory.php b/src/Entity/Security/SecurityAdvisory.php index 1789caf3..5c093cc2 100644 --- a/src/Entity/Security/SecurityAdvisory.php +++ b/src/Entity/Security/SecurityAdvisory.php @@ -33,17 +33,17 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class SecurityAdvisory implements JsonSerializable +final class SecurityAdvisory implements JsonSerializable { public function __construct( - private string $packageName, - private string $advisoryId, - private string $affectedVersions, - private string $title, - private DateTimeImmutable $reportedAt, - private string $severity, - private ?string $cve = null, - private ?UriInterface $link = null, + private readonly string $packageName, + private readonly string $advisoryId, + private readonly string $affectedVersions, + private readonly string $title, + private readonly DateTimeImmutable $reportedAt, + private readonly string $severity, + private readonly ?string $cve = null, + private readonly ?UriInterface $link = null, ) {} public function getPackageName(): string diff --git a/src/Entity/Version.php b/src/Entity/Version.php index 9fdbfd10..87d6228d 100644 --- a/src/Entity/Version.php +++ b/src/Entity/Version.php @@ -31,10 +31,10 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class Version implements Stringable +final class Version implements Stringable { public function __construct( - private string $version, + private readonly string $version, ) {} public function get(): string diff --git a/src/IO/Formatter/Formatter.php b/src/IO/Formatter/Formatter.php index 20c955ef..287a8319 100644 --- a/src/IO/Formatter/Formatter.php +++ b/src/IO/Formatter/Formatter.php @@ -24,8 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\Console\Style\SymfonyStyle; /** * Formatter. @@ -37,7 +36,7 @@ interface Formatter { public function formatResult(UpdateCheckResult $result): void; - public function setIO(OutputInterface&StyleInterface $io): void; + public function setIO(SymfonyStyle $io): void; public static function getFormat(): string; } diff --git a/src/IO/Formatter/FormatterFactory.php b/src/IO/Formatter/FormatterFactory.php index 33cf9b5a..8b4bcb2f 100644 --- a/src/IO/Formatter/FormatterFactory.php +++ b/src/IO/Formatter/FormatterFactory.php @@ -24,8 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\IO\Formatter; use EliasHaeussler\ComposerUpdateCheck\Exception\FormatterIsNotSupported; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\ServiceLocator; /** @@ -41,7 +40,7 @@ final class FormatterFactory */ public function __construct( private readonly ServiceLocator $formatters, - private (OutputInterface&StyleInterface)|null $io = null, + private ?SymfonyStyle $io = null, ) {} /** @@ -62,7 +61,7 @@ public function make(string $format): Formatter return $formatter; } - public function setIO(OutputInterface&StyleInterface $io): void + public function setIO(SymfonyStyle $io): void { $this->io = $io; } diff --git a/src/IO/Formatter/GitHubFormatter.php b/src/IO/Formatter/GitHubFormatter.php index b23a5a95..e81b2108 100644 --- a/src/IO/Formatter/GitHubFormatter.php +++ b/src/IO/Formatter/GitHubFormatter.php @@ -26,8 +26,7 @@ use Composer\Factory; use Composer\Util\Platform; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Path; use function realpath; @@ -44,7 +43,7 @@ final class GitHubFormatter implements Formatter public const FORMAT = 'github'; public function __construct( - private (OutputInterface&StyleInterface)|null $io = null, + private ?SymfonyStyle $io = null, ) {} public function formatResult(UpdateCheckResult $result): void @@ -96,7 +95,7 @@ private function writePackageToOutput(string $composerFile, string $title, strin ); } - public function setIO(OutputInterface&StyleInterface $io): void + public function setIO(SymfonyStyle $io): void { $this->io = $io; } diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index 03bb3470..01206b65 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -26,8 +26,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\Console\Style\SymfonyStyle; use function count; use function json_encode; @@ -44,7 +43,7 @@ final class JsonFormatter implements Formatter public const FORMAT = 'json'; public function __construct( - private (OutputInterface&StyleInterface)|null $io = null, + private ?SymfonyStyle $io = null, ) {} public function formatResult(UpdateCheckResult $result): void @@ -183,7 +182,7 @@ private function renderJson(array $json): void $this->io->writeln(json_encode($json, $flags)); } - public function setIO(OutputInterface&StyleInterface $io): void + public function setIO(SymfonyStyle $io): void { $this->io = $io; } diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php index b94b63bd..b81ab665 100644 --- a/src/IO/Formatter/TextFormatter.php +++ b/src/IO/Formatter/TextFormatter.php @@ -26,8 +26,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\StyleInterface; +use Symfony\Component\Console\Style\SymfonyStyle; use function count; use function sprintf; @@ -43,7 +42,7 @@ final class TextFormatter implements Formatter public const FORMAT = 'text'; public function __construct( - private (OutputInterface&StyleInterface)|null $io = null, + private ?SymfonyStyle $io = null, ) {} public function formatResult(UpdateCheckResult $result): void @@ -124,7 +123,7 @@ private function renderTable(array $outdatedPackages): void $this->io->table(['Package', 'Outdated version', 'New version'], $tableRows); } - public function setIO(OutputInterface&StyleInterface $io): void + public function setIO(SymfonyStyle $io): void { $this->io = $io; } diff --git a/src/Security/SecurityScanner.php b/src/Security/SecurityScanner.php index 0a8f7efb..e073829b 100644 --- a/src/Security/SecurityScanner.php +++ b/src/Security/SecurityScanner.php @@ -43,12 +43,12 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class SecurityScanner +final class SecurityScanner { - private TreeMapper $mapper; + private readonly TreeMapper $mapper; public function __construct( - private PackagistClient $client, + private readonly PackagistClient $client, ) { $this->mapper = $this->createMapper(); } diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index a42b8011..4d5d217c 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -46,13 +46,13 @@ * @author Elias Häußler * @license GPL-3.0-or-later */ -final readonly class UpdateChecker +final class UpdateChecker { public function __construct( - private Composer $composer, - private ComposerInstaller $installer, - private IOInterface $io, - private SecurityScanner $securityScanner, + private readonly Composer $composer, + private readonly ComposerInstaller $installer, + private readonly IOInterface $io, + private readonly SecurityScanner $securityScanner, ) {} public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult From 78efe7759f51d20280ad1106f774fa301042c2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 5 Dec 2023 21:51:10 +0100 Subject: [PATCH 028/286] [FEATURE] Render security advisories on verbose output --- src/IO/Formatter/JsonFormatter.php | 73 ++++++++++++++++++++++++++++-- src/IO/Formatter/TextFormatter.php | 42 +++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index 01206b65..66803aa9 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -63,7 +63,14 @@ public function formatResult(UpdateCheckResult $result): void return; } - $this->renderTable($outdatedPackages, $excludedPackages); + $json = $this->renderTable($outdatedPackages, $excludedPackages); + $securityAdvisories = $this->renderSecurityAdvisories($outdatedPackages); + + if ([] !== $securityAdvisories) { + $json['securityAdvisories'] = $securityAdvisories; + } + + $this->renderJson($json); } /** @@ -97,8 +104,19 @@ private function renderUpToDateMessage(array $excludedPackages): void /** * @param list $outdatedPackages * @param list $excludedPackages + * + * @return array{ + * status: string, + * outdatedPackages: list, + * excludedPackages: list, + * } */ - private function renderTable(array $outdatedPackages, array $excludedPackages): void + private function renderTable(array $outdatedPackages, array $excludedPackages): array { $numberOfOutdatedPackages = count($outdatedPackages); $hasInsecurePackages = false; @@ -132,7 +150,7 @@ private function renderTable(array $outdatedPackages, array $excludedPackages): $json['excludedPackages'] = $excludedPackages; } - $this->renderJson($json); + return $json; } /** @@ -162,6 +180,55 @@ private function parseTableRows(array $outdatedPackages, bool &$hasInsecurePacka return $tableRows; } + /** + * @param list $outdatedPackages + * + * @return array> + */ + private function renderSecurityAdvisories(array $outdatedPackages): array + { + if (!$this->io->isVerbose()) { + return []; + } + + $securityAdvisories = []; + + foreach ($outdatedPackages as $outdatedPackage) { + if (!$outdatedPackage->isInsecure()) { + continue; + } + + $securityAdvisories[$outdatedPackage->getName()] = []; + + foreach ($outdatedPackage->getSecurityAdvisories() as $securityAdvisory) { + $link = $securityAdvisory->getLink(); + + $json = [ + 'title' => $securityAdvisory->getTitle(), + 'advisoryId' => $securityAdvisory->getAdvisoryId(), + 'reportedAt' => $securityAdvisory->getReportedAt()->format('Y-m-d H:i:s'), + 'severity' => $securityAdvisory->getSeverity(), + 'cve' => $securityAdvisory->getCVE(), + ]; + + if (null !== $link) { + $json['link'] = (string) $link; + } + + $securityAdvisories[$outdatedPackage->getName()][] = $json; + } + } + + return $securityAdvisories; + } + /** * @param array $json */ diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php index b81ab665..dc6909a5 100644 --- a/src/IO/Formatter/TextFormatter.php +++ b/src/IO/Formatter/TextFormatter.php @@ -26,6 +26,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use Symfony\Component\Console\Helper\TableSeparator; use Symfony\Component\Console\Style\SymfonyStyle; use function count; @@ -73,6 +74,7 @@ public function formatResult(UpdateCheckResult $result): void } $this->renderTable($outdatedPackages); + $this->renderSecurityAdvisories($outdatedPackages); } /** @@ -123,6 +125,46 @@ private function renderTable(array $outdatedPackages): void $this->io->table(['Package', 'Outdated version', 'New version'], $tableRows); } + /** + * @param list $outdatedPackages + */ + private function renderSecurityAdvisories(array $outdatedPackages): void + { + if (!$this->io->isVerbose()) { + return; + } + + foreach ($outdatedPackages as $outdatedPackage) { + if (!$outdatedPackage->isInsecure()) { + continue; + } + + $this->io->title( + sprintf('Security advisories for "%s"', $outdatedPackage->getName()), + ); + + foreach ($outdatedPackage->getSecurityAdvisories() as $securityAdvisory) { + $link = $securityAdvisory->getLink(); + + $this->io->section($securityAdvisory->getTitle()); + + $definitionList = [ + ['ID' => $securityAdvisory->getAdvisoryId()], + ['Reported at' => $securityAdvisory->getReportedAt()->format('Y-m-d H:i:s')], + ['Severity' => $securityAdvisory->getSeverity()], + ['CVE' => $securityAdvisory->getCVE() ?? 'Unknown'], + ]; + + if (null !== $link) { + $definitionList[] = new TableSeparator(); + $definitionList[] = ['Read more' => (string) $link]; + } + + $this->io->definitionList(...$definitionList); + } + } + } + public function setIO(SymfonyStyle $io): void { $this->io = $io; From a65286e13982f7b3b152e75e903f8c49522ff7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 5 Dec 2023 21:51:53 +0100 Subject: [PATCH 029/286] [TASK] Make insecure package more prominent in GitHub formatter --- src/IO/Formatter/GitHubFormatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/Formatter/GitHubFormatter.php b/src/IO/Formatter/GitHubFormatter.php index e81b2108..fe1ed84c 100644 --- a/src/IO/Formatter/GitHubFormatter.php +++ b/src/IO/Formatter/GitHubFormatter.php @@ -71,7 +71,7 @@ public function formatResult(UpdateCheckResult $result): void 'Outdated version: %s%%0ANew version: %s%s', $outdatedPackage->getOutdatedVersion(), $outdatedPackage->getNewVersion(), - $outdatedPackage->isInsecure() ? '%0APackage is insecure' : '', + $outdatedPackage->isInsecure() ? '%0A🚨 Package is insecure' : '', ), 'warning', ); From 328918d6c76dc5ac15955580e519511b34f10491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Tue, 5 Dec 2023 22:25:23 +0100 Subject: [PATCH 030/286] [FEATURE] Introduce CommandResultParser --- src/Composer/CommandResultParser.php | 87 +++++++++++++++++++++++++ src/Entity/Result/UpdateCheckResult.php | 56 ---------------- src/UpdateChecker.php | 6 +- 3 files changed, 92 insertions(+), 57 deletions(-) create mode 100644 src/Composer/CommandResultParser.php diff --git a/src/Composer/CommandResultParser.php b/src/Composer/CommandResultParser.php new file mode 100644 index 00000000..11a8c3f3 --- /dev/null +++ b/src/Composer/CommandResultParser.php @@ -0,0 +1,87 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Composer; + +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Version; + +use function array_map; +use function array_values; +use function in_array; +use function preg_match_all; + +/** + * CommandResultParser. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class CommandResultParser +{ + private const COMMAND_OUTPUT_PATTERN = + '#^'. + '\s*- Upgrading '. + '(?P\S+) \('. + '(?Pdev-\S+ \S+|(?!dev-)\S+)'. + ' => '. + '(?Pdev-\S+ \S+|(?!dev-)\S+)'. + '\)'. + '$#m'; + + /** + * @param list $packages + * + * @return list + */ + public function parse(string $output, array $packages): array + { + $outdatedPackages = []; + $allowedPackageNames = array_map( + static fn (Package $package) => $package->getName(), + $packages, + ); + + // Early return on regex failure + if (false === preg_match_all(self::COMMAND_OUTPUT_PATTERN, $output, $matches, PREG_SET_ORDER)) { + return []; + } + + foreach ($matches as ['name' => $packageName, 'outdated' => $outdatedVersion, 'new' => $newVersion]) { + if (!in_array($packageName, $allowedPackageNames, true)) { + continue; + } + + if (!isset($outdatedPackages[$packageName])) { + $outdatedPackages[$packageName] = new OutdatedPackage( + $packageName, + new Version($outdatedVersion), + new Version($newVersion), + ); + } + } + + return array_values($outdatedPackages); + } +} diff --git a/src/Entity/Result/UpdateCheckResult.php b/src/Entity/Result/UpdateCheckResult.php index 91276795..2066f209 100644 --- a/src/Entity/Result/UpdateCheckResult.php +++ b/src/Entity/Result/UpdateCheckResult.php @@ -25,7 +25,6 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; -use EliasHaeussler\ComposerUpdateCheck\Entity\Version; /** * UpdateCheckResult. @@ -35,16 +34,6 @@ */ final class UpdateCheckResult { - private const COMMAND_OUTPUT_PATTERN = - '#^'. - '\\s*- Upgrading '. - '(?P\\S+) \\('. - '(?Pdev-\\S+ \\S+|(?!dev-)\\S+)'. - ' => '. - '(?Pdev-\S+ \S+|(?!dev-)\S+)'. - '\\)'. - '$#'; - /** * @var list */ @@ -65,38 +54,6 @@ public function __construct(array $outdatedPackages, array $excludedPackages = [ $this->excludedPackages = $this->sortPackages($excludedPackages); } - /** - * @param list $allowedPackages - * @param list $excludedPackages - */ - public static function fromCommandOutput( - string $output, - array $allowedPackages, - array $excludedPackages = [], - ): self { - $allowedPackageNames = array_map( - static fn (Package $package) => $package->getName(), - $allowedPackages, - ); - - $outputParts = explode(PHP_EOL, $output); - $outdatedPackages = array_unique( - array_filter( - array_map(self::parseCommandOutput(...), $outputParts), - static function (?OutdatedPackage $outdatedPackage) use ($allowedPackageNames) { - if (null === $outdatedPackage) { - return false; - } - - return in_array($outdatedPackage->getName(), $allowedPackageNames, true); - }, - ), - SORT_REGULAR, - ); - - return new self($outdatedPackages, $excludedPackages); - } - /** * @return list */ @@ -113,19 +70,6 @@ public function getExcludedPackages(): array return $this->excludedPackages; } - private static function parseCommandOutput(string $output): ?OutdatedPackage - { - if (1 !== preg_match(self::COMMAND_OUTPUT_PATTERN, $output, $matches)) { - return null; - } - - return new OutdatedPackage( - $matches['name'], - new Version($matches['outdated']), - new Version($matches['new']), - ); - } - /** * @template T of Package * diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 4d5d217c..c5a8eb8f 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -26,6 +26,7 @@ use Composer\Composer; use Composer\IO\BufferIO; use Composer\IO\IOInterface; +use EliasHaeussler\ComposerUpdateCheck\Composer\CommandResultParser; use EliasHaeussler\ComposerUpdateCheck\Composer\ComposerInstaller; use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; use EliasHaeussler\ComposerUpdateCheck\Configuration\Options\PackageExcludePattern; @@ -49,6 +50,7 @@ final class UpdateChecker { public function __construct( + private readonly CommandResultParser $commandResultParser, private readonly Composer $composer, private readonly ComposerInstaller $installer, private readonly IOInterface $io, @@ -103,7 +105,9 @@ private function runUpdateCheck(array $packages, array $excludedPackages): Updat throw new ComposerUpdateFailed($exitCode); } - return UpdateCheckResult::fromCommandOutput($io->getOutput(), $packages, $excludedPackages); + $outdatedPackages = $this->commandResultParser->parse($io->getOutput(), $packages); + + return new UpdateCheckResult($outdatedPackages, $excludedPackages); } /** From 560d65180990d0e608ec756c72c131e368b15925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Wed, 6 Dec 2023 21:42:25 +0100 Subject: [PATCH 031/286] [TASK] Update to PHPStan level 7 --- phpstan.php | 7 ++- .../ContainerBuilderDebugDumpPass.php | 55 +++++++++++++++++++ src/DependencyInjection/ContainerFactory.php | 24 +++++++- src/IO/Formatter/GitHubFormatter.php | 2 +- src/IO/Formatter/JsonFormatter.php | 2 +- src/UpdateChecker.php | 8 ++- 6 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 src/DependencyInjection/CompilerPass/ContainerBuilderDebugDumpPass.php diff --git a/phpstan.php b/phpstan.php index 314b7dac..3da2c61e 100644 --- a/phpstan.php +++ b/phpstan.php @@ -21,10 +21,15 @@ * along with this program. If not, see . */ +use EliasHaeussler\ComposerUpdateCheck\DependencyInjection; use EliasHaeussler\PHPStanConfig; +$container = (new DependencyInjection\ContainerFactory())->make(true); +$containerXmlFile = $container->getParameter('debug.container_xml_filename'); + $symfonySet = PHPStanConfig\Set\SymfonySet::create() ->withConsoleApplicationLoader('Tests/Build/phpstan/console-application.php') + ->withContainerXmlPath($containerXmlFile) ; return PHPStanConfig\Config\Config::create(__DIR__) @@ -36,7 +41,7 @@ 'tests/Build/*', ) ->withBaseline() - ->level(6) + ->level(7) ->withSets($symfonySet) ->toArray() ; diff --git a/src/DependencyInjection/CompilerPass/ContainerBuilderDebugDumpPass.php b/src/DependencyInjection/CompilerPass/ContainerBuilderDebugDumpPass.php new file mode 100644 index 00000000..989806e1 --- /dev/null +++ b/src/DependencyInjection/CompilerPass/ContainerBuilderDebugDumpPass.php @@ -0,0 +1,55 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\DependencyInjection\CompilerPass; + +use Symfony\Component\Config; +use Symfony\Component\DependencyInjection; + +/** + * Dumps the ContainerBuilder to a cache file so that it can be used by + * debugging tools such as the debug:container console command. + * + * @author Ryan Weaver + * @author Fabien Potencier + * + * @internal Only to be used for testing purposes + * + * @codeCoverageIgnore + * + * @see https://github.com/symfony/framework-bundle/blob/5.4/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php + */ +final class ContainerBuilderDebugDumpPass implements DependencyInjection\Compiler\CompilerPassInterface +{ + public function __construct( + private readonly string $cachePath, + ) {} + + public function process(DependencyInjection\ContainerBuilder $container): void + { + $cache = new Config\ConfigCache($this->cachePath, true); + if (!$cache->isFresh()) { + $cache->write((new DependencyInjection\Dumper\XmlDumper($container))->dump(), $container->getResources()); + } + } +} diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index 73d1c125..72a5d014 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -23,6 +23,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\DependencyInjection; +use EliasHaeussler\ComposerUpdateCheck\DependencyInjection\CompilerPass\ContainerBuilderDebugDumpPass; use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileIsNotSupported; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\LoaderInterface; @@ -34,7 +35,10 @@ use Symfony\Component\Filesystem\Path; use function dirname; +use function file_exists; use function in_array; +use function sys_get_temp_dir; +use function uniqid; /** * ContainerFactory. @@ -71,7 +75,7 @@ public function __construct(array $configs = []) /** * @throws ConfigFileIsNotSupported */ - public function make(): ContainerInterface + public function make(bool $debug = false): ContainerInterface { $container = new ContainerBuilder(); @@ -80,6 +84,11 @@ public function make(): ContainerInterface $loader->load($config); } + if ($debug) { + $containerXmlFilename = $this->buildContainerXmlFilename($container); + $container->addCompilerPass(new ContainerBuilderDebugDumpPass($containerXmlFilename)); + } + $container->compile(); return $container; @@ -104,4 +113,17 @@ private function getDefaultConfigurationFile(): string { return dirname(__DIR__, 2).'/config/services.yaml'; } + + private function buildContainerXmlFilename(ContainerBuilder $container): string + { + $tempDir = sys_get_temp_dir(); + + do { + $filename = Path::join($tempDir, uniqid('ComposerUpdateCheck_')).'.xml'; + } while (file_exists($filename)); + + $container->setParameter('debug.container_xml_filename', $filename); + + return $filename; + } } diff --git a/src/IO/Formatter/GitHubFormatter.php b/src/IO/Formatter/GitHubFormatter.php index fe1ed84c..fe309d2b 100644 --- a/src/IO/Formatter/GitHubFormatter.php +++ b/src/IO/Formatter/GitHubFormatter.php @@ -55,7 +55,7 @@ public function formatResult(UpdateCheckResult $result): void // Resolve path to composer.json file $composerFile = Path::makeRelative( - realpath(Factory::getComposerFile()), + (string) realpath(Factory::getComposerFile()), Platform::getCwd(), ); diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index 66803aa9..b15d8bdc 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -113,7 +113,7 @@ private function renderUpToDateMessage(array $excludedPackages): void * newVersion: string, * insecure?: bool, * }>, - * excludedPackages: list, + * excludedPackages?: list, * } */ private function renderTable(array $outdatedPackages, array $excludedPackages): array diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index c5a8eb8f..424744d4 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -135,7 +135,9 @@ private function resolvePackagesForUpdateCheck(ComposerUpdateCheckConfig $config $this->io->writeError('📦 Resolving packages...', true, IOInterface::VERBOSE); $rootPackage = $this->composer->getPackage(); + /** @var array $requiredPackages */ $requiredPackages = array_keys($rootPackage->getRequires()); + /** @var array $requiredDevPackages */ $requiredDevPackages = array_keys($rootPackage->getDevRequires()); $excludedPackages = []; @@ -161,10 +163,10 @@ private function resolvePackagesForUpdateCheck(ComposerUpdateCheckConfig $config } /** - * @param string[] $packages + * @param array $packages * @param list $excludePatterns * - * @return string[] + * @return array */ private function removeByExcludePatterns(array &$packages, array $excludePatterns): array { @@ -188,7 +190,7 @@ private function removeByExcludePatterns(array &$packages, array $excludePattern } /** - * @param array $packageNames + * @param array $packageNames * * @return array */ From 9013c6088db2f3ea51ed13f3918e679b6ee84e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Wed, 6 Dec 2023 21:52:31 +0100 Subject: [PATCH 032/286] [TASK] Update to PHPStan level 8 --- phpstan.php | 2 +- src/IO/Formatter/JsonFormatter.php | 4 ++-- src/IO/Formatter/TextFormatter.php | 6 +++--- src/Plugin.php | 8 ++++++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/phpstan.php b/phpstan.php index 3da2c61e..3f4ba065 100644 --- a/phpstan.php +++ b/phpstan.php @@ -41,7 +41,7 @@ 'tests/Build/*', ) ->withBaseline() - ->level(7) + ->level(8) ->withSets($symfonySet) ->toArray() ; diff --git a/src/IO/Formatter/JsonFormatter.php b/src/IO/Formatter/JsonFormatter.php index b15d8bdc..ba2ecaa8 100644 --- a/src/IO/Formatter/JsonFormatter.php +++ b/src/IO/Formatter/JsonFormatter.php @@ -194,7 +194,7 @@ private function parseTableRows(array $outdatedPackages, bool &$hasInsecurePacka */ private function renderSecurityAdvisories(array $outdatedPackages): array { - if (!$this->io->isVerbose()) { + if (true !== $this->io?->isVerbose()) { return []; } @@ -235,7 +235,7 @@ private function renderSecurityAdvisories(array $outdatedPackages): array private function renderJson(array $json): void { // Early return if output is quiet - if ($this->io->isQuiet()) { + if (false !== $this->io?->isQuiet()) { return; } diff --git a/src/IO/Formatter/TextFormatter.php b/src/IO/Formatter/TextFormatter.php index dc6909a5..56a90bf9 100644 --- a/src/IO/Formatter/TextFormatter.php +++ b/src/IO/Formatter/TextFormatter.php @@ -94,7 +94,7 @@ private function renderUpToDateMessage(array $excludedPackages): void $additionalInformation = ''; } - $this->io->success( + $this->io?->success( sprintf('All packages are up to date%s.', $additionalInformation), ); } @@ -122,7 +122,7 @@ private function renderTable(array $outdatedPackages): void } // Print table - $this->io->table(['Package', 'Outdated version', 'New version'], $tableRows); + $this->io?->table(['Package', 'Outdated version', 'New version'], $tableRows); } /** @@ -130,7 +130,7 @@ private function renderTable(array $outdatedPackages): void */ private function renderSecurityAdvisories(array $outdatedPackages): void { - if (!$this->io->isVerbose()) { + if (true !== $this->io?->isVerbose()) { return; } diff --git a/src/Plugin.php b/src/Plugin.php index bf3da953..3f13fdd6 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -41,11 +41,15 @@ */ final class Plugin implements PluginInterface, Capable, CommandProvider { - private static ?ContainerInterface $container = null; + private static ContainerInterface $container; + + public function __construct() + { + self::$container ??= (new ContainerFactory())->make(); + } public function activate(Composer $composer, IOInterface $io): void { - self::$container = (new ContainerFactory())->make(); self::$container->set(Composer::class, $composer); self::$container->set(IOInterface::class, $io); } From f1093669a4b1695f57076bda9183f7eacc327744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Wed, 6 Dec 2023 21:55:19 +0100 Subject: [PATCH 033/286] [TASK] Update to PHPStan max level --- phpstan.php | 2 +- src/Configuration/Adapter/CommandInputConfigAdapter.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/phpstan.php b/phpstan.php index 3f4ba065..2f774433 100644 --- a/phpstan.php +++ b/phpstan.php @@ -41,7 +41,7 @@ 'tests/Build/*', ) ->withBaseline() - ->level(8) + ->maxLevel() ->withSets($symfonySet) ->toArray() ; diff --git a/src/Configuration/Adapter/CommandInputConfigAdapter.php b/src/Configuration/Adapter/CommandInputConfigAdapter.php index b03aaefb..75ef5b49 100644 --- a/src/Configuration/Adapter/CommandInputConfigAdapter.php +++ b/src/Configuration/Adapter/CommandInputConfigAdapter.php @@ -47,7 +47,10 @@ public function resolve(): ComposerUpdateCheckConfig $config = new ComposerUpdateCheckConfig(); if ($this->input->hasOption('ignore-packages')) { - foreach ($this->input->getOption('ignore-packages') as $pattern) { + /** @var array $excludePatterns */ + $excludePatterns = $this->input->getOption('ignore-packages'); + + foreach ($excludePatterns as $pattern) { $excludePattern = $this->resolveExcludePattern($pattern); $config->excludePackageByPattern($excludePattern); } From 06d519df66297820bcf2f349a9b8082b410c70bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 11:51:36 +0100 Subject: [PATCH 034/286] [TASK] Exclude several dev-only files from dist archives and Docker image --- .dockerignore | 2 ++ .gitattributes | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.dockerignore b/.dockerignore index 706eb8f8..dacc4034 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,3 +14,5 @@ /phpstan.php /phpstan-baseline.neon /phpunit.xml +/rector.php +/renovate.json diff --git a/.gitattributes b/.gitattributes index 784b8386..43546061 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,7 @@ /bin export-ignore /docker export-ignore /docs/build export-ignore +/docs/theme export-ignore /docs/hooks.py export-ignore /tests export-ignore /.dockerignore export-ignore @@ -17,4 +18,5 @@ /phpstan.php export-ignore /phpstan-baseline.neon export-ignore /phpunit.xml export-ignore +/rector.php export-ignore /renovate.json export-ignore From 1497ccf860837923caa92891915b99a861c03d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 17:45:51 +0100 Subject: [PATCH 035/286] [FEATURE] Introduce Reporter component and provide Mattermost reporter --- composer.json | 1 + composer.lock | 138 ++++++------ config/services.php | 33 +++ config/services.yaml | 10 +- .../Adapter/ChainedConfigAdapter.php | 4 + .../Adapter/FileBasedConfigAdapter.php | 1 + .../ComposerUpdateCheckConfig.php | 29 ++- src/DependencyInjection/ContainerFactory.php | 30 +-- .../Attachment/MattermostAttachment.php | 51 +++++ src/Entity/Report/MattermostReport.php | 200 ++++++++++++++++++ src/Entity/Result/UpdateCheckResult.php | 38 ++++ src/Exception/ReporterIsNotSupported.php | 43 ++++ src/Exception/ReporterOptionsAreInvalid.php | 43 ++++ src/Reporter/MattermostReporter.php | 127 +++++++++++ src/Reporter/Reporter.php | 44 ++++ src/Reporter/ReporterFactory.php | 60 ++++++ src/UpdateChecker.php | 34 ++- 17 files changed, 791 insertions(+), 95 deletions(-) create mode 100644 config/services.php create mode 100644 src/Entity/Report/Attachment/MattermostAttachment.php create mode 100644 src/Entity/Report/MattermostReport.php create mode 100644 src/Exception/ReporterIsNotSupported.php create mode 100644 src/Exception/ReporterOptionsAreInvalid.php create mode 100644 src/Reporter/MattermostReporter.php create mode 100644 src/Reporter/Reporter.php create mode 100644 src/Reporter/ReporterFactory.php diff --git a/composer.json b/composer.json index 4e3fa0fb..724d1a07 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "symfony/dependency-injection": "^5.4 || ^6.0", "symfony/filesystem": "^5.4 || ^6.0", "symfony/http-client": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", "symfony/yaml": "^5.4 || ^6.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 52614d08..977dab67 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "67b7e817c9b9d2c99f17defb884b077a", + "content-hash": "f0549de371e85a7cd7998fb27f13b28f", "packages": [ { "name": "composer/semver", @@ -1469,6 +1469,73 @@ ], "time": "2023-07-30T20:28:31+00:00" }, + { + "name": "symfony/options-resolver", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "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 an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.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-08-08T10:16:24+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.28.0", @@ -6524,73 +6591,6 @@ ], "time": "2023-10-17T11:49:05+00:00" }, - { - "name": "symfony/options-resolver", - "version": "v6.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "22301f0e7fdeaacc14318928612dee79be99860e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", - "reference": "22301f0e7fdeaacc14318928612dee79be99860e", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "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 an improved replacement for the array_replace PHP function", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.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-08-08T10:16:24+00:00" - }, { "name": "symfony/polyfill-intl-idn", "version": "v1.28.0", @@ -7180,5 +7180,5 @@ "composer-plugin-api": "^2.1" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/config/services.php b/config/services.php new file mode 100644 index 00000000..4c519d06 --- /dev/null +++ b/config/services.php @@ -0,0 +1,33 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\DependencyInjection; + +use EliasHaeussler\ComposerUpdateCheck\IO; +use EliasHaeussler\ComposerUpdateCheck\Reporter; +use Symfony\Component\DependencyInjection; + +return static function (DependencyInjection\ContainerBuilder $container): void { + $container->registerForAutoconfiguration(IO\Formatter\Formatter::class)->addTag('io.formatter'); + $container->registerForAutoconfiguration(Reporter\Reporter::class)->addTag('reporter'); +}; diff --git a/config/services.yaml b/config/services.yaml index f29d7250..3e127113 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -14,16 +14,16 @@ services: - '../src/Plugin.php' - '../src/UpdateCheckResult.php' - _instanceof: - EliasHaeussler\ComposerUpdateCheck\IO\Formatter\Formatter: - tags: ['io.formatter'] + EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand: + public: true EliasHaeussler\ComposerUpdateCheck\IO\Formatter\FormatterFactory: arguments: $formatters: !tagged_locator { tag: 'io.formatter', default_index_method: 'getFormat' } - EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand: - public: true + EliasHaeussler\ComposerUpdateCheck\Reporter\ReporterFactory: + arguments: + $reporters: !tagged_locator { tag: 'reporter', default_index_method: 'getName' } # Synthetic services (set when the container is built on runtime) Composer\Composer: diff --git a/src/Configuration/Adapter/ChainedConfigAdapter.php b/src/Configuration/Adapter/ChainedConfigAdapter.php index dd57c54c..06d01bb1 100644 --- a/src/Configuration/Adapter/ChainedConfigAdapter.php +++ b/src/Configuration/Adapter/ChainedConfigAdapter.php @@ -69,5 +69,9 @@ private function mergeConfigs(ComposerUpdateCheckConfig $config, ComposerUpdateC if (TextFormatter::FORMAT !== $other->getFormat()) { $config->setFormat($other->getFormat()); } + + foreach ($other->getReporters() as $name => $options) { + $config->enableReporter($name, $options); + } } } diff --git a/src/Configuration/Adapter/FileBasedConfigAdapter.php b/src/Configuration/Adapter/FileBasedConfigAdapter.php index 199f7aea..3c9e8628 100644 --- a/src/Configuration/Adapter/FileBasedConfigAdapter.php +++ b/src/Configuration/Adapter/FileBasedConfigAdapter.php @@ -71,6 +71,7 @@ private function resolveFilename(string $filename): string private function createMapper(): TreeMapper { return (new MapperBuilder()) + ->allowPermissiveTypes() ->mapper() ; } diff --git a/src/Configuration/ComposerUpdateCheckConfig.php b/src/Configuration/ComposerUpdateCheckConfig.php index 7fc4a83f..8120a884 100644 --- a/src/Configuration/ComposerUpdateCheckConfig.php +++ b/src/Configuration/ComposerUpdateCheckConfig.php @@ -35,13 +35,15 @@ final class ComposerUpdateCheckConfig { /** - * @param list $excludePatterns + * @param list $excludePatterns + * @param array> $reporters */ public function __construct( private array $excludePatterns = [], private bool $includeDevPackages = true, private bool $performSecurityScan = false, private string $format = TextFormatter::FORMAT, + private array $reporters = [], ) {} public function excludePackageByName(string $name): self @@ -122,4 +124,29 @@ public function getFormat(): string { return $this->format; } + + /** + * @param array $options + */ + public function enableReporter(string $name, array $options = []): self + { + $this->reporters[$name] = $options; + + return $this; + } + + public function disableReporter(string $name): self + { + unset($this->reporters[$name]); + + return $this; + } + + /** + * @return array> + */ + public function getReporters(): array + { + return $this->reporters; + } } diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index 72a5d014..0c68aaf6 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -34,9 +34,9 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\Filesystem\Path; +use function array_unique; use function dirname; use function file_exists; -use function in_array; use function sys_get_temp_dir; use function uniqid; @@ -60,16 +60,12 @@ final class ContainerFactory */ public function __construct(array $configs = []) { - $defaultConfigurationFile = $this->getDefaultConfigurationFile(); - - if (!in_array($defaultConfigurationFile, $configs, true)) { - $this->configs = [ - $defaultConfigurationFile, - ...$configs, - ]; - } else { - $this->configs = $configs; - } + $defaultConfigurationFiles = $this->getDefaultConfigurationFiles(); + + $this->configs = array_unique([ + ...$defaultConfigurationFiles, + ...$configs, + ]); } /** @@ -109,9 +105,17 @@ private function createLoader(string $filename, ContainerBuilder $container): Lo }; } - private function getDefaultConfigurationFile(): string + /** + * @return list + */ + private function getDefaultConfigurationFiles(): array { - return dirname(__DIR__, 2).'/config/services.yaml'; + $configDir = dirname(__DIR__, 2).'/config'; + + return [ + $configDir.'/services.php', + $configDir.'/services.yaml', + ]; } private function buildContainerXmlFilename(ContainerBuilder $container): string diff --git a/src/Entity/Report/Attachment/MattermostAttachment.php b/src/Entity/Report/Attachment/MattermostAttachment.php new file mode 100644 index 00000000..e412dfa1 --- /dev/null +++ b/src/Entity/Report/Attachment/MattermostAttachment.php @@ -0,0 +1,51 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report\Attachment; + +use JsonSerializable; + +/** + * MattermostAttachment. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class MattermostAttachment implements JsonSerializable +{ + public function __construct( + public readonly string $color, + public readonly string $text, + ) {} + + /** + * @return array{color: string, text: string} + */ + public function jsonSerialize(): array + { + return [ + 'color' => $this->color, + 'text' => $this->text, + ]; + } +} diff --git a/src/Entity/Report/MattermostReport.php b/src/Entity/Report/MattermostReport.php new file mode 100644 index 00000000..689cdfea --- /dev/null +++ b/src/Entity/Report/MattermostReport.php @@ -0,0 +1,200 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report; + +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; +use JsonSerializable; + +use function count; +use function implode; +use function sprintf; + +/** + * MattermostReport. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class MattermostReport implements JsonSerializable +{ + /** + * @param list $attachments + */ + private function __construct( + public readonly string $channel, + public readonly string $text, + public readonly array $attachments, + public readonly ?string $iconEmoji = null, + public readonly ?string $username = null, + ) {} + + public static function create( + string $channel, + ?string $username, + UpdateCheckResult $result, + string $rootPackageName = null, + ): self { + return new self( + $channel, + self::createText($result), + self::createAttachments($result, $rootPackageName), + $result->hasInsecureOutdatedPackages() ? ':warning:' : ':package:', + $username, + ); + } + + private static function createText(UpdateCheckResult $result): string + { + $numberOfOutdatedPackages = 0; + $numberOfInsecurePackages = 0; + + // Count outdated and insecure packages + foreach ($result->getOutdatedPackages() as $outdatedPackage) { + ++$numberOfOutdatedPackages; + + if ($outdatedPackage->isInsecure()) { + ++$numberOfInsecurePackages; + } + } + + return sprintf( + '#### :rotating_light: %d outdated%s package%s', + $numberOfOutdatedPackages, + $numberOfInsecurePackages > 0 ? sprintf(' (%d insecure)', $numberOfInsecurePackages) : '', + 1 !== $numberOfOutdatedPackages ? 's' : '', + ); + } + + /** + * @return list + */ + private static function createAttachments(UpdateCheckResult $result, string $rootPackageName = null): array + { + $securityAdvisories = $result->getSecurityAdvisories(); + $attachments = []; + + // Outdated packages + $attachments[] = new Attachment\MattermostAttachment( + '#EE0000', + self::renderOutdatedPackagesTable($result, $rootPackageName), + ); + + // Security advisories + if ([] !== $securityAdvisories) { + $attachments[] = new Attachment\MattermostAttachment( + '#EE0000', + self::renderSecurityAdvisoriesTable($securityAdvisories), + ); + } + + return $attachments; + } + + private static function renderOutdatedPackagesTable(UpdateCheckResult $result, string $rootPackageName = null): string + { + $numberOfExcludedPackages = count($result->getExcludedPackages()); + $textParts = []; + + if (null !== $rootPackageName) { + $textParts[] = sprintf('##### %s', $rootPackageName); + } + + $textParts[] = '| Package | Current version | New version |'; + $textParts[] = '|:------- |:--------------- |:----------- |'; + + foreach ($result->getOutdatedPackages() as $outdatedPackage) { + $textParts[] = sprintf( + '| [%s](%s) | %s%s | **%s** |', + $outdatedPackage->getName(), + $outdatedPackage->getProviderLink(), + $outdatedPackage->getOutdatedVersion(), + $outdatedPackage->isInsecure() ? ' :warning:' : '', + $outdatedPackage->getNewVersion(), + ); + } + + if ($numberOfExcludedPackages > 0) { + $textParts[] = sprintf( + '_%d package%s excluded from update check._', + $numberOfExcludedPackages, + 1 !== $numberOfExcludedPackages ? 's were' : ' was', + ); + } + + return implode(PHP_EOL, $textParts); + } + + /** + * @param list $securityAdvisories + */ + private static function renderSecurityAdvisoriesTable(array $securityAdvisories): string + { + $textParts = [ + '##### Security advisories', + ]; + + foreach ($securityAdvisories as $securityAdvisory) { + $textParts[] = sprintf('###### %s', $securityAdvisory->getTitle()); + $textParts[] = sprintf('* Package: `%s`', $securityAdvisory->getPackageName()); + $textParts[] = sprintf('* Advisory ID: `%s`', $securityAdvisory->getAdvisoryId()); + $textParts[] = sprintf('* Reported at: `%s`', $securityAdvisory->getReportedAt()->format('Y-m-d H:i:s')); + $textParts[] = sprintf('* Severity: `%s`', $securityAdvisory->getSeverity()); + + if (null !== $securityAdvisory->getCVE()) { + $textParts[] = sprintf('* CVE: `%s`', $securityAdvisory->getCVE()); + } + + if (null !== $securityAdvisory->getLink()) { + $textParts[] = sprintf('[Read more](%s)', $securityAdvisory->getLink()); + } + } + + return implode(PHP_EOL, $textParts); + } + + /** + * @return array{ + * channel: string, + * text: string, + * attachments: list, + * username?: string, + * } + */ + public function jsonSerialize(): array + { + $json = [ + 'channel' => $this->channel, + 'text' => $this->text, + 'attachments' => $this->attachments, + 'icon_emoji' => $this->iconEmoji, + ]; + + if (null !== $this->username) { + $json['username'] = $this->username; + } + + return $json; + } +} diff --git a/src/Entity/Result/UpdateCheckResult.php b/src/Entity/Result/UpdateCheckResult.php index 2066f209..bdb5dcd1 100644 --- a/src/Entity/Result/UpdateCheckResult.php +++ b/src/Entity/Result/UpdateCheckResult.php @@ -25,6 +25,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; /** * UpdateCheckResult. @@ -70,6 +71,43 @@ public function getExcludedPackages(): array return $this->excludedPackages; } + /** + * @return list + */ + public function getSecurityAdvisories(): array + { + $securityAdvisories = []; + + foreach ($this->outdatedPackages as $outdatedPackage) { + foreach ($outdatedPackage->getSecurityAdvisories() as $securityAdvisory) { + $securityAdvisories[] = $securityAdvisory; + } + } + + return $securityAdvisories; + } + + /** + * @return list + */ + public function getInsecureOutdatedPackages(): array + { + $insecurePackages = []; + + foreach ($this->outdatedPackages as $outdatedPackage) { + if ($outdatedPackage->isInsecure()) { + $insecurePackages[] = $outdatedPackage; + } + } + + return $insecurePackages; + } + + public function hasInsecureOutdatedPackages(): bool + { + return [] !== $this->getInsecureOutdatedPackages(); + } + /** * @template T of Package * diff --git a/src/Exception/ReporterIsNotSupported.php b/src/Exception/ReporterIsNotSupported.php new file mode 100644 index 00000000..dbd44a28 --- /dev/null +++ b/src/Exception/ReporterIsNotSupported.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * ReporterIsNotSupported. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ReporterIsNotSupported extends Exception +{ + public function __construct(string $name) + { + parent::__construct( + sprintf('The reporter "%s" is not supported.', $name), + 1701950099, + ); + } +} diff --git a/src/Exception/ReporterOptionsAreInvalid.php b/src/Exception/ReporterOptionsAreInvalid.php new file mode 100644 index 00000000..e2090f12 --- /dev/null +++ b/src/Exception/ReporterOptionsAreInvalid.php @@ -0,0 +1,43 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Exception; + +use function sprintf; + +/** + * ReporterOptionsAreInvalid. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ReporterOptionsAreInvalid extends Exception +{ + public function __construct(string $name) + { + parent::__construct( + sprintf('The options for reporter "%s" are either not set or invalid.', $name), + 1701967125, + ); + } +} diff --git a/src/Reporter/MattermostReporter.php b/src/Reporter/MattermostReporter.php new file mode 100644 index 00000000..94705acb --- /dev/null +++ b/src/Reporter/MattermostReporter.php @@ -0,0 +1,127 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Reporter; + +use Composer\Composer; +use Composer\IO\IOInterface; +use EliasHaeussler\ComposerUpdateCheck\Entity\Report\MattermostReport; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Exception\ReporterOptionsAreInvalid; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Psr7\Uri; +use GuzzleHttp\RequestOptions; +use Psr\Http\Message\UriInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * MattermostReporter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class MattermostReporter implements Reporter +{ + public const NAME = 'mattermost'; + + private readonly OptionsResolver $resolver; + private ?UriInterface $url = null; + private ?string $channel = null; + private ?string $username = null; + + public function __construct( + private readonly Client $client, + private readonly Composer $composer, + private readonly IOInterface $io, + ) { + $this->resolver = $this->createOptionsResolver(); + } + + /** + * @throws ReporterOptionsAreInvalid + */ + public function report(UpdateCheckResult $result): bool + { + // Validate options + if (null === $this->url || null === $this->channel) { + throw new ReporterOptionsAreInvalid(self::NAME); + } + + // Resolve root package name from composer.json + $rootPackageName = $this->composer->getPackage()->getName(); + if ('__root__' === $rootPackageName) { + $rootPackageName = null; + } + + // Create report + $report = MattermostReport::create($this->channel, $this->username, $result, $rootPackageName); + + // Send report + try { + $this->io->write('📤 Sending report to Mattermost...', true, IOInterface::VERBOSE); + + $response = $this->client->post($this->url, [ + RequestOptions::JSON => $report, + ]); + } catch (GuzzleException) { + return false; + } + + return 200 === $response->getStatusCode(); + } + + public function setOptions(array $options): void + { + ['url' => $this->url, 'channel' => $this->channel, 'username' => $this->username] = $this->resolver->resolve($options); + } + + public static function getName(): string + { + return self::NAME; + } + + private function createOptionsResolver(): OptionsResolver + { + $resolver = new OptionsResolver(); + + $resolver->define('channel') + ->allowedTypes('string') + ->required() + ; + + $resolver->define('url') + ->allowedTypes('string') + ->required() + ->normalize( + static fn (OptionsResolver $resolver, string $url) => new Uri($url), + ) + ; + + $resolver->define('username') + ->allowedTypes('string') + ; + + return $resolver; + } +} diff --git a/src/Reporter/Reporter.php b/src/Reporter/Reporter.php new file mode 100644 index 00000000..c70e2f3d --- /dev/null +++ b/src/Reporter/Reporter.php @@ -0,0 +1,44 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Reporter; + +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; + +/** + * Reporter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +interface Reporter +{ + public function report(UpdateCheckResult $result): bool; + + /** + * @param array $options + */ + public function setOptions(array $options): void; + + public static function getName(): string; +} diff --git a/src/Reporter/ReporterFactory.php b/src/Reporter/ReporterFactory.php new file mode 100644 index 00000000..19efa389 --- /dev/null +++ b/src/Reporter/ReporterFactory.php @@ -0,0 +1,60 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Reporter; + +use EliasHaeussler\ComposerUpdateCheck\Exception\ReporterIsNotSupported; +use Symfony\Component\DependencyInjection\ServiceLocator; + +/** + * ReporterFactory. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class ReporterFactory +{ + /** + * @param ServiceLocator $reporters + */ + public function __construct( + private readonly ServiceLocator $reporters, + ) {} + + /** + * @param array $options + * + * @throws ReporterIsNotSupported + */ + public function make(string $name, array $options = []): Reporter + { + if (!$this->reporters->has($name)) { + throw new ReporterIsNotSupported($name); + } + + $reporter = $this->reporters->get($name); + $reporter->setOptions($options); + + return $reporter; + } +} diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 424744d4..0240fd53 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -34,8 +34,7 @@ use EliasHaeussler\ComposerUpdateCheck\Entity\Package\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; use EliasHaeussler\ComposerUpdateCheck\Event\PostUpdateCheckEvent; -use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerInstallFailed; -use EliasHaeussler\ComposerUpdateCheck\Exception\ComposerUpdateFailed; +use EliasHaeussler\ComposerUpdateCheck\Reporter\ReporterFactory; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; use function array_map; @@ -55,10 +54,26 @@ public function __construct( private readonly ComposerInstaller $installer, private readonly IOInterface $io, private readonly SecurityScanner $securityScanner, + private readonly ReporterFactory $reporterFactory, ) {} + /** + * @throws Exception\ComposerInstallFailed + * @throws Exception\ComposerUpdateFailed + * @throws Exception\PackagistResponseHasErrors + * @throws Exception\ReporterIsNotSupported + * @throws Exception\UnableToFetchSecurityAdvisories + */ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult { + $reporters = []; + + // Resolve reporters + foreach ($config->getReporters() as $name => $options) { + $reporters[] = $this->reporterFactory->make($name, $options); + } + + // Run update check [$packages, $excludedPackages] = $this->resolvePackagesForUpdateCheck($config); $result = $this->runUpdateCheck($packages, $excludedPackages); @@ -71,6 +86,11 @@ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult // Dispatch event $this->dispatchPostUpdateCheckEvent($result); + // Report update check result + foreach ($reporters as $reporter) { + $reporter->report($result); + } + return $result; } @@ -78,8 +98,8 @@ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult * @param list $packages * @param list $excludedPackages * - * @throws ComposerInstallFailed - * @throws ComposerUpdateFailed + * @throws Exception\ComposerInstallFailed + * @throws Exception\ComposerUpdateFailed */ private function runUpdateCheck(array $packages, array $excludedPackages): UpdateCheckResult { @@ -102,7 +122,7 @@ private function runUpdateCheck(array $packages, array $excludedPackages): Updat if ($exitCode > 0) { $this->io->writeError($io->getOutput()); - throw new ComposerUpdateFailed($exitCode); + throw new Exception\ComposerUpdateFailed($exitCode); } $outdatedPackages = $this->commandResultParser->parse($io->getOutput(), $packages); @@ -111,7 +131,7 @@ private function runUpdateCheck(array $packages, array $excludedPackages): Updat } /** - * @throws ComposerInstallFailed + * @throws Exception\ComposerInstallFailed */ private function installDependencies(): void { @@ -123,7 +143,7 @@ private function installDependencies(): void if ($exitCode > 0) { $this->io->writeError($io->getOutput()); - throw new ComposerInstallFailed($exitCode); + throw new Exception\ComposerInstallFailed($exitCode); } } From 79148e0da9a5019a850914d7ff3b966e2e2cffe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 17:47:54 +0100 Subject: [PATCH 036/286] [BUGFIX] Skip annotation to attribute migration in sources --- rector.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/rector.php b/rector.php index f59a6006..65bb5cde 100644 --- a/rector.php +++ b/rector.php @@ -25,7 +25,6 @@ use Rector\Config\RectorConfig; use Rector\Core\ValueObject\PhpVersion; use Rector\Php80\Rector\Class_\AnnotationToAttributeRector; -use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector; return static function (RectorConfig $rectorConfig): void { Config::create($rectorConfig, PhpVersion::PHP_81) @@ -37,20 +36,11 @@ ->skip( AnnotationToAttributeRector::class, [ + __DIR__.'/src/DependencyInjection/CompilerPass/ContainerBuilderDebugDumpPass.php', __DIR__.'/src/Event/PostUpdateCheckEvent.php', __DIR__.'/src/Plugin.php', ], ) -// ->skip( -// FinalizeClassesWithoutChildrenRector::class, -// [ -// __DIR__.'/src/Sitemap/Sitemap.php', -// __DIR__.'/src/Sitemap/Url.php', -// // For some reason Rector does not recognize child classes -// // of this fixture class, therefore we need to skip it here -// __DIR__.'/tests/src/Fixtures/Classes/DummyCrawler.php', -// ], -// ) ->apply() ; }; From 3f78764e5a80c51700c388f1644b5ddcad07144b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 20:16:27 +0100 Subject: [PATCH 037/286] [TASK] Make reporters immutable --- src/Reporter/MattermostReporter.php | 24 ++++-------------------- src/Reporter/Reporter.php | 7 ++++--- src/Reporter/ReporterFactory.php | 9 ++------- src/UpdateChecker.php | 13 ++++--------- 4 files changed, 14 insertions(+), 39 deletions(-) diff --git a/src/Reporter/MattermostReporter.php b/src/Reporter/MattermostReporter.php index 94705acb..ebcd0de9 100644 --- a/src/Reporter/MattermostReporter.php +++ b/src/Reporter/MattermostReporter.php @@ -27,12 +27,10 @@ use Composer\IO\IOInterface; use EliasHaeussler\ComposerUpdateCheck\Entity\Report\MattermostReport; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use EliasHaeussler\ComposerUpdateCheck\Exception\ReporterOptionsAreInvalid; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Psr7\Uri; use GuzzleHttp\RequestOptions; -use Psr\Http\Message\UriInterface; use Symfony\Component\OptionsResolver\OptionsResolver; /** @@ -46,9 +44,6 @@ final class MattermostReporter implements Reporter public const NAME = 'mattermost'; private readonly OptionsResolver $resolver; - private ?UriInterface $url = null; - private ?string $channel = null; - private ?string $username = null; public function __construct( private readonly Client $client, @@ -58,15 +53,9 @@ public function __construct( $this->resolver = $this->createOptionsResolver(); } - /** - * @throws ReporterOptionsAreInvalid - */ - public function report(UpdateCheckResult $result): bool + public function report(UpdateCheckResult $result, array $options): bool { - // Validate options - if (null === $this->url || null === $this->channel) { - throw new ReporterOptionsAreInvalid(self::NAME); - } + ['url' => $url, 'channel' => $channel, 'username' => $username] = $this->resolver->resolve($options); // Resolve root package name from composer.json $rootPackageName = $this->composer->getPackage()->getName(); @@ -75,13 +64,13 @@ public function report(UpdateCheckResult $result): bool } // Create report - $report = MattermostReport::create($this->channel, $this->username, $result, $rootPackageName); + $report = MattermostReport::create($channel, $username, $result, $rootPackageName); // Send report try { $this->io->write('📤 Sending report to Mattermost...', true, IOInterface::VERBOSE); - $response = $this->client->post($this->url, [ + $response = $this->client->post($url, [ RequestOptions::JSON => $report, ]); } catch (GuzzleException) { @@ -91,11 +80,6 @@ public function report(UpdateCheckResult $result): bool return 200 === $response->getStatusCode(); } - public function setOptions(array $options): void - { - ['url' => $this->url, 'channel' => $this->channel, 'username' => $this->username] = $this->resolver->resolve($options); - } - public static function getName(): string { return self::NAME; diff --git a/src/Reporter/Reporter.php b/src/Reporter/Reporter.php index c70e2f3d..97d12f95 100644 --- a/src/Reporter/Reporter.php +++ b/src/Reporter/Reporter.php @@ -24,6 +24,7 @@ namespace EliasHaeussler\ComposerUpdateCheck\Reporter; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Exception\ReporterOptionsAreInvalid; /** * Reporter. @@ -33,12 +34,12 @@ */ interface Reporter { - public function report(UpdateCheckResult $result): bool; - /** * @param array $options + * + * @throws ReporterOptionsAreInvalid */ - public function setOptions(array $options): void; + public function report(UpdateCheckResult $result, array $options): bool; public static function getName(): string; } diff --git a/src/Reporter/ReporterFactory.php b/src/Reporter/ReporterFactory.php index 19efa389..a77fe4f2 100644 --- a/src/Reporter/ReporterFactory.php +++ b/src/Reporter/ReporterFactory.php @@ -42,19 +42,14 @@ public function __construct( ) {} /** - * @param array $options - * * @throws ReporterIsNotSupported */ - public function make(string $name, array $options = []): Reporter + public function make(string $name): Reporter { if (!$this->reporters->has($name)) { throw new ReporterIsNotSupported($name); } - $reporter = $this->reporters->get($name); - $reporter->setOptions($options); - - return $reporter; + return $this->reporters->get($name); } } diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 0240fd53..d724e2ad 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -62,17 +62,11 @@ public function __construct( * @throws Exception\ComposerUpdateFailed * @throws Exception\PackagistResponseHasErrors * @throws Exception\ReporterIsNotSupported + * @throws Exception\ReporterOptionsAreInvalid * @throws Exception\UnableToFetchSecurityAdvisories */ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult { - $reporters = []; - - // Resolve reporters - foreach ($config->getReporters() as $name => $options) { - $reporters[] = $this->reporterFactory->make($name, $options); - } - // Run update check [$packages, $excludedPackages] = $this->resolvePackagesForUpdateCheck($config); $result = $this->runUpdateCheck($packages, $excludedPackages); @@ -87,8 +81,9 @@ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult $this->dispatchPostUpdateCheckEvent($result); // Report update check result - foreach ($reporters as $reporter) { - $reporter->report($result); + foreach ($config->getReporters() as $name => $options) { + $reporter = $this->reporterFactory->make($name); + $reporter->report($result, $options); } return $result; From 6992e61793c1f5197f61190f95e5c155e85d5321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 20:25:25 +0100 Subject: [PATCH 038/286] [TASK] Show outcome in progress messages --- src/Reporter/MattermostReporter.php | 13 ++++++++++--- src/UpdateChecker.php | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Reporter/MattermostReporter.php b/src/Reporter/MattermostReporter.php index ebcd0de9..7106a921 100644 --- a/src/Reporter/MattermostReporter.php +++ b/src/Reporter/MattermostReporter.php @@ -68,16 +68,23 @@ public function report(UpdateCheckResult $result, array $options): bool // Send report try { - $this->io->write('📤 Sending report to Mattermost...', true, IOInterface::VERBOSE); + $this->io->writeError('📤 Sending report to Mattermost... ', false, IOInterface::VERBOSE); $response = $this->client->post($url, [ RequestOptions::JSON => $report, ]); + $successful = 200 === $response->getStatusCode(); } catch (GuzzleException) { - return false; + $successful = false; } - return 200 === $response->getStatusCode(); + if ($successful) { + $this->io->writeError('Done', true, IOInterface::VERBOSE); + } else { + $this->io->writeError('Failed', true, IOInterface::VERBOSE); + } + + return $successful; } public static function getName(): string diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index d724e2ad..07fc5212 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -73,8 +73,15 @@ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult // Overlay security scan if ($config->shouldPerformSecurityScan() && [] !== $result->getOutdatedPackages()) { - $this->io->writeError('🚨 Checking for insecure packages...', true, IOInterface::VERBOSE); - $this->securityScanner->scanAndOverlayResult($result); + try { + $this->io->writeError('🚨 Checking for insecure packages... ', false, IOInterface::VERBOSE); + $this->securityScanner->scanAndOverlayResult($result); + $this->io->writeError('Done', true, IOInterface::VERBOSE); + } catch (Exception\PackagistResponseHasErrors|Exception\UnableToFetchSecurityAdvisories $exception) { + $this->io->writeError('Failed', true, IOInterface::VERBOSE); + + throw $exception; + } } // Dispatch event @@ -107,7 +114,7 @@ private function runUpdateCheck(array $packages, array $excludedPackages): Updat $this->installDependencies(); // Show progress - $this->io->writeError('⏳ Checking for outdated packages...', true, IOInterface::VERBOSE); + $this->io->writeError('⏳ Checking for outdated packages... ', false, IOInterface::VERBOSE); // Run Composer installer $io = new BufferIO(); @@ -115,11 +122,14 @@ private function runUpdateCheck(array $packages, array $excludedPackages): Updat // Handle installer failures if ($exitCode > 0) { + $this->io->writeError('Failed', true, IOInterface::VERBOSE); $this->io->writeError($io->getOutput()); throw new Exception\ComposerUpdateFailed($exitCode); } + $this->io->writeError('Done', true, IOInterface::VERBOSE); + $outdatedPackages = $this->commandResultParser->parse($io->getOutput(), $packages); return new UpdateCheckResult($outdatedPackages, $excludedPackages); From e3c70515f4ef79719eac9518418b6ae415bc67eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 20:36:08 +0100 Subject: [PATCH 039/286] [TASK] Rename Entity\Report\Attachment -> Entity\Report\Dto --- .../{Attachment => Dto}/MattermostAttachment.php | 2 +- src/Entity/Report/MattermostReport.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/Entity/Report/{Attachment => Dto}/MattermostAttachment.php (95%) diff --git a/src/Entity/Report/Attachment/MattermostAttachment.php b/src/Entity/Report/Dto/MattermostAttachment.php similarity index 95% rename from src/Entity/Report/Attachment/MattermostAttachment.php rename to src/Entity/Report/Dto/MattermostAttachment.php index e412dfa1..2fe12d2c 100644 --- a/src/Entity/Report/Attachment/MattermostAttachment.php +++ b/src/Entity/Report/Dto/MattermostAttachment.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report\Attachment; +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report\Dto; use JsonSerializable; diff --git a/src/Entity/Report/MattermostReport.php b/src/Entity/Report/MattermostReport.php index 689cdfea..8842c4f1 100644 --- a/src/Entity/Report/MattermostReport.php +++ b/src/Entity/Report/MattermostReport.php @@ -40,7 +40,7 @@ final class MattermostReport implements JsonSerializable { /** - * @param list $attachments + * @param list $attachments */ private function __construct( public readonly string $channel, @@ -88,7 +88,7 @@ private static function createText(UpdateCheckResult $result): string } /** - * @return list + * @return list */ private static function createAttachments(UpdateCheckResult $result, string $rootPackageName = null): array { @@ -96,14 +96,14 @@ private static function createAttachments(UpdateCheckResult $result, string $roo $attachments = []; // Outdated packages - $attachments[] = new Attachment\MattermostAttachment( + $attachments[] = new Dto\MattermostAttachment( '#EE0000', self::renderOutdatedPackagesTable($result, $rootPackageName), ); // Security advisories if ([] !== $securityAdvisories) { - $attachments[] = new Attachment\MattermostAttachment( + $attachments[] = new Dto\MattermostAttachment( '#EE0000', self::renderSecurityAdvisoriesTable($securityAdvisories), ); @@ -178,7 +178,7 @@ private static function renderSecurityAdvisoriesTable(array $securityAdvisories) * @return array{ * channel: string, * text: string, - * attachments: list, + * attachments: list, * username?: string, * } */ From 31f5c8a83e7d10cf4c23e4013180a3b94d4f6ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 21:37:36 +0100 Subject: [PATCH 040/286] [FEATURE] Provide Slack reporter --- src/Entity/Report/Dto/SlackBlock.php | 103 +++++++++ src/Entity/Report/Dto/SlackBlockElement.php | 64 ++++++ src/Entity/Report/SlackReport.php | 231 ++++++++++++++++++++ src/Reporter/SlackReporter.php | 109 +++++++++ 4 files changed, 507 insertions(+) create mode 100644 src/Entity/Report/Dto/SlackBlock.php create mode 100644 src/Entity/Report/Dto/SlackBlockElement.php create mode 100644 src/Entity/Report/SlackReport.php create mode 100644 src/Reporter/SlackReporter.php diff --git a/src/Entity/Report/Dto/SlackBlock.php b/src/Entity/Report/Dto/SlackBlock.php new file mode 100644 index 00000000..601168a6 --- /dev/null +++ b/src/Entity/Report/Dto/SlackBlock.php @@ -0,0 +1,103 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report\Dto; + +use JsonSerializable; + +/** + * SlackBlock. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class SlackBlock implements JsonSerializable +{ + /** + * @param list|null $fields + * @param list|null $elements + */ + private function __construct( + public readonly string $type, + public readonly ?SlackBlockElement $text = null, + public readonly ?array $fields = null, + public readonly ?array $elements = null, + ) {} + + /** + * @param list $elements + */ + public static function context(array $elements): self + { + return new self('context', elements: $elements); + } + + public static function divider(): self + { + return new self('divider'); + } + + public static function header(SlackBlockElement $text): self + { + return new self('header', $text); + } + + /** + * @param list|null $fields + */ + public static function section( + SlackBlockElement $text = null, + array $fields = null, + ): self { + return new self('section', $text, $fields); + } + + /** + * @return array{ + * type: string, + * text?: SlackBlockElement, + * fields?: list, + * elements?: list, + * } + */ + public function jsonSerialize(): array + { + $json = [ + 'type' => $this->type, + ]; + + if (null !== $this->text) { + $json['text'] = $this->text; + } + + if (null !== $this->fields) { + $json['fields'] = $this->fields; + } + + if (null !== $this->elements) { + $json['elements'] = $this->elements; + } + + return $json; + } +} diff --git a/src/Entity/Report/Dto/SlackBlockElement.php b/src/Entity/Report/Dto/SlackBlockElement.php new file mode 100644 index 00000000..dbb98447 --- /dev/null +++ b/src/Entity/Report/Dto/SlackBlockElement.php @@ -0,0 +1,64 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report\Dto; + +use JsonSerializable; + +/** + * SlackBlockElement. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class SlackBlockElement implements JsonSerializable +{ + private function __construct( + public readonly string $type, + public readonly string $text, + ) {} + + public static function markdown(string $text): self + { + return new self('mrkdwn', $text); + } + + public static function plainText(string $text): self + { + return new self('plain_text', $text); + } + + /** + * @return array{ + * type: string, + * text: string, + * } + */ + public function jsonSerialize(): array + { + return [ + 'type' => $this->type, + 'text' => $this->text, + ]; + } +} diff --git a/src/Entity/Report/SlackReport.php b/src/Entity/Report/SlackReport.php new file mode 100644 index 00000000..35b14902 --- /dev/null +++ b/src/Entity/Report/SlackReport.php @@ -0,0 +1,231 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Entity\Report; + +use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; +use JsonSerializable; + +use function count; +use function implode; +use function sprintf; + +/** + * SlackReport. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class SlackReport implements JsonSerializable +{ + private const MAX_BLOCKS = 45; + + /** + * @param list $blocks + */ + private function __construct( + public readonly array $blocks, + ) {} + + public static function create( + UpdateCheckResult $result, + string $rootPackageName = null, + ): self { + $remainingBlocks = self::MAX_BLOCKS; + $remainingPackages = count($result->getOutdatedPackages()); + + // Create header block + $blocks = [ + self::createHeaderBlock($result), + ]; + + // Create package name block + if (null !== $rootPackageName) { + $blocks[] = self::createPackageNameBlock($rootPackageName); + } + + // Create outdated package blocks + foreach ($result->getOutdatedPackages() as $outdatedPackage) { + if (--$remainingBlocks > 0) { + $blocks[] = self::createOutdatedPackageBlock($outdatedPackage); + } else { + // Slack allows only a limited number of blocks, therefore + // we have to omit the remaining packages and show a message instead + $blocks[] = self::createMoreBlock($remainingPackages); + } + + --$remainingPackages; + } + + // Create security advisories block + if ($remainingBlocks > 4) { + $remainingSecurityAdvisories = count($result->getSecurityAdvisories()); + $remainingBlocks -= 2; + $blocks[] = Dto\SlackBlock::divider(); + $blocks[] = Dto\SlackBlock::header( + Dto\SlackBlockElement::plainText('Security advisories'), + ); + + foreach ($result->getSecurityAdvisories() as $securityAdvisory) { + if (--$remainingBlocks > 1) { + $blocks[] = self::createSecurityAdvisoryBlock($securityAdvisory); + } else { + // Slack allows only a limited number of blocks, therefore + // we have to omit the remaining security advisories and show a message instead + $blocks[] = self::createMoreBlock($remainingSecurityAdvisories); + } + + --$remainingSecurityAdvisories; + } + } + + // Create insecure packages block + if ($result->hasInsecureOutdatedPackages()) { + $blocks[] = Dto\SlackBlock::divider(); + $blocks[] = self::createInsecurePackagesBlock(); + } + + return new self($blocks); + } + + private static function createHeaderBlock(UpdateCheckResult $result): Dto\SlackBlock + { + $numberOfOutdatedPackages = 0; + $numberOfInsecurePackages = 0; + + // Count outdated and insecure packages + foreach ($result->getOutdatedPackages() as $outdatedPackage) { + ++$numberOfOutdatedPackages; + + if ($outdatedPackage->isInsecure()) { + ++$numberOfInsecurePackages; + } + } + + return Dto\SlackBlock::header( + Dto\SlackBlockElement::plainText( + sprintf( + '%d outdated%s package%s', + $numberOfOutdatedPackages, + $numberOfInsecurePackages > 0 ? sprintf(' (%d insecure)', $numberOfInsecurePackages) : '', + 1 !== $numberOfOutdatedPackages ? 's' : '', + ), + ), + ); + } + + private static function createPackageNameBlock(string $rootPackageName): Dto\SlackBlock + { + return Dto\SlackBlock::section( + Dto\SlackBlockElement::markdown( + sprintf('Project: *%s*', $rootPackageName), + ), + ); + } + + private static function createOutdatedPackageBlock(OutdatedPackage $outdatedPackage): Dto\SlackBlock + { + return Dto\SlackBlock::section( + fields: [ + Dto\SlackBlockElement::markdown( + sprintf( + '<%s|%s>', + $outdatedPackage->getProviderLink(), + $outdatedPackage->getName(), + ), + ), + Dto\SlackBlockElement::markdown( + sprintf( + "*Current version:* %s%s\n*New version:* %s", + $outdatedPackage->getOutdatedVersion()->get(), + $outdatedPackage->isInsecure() ? ' :warning:' : '', + $outdatedPackage->getNewVersion()->get(), + ), + ), + ], + ); + } + + private static function createSecurityAdvisoryBlock(SecurityAdvisory $securityAdvisory): Dto\SlackBlock + { + $textParts = [ + sprintf('*%s*', $securityAdvisory->getTitle()), + sprintf('• Package: `%s`', $securityAdvisory->getPackageName()), + sprintf('• Advisory ID: `%s`', $securityAdvisory->getAdvisoryId()), + sprintf( + '• Reported at: ``', + $securityAdvisory->getReportedAt()->getTimestamp(), + $securityAdvisory->getReportedAt()->format('Y-m-d H:i:s'), + ), + sprintf('• Severity: `%s`', $securityAdvisory->getSeverity()), + ]; + + if (null !== $securityAdvisory->getCVE()) { + $textParts[] = sprintf('• CVE: `%s`', $securityAdvisory->getCVE()); + } + + if (null !== $securityAdvisory->getLink()) { + $textParts[] = sprintf('<%s|Read more>', $securityAdvisory->getLink()); + } + + return Dto\SlackBlock::section( + Dto\SlackBlockElement::markdown( + implode(PHP_EOL, $textParts), + ), + ); + } + + private static function createMoreBlock(int $remaining): Dto\SlackBlock + { + return Dto\SlackBlock::section( + Dto\SlackBlockElement::markdown( + sprintf('_... and %d more_', $remaining), + ), + ); + } + + private static function createInsecurePackagesBlock(): Dto\SlackBlock + { + return Dto\SlackBlock::context( + elements: [ + Dto\SlackBlockElement::markdown( + 'Package versions marked with :warning: are insecure.', + ), + ], + ); + } + + /** + * @return array{ + * blocks: list, + * } + */ + public function jsonSerialize(): array + { + return [ + 'blocks' => $this->blocks, + ]; + } +} diff --git a/src/Reporter/SlackReporter.php b/src/Reporter/SlackReporter.php new file mode 100644 index 00000000..82a98812 --- /dev/null +++ b/src/Reporter/SlackReporter.php @@ -0,0 +1,109 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Reporter; + +use Composer\Composer; +use Composer\IO\IOInterface; +use EliasHaeussler\ComposerUpdateCheck\Entity\Report\SlackReport; +use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Psr7\Uri; +use GuzzleHttp\RequestOptions; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * SlackReporter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class SlackReporter implements Reporter +{ + public const NAME = 'slack'; + + private readonly OptionsResolver $resolver; + + public function __construct( + private readonly Client $client, + private readonly Composer $composer, + private readonly IOInterface $io, + ) { + $this->resolver = $this->createOptionsResolver(); + } + + public function report(UpdateCheckResult $result, array $options): bool + { + ['url' => $url] = $this->resolver->resolve($options); + + // Resolve root package name from composer.json + $rootPackageName = $this->composer->getPackage()->getName(); + if ('__root__' === $rootPackageName) { + $rootPackageName = null; + } + + // Create report + $report = SlackReport::create($result, $rootPackageName); + + // Send report + try { + $this->io->writeError('📤 Sending report to Slack... ', false, IOInterface::VERBOSE); + + $response = $this->client->post($url, [ + RequestOptions::JSON => $report, + ]); + $successful = 200 === $response->getStatusCode(); + } catch (GuzzleException) { + $successful = false; + } + + if ($successful) { + $this->io->writeError('Done', true, IOInterface::VERBOSE); + } else { + $this->io->writeError('Failed', true, IOInterface::VERBOSE); + } + + return $successful; + } + + public static function getName(): string + { + return self::NAME; + } + + private function createOptionsResolver(): OptionsResolver + { + $resolver = new OptionsResolver(); + + $resolver->define('url') + ->allowedTypes('string') + ->required() + ->normalize( + static fn (OptionsResolver $optionsResolver, string $url) => new Uri($url), + ) + ; + + return $resolver; + } +} From 3313abf2be1e175ebcb0fbda513cee26454cc8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Thu, 7 Dec 2023 22:26:03 +0100 Subject: [PATCH 041/286] [TASK] Validate configured reporters early --- src/UpdateChecker.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/UpdateChecker.php b/src/UpdateChecker.php index 07fc5212..c0e2f0c6 100644 --- a/src/UpdateChecker.php +++ b/src/UpdateChecker.php @@ -37,6 +37,7 @@ use EliasHaeussler\ComposerUpdateCheck\Reporter\ReporterFactory; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; +use function array_keys; use function array_map; use function array_merge; @@ -67,6 +68,8 @@ public function __construct( */ public function run(ComposerUpdateCheckConfig $config): UpdateCheckResult { + $this->validateReporters($config->getReporters()); + // Run update check [$packages, $excludedPackages] = $this->resolvePackagesForUpdateCheck($config); $result = $this->runUpdateCheck($packages, $excludedPackages); @@ -214,6 +217,19 @@ private function removeByExcludePatterns(array &$packages, array $excludePattern return $excludedPackages; } + /** + * @param array> $reporters + * + * @throws Exception\ReporterIsNotSupported + */ + private function validateReporters(array $reporters): void + { + foreach (array_keys($reporters) as $name) { + // Will throw an exception if reporter is not supported + $this->reporterFactory->make($name); + } + } + /** * @param array $packageNames * From 33abf3715fced5ee4c0b4656fa1d421155755317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 08:21:42 +0100 Subject: [PATCH 042/286] [!!!][TASK] Drop Docker integration --- .dockerignore | 18 ---- .gitattributes | 3 - .github/workflows/docker.yaml | 59 ------------- .github/workflows/tests.yaml | 18 ---- Dockerfile | 21 ----- bin/run-docker-tests.sh | 82 ------------------ docker/docker-entrypoint.sh | 20 ----- docker/install-composer.sh | 18 ---- docs/contribute.md | 16 ---- docs/docker.md | 154 ---------------------------------- mkdocs.yml | 1 - 11 files changed, 410 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .github/workflows/docker.yaml delete mode 100644 Dockerfile delete mode 100755 bin/run-docker-tests.sh delete mode 100755 docker/docker-entrypoint.sh delete mode 100755 docker/install-composer.sh delete mode 100644 docs/docker.md diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index dacc4034..00000000 --- a/.dockerignore +++ /dev/null @@ -1,18 +0,0 @@ -/.github -/bin -/docs -/tests -/.dockerignore -/.editorconfig -/.gitattributes -/.gitignore -/.php-cs-fixer.php -/codecov.yml -/composer.lock -/Dockerfile -/mkdocs.yml -/phpstan.php -/phpstan-baseline.neon -/phpunit.xml -/rector.php -/renovate.json diff --git a/.gitattributes b/.gitattributes index 43546061..298badd5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,19 +1,16 @@ * text=auto /.github export-ignore /bin export-ignore -/docker export-ignore /docs/build export-ignore /docs/theme export-ignore /docs/hooks.py export-ignore /tests export-ignore -/.dockerignore export-ignore /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.php-cs-fixer.php export-ignore /codecov.yml export-ignore /composer.lock export-ignore -/Dockerfile export-ignore /mkdocs.yml export-ignore /phpstan.php export-ignore /phpstan-baseline.neon export-ignore diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml deleted file mode 100644 index 0ab12b29..00000000 --- a/.github/workflows/docker.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: Docker deploy -on: - push: - tags: - - '*' - -jobs: - deploy: - name: Composer ${{ matrix.composer-version }} - if: startsWith(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - strategy: - matrix: - include: - - composer-version: 2 - tags: | - type=semver,pattern={{version}}-v2 - type=semver,pattern={{version}} - type=raw,value=v2 - latest: true - steps: - # Check if tag is valid - - name: Check tag - run: | - if ! [[ ${{ github.ref }} =~ ^refs/tags/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then - exit 1 - fi - - # Generate metadata - - name: Generate image metadata - id: meta - uses: docker/metadata-action@v4 - with: - images: eliashaeussler/composer-update-check - flavor: | - latest=${{ matrix.latest }} - tags: ${{ matrix.tags }} - - # Prepare build - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - # Login at Docker Hub - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - # Build and push image - - name: Build and push - uses: docker/build-push-action@v3 - with: - push: true - build-args: | - COMPOSER_VERSION=${{ matrix.composer-version }} - tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e03a61b5..99b46f37 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -94,24 +94,6 @@ jobs: fail_ci_if_error: true verbose: true - # Job: Run Docker tests - tests-docker: - name: Tests with Docker (PHP ${{ matrix.php-version }} & Composer ${{ matrix.composer-version }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - php-version: ["8.1", "8.2", "8.3"] - composer-version: ["2"] - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - # Run tests - - name: Run tests - run: ./bin/run-docker-tests.sh --composer-version "${{ matrix.composer-version }}" --php-version "${{ matrix.php-version }}" - # Job: Run unit tests of composer-update-reporter tests-reporter: name: Tests of eliashaeussler/composer-update-reporter diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f301e1a2..00000000 --- a/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -ARG PHP_VERSION=8.1 -FROM php:${PHP_VERSION}-alpine -LABEL maintainer="Elias Häußler " - -ARG COMPOSER_VERSION=2 - -# Install ssh client -RUN set -eux; apk add --no-cache openssh-client - -# Install Composer -ADD . /update-check -RUN /update-check/docker/install-composer.sh -RUN composer self-update --$COMPOSER_VERSION - -# Require update check package -RUN composer global config repositories.update-check path /update-check -RUN if [ "$COMPOSER_VERSION" = 2 ]; then composer global config allow-plugins.eliashaeussler/composer-update-check true; fi -RUN composer global require --dev "eliashaeussler/composer-update-check:*@dev" - -WORKDIR /app -ENTRYPOINT ["/update-check/docker/docker-entrypoint.sh"] diff --git a/bin/run-docker-tests.sh b/bin/run-docker-tests.sh deleted file mode 100755 index f0726361..00000000 --- a/bin/run-docker-tests.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env bash -set -e - -# Resolve variables -ROOT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)" -APP_PATH="${ROOT_PATH}/tests/Build" -PHP_VERSION="" -PHP_MAJOR_VERSION="" -COMPOSER_VERSION="" - -# Set PHP version from input -set_php_version() { - if [[ ! $1 =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then - echo >&2 "Please pass a valid PHP version using the \"--php-version\" argument." && exit 1 - fi - - PHP_VERSION="$(echo "$1" | cut -f1,2 -d".")" - PHP_MAJOR_VERSION="$(echo "$PHP_VERSION" | cut -f1 -d".")" -} - -# Print check mark with text -_check() { - echo -e "\xE2\x9C\x94 $1" -} - -# Resolve parameters -POSITIONAL=() -while [ $# -gt 0 ]; do - key="$1" - case ${key} in - -c|--composer-version) - COMPOSER_VERSION="$2" - shift - shift - ;; - -p|--php-version) - set_php_version "$2" - shift - shift - ;; - *) - POSITIONAL+=("$1") - shift - ;; - esac -done -set -- "${POSITIONAL[@]}" - -# Use current PHP version if it's not passed as command argument -if [ -z "$PHP_VERSION" ]; then - set_php_version "$(php -r 'echo PHP_VERSION;')" -fi - -# Ensure Composer version is specified -if [ -z "${COMPOSER_VERSION}" ]; then - echo >&2 "Please pass a valid Composer version using the \"--composer-version\" argument." && exit 1 -fi - -# Build Docker images -DOCKER_IMAGE="composer-update-check/test-${COMPOSER_VERSION}" -docker build \ - --build-arg COMPOSER_VERSION="${COMPOSER_VERSION}" \ - --build-arg PHP_VERSION="${PHP_VERSION}" \ - --tag "${DOCKER_IMAGE}" \ - --quiet \ - "${ROOT_PATH}" - -# Print build Docker image -_check "Successfully built Docker image: \"${DOCKER_IMAGE}\"" - -# Test Docker image in test applications -for testApplication in "${APP_PATH}/test-application/v${PHP_MAJOR_VERSION}" "${APP_PATH}/test-application-empty"; do - _check "Running update check for \"${testApplication#"$APP_PATH/"}\" (see output below)" - if [ $# -gt 0 ]; then - echo " Command options: $*" - fi - - echo - git clean -xdfq "${testApplication}" - docker run --rm -v "${testApplication}:/app" "${DOCKER_IMAGE}" --ansi "$@" - echo -done diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh deleted file mode 100755 index 2a1b0125..00000000 --- a/docker/docker-entrypoint.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env sh -set -e - -# Show deprecation warning -printf "\x1b[31m%s\x1b[0m\n" "Usage of this Docker image is deprecated and will be dropped with version 2.0.0." -printf "\x1b[31m%s\x1b[0m\n" "Consider using the Composer plugin \"eliashaeussler/composer-update-check\" instead." -echo - -# Add private SSH keys -eval "$(ssh-agent -s)" >/dev/null -if [ -d "${HOME}/.ssh" ]; then - for file in ${HOME}/.ssh/*; do - if grep -q PRIVATE "${file}"; then - ssh-add "${file}" - fi - done -fi - -# Run update check -composer update-check "$@" diff --git a/docker/install-composer.sh b/docker/install-composer.sh deleted file mode 100755 index a8efbae7..00000000 --- a/docker/install-composer.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env sh - -# Source: https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md - -EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')" -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" - -if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then - echo >&2 'ERROR: Invalid installer checksum' - rm composer-setup.php - exit 1 -fi - -php composer-setup.php --install-dir=/usr/local/bin --filename=composer -RESULT=$? -rm composer-setup.php -exit $RESULT diff --git a/docs/contribute.md b/docs/contribute.md index 6ba44c94..d95201e5 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -58,22 +58,6 @@ composer test composer test:coverage ``` -## :octicons-server-24: Run Docker tests - -All test applications can also be executed with the generated Docker -images. All available parameters for the `update-check` command can be passed. - -```bash -# Run tests for the Docker image using Composer 2.x -./bin/run-docker-tests.sh --composer-version 2 - -# Run tests for the Docker image using Composer 2.x and PHP 8.0 -./bin/run-docker-tests.sh --composer-version 2 --php-version "8.0" - -# Run tests with optional parameters -./bin/run-docker-tests.sh --composer-version 2 --security-scan --no-dev -``` - ## :technologist: Simulate application A Composer script `simulate` exists which lets you run the Composer diff --git a/docs/docker.md b/docs/docker.md deleted file mode 100644 index 6f780b64..00000000 --- a/docs/docker.md +++ /dev/null @@ -1,154 +0,0 @@ -# Docker image - -!!! attention - The Docker image is deprecated and will be dropped with version 2.0.0.
- Consider using the [Composer plugin](install.md) instead. - -The Composer plugin is also available as Docker image. This allows -its usage without explicitly requiring it in your project. It also -ensures the plugin can be safely used regardless of any requirements. - -## Available images - -You can choose from one of the following images, depending on the -Composer version you're using in your project: - -| Image | Composer version | Plugin version | -| ----- | ---------------- | -------------- | -| `eliashaeussler/composer-update-check:latest` | v2 | latest | -| `eliashaeussler/composer-update-check:-v2` | v2 | `` | -| `eliashaeussler/composer-update-check:v2` | v2 | latest | - -## Usage - -!!! important - Make sure to mount your project into the `/app` directory of the container. - -### General usage - -```bash -docker run --rm -it -v $(pwd):/app eliashaeussler/composer-update-check [options] -``` - -[:octicons-link-external-16: Available options](usage.md#command-line-usage) - -### Usage with docker-compose - -Example `docker-compose.yaml` file: - -```yaml -version: '3.6' - -services: - update-check: - image: eliashaeussler/composer-update-check - command: [] - volumes: - - ./:/app -``` - -Usage: - -```bash -docker-compose run --rm update-check [options] -``` - -## Handling SSH key authentication - -!!! attention - In case you need to authenticate yourself for specific packages - within your project, you have to add your SSH key(s) to the - container. - -Make sure to add all relevant SSH keys to the Docker container, -either by mounting the whole `.ssh` directory or by adding each -key on its own. - -The target directory inside the container is `/root/.ssh`. - -### Mount the whole `.ssh` directory - -#### General usage - -```bash -docker run --rm -it \ - -v $(pwd):/app \ - -v ~/.ssh:/root/.ssh \ - eliashaeussler/composer-update-check -``` - -#### Usage with docker-compose - -```yaml -version: '3.6' - -services: - update-check: - image: eliashaeussler/composer-update-check - volumes: - - ./:/app - - ~/.ssh:/root/.ssh -``` - -### Mount only relevant SSH keys - -!!! tip - In case you need multiple SSH keys for authentication, you're - free to mount each of them separately into the Container. This - can be achieved by declaring multiple volumes. - -#### General usage - -```bash -docker run --rm -it \ - -v $(pwd):/app \ - -v ~/.ssh/id_rsa:/root/.ssh/id_rsa \ - -v ~/.ssh/another_key:/root/.ssh/another_key \ - eliashaeussler/composer-update-check -``` - -#### Usage with docker-compose - -```yaml -version: '3.6' - -services: - update-check: - image: eliashaeussler/composer-update-check - volumes: - - ./:/app - - ~/.ssh/id_rsa:/root/.ssh/id_rsa - - ~/.ssh/another_key:/root/.ssh/another_key -``` - -### Provide `known_hosts` file - -Especially when running the Docker image in CI pipelines, it might -be helpful to additionally mount a `known_hosts` file into the -container. This ensures all target hosts don't need to be rescanned. - -The target file inside the container is `/root/.ssh/known_hosts`. - -#### General usage - -```bash -docker run --rm -it \ - -v $(pwd):/app \ - -v ~/.ssh/id_rsa:/root/.ssh/id_rsa \ - -v ~/.ssh/known_hosts:/root/.ssh/known_hosts \ - eliashaeussler/composer-update-check -``` - -#### Usage with docker-compose - -```yaml -version: '3.6' - -services: - update-check: - image: eliashaeussler/composer-update-check - volumes: - - ./:/app - - ~/.ssh/id_rsa:/root/.ssh/id_rsa - - ~/.ssh/known_hosts:/root/.ssh/known_hosts -``` diff --git a/mkdocs.yml b/mkdocs.yml index b7d98fa4..240cf874 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,7 +19,6 @@ nav: - Installation: install.md - Usage: usage.md - API: api.md - - 'Docker image': docker.md - Customization: - Events: events.md - Plugins: plugins.md From 85e39405067e44bde1d8831abee853513074db86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 08:22:45 +0100 Subject: [PATCH 043/286] [TASK] Remove tests of external composer-update-reporter package --- .github/workflows/tests.yaml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 99b46f37..792f66d1 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -93,22 +93,3 @@ jobs: directory: .build/coverage fail_ci_if_error: true verbose: true - - # Job: Run unit tests of composer-update-reporter - tests-reporter: - name: Tests of eliashaeussler/composer-update-reporter - runs-on: ubuntu-latest - if: ${{ github.actor != 'renovate[bot]' }} - steps: - - id: set-branch - run: echo "branch=${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}" >> $GITHUB_OUTPUT - - id: set-sha - run: echo "sha=${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}" >> $GITHUB_OUTPUT - - name: Trigger workflow - uses: benc-uk/workflow-dispatch@v1 - with: - workflow: 'Tests for composer-update-check' - token: ${{ secrets.PAT_REPORTER_TRIGGER }} - repo: eliashaeussler/composer-update-reporter - ref: 'main' - inputs: '{ "update-check-branch": "${{ steps.set-branch.outputs.branch }}", "update-check-sha": "${{ steps.set-sha.outputs.sha }}" }' From 0f4990b08222801db21f212b4bd461845d920c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 08:23:03 +0100 Subject: [PATCH 044/286] [TASK] Run GitHub workflows for PRs against main only --- .github/workflows/cgl.yaml | 2 ++ .github/workflows/tests.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/cgl.yaml b/.github/workflows/cgl.yaml index 72071fff..d61ba29c 100644 --- a/.github/workflows/cgl.yaml +++ b/.github/workflows/cgl.yaml @@ -4,6 +4,8 @@ on: branches: - main pull_request: + branches: + - main jobs: cgl: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 792f66d1..ca9006b4 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,6 +4,8 @@ on: branches: - main pull_request: + branches: + - main jobs: # Job: Run unit tests From d0422edaaeb3cb4e6d145e764bc885a8cdea81ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 08:32:07 +0100 Subject: [PATCH 045/286] [TASK] Align test directory with project template --- .gitignore | 8 ++++---- bin/simulate-application.sh | 2 +- composer.json | 8 ++++---- phpstan-baseline.neon | 4 ++-- phpstan.php | 4 ++-- tests/{Build => build}/phpstan/console-application.php | 0 .../{Build => build}/test-application-empty/composer.json | 0 .../test-application-erroneous/composer.json | 0 .../test-application-erroneous/composer.lock | 0 tests/{Build => build}/test-application/composer.json | 0 tests/{Build => build}/test-application/composer.lock | 0 tests/{Unit => src}/AbstractTestCase.php | 8 ++++---- tests/{Unit => src}/Command/UpdateCheckCommandTest.php | 6 +++--- tests/{Unit => src}/ExpectedCommandOutputTrait.php | 2 +- tests/{Unit => src}/IO/StyleTest.php | 4 ++-- tests/{Unit => src}/IO/VerbosityTest.php | 4 ++-- tests/{Unit => src}/OptionsTest.php | 2 +- tests/{Unit => src}/Package/OutdatedPackageTest.php | 4 ++-- tests/{Unit => src}/Package/UpdateCheckResultTest.php | 6 +++--- tests/{Unit => src}/Security/InsecurePackageTest.php | 4 ++-- tests/{Unit => src}/Security/ScanResultTest.php | 4 ++-- tests/{Unit => src}/Security/SecurityScannerTest.php | 4 ++-- tests/{Unit => src}/TestApplicationTrait.php | 2 +- tests/{Unit => src}/UpdateCheckerTest.php | 2 +- tests/{Unit => src}/Utility/ComposerTest.php | 4 ++-- tests/{Unit => src}/Utility/InstallerTest.php | 8 ++++---- tests/{Unit => src}/Utility/SecurityTest.php | 6 +++--- 27 files changed, 48 insertions(+), 48 deletions(-) rename tests/{Build => build}/phpstan/console-application.php (100%) rename tests/{Build => build}/test-application-empty/composer.json (100%) rename tests/{Build => build}/test-application-erroneous/composer.json (100%) rename tests/{Build => build}/test-application-erroneous/composer.lock (100%) rename tests/{Build => build}/test-application/composer.json (100%) rename tests/{Build => build}/test-application/composer.lock (100%) rename tests/{Unit => src}/AbstractTestCase.php (86%) rename tests/{Unit => src}/Command/UpdateCheckCommandTest.php (97%) rename tests/{Unit => src}/ExpectedCommandOutputTrait.php (96%) rename tests/{Unit => src}/IO/StyleTest.php (95%) rename tests/{Unit => src}/IO/VerbosityTest.php (96%) rename tests/{Unit => src}/OptionsTest.php (98%) rename tests/{Unit => src}/Package/OutdatedPackageTest.php (97%) rename tests/{Unit => src}/Package/UpdateCheckResultTest.php (96%) rename tests/{Unit => src}/Security/InsecurePackageTest.php (94%) rename tests/{Unit => src}/Security/ScanResultTest.php (97%) rename tests/{Unit => src}/Security/SecurityScannerTest.php (97%) rename tests/{Unit => src}/TestApplicationTrait.php (97%) rename tests/{Unit => src}/UpdateCheckerTest.php (99%) rename tests/{Unit => src}/Utility/ComposerTest.php (94%) rename tests/{Unit => src}/Utility/InstallerTest.php (92%) rename tests/{Unit => src}/Utility/SecurityTest.php (92%) diff --git a/.gitignore b/.gitignore index cba104b0..ee26090b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,8 @@ /.phpunit.result.cache /.build /docs/__pycache__ -/tests/Build/test-application/*/vendor -/tests/Build/test-application-empty/composer.lock -/tests/Build/test-application-empty/vendor -/tests/Build/test-application-erroneous/vendor +/tests/build/test-application/vendor +/tests/build/test-application-empty/composer.lock +/tests/build/test-application-empty/vendor +/tests/build/test-application-erroneous/vendor /site diff --git a/bin/simulate-application.sh b/bin/simulate-application.sh index 0cd445de..374b5f25 100755 --- a/bin/simulate-application.sh +++ b/bin/simulate-application.sh @@ -3,7 +3,7 @@ set -e # Resolve variables ROOT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)" -APP_PATH="${ROOT_PATH}/tests/Build/test-application" +APP_PATH="${ROOT_PATH}/tests/build/test-application" TEMP_DIR="/tmp" # Check if temp directory is writeable diff --git a/composer.json b/composer.json index 724d1a07..200db6cc 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ }, "autoload-dev": { "psr-4": { - "EliasHaeussler\\ComposerUpdateCheck\\Tests\\": "tests" + "EliasHaeussler\\ComposerUpdateCheck\\Tests\\": "tests/src" } }, "config": { @@ -91,9 +91,9 @@ ], "fix:composer": [ "@composer normalize", - "@composer normalize tests/Build/test-application/composer.json", - "@composer normalize tests/Build/test-application-empty/composer.json", - "@composer normalize tests/Build/test-application-erroneous/composer.json --no-check-lock --no-update-lock" + "@composer normalize tests/build/test-application/composer.json", + "@composer normalize tests/build/test-application-empty/composer.json", + "@composer normalize tests/build/test-application-erroneous/composer.json --no-check-lock --no-update-lock" ], "fix:editorconfig": "@lint:editorconfig --fix", "fix:php": "php-cs-fixer fix", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 757016aa..9dc9b32b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6,6 +6,6 @@ parameters: path: src/Composer/ComposerInstaller.php - - message: "#^Variable property access on \\$this\\(EliasHaeussler\\\\ComposerUpdateCheck\\\\Tests\\\\Unit\\\\AbstractTestCase\\)\\.$#" + message: "#^Variable property access on \\$this\\(EliasHaeussler\\\\ComposerUpdateCheck\\\\Tests\\\\AbstractTestCase\\)\\.$#" count: 1 - path: tests/Unit/AbstractTestCase.php + path: tests/src/AbstractTestCase.php diff --git a/phpstan.php b/phpstan.php index 2f774433..2a3a9af1 100644 --- a/phpstan.php +++ b/phpstan.php @@ -28,7 +28,7 @@ $containerXmlFile = $container->getParameter('debug.container_xml_filename'); $symfonySet = PHPStanConfig\Set\SymfonySet::create() - ->withConsoleApplicationLoader('Tests/Build/phpstan/console-application.php') + ->withConsoleApplicationLoader('Tests/build/phpstan/console-application.php') ->withContainerXmlPath($containerXmlFile) ; @@ -38,7 +38,7 @@ 'tests', ) ->not( - 'tests/Build/*', + 'tests/build/*', ) ->withBaseline() ->maxLevel() diff --git a/tests/Build/phpstan/console-application.php b/tests/build/phpstan/console-application.php similarity index 100% rename from tests/Build/phpstan/console-application.php rename to tests/build/phpstan/console-application.php diff --git a/tests/Build/test-application-empty/composer.json b/tests/build/test-application-empty/composer.json similarity index 100% rename from tests/Build/test-application-empty/composer.json rename to tests/build/test-application-empty/composer.json diff --git a/tests/Build/test-application-erroneous/composer.json b/tests/build/test-application-erroneous/composer.json similarity index 100% rename from tests/Build/test-application-erroneous/composer.json rename to tests/build/test-application-erroneous/composer.json diff --git a/tests/Build/test-application-erroneous/composer.lock b/tests/build/test-application-erroneous/composer.lock similarity index 100% rename from tests/Build/test-application-erroneous/composer.lock rename to tests/build/test-application-erroneous/composer.lock diff --git a/tests/Build/test-application/composer.json b/tests/build/test-application/composer.json similarity index 100% rename from tests/Build/test-application/composer.json rename to tests/build/test-application/composer.json diff --git a/tests/Build/test-application/composer.lock b/tests/build/test-application/composer.lock similarity index 100% rename from tests/Build/test-application/composer.lock rename to tests/build/test-application/composer.lock diff --git a/tests/Unit/AbstractTestCase.php b/tests/src/AbstractTestCase.php similarity index 86% rename from tests/Unit/AbstractTestCase.php rename to tests/src/AbstractTestCase.php index b4fc7102..e93034b1 100644 --- a/tests/Unit/AbstractTestCase.php +++ b/tests/src/AbstractTestCase.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; +namespace EliasHaeussler\ComposerUpdateCheck\Tests; use PHPUnit\Framework\TestCase; use ReflectionClass; @@ -34,9 +34,9 @@ */ abstract class AbstractTestCase extends TestCase { - final public const TEST_APPLICATION_NORMAL = 'tests/Build/test-application'; - final public const TEST_APPLICATION_EMPTY = 'tests/Build/test-application-empty'; - final public const TEST_APPLICATION_ERRONEOUS = 'tests/Build/test-application-erroneous'; + final public const TEST_APPLICATION_NORMAL = 'tests/build/test-application'; + final public const TEST_APPLICATION_EMPTY = 'tests/build/test-application-empty'; + final public const TEST_APPLICATION_ERRONEOUS = 'tests/build/test-application-erroneous'; protected function tearDown(): void { diff --git a/tests/Unit/Command/UpdateCheckCommandTest.php b/tests/src/Command/UpdateCheckCommandTest.php similarity index 97% rename from tests/Unit/Command/UpdateCheckCommandTest.php rename to tests/src/Command/UpdateCheckCommandTest.php index 09aa61bf..84a8944c 100644 --- a/tests/Unit/Command/UpdateCheckCommandTest.php +++ b/tests/src/Command/UpdateCheckCommandTest.php @@ -21,12 +21,12 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Command; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Command; use Composer\Console\Application; use EliasHaeussler\ComposerUpdateCheck\Command\UpdateCheckCommand; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\TestApplicationTrait; use PHPUnit\Framework\Attributes\Test; use Symfony\Component\Console\Tester\CommandTester; diff --git a/tests/Unit/ExpectedCommandOutputTrait.php b/tests/src/ExpectedCommandOutputTrait.php similarity index 96% rename from tests/Unit/ExpectedCommandOutputTrait.php rename to tests/src/ExpectedCommandOutputTrait.php index 9b1d7d5d..51bf122c 100644 --- a/tests/Unit/ExpectedCommandOutputTrait.php +++ b/tests/src/ExpectedCommandOutputTrait.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; +namespace EliasHaeussler\ComposerUpdateCheck\Tests; /** * ExpectedCommandOutputTrait. diff --git a/tests/Unit/IO/StyleTest.php b/tests/src/IO/StyleTest.php similarity index 95% rename from tests/Unit/IO/StyleTest.php rename to tests/src/IO/StyleTest.php index 844e5760..83a681af 100644 --- a/tests/Unit/IO/StyleTest.php +++ b/tests/src/IO/StyleTest.php @@ -21,10 +21,10 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\IO; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\IO; use EliasHaeussler\ComposerUpdateCheck\IO\Style; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use Generator; use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/IO/VerbosityTest.php b/tests/src/IO/VerbosityTest.php similarity index 96% rename from tests/Unit/IO/VerbosityTest.php rename to tests/src/IO/VerbosityTest.php index 3efceb17..93fcd0e8 100644 --- a/tests/Unit/IO/VerbosityTest.php +++ b/tests/src/IO/VerbosityTest.php @@ -21,10 +21,10 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\IO; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\IO; use EliasHaeussler\ComposerUpdateCheck\IO\Verbosity; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use Generator; use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/OptionsTest.php b/tests/src/OptionsTest.php similarity index 98% rename from tests/Unit/OptionsTest.php rename to tests/src/OptionsTest.php index 389c902a..5f822de2 100644 --- a/tests/Unit/OptionsTest.php +++ b/tests/src/OptionsTest.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; +namespace EliasHaeussler\ComposerUpdateCheck\Tests; use EliasHaeussler\ComposerUpdateCheck\Options; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Package/OutdatedPackageTest.php b/tests/src/Package/OutdatedPackageTest.php similarity index 97% rename from tests/Unit/Package/OutdatedPackageTest.php rename to tests/src/Package/OutdatedPackageTest.php index a6f4617e..95f30b6e 100644 --- a/tests/Unit/Package/OutdatedPackageTest.php +++ b/tests/src/Package/OutdatedPackageTest.php @@ -21,10 +21,10 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use Nyholm\Psr7\Uri; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Package/UpdateCheckResultTest.php b/tests/src/Package/UpdateCheckResultTest.php similarity index 96% rename from tests/Unit/Package/UpdateCheckResultTest.php rename to tests/src/Package/UpdateCheckResultTest.php index 9e4d8c57..d143c318 100644 --- a/tests/Unit/Package/UpdateCheckResultTest.php +++ b/tests/src/Package/UpdateCheckResultTest.php @@ -21,12 +21,12 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Package; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Package; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\ExpectedCommandOutputTrait; use Generator; use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Security/InsecurePackageTest.php b/tests/src/Security/InsecurePackageTest.php similarity index 94% rename from tests/Unit/Security/InsecurePackageTest.php rename to tests/src/Security/InsecurePackageTest.php index ef06d2ff..2f83b9dd 100644 --- a/tests/Unit/Security/InsecurePackageTest.php +++ b/tests/src/Security/InsecurePackageTest.php @@ -21,10 +21,10 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Security; use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use PHPUnit\Framework\Attributes\Test; /** diff --git a/tests/Unit/Security/ScanResultTest.php b/tests/src/Security/ScanResultTest.php similarity index 97% rename from tests/Unit/Security/ScanResultTest.php rename to tests/src/Security/ScanResultTest.php index 904cad71..1a8a82e9 100644 --- a/tests/Unit/Security/ScanResultTest.php +++ b/tests/src/Security/ScanResultTest.php @@ -21,12 +21,12 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Security; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Entity\Security\SecurityAdvisory; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use Generator; use InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Security/SecurityScannerTest.php b/tests/src/Security/SecurityScannerTest.php similarity index 97% rename from tests/Unit/Security/SecurityScannerTest.php rename to tests/src/Security/SecurityScannerTest.php index 6e3005b9..45f6c8aa 100644 --- a/tests/Unit/Security/SecurityScannerTest.php +++ b/tests/src/Security/SecurityScannerTest.php @@ -21,12 +21,12 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Security; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Security; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\ScanResult; use EliasHaeussler\ComposerUpdateCheck\Security\SecurityScanner; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use Http\Client\Exception\TransferException; use Http\Message\RequestMatcher\CallbackRequestMatcher; use Http\Mock\Client; diff --git a/tests/Unit/TestApplicationTrait.php b/tests/src/TestApplicationTrait.php similarity index 97% rename from tests/Unit/TestApplicationTrait.php rename to tests/src/TestApplicationTrait.php index 7db738ae..7cbd8aa0 100644 --- a/tests/Unit/TestApplicationTrait.php +++ b/tests/src/TestApplicationTrait.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; +namespace EliasHaeussler\ComposerUpdateCheck\Tests; use Symfony\Component\Filesystem\Filesystem; diff --git a/tests/Unit/UpdateCheckerTest.php b/tests/src/UpdateCheckerTest.php similarity index 99% rename from tests/Unit/UpdateCheckerTest.php rename to tests/src/UpdateCheckerTest.php index 0f262118..32d44225 100644 --- a/tests/Unit/UpdateCheckerTest.php +++ b/tests/src/UpdateCheckerTest.php @@ -21,7 +21,7 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit; +namespace EliasHaeussler\ComposerUpdateCheck\Tests; use Composer\Composer; use Composer\Console\Application; diff --git a/tests/Unit/Utility/ComposerTest.php b/tests/src/Utility/ComposerTest.php similarity index 94% rename from tests/Unit/Utility/ComposerTest.php rename to tests/src/Utility/ComposerTest.php index b8382068..fe9acec9 100644 --- a/tests/Unit/Utility/ComposerTest.php +++ b/tests/src/Utility/ComposerTest.php @@ -21,10 +21,10 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Utility; use Composer\Plugin\PluginInterface; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; use EliasHaeussler\ComposerUpdateCheck\Utility\Composer; use InvalidArgumentException; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Utility/InstallerTest.php b/tests/src/Utility/InstallerTest.php similarity index 92% rename from tests/Unit/Utility/InstallerTest.php rename to tests/src/Utility/InstallerTest.php index 657a3e26..696641e4 100644 --- a/tests/Unit/Utility/InstallerTest.php +++ b/tests/src/Utility/InstallerTest.php @@ -21,14 +21,14 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Utility; use Composer\Console\Application; use Composer\Json\JsonValidationException; use EliasHaeussler\ComposerUpdateCheck\Composer\ComposerInstaller; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\ExpectedCommandOutputTrait; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\ExpectedCommandOutputTrait; +use EliasHaeussler\ComposerUpdateCheck\Tests\TestApplicationTrait; use Generator; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; diff --git a/tests/Unit/Utility/SecurityTest.php b/tests/src/Utility/SecurityTest.php similarity index 92% rename from tests/Unit/Utility/SecurityTest.php rename to tests/src/Utility/SecurityTest.php index f5dc57dc..b79f2c40 100644 --- a/tests/Unit/Utility/SecurityTest.php +++ b/tests/src/Utility/SecurityTest.php @@ -21,12 +21,12 @@ * along with this program. If not, see . */ -namespace EliasHaeussler\ComposerUpdateCheck\Tests\Unit\Utility; +namespace EliasHaeussler\ComposerUpdateCheck\Tests\Utility; use EliasHaeussler\ComposerUpdateCheck\Entity\Package\OutdatedPackage; use EliasHaeussler\ComposerUpdateCheck\Entity\Result\UpdateCheckResult; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\AbstractTestCase; -use EliasHaeussler\ComposerUpdateCheck\Tests\Unit\TestApplicationTrait; +use EliasHaeussler\ComposerUpdateCheck\Tests\AbstractTestCase; +use EliasHaeussler\ComposerUpdateCheck\Tests\TestApplicationTrait; use EliasHaeussler\ComposerUpdateCheck\Utility\Security; use PHPUnit\Framework\Attributes\Test; From b504af26dee06e6e50e05d1a0c85f7d3d889e27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 08:38:19 +0100 Subject: [PATCH 046/286] [TASK] Enable Rector migration for Symfony components --- rector.php | 16 ++++++++++++++++ src/DependencyInjection/ContainerFactory.php | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/rector.php b/rector.php index 65bb5cde..b889ba28 100644 --- a/rector.php +++ b/rector.php @@ -22,9 +22,12 @@ */ use EliasHaeussler\RectorConfig\Config\Config; +use EliasHaeussler\RectorConfig\Entity\Version; use Rector\Config\RectorConfig; use Rector\Core\ValueObject\PhpVersion; use Rector\Php80\Rector\Class_\AnnotationToAttributeRector; +use Rector\Symfony\Symfony42\Rector\MethodCall\ContainerGetToConstructorInjectionRector; +use Rector\Symfony\Symfony53\Rector\Class_\CommandDescriptionToPropertyRector; return static function (RectorConfig $rectorConfig): void { Config::create($rectorConfig, PhpVersion::PHP_81) @@ -32,6 +35,7 @@ __DIR__.'/src', __DIR__.'/tests', ) + ->withSymfony(Version::createMinor(5, 4)) ->withPHPUnit() ->skip( AnnotationToAttributeRector::class, @@ -41,6 +45,18 @@ __DIR__.'/src/Plugin.php', ], ) + ->skip( + CommandDescriptionToPropertyRector::class, + [ + __DIR__.'/src/Command/UpdateCheckCommand.php', + ], + ) + ->skip( + ContainerGetToConstructorInjectionRector::class, + [ + __DIR__.'/src/Plugin.php', + ], + ) ->apply() ; }; diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index 0c68aaf6..45dcd67d 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -85,7 +85,7 @@ public function make(bool $debug = false): ContainerInterface $container->addCompilerPass(new ContainerBuilderDebugDumpPass($containerXmlFilename)); } - $container->compile(); + $container->compile(true); return $container; } From f43d4b319e0c6836b130e16e3a766d6b0f00f924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 08:41:44 +0100 Subject: [PATCH 047/286] [TASK] Rename PackageExcludePattern named constructors --- src/Configuration/Adapter/CommandInputConfigAdapter.php | 4 ++-- src/Configuration/ComposerUpdateCheckConfig.php | 4 ++-- src/Configuration/Options/PackageExcludePattern.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Configuration/Adapter/CommandInputConfigAdapter.php b/src/Configuration/Adapter/CommandInputConfigAdapter.php index 75ef5b49..fd6022be 100644 --- a/src/Configuration/Adapter/CommandInputConfigAdapter.php +++ b/src/Configuration/Adapter/CommandInputConfigAdapter.php @@ -74,9 +74,9 @@ public function resolve(): ComposerUpdateCheckConfig private function resolveExcludePattern(string $pattern): PackageExcludePattern { if (str_starts_with($pattern, '/') || str_starts_with($pattern, '#')) { - return PackageExcludePattern::regex($pattern); + return PackageExcludePattern::byRegularExpression($pattern); } - return PackageExcludePattern::name($pattern); + return PackageExcludePattern::byName($pattern); } } diff --git a/src/Configuration/ComposerUpdateCheckConfig.php b/src/Configuration/ComposerUpdateCheckConfig.php index 8120a884..ffec9bc7 100644 --- a/src/Configuration/ComposerUpdateCheckConfig.php +++ b/src/Configuration/ComposerUpdateCheckConfig.php @@ -48,14 +48,14 @@ public function __construct( public function excludePackageByName(string $name): self { - $this->excludePatterns[] = PackageExcludePattern::name($name); + $this->excludePatterns[] = PackageExcludePattern::byName($name); return $this; } public function excludePackageByRegex(string $regex): self { - $this->excludePatterns[] = PackageExcludePattern::regex($regex); + $this->excludePatterns[] = PackageExcludePattern::byRegularExpression($regex); return $this; } diff --git a/src/Configuration/Options/PackageExcludePattern.php b/src/Configuration/Options/PackageExcludePattern.php index 6548ae38..911d904c 100644 --- a/src/Configuration/Options/PackageExcludePattern.php +++ b/src/Configuration/Options/PackageExcludePattern.php @@ -47,14 +47,14 @@ private function __construct(callable $matchFunction) $this->matchFunction = $matchFunction; } - public static function name(string $name): self + public static function byName(string $name): self { return new self( static fn (string $packageName) => fnmatch($name, $packageName), ); } - public static function regex(string $regex): self + public static function byRegularExpression(string $regex): self { return new self( static fn (string $packageName) => 1 === preg_match($regex, $packageName), From 18cc845af7ce2ce520cb27b6102c2572bf789b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20H=C3=A4u=C3=9Fler?= Date: Fri, 8 Dec 2023 09:16:53 +0100 Subject: [PATCH 048/286] [FEATURE] Add support for configuration with environment variables --- src/Command/UpdateCheckCommand.php | 15 +- .../Adapter/CommandInputConfigAdapter.php | 12 +- .../EnvironmentVariablesConfigAdapter.php | 172 ++++++++++++++++++ .../Options/PackageExcludePattern.php | 10 + 4 files changed, 193 insertions(+), 16 deletions(-) create mode 100644 src/Configuration/Adapter/EnvironmentVariablesConfigAdapter.php diff --git a/src/Command/UpdateCheckCommand.php b/src/Command/UpdateCheckCommand.php index 78410848..6a654694 100644 --- a/src/Command/UpdateCheckCommand.php +++ b/src/Command/UpdateCheckCommand.php @@ -29,6 +29,7 @@ use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\ChainedConfigAdapter; use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\CommandInputConfigAdapter; use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\ConfigAdapterFactory; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter\EnvironmentVariablesConfigAdapter; use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; use EliasHaeussler\ComposerUpdateCheck\Exception\ConfigFileHasErrors; use EliasHaeussler\ComposerUpdateCheck\IO\Formatter\FormatterFactory; @@ -39,6 +40,7 @@ use Symfony\Component\Console\Style\SymfonyStyle; use function array_map; +use function array_unshift; use function sprintf; /** @@ -120,16 +122,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function resolveConfiguration(InputInterface $input): ComposerUpdateCheckConfig { $filename = $input->getOption('config'); - $configAdapter = new CommandInputConfigAdapter($input); + $adapters = [ + new CommandInputConfigAdapter($input), + new EnvironmentVariablesConfigAdapter(), + ]; if (null !== $filename && '' !== $filename) { $configAdapterFactory = new ConfigAdapterFactory(); - $configAdapter = new ChainedConfigAdapter([ - $configAdapterFactory->make($filename), - $configAdapter, - ]); + + array_unshift($adapters, $configAdapterFactory->make($filename)); } + $configAdapter = new ChainedConfigAdapter($adapters); + return $configAdapter->resolve(); } diff --git a/src/Configuration/Adapter/CommandInputConfigAdapter.php b/src/Configuration/Adapter/CommandInputConfigAdapter.php index fd6022be..3b8fe3f8 100644 --- a/src/Configuration/Adapter/CommandInputConfigAdapter.php +++ b/src/Configuration/Adapter/CommandInputConfigAdapter.php @@ -28,7 +28,6 @@ use Symfony\Component\Console\Input\InputInterface; use function is_string; -use function str_starts_with; /** * CommandInputConfigAdapter. @@ -51,7 +50,7 @@ public function resolve(): ComposerUpdateCheckConfig $excludePatterns = $this->input->getOption('ignore-packages'); foreach ($excludePatterns as $pattern) { - $excludePattern = $this->resolveExcludePattern($pattern); + $excludePattern = PackageExcludePattern::create($pattern); $config->excludePackageByPattern($excludePattern); } } @@ -70,13 +69,4 @@ public function resolve(): ComposerUpdateCheckConfig return $config; } - - private function resolveExcludePattern(string $pattern): PackageExcludePattern - { - if (str_starts_with($pattern, '/') || str_starts_with($pattern, '#')) { - return PackageExcludePattern::byRegularExpression($pattern); - } - - return PackageExcludePattern::byName($pattern); - } } diff --git a/src/Configuration/Adapter/EnvironmentVariablesConfigAdapter.php b/src/Configuration/Adapter/EnvironmentVariablesConfigAdapter.php new file mode 100644 index 00000000..300808df --- /dev/null +++ b/src/Configuration/Adapter/EnvironmentVariablesConfigAdapter.php @@ -0,0 +1,172 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +namespace EliasHaeussler\ComposerUpdateCheck\Configuration\Adapter; + +use EliasHaeussler\ComposerUpdateCheck\Configuration\ComposerUpdateCheckConfig; +use EliasHaeussler\ComposerUpdateCheck\Configuration\Options\PackageExcludePattern; +use Generator; + +use function array_filter; +use function explode; +use function getenv; +use function preg_match; +use function sprintf; +use function str_starts_with; +use function strtolower; +use function trim; + +/** + * EnvironmentVariablesConfigAdapter. + * + * @author Elias Häußler + * @license GPL-3.0-or-later + */ +final class EnvironmentVariablesConfigAdapter implements ConfigAdapter +{ + private const ENV_VAR_PREFIX = 'COMPOSER_UPDATE_CHECK_'; + + public function resolve(): ComposerUpdateCheckConfig + { + $config = new ComposerUpdateCheckConfig(); + + // Exclude patterns + $excludePatterns = $this->getEnv('EXCLUDE_PATTERNS', true); + foreach ($excludePatterns as $excludePattern) { + $config->excludePackageByPattern(PackageExcludePattern::create($excludePattern)); + } + + // Include dev packages + $noDev = $this->getEnv('NO_DEV'); + if ($this->isTrue($noDev)) { + $config->excludeDevPackages(); + } + + // Perform security scan + $securityScan = $this->getEnv('SECURITY_SCAN'); + if ($this->isTrue($securityScan)) { + $config->performSecurityScan(); + } + + // Format + $format = $this->getEnv('FORMAT'); + if (null !== $format) { + $config->setFormat($format); + } + + // Reporters + foreach ($this->getReporterEnvVariables() as $name => $reporterConfig) { + if ($reporterConfig['enable']) { + $config->enableReporter($name, $reporterConfig['options'] ?? []); + } else { + $config->disableReporter($name); + } + } + + return $config; + } + + /** + * @phpstan-return ($list is true ? array : string|null) + */ + private function getEnv(string $name, bool $list = false): string|array|null + { + $value = getenv(self::ENV_VAR_PREFIX.$name); + + if (false === $value || '' === trim($value)) { + return $list ? [] : null; + } + + if (!$list) { + return $value; + } + + return explode(',', $value); + } + + /** + * @return Generator}> + */ + private function getReporterEnvVariables(): Generator + { + $reporterConfig = []; + $envVarPrefix = self::ENV_VAR_PREFIX.'REPORTER_'; + $envVarPattern = sprintf('/^%s_(?P[^_]+)_(?P