diff --git a/CHANGELOG.md b/CHANGELOG.md index d8fcb764..aa8408dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ To get the diff between two versions, go to https://github.com/SonsOfPHP/sonsofp ## [Unreleased] +* [PR #228](https://github.com/SonsOfPHP/sonsofphp/pull/228) [Bard] Various updates * [PR #227](https://github.com/SonsOfPHP/sonsofphp/pull/227) [Cache] FilesystemAdapter, Marshallers, and other updates * [PR #226](https://github.com/SonsOfPHP/sonsofphp/pull/226) [Registry] New Component and Contract * [PR #225](https://github.com/SonsOfPHP/sonsofphp/pull/225) Maintenance diff --git a/composer.json b/composer.json index ef7944b4..ccc87b3f 100644 --- a/composer.json +++ b/composer.json @@ -33,163 +33,131 @@ } ], "provide": { - "psr/event-dispatcher-implementation": "1.0", + "psr/cache-implementation": "^2.0 || ^3.0", "psr/clock-implementation": "1.0", - "psr/http-message-implementation": "^1.0 || ^2.0", + "psr/container-implementation": "^1.0 || ^2.0", + "psr/event-dispatcher-implementation": "1.0", "psr/http-factory-implementation": "^1.0", - "psr/cache-implementation": "^2.0 || ^3.0", - "psr/simple-cache-implementation": "^1.0 || ^2.0 || ^3.0", + "psr/http-message-implementation": "^1.0 || ^2.0", + "psr/http-server-handler-implementation": "^1.0", + "psr/http-server-middleware-implementation": "^1.0", + "psr/link-implementation": "^1.0 || ^2.0", + "psr/log-implementation": "^1.0 || ^2.0 || ^3.0", + "psr/simple-cache-implementation": "^2.0 || ^3.0", + "sonsofphp/cookie-implementation": "0.3.x-dev", "sonsofphp/cqrs-implementation": "0.3.x-dev", "sonsofphp/event-sourcing-implementation": "0.3.x-dev", "sonsofphp/feature-toggle-implementation": "0.3.x-dev", "sonsofphp/filesystem-implementation": "0.3.x-dev", - "sonsofphp/money-implementation": "0.3.x-dev", - "sonsofphp/version-implementation": "0.3.x-dev", - "psr/log-implementation": "^1.0 || ^2.0 || ^3.0", - "sonsofphp/logger-implementation": "0.3.x-dev", - "sonsofphp/pager-implementation": "0.3.x-dev", - "psr/link-implementation": "^1.0 || ^2.0", - "sonsofphp/cookie-implementation": "0.3.x-dev", - "psr/container-implementation": "^1.0 || ^2.0", - "psr/http-server-handler-implementation": "^1.0", - "psr/http-server-middleware-implementation": "^1.0", "sonsofphp/http-handler-implementation": "0.3.x-dev", + "sonsofphp/logger-implementation": "0.3.x-dev", "sonsofphp/mailer-implementation": "0.3.x-dev", + "sonsofphp/money-implementation": "0.3.x-dev", + "sonsofphp/pager-implementation": "0.3.x-dev", + "sonsofphp/registry-implementation": "0.3.x-dev", "sonsofphp/state-machine-implementation": "0.3.x-dev", - "sonsofphp/registry-implementation": "0.3.x-dev" + "sonsofphp/version-implementation": "0.3.x-dev" }, "require": { - "php": ">=8.2", + "aws/aws-sdk-php": "^3.0", + "doctrine/collections": "^2", + "doctrine/dbal": "^3", + "doctrine/orm": "^2 || ^3", + "ext-intl": "*", "ext-json": "*", + "liip/imagine-bundle": "^2.0", + "php": ">=8.2", + "psr/cache": "^2.0 || ^3.0", + "psr/clock": "^1.0", + "psr/container": "^1.0 || ^2.0", "psr/event-dispatcher": "^1.0", - "doctrine/dbal": "^3", - "symfony/options-resolver": "^6 || ^7", - "symfony/uid": "^5 || ^6 || ^7", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/link": "^1.0 || ^2.0", + "psr/log": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sonsofphp/cookie-contract": "0.3.x-dev", + "sonsofphp/cqrs-contract": "0.3.x-dev", + "sonsofphp/event-dispatcher": "0.3.x-dev", + "sonsofphp/event-sourcing": "^0.3.x-dev", + "sonsofphp/event-sourcing-contract": "^0.3.x-dev", + "sonsofphp/feature-toggle-contract": "0.3.x-dev", + "sonsofphp/http-handler-contract": "0.3.x-dev", + "sonsofphp/http-message": "^0.3.x-dev", + "sonsofphp/json": "^0.3.x-dev", + "sonsofphp/logger": "^0.3.x-dev", + "sonsofphp/logger-contract": "0.3.x-dev", + "sonsofphp/money": "^0.3.x-dev", + "sonsofphp/money-contract": "0.3.x-dev", + "sonsofphp/pager-contract": "0.3.x-dev", + "sonsofphp/registry-contract": "0.3.x-dev", + "sonsofphp/state-machine-contract": "0.3.x-dev", + "sonsofphp/version": "^0.3.x-dev", + "sonsofphp/version-contract": "0.3.x-dev", "symfony/console": "^4 || ^5 || ^6 || ^7", + "symfony/dependency-injection": "^5 || ^6 || ^7", "symfony/dotenv": "^5 || ^6 || ^7", "symfony/finder": "^5 || ^6 || ^7", - "symfony/process": "^5 || ^6 || ^7", - "symfony/dependency-injection": "^5 || ^6 || ^7", "symfony/http-kernel": "^5 || ^6 || ^7", - "symfony/security-bundle": "^6 || ^7", "symfony/messenger": "^5 || ^6 || ^7", - "psr/clock": "^1.0", - "psr/http-message": "^1.0 || ^2.0", - "psr/http-factory": "^1.0", - "psr/cache": "^2.0 || ^3.0", - "psr/simple-cache": "^3.0", - "psr/log": "^2.0 || ^3.0", - "psr/link": "^1.0 || ^2.0", - "twig/twig": "^3.0", - "ext-intl": "*", - "doctrine/collections": "^2", - "doctrine/orm": "^2 || ^3", - "psr/container": "^1.0 || ^2.0", - "psr/http-server-handler": "^1.0", - "psr/http-server-middleware": "^1.0", - "aws/aws-sdk-php": "^3.0", - "liip/imagine-bundle": "^2.0" + "symfony/options-resolver": "^6 || ^7", + "symfony/process": "^5 || ^6 || ^7", + "symfony/security-bundle": "^6 || ^7", + "symfony/uid": "^5 || ^6 || ^7", + "twig/twig": "^3.0" }, "replace": { + "sonsofphp/assert": "self.version", "sonsofphp/bard": "self.version", + "sonsofphp/cache": "self.version", "sonsofphp/clock": "self.version", + "sonsofphp/common-contract": "self.version", + "sonsofphp/container": "self.version", + "sonsofphp/cookie": "self.version", + "sonsofphp/cookie-contract": "self.version", "sonsofphp/cqrs": "self.version", + "sonsofphp/cqrs-bundle": "self.version", + "sonsofphp/cqrs-contract": "self.version", "sonsofphp/cqrs-symfony": "self.version", "sonsofphp/event-dispatcher": "self.version", "sonsofphp/event-sourcing": "self.version", + "sonsofphp/event-sourcing-contract": "self.version", "sonsofphp/event-sourcing-doctrine": "self.version", "sonsofphp/event-sourcing-symfony": "self.version", "sonsofphp/feature-toggle": "self.version", - "sonsofphp/json": "self.version", - "sonsofphp/money": "self.version", - "sonsofphp/version": "self.version", - "sonsofphp/cqrs-bundle": "self.version", - "sonsofphp/filesystem": "self.version", - "sonsofphp/http-message": "self.version", - "sonsofphp/http-factory": "self.version", - "sonsofphp/core-contract": "self.version", - "sonsofphp/cache": "self.version", - "sonsofphp/cqrs-contract": "self.version", - "sonsofphp/event-sourcing-contract": "self.version", "sonsofphp/feature-toggle-contract": "self.version", + "sonsofphp/filesystem": "self.version", + "sonsofphp/filesystem-aws": "self.version", "sonsofphp/filesystem-contract": "self.version", - "sonsofphp/money-contract": "self.version", - "sonsofphp/version-contract": "self.version", - "sonsofphp/common-contract": "self.version", + "sonsofphp/filesystem-liip-imagine": "self.version", + "sonsofphp/http-factory": "self.version", + "sonsofphp/http-handler": "self.version", + "sonsofphp/http-handler-contract": "self.version", + "sonsofphp/http-message": "self.version", + "sonsofphp/json": "self.version", + "sonsofphp/link": "self.version", "sonsofphp/logger": "self.version", "sonsofphp/logger-contract": "self.version", - "sonsofphp/pager-contract": "self.version", - "sonsofphp/pager": "self.version", - "sonsofphp/link": "self.version", + "sonsofphp/mailer": "self.version", + "sonsofphp/mailer-contract": "self.version", + "sonsofphp/money": "self.version", + "sonsofphp/money-contract": "self.version", "sonsofphp/money-twig": "self.version", + "sonsofphp/pager": "self.version", + "sonsofphp/pager-contract": "self.version", "sonsofphp/pager-doctrine-collections": "self.version", "sonsofphp/pager-doctrine-dbal": "self.version", "sonsofphp/pager-doctrine-orm": "self.version", - "sonsofphp/cookie": "self.version", - "sonsofphp/cookie-contract": "self.version", - "sonsofphp/container": "self.version", - "sonsofphp/http-handler": "self.version", - "sonsofphp/http-handler-contract": "self.version", - "sonsofphp/mailer-contract": "self.version", - "sonsofphp/mailer": "self.version", - "sonsofphp/filesystem-aws": "self.version", - "sonsofphp/filesystem-liip-imagine": "self.version", + "sonsofphp/registry": "self.version", + "sonsofphp/registry-contract": "self.version", "sonsofphp/state-machine": "self.version", "sonsofphp/state-machine-contract": "self.version", - "sonsofphp/assert": "self.version", - "sonsofphp/registry": "self.version", - "sonsofphp/registry-contract": "self.version" + "sonsofphp/version": "self.version", + "sonsofphp/version-contract": "self.version" }, "autoload": { - "psr-4": { - "SonsOfPHP\\Bard\\": "src/SonsOfPHP/Bard/src", - "SonsOfPHP\\Component\\Assert\\": "src/SonsOfPHP/Component/Assert", - "SonsOfPHP\\Component\\StateMachine\\": "src/SonsOfPHP/Component/StateMachine", - "SonsOfPHP\\Contract\\StateMachine\\": "src/SonsOfPHP/Contract/StateMachine", - "SonsOfPHP\\Contract\\Mailer\\": "src/SonsOfPHP/Contract/Mailer", - "SonsOfPHP\\Component\\Mailer\\": "src/SonsOfPHP/Component/Mailer", - "SonsOfPHP\\Component\\Cache\\": "src/SonsOfPHP/Component/Cache", - "SonsOfPHP\\Component\\Clock\\": "src/SonsOfPHP/Component/Clock", - "SonsOfPHP\\Component\\Container\\": "src/SonsOfPHP/Component/Container", - "SonsOfPHP\\Component\\Cookie\\": "src/SonsOfPHP/Component/Cookie", - "SonsOfPHP\\Component\\Cqrs\\": "src/SonsOfPHP/Component/Cqrs", - "SonsOfPHP\\Bundle\\Cqrs\\": "src/SonsOfPHP/Bundle/Cqrs", - "SonsOfPHP\\Bridge\\Symfony\\Cqrs\\": "src/SonsOfPHP/Bridge/Symfony/Cqrs", - "SonsOfPHP\\Bridge\\Symfony\\EventSourcing\\": "src/SonsOfPHP/Bridge/Symfony/EventSourcing", - "SonsOfPHP\\Bridge\\Twig\\Money\\": "src/SonsOfPHP/Bridge/Twig/Money", - "SonsOfPHP\\Component\\EventDispatcher\\": "src/SonsOfPHP/Component/EventDispatcher", - "SonsOfPHP\\Component\\EventSourcing\\": "src/SonsOfPHP/Component/EventSourcing", - "SonsOfPHP\\Bridge\\Doctrine\\EventSourcing\\": "src/SonsOfPHP/Bridge/Doctrine/EventSourcing", - "SonsOfPHP\\Component\\FeatureToggle\\": "src/SonsOfPHP/Component/FeatureToggle", - "SonsOfPHP\\Contract\\Filesystem\\": "src/SonsOfPHP/Contract/Filesystem", - "SonsOfPHP\\Component\\Filesystem\\": "src/SonsOfPHP/Component/Filesystem", - "SonsOfPHP\\Bridge\\Aws\\Filesystem\\": "src/SonsOfPHP/Bridge/Aws/Filesystem", - "SonsOfPHP\\Bridge\\LiipImagine\\Filesystem\\": "src/SonsOfPHP/Bridge/LiipImagine/Filesystem", - "SonsOfPHP\\Component\\HttpFactory\\": "src/SonsOfPHP/Component/HttpFactory", - "SonsOfPHP\\Component\\HttpHandler\\": "src/SonsOfPHP/Component/HttpHandler", - "SonsOfPHP\\Contract\\HttpHandler\\": "src/SonsOfPHP/Contract/HttpHandler", - "SonsOfPHP\\Component\\HttpMessage\\": "src/SonsOfPHP/Component/HttpMessage", - "SonsOfPHP\\Component\\Json\\": "src/SonsOfPHP/Component/Json", - "SonsOfPHP\\Component\\Link\\": "src/SonsOfPHP/Component/Link", - "SonsOfPHP\\Component\\Logger\\": "src/SonsOfPHP/Component/Logger", - "SonsOfPHP\\Component\\Money\\": "src/SonsOfPHP/Component/Money", - "SonsOfPHP\\Component\\Pager\\": "src/SonsOfPHP/Component/Pager", - "SonsOfPHP\\Bridge\\Doctrine\\Collections\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/Collections/Pager", - "SonsOfPHP\\Bridge\\Doctrine\\DBAL\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/DBAL/Pager", - "SonsOfPHP\\Bridge\\Doctrine\\ORM\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/ORM/Pager", - "SonsOfPHP\\Component\\Version\\": "src/SonsOfPHP/Component/Version", - "SonsOfPHP\\Contract\\Common\\": "src/SonsOfPHP/Contract/Common", - "SonsOfPHP\\Contract\\Cookie\\": "src/SonsOfPHP/Contract/Cookie", - "SonsOfPHP\\Contract\\Cqrs\\": "src/SonsOfPHP/Contract/Cqrs", - "SonsOfPHP\\Contract\\EventSourcing\\": "src/SonsOfPHP/Contract/EventSourcing", - "SonsOfPHP\\Contract\\FeatureToggle\\": "src/SonsOfPHP/Contract/FeatureToggle", - "SonsOfPHP\\Contract\\Logger\\": "src/SonsOfPHP/Contract/Logger", - "SonsOfPHP\\Contract\\Money\\": "src/SonsOfPHP/Contract/Money", - "SonsOfPHP\\Contract\\Pager\\": "src/SonsOfPHP/Contract/Pager", - "SonsOfPHP\\Component\\Registry\\": "src/SonsOfPHP/Component/Registry", - "SonsOfPHP\\Contract\\Registry\\": "src/SonsOfPHP/Contract/Registry", - "SonsOfPHP\\Contract\\Version\\": "src/SonsOfPHP/Contract/Version" - }, "exclude-from-classmap": [ "src/SonsOfPHP/Bard/Tests", "src/SonsOfPHP/Component/Assert/Tests", @@ -224,7 +192,56 @@ "src/SonsOfPHP/Bridge/Doctrine/ORM/Pager/Tests", "src/SonsOfPHP/Component/Version/Tests", "src/SonsOfPHP/Component/Registry/Tests" - ] + ], + "psr-4": { + "SonsOfPHP\\Bard\\": "src/SonsOfPHP/Bard/src", + "SonsOfPHP\\Bridge\\Aws\\Filesystem\\": "src/SonsOfPHP/Bridge/Aws/Filesystem", + "SonsOfPHP\\Bridge\\Doctrine\\Collections\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/Collections/Pager", + "SonsOfPHP\\Bridge\\Doctrine\\DBAL\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/DBAL/Pager", + "SonsOfPHP\\Bridge\\Doctrine\\EventSourcing\\": "src/SonsOfPHP/Bridge/Doctrine/EventSourcing", + "SonsOfPHP\\Bridge\\Doctrine\\ORM\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/ORM/Pager", + "SonsOfPHP\\Bridge\\LiipImagine\\Filesystem\\": "src/SonsOfPHP/Bridge/LiipImagine/Filesystem", + "SonsOfPHP\\Bridge\\Symfony\\Cqrs\\": "src/SonsOfPHP/Bridge/Symfony/Cqrs", + "SonsOfPHP\\Bridge\\Symfony\\EventSourcing\\": "src/SonsOfPHP/Bridge/Symfony/EventSourcing", + "SonsOfPHP\\Bridge\\Twig\\Money\\": "src/SonsOfPHP/Bridge/Twig/Money", + "SonsOfPHP\\Bundle\\Cqrs\\": "src/SonsOfPHP/Bundle/Cqrs", + "SonsOfPHP\\Component\\Assert\\": "src/SonsOfPHP/Component/Assert", + "SonsOfPHP\\Component\\Cache\\": "src/SonsOfPHP/Component/Cache", + "SonsOfPHP\\Component\\Clock\\": "src/SonsOfPHP/Component/Clock", + "SonsOfPHP\\Component\\Container\\": "src/SonsOfPHP/Component/Container", + "SonsOfPHP\\Component\\Cookie\\": "src/SonsOfPHP/Component/Cookie", + "SonsOfPHP\\Component\\Cqrs\\": "src/SonsOfPHP/Component/Cqrs", + "SonsOfPHP\\Component\\EventDispatcher\\": "src/SonsOfPHP/Component/EventDispatcher", + "SonsOfPHP\\Component\\EventSourcing\\": "src/SonsOfPHP/Component/EventSourcing", + "SonsOfPHP\\Component\\FeatureToggle\\": "src/SonsOfPHP/Component/FeatureToggle", + "SonsOfPHP\\Component\\Filesystem\\": "src/SonsOfPHP/Component/Filesystem", + "SonsOfPHP\\Component\\HttpFactory\\": "src/SonsOfPHP/Component/HttpFactory", + "SonsOfPHP\\Component\\HttpHandler\\": "src/SonsOfPHP/Component/HttpHandler", + "SonsOfPHP\\Component\\HttpMessage\\": "src/SonsOfPHP/Component/HttpMessage", + "SonsOfPHP\\Component\\Json\\": "src/SonsOfPHP/Component/Json", + "SonsOfPHP\\Component\\Link\\": "src/SonsOfPHP/Component/Link", + "SonsOfPHP\\Component\\Logger\\": "src/SonsOfPHP/Component/Logger", + "SonsOfPHP\\Component\\Mailer\\": "src/SonsOfPHP/Component/Mailer", + "SonsOfPHP\\Component\\Money\\": "src/SonsOfPHP/Component/Money", + "SonsOfPHP\\Component\\Pager\\": "src/SonsOfPHP/Component/Pager", + "SonsOfPHP\\Component\\Registry\\": "src/SonsOfPHP/Component/Registry", + "SonsOfPHP\\Component\\StateMachine\\": "src/SonsOfPHP/Component/StateMachine", + "SonsOfPHP\\Component\\Version\\": "src/SonsOfPHP/Component/Version", + "SonsOfPHP\\Contract\\Common\\": "src/SonsOfPHP/Contract/Common", + "SonsOfPHP\\Contract\\Cookie\\": "src/SonsOfPHP/Contract/Cookie", + "SonsOfPHP\\Contract\\Cqrs\\": "src/SonsOfPHP/Contract/Cqrs", + "SonsOfPHP\\Contract\\EventSourcing\\": "src/SonsOfPHP/Contract/EventSourcing", + "SonsOfPHP\\Contract\\FeatureToggle\\": "src/SonsOfPHP/Contract/FeatureToggle", + "SonsOfPHP\\Contract\\Filesystem\\": "src/SonsOfPHP/Contract/Filesystem", + "SonsOfPHP\\Contract\\HttpHandler\\": "src/SonsOfPHP/Contract/HttpHandler", + "SonsOfPHP\\Contract\\Logger\\": "src/SonsOfPHP/Contract/Logger", + "SonsOfPHP\\Contract\\Mailer\\": "src/SonsOfPHP/Contract/Mailer", + "SonsOfPHP\\Contract\\Money\\": "src/SonsOfPHP/Contract/Money", + "SonsOfPHP\\Contract\\Pager\\": "src/SonsOfPHP/Contract/Pager", + "SonsOfPHP\\Contract\\Registry\\": "src/SonsOfPHP/Contract/Registry", + "SonsOfPHP\\Contract\\StateMachine\\": "src/SonsOfPHP/Contract/StateMachine", + "SonsOfPHP\\Contract\\Version\\": "src/SonsOfPHP/Contract/Version" + } }, "extra": { "sort-packages": true, @@ -233,17 +250,16 @@ } }, "require-dev": { + "phpunit/phpunit": "^10.4", + "sonsofphp/filesystem": "0.3.x-dev", "symfony/http-foundation": "^5 || ^6 || ^7", - "symfony/serializer": "^5 || ^6 || ^7", - "symfony/phpunit-bridge": "^6 || ^7", - "symfony/error-handler": "^6", - "phpunit/phpunit": "^10.4" + "symfony/serializer": "^5 || ^6 || ^7" }, "autoload-dev": { "psr-4": { "SonsOfPHP\\Bard\\Tests\\": "src/SonsOfPHP/Bard/Tests", - "SonsOfPHP\\Bundle\\Cqrs\\Tests\\": "src/SonsOfPHP/Bundle/Cqrs/Tests", - "SonsOfPHP\\Bridge\\Symfony\\Cqrs\\Tests\\": "src/SonsOfPHP/Bridge/Symfony/Cqrs/Tests" + "SonsOfPHP\\Bridge\\Symfony\\Cqrs\\Tests\\": "src/SonsOfPHP/Bridge/Symfony/Cqrs/Tests", + "SonsOfPHP\\Bundle\\Cqrs\\Tests\\": "src/SonsOfPHP/Bundle/Cqrs/Tests" } } -} +} \ No newline at end of file diff --git a/src/SonsOfPHP/Bard/dist/.gitignore b/src/SonsOfPHP/Bard/dist/.gitignore new file mode 100644 index 00000000..86d84656 --- /dev/null +++ b/src/SonsOfPHP/Bard/dist/.gitignore @@ -0,0 +1 @@ +*.phar diff --git a/src/SonsOfPHP/Bard/src/Console/Command/MergeCommand.php b/src/SonsOfPHP/Bard/src/Console/Command/MergeCommand.php index 361863e1..fbda5c42 100644 --- a/src/SonsOfPHP/Bard/src/Console/Command/MergeCommand.php +++ b/src/SonsOfPHP/Bard/src/Console/Command/MergeCommand.php @@ -10,13 +10,13 @@ use SonsOfPHP\Bard\Worker\File\Composer\Package\BranchAlias; use SonsOfPHP\Bard\Worker\File\Composer\Package\Funding; use SonsOfPHP\Bard\Worker\File\Composer\Package\Support; +use SonsOfPHP\Bard\Worker\File\Composer\Root\ClearSection; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateAutoloadDevSection; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateAutoloadSection; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateProvideSection; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateReplaceSection; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateRequireDevSection; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateRequireSection; -use SonsOfPHP\Component\Json\Json; use Symfony\Component\Console\Helper\HelperInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -31,21 +31,12 @@ */ final class MergeCommand extends AbstractCommand { - private readonly Json $json; - - private array $bardConfig; + private JsonFile $bardConfig; private string $mainComposerFile; private ?HelperInterface $formatter = null; - public function __construct() - { - $this->json = new Json(); - - parent::__construct(); - } - protected function configure(): void { $this @@ -63,9 +54,7 @@ protected function initialize(InputInterface $input, OutputInterface $output): v throw new RuntimeException(sprintf('"%s" file does not exist', $bardConfigFile)); } - $this->bardConfig = $this->json->getDecoder() - ->objectAsArray() - ->decode(file_get_contents($bardConfigFile)); + $this->bardConfig = new JsonFile($bardConfigFile); $this->mainComposerFile = $input->getOption('working-dir') . '/composer.json'; if (!file_exists($this->mainComposerFile)) { @@ -83,10 +72,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int $rootComposerJsonFile = new JsonFile($input->getOption('working-dir') . '/composer.json'); // Clean out a few of the sections in root composer.json file - $rootComposerJsonFile = $rootComposerJsonFile->setSection('autoload', []); - $rootComposerJsonFile = $rootComposerJsonFile->setSection('autoload-dev', []); - - foreach ($this->bardConfig['packages'] as $pkg) { + $rootComposerJsonFile = $rootComposerJsonFile->with(new ClearSection('autoload')); + $rootComposerJsonFile = $rootComposerJsonFile->with(new ClearSection('autoload-dev')); + $rootComposerJsonFile = $rootComposerJsonFile->with(new ClearSection('require')); + $rootComposerJsonFile = $rootComposerJsonFile->with(new ClearSection('require-dev')); + $rootComposerJsonFile = $rootComposerJsonFile->with(new ClearSection('replace')); + $rootComposerJsonFile = $rootComposerJsonFile->with(new ClearSection('provide')); + + foreach ($this->bardConfig->getSection('packages') as $pkg) { $pkgComposerFile = realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json'); if (!file_exists($pkgComposerFile)) { $output->writeln(sprintf('No "%s" found, skipping', $packageComposerFile)); diff --git a/src/SonsOfPHP/Bard/src/Console/Command/PushCommand.php b/src/SonsOfPHP/Bard/src/Console/Command/PushCommand.php index bafb0026..98597fcb 100644 --- a/src/SonsOfPHP/Bard/src/Console/Command/PushCommand.php +++ b/src/SonsOfPHP/Bard/src/Console/Command/PushCommand.php @@ -50,7 +50,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int ['git', 'subtree', 'push', '-P', $pkg['path'], $pkg['repository'], $input->getOption('branch')], ]; - $io->text(sprintf('Pushing %s', $pkgName)); + $output->writeln($this->getHelper('formatter')->formatSection($pkgName, 'Pushing...')); foreach ($commands as $cmd) { $process = new Process($cmd); $io->text($process->getCommandLine()); @@ -60,6 +60,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->wait(); } } + + $output->writeln($this->getHelper('formatter')->formatSection($pkgName, '...Done')); + $io->newLine(); } $io->success('All Packages have been published.'); diff --git a/src/SonsOfPHP/Bard/src/Console/Command/ReleaseCommand.php b/src/SonsOfPHP/Bard/src/Console/Command/ReleaseCommand.php index aebc36ae..190d40bc 100644 --- a/src/SonsOfPHP/Bard/src/Console/Command/ReleaseCommand.php +++ b/src/SonsOfPHP/Bard/src/Console/Command/ReleaseCommand.php @@ -7,9 +7,11 @@ use RuntimeException; use SonsOfPHP\Bard\JsonFile; use SonsOfPHP\Bard\Worker\File\Bard\UpdateVersion; +use SonsOfPHP\Bard\Worker\File\Composer\Package\BranchAlias; use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateReplaceSection; use SonsOfPHP\Component\Version\Version; use SonsOfPHP\Component\Version\VersionInterface; +use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -26,10 +28,14 @@ final class ReleaseCommand extends AbstractCommand { private JsonFile $bardConfig; - private VersionInterface|Version|null $releaseVersion = null; + private VersionInterface|null $releaseVersion = null; private bool $isDryRun = true; + private JsonFile $rootComposerJsonFile; + + private SymfonyStyle $io; + protected function configure(): void { $this @@ -40,14 +46,14 @@ protected function configure(): void ->addArgument('release', InputArgument::REQUIRED, 'Next Release you want to start? Use format ..-+ or "major", "minor", "patch"') ->setHelp( <<<'EOT' - This command allows you to create a new release and will update the various - repos that have been configured. The current version can be found in the - `bard.json` file. This will will update the version based on the type of release - that you are doing. + This command allows you to create a new release and will update the various + repos that have been configured. The current version can be found in the + `bard.json` file. This will will update the version based on the type of release + that you are doing. - %command.full_name% + %command.full_name% - Read more at https://docs.SonsOfPHP.com + Read more at https://docs.SonsOfPHP.com EOT ); } @@ -83,62 +89,87 @@ protected function initialize(InputInterface $input, OutputInterface $output): v } $this->isDryRun = $input->getOption('dry-run'); + $this->io = new SymfonyStyle($input, $output); + + $this->rootComposerJsonFile = new JsonFile($input->getOption('working-dir') . '/composer.json'); } protected function execute(InputInterface $input, OutputInterface $output): int { - $formatter = $this->getHelper('formatter'); - $io = new SymfonyStyle($input, $output); if ($this->isDryRun) { - $io->note('dry-run enabled no changes will be made'); + $this->io->note('dry-run enabled no changes will be made'); } - $io->text([ - sprintf('Bumping release from %s to %s', $this->bardConfig->getSection('version'), $this->releaseVersion->toString()), - ]); + $this->io->text(sprintf('Bumping release from %s to %s', $this->bardConfig->getSection('version'), $this->releaseVersion->toString())); + + // 0. Make sure we have the latest changes + $this->pullLatestChanges($input, $output); + + // 1. Update "replace" in main composer.json with the Package Names + // "package/name": "self.version" + $this->updateReplace($input, $output); + + // @todo + // 2. Update Changelog + // Changes the "Unreleased" headline to the version we are releaseing + // Adds new headline at top for unreleased features + + // 3. Tag Release and push + $this->tagReleaseAndPushMonorepo($input, $output); + + // 4. Subtree Split for each package + $this->tagReleaseAndPushPackages($input, $output); + + // 5. Update branch alias in all composer.json files + $this->updateBranchAliasForPackages($input, $output); + + // 6. Update bard.json with current version + $this->updateBardConfigVersion(); - // Make sure we have the latest changes + // 7. Commit and push updates + $this->commitAndPushNewChanges($input, $output); + + $this->io->success('Congrations on your new release'); + if ($this->isDryRun) { + $this->io->note([ + 'dry-run was enabled so no files were changed and no code was pushed', + ]); + } + + return self::SUCCESS; + } + + private function pullLatestChanges(InputInterface $input, OutputInterface $output): void + { + $this->io->section('Making sure branch is up to date with latest changes'); $process = new Process(['git', 'pull', 'origin', $input->getOption('branch')]); - $io->text($process->getCommandLine()); + $this->io->text($process->getCommandLine()); if (!$this->isDryRun) { $this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine())); } - $rootComposerJsonFile = new JsonFile($input->getOption('working-dir') . '/composer.json'); + $this->io->success('Done'); + } - // 1. Update "replace" in main composer.json with the Package Names - // "package/name": "self.version" - $io->section('updating root composer.json "replace" section with package information'); + private function updateReplace(InputInterface $input, OutputInterface $output): void + { + $this->io->section('updating root composer.json "replace" section with package information'); foreach ($this->bardConfig->getSection('packages') as $pkg) { $pkgComposerJsonFile = new JsonFile(realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json')); - $output->writeln([ - $formatter->formatSection($pkgComposerJsonFile->getSection('name'), 'Updating root composer.json'), - ]); - $rootComposerJsonFile = $rootComposerJsonFile->with(new UpdateReplaceSection($pkgComposerJsonFile)); + $output->writeln($this->getHelper('formatter')->formatSection($pkgComposerJsonFile->getSection('name'), 'Updating root composer.json')); + $this->rootComposerJsonFile = $this->rootComposerJsonFile->with(new UpdateReplaceSection($pkgComposerJsonFile)); } - $output->writeln([ - 'saving root composer.json', - ]); if (!$this->isDryRun) { - file_put_contents($rootComposerJsonFile->getFilename(), $rootComposerJsonFile->toJson()); + $this->rootComposerJsonFile->save(); } - $output->writeln([ - 'root composer.json file saved', - ]); - $io->newLine(); - $io->success('root "composer.json" update complete'); - - // @todo - // 2. Update Changelog - // Changes the "Unreleased" headline to the version we are releaseing - // Adds new headline at top for unreleased features - - // 3. Tag Release and push - $io->newLine(); - $io->section(sprintf('updating mother repo for release %s', $this->releaseVersion->toString())); + $this->io->success('Done'); + } + private function tagReleaseAndPushMonorepo(InputInterface $input, OutputInterface $output): void + { + $this->io->section(sprintf('updating mother repo for release %s', $this->releaseVersion->toString())); $processCommands = [ ['git', 'add', '.'], ['git', 'commit', '--allow-empty', '-m', sprintf('"Preparing for Release v%s"', $this->releaseVersion->toString())], @@ -148,22 +179,22 @@ protected function execute(InputInterface $input, OutputInterface $output): int ]; foreach ($processCommands as $cmd) { $process = new Process($cmd); - $io->text($process->getCommandLine()); + $this->io->text($process->getCommandLine()); if (!$this->isDryRun) { $this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine())); } } - $io->success('Mother Repository Released'); + $this->io->success('Mother Repository Released'); + } - // 4. Subtree Split for each package - // @todo run split command - $io->newLine(); - $io->title(sprintf('updating package repos with release %s', $this->releaseVersion->toString())); + private function tagReleaseAndPushPackages(InputInterface $input, OutputInterface $output): void + { + $this->io->section(sprintf('updating package repos with release %s', $this->releaseVersion->toString())); foreach ($this->bardConfig->getSection('packages') as $pkg) { $pkgComposerJsonFile = new JsonFile(realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json')); $pkgName = $pkgComposerJsonFile->getSection('name'); - $io->text(sprintf('Package %s is being released', $pkgName)); + $output->writeln($this->getHelper('formatter')->formatSection($pkgName, 'Releasing...')); $processCommands = [ ['git', 'subtree', 'split', '-P', $pkg['path'], '-b', $pkgName], ['git', 'checkout', $pkgName], @@ -176,56 +207,83 @@ protected function execute(InputInterface $input, OutputInterface $output): int ]; foreach ($processCommands as $cmd) { $process = new Process($cmd); - $io->text($process->getCommandLine()); + $this->io->text($process->getCommandLine()); if (!$this->isDryRun) { $this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine())); } } - $io->newLine(); + $output->writeln($this->getHelper('formatter')->formatSection($pkgName, '...Done')); + $this->io->newLine(); } - $io->text('All Packages have been Released'); - // $io->success('All Packages have been Released'); + $this->io->success('All Packages have been Released'); + } - // 5. Update branch alias in all composer.json files - // - Only if update is major or minor - // $io->section('Updating Branch Alias in root and packages'); + /** + * Foreach package, this will update the extra.branch-alias to the same + * value as the root composer.json value + */ + private function updateBranchAliasForPackages(InputInterface $input, OutputInterface $output): void + { + $this->io->section('Updating the Branch Alias for root and packages'); + $extra = $this->rootComposerJsonFile->getSection('extra'); + $branchAlias = explode('.', $this->releaseVersion->toString()); + $branchAlias[2] = 'x-dev'; + $branchAlias = implode('.', $branchAlias); + $extra['branch-alias'] = $branchAlias; + $this->rootComposerJsonFile->setSection('extra', $extra); + $this->io->text('root composer.json updated to ' . $branchAlias); + if (!$this->isDryRun) { + $this->rootComposerJsonFile->save(); + } - // 6. Update bard.json with current version - $io->section('Updating version in bard.json'); + foreach ($this->bardConfig->getSection('packages') as $pkg) { + $pkgComposerJsonFile = new JsonFile(realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json')); + $pkgComposerJsonFile = $pkgComposerJsonFile->with(new BranchAlias($this->rootComposerJsonFile)); + $output->writeln($this->getHelper('formatter')->formatSection($pkgComposerJsonFile->getSection('name'), 'Updated branch alias to "' . $branchAlias . '"')); + if (!$this->isDryRun) { + $pkgComposerJsonFile->save(); + } + } + $this->io->success('Done'); + } + + private function updateBardConfigVersion(): void + { + $this->io->section('Updating version in bard.json'); $this->bardConfig = $this->bardConfig->with(new UpdateVersion($this->releaseVersion)); if (!$this->isDryRun) { - file_put_contents($this->bardConfig->getFilename(), $this->bardConfig->toJson()); + $this->bardConfig->save(); } - $io->text('bard.json updated with new version'); + $this->io->success('bard.json updated with new version'); + } - // 7. Commit and push updates - // $io->section('Updating mother repo'); - // $processCommands = [ - // ['git', 'add', '.'], - // ['git', 'commit', '-m', '"starting release"'], - // ['git', 'push', 'origin', $input->getOption('branch')], - // ]; - // foreach ($processCommands as $cmd) { - // $process = new Process($cmd); - // $io->text($process->getCommandLine()); - // if (!$this->isDryRun) { - // $this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine())); - // } - // } - // $io->text('done'); - - $io->newLine(); - $io->success('Congrations on your new release'); - if ($this->isDryRun) { - $io->note([ - 'dry-run was enabled so no files were changed and no code was pushed', - ]); + private function commitAndPushNewChanges(InputInterface $input, OutputInterface $output): void + { + $this->io->section('Commiting and new Pushing Changes'); + $processCommands = [ + ['git', 'add', '.'], + ['git', 'commit', '-m', '"starting next release"'], + ['git', 'push', 'origin', $input->getOption('branch')], + ]; + foreach ($processCommands as $cmd) { + $process = new Process($cmd); + $this->io->text($process->getCommandLine()); + if (!$this->isDryRun) { + $this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine())); + } } - return self::SUCCESS; + $cmdInput = new ArrayInput([ + 'command' => 'push', + '--dry-run' => $this->isDryRun, + '--branch' => $input->getOption('branch'), + ]); + $this->getApplication()->doRun($cmdInput, $output); + + $this->io->success('Done'); } } diff --git a/src/SonsOfPHP/Bard/src/JsonFile.php b/src/SonsOfPHP/Bard/src/JsonFile.php index 4f8e20cb..911fe6fd 100644 --- a/src/SonsOfPHP/Bard/src/JsonFile.php +++ b/src/SonsOfPHP/Bard/src/JsonFile.php @@ -4,8 +4,6 @@ namespace SonsOfPHP\Bard; -use SonsOfPHP\Component\Json\Json; - /** * Used to manage bard.json and composer.json files * @@ -15,20 +13,15 @@ final class JsonFile { private array $config = []; - private Json $json; - public function __construct( private string $filename, ) { - $this->json = new Json(); $this->load(); } private function load(): void { - $this->config = $this->json->getDecoder() - ->objectAsArray() - ->decode(file_get_contents($this->filename)); + $this->config = json_decode(file_get_contents($this->filename), true); } public function getFilename(): string @@ -43,7 +36,7 @@ public function getFilename(): string */ public function getSection(string $section): mixed { - if (!isset($this->config)) { + if ([] === $this->config) { $this->load(); } @@ -54,7 +47,7 @@ public function getSection(string $section): mixed */ public function setSection(string $section, $value): self { - if (!isset($this->config)) { + if ([] === $this->config) { $this->load(); } @@ -64,23 +57,21 @@ public function setSection(string $section, $value): self return $clone; } - /** - */ public function toJson(): string { - return $this->json->getEncoder() - ->prettyPrint() - ->unescapedUnicode() - ->unescapedSlashes() - ->encode($this->config); + return json_encode($this->config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } /** - * $operator = new Operator(); * $jsonFile->with(new ExampleOperator()); */ public function with($operator): self { return $operator->apply($this); } + + public function save(): void + { + file_put_contents($this->filename, $this->toJson()); + } } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Package/Support.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Package/Support.php index 1c20196a..5860ce6f 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Package/Support.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Package/Support.php @@ -17,6 +17,11 @@ public function __construct(private JsonFile $rootComposerJsonFile) {} public function apply(JsonFile $pkgComposerJsonFile): JsonFile { $rootSupportSection = $this->rootComposerJsonFile->getSection('support'); + $pkgSupportSection = $pkgComposerJsonFile->getSection('support'); + + // Docs may be different for package so we do not want to overwrite + // that value + $rootSupportSection['docs'] = $pkgSupportSection['docs']; return $pkgComposerJsonFile->setSection('support', $rootSupportSection); } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/ClearSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/ClearSection.php new file mode 100644 index 00000000..9708a06a --- /dev/null +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/ClearSection.php @@ -0,0 +1,21 @@ + + */ +final readonly class ClearSection implements WorkerInterface +{ + public function __construct(private string $section) {} + + public function apply(JsonFile $rootComposerJsonFile): JsonFile + { + return $rootComposerJsonFile->setSection($this->section, []); + } +} diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadDevSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadDevSection.php index d405186d..1ebbfd4f 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadDevSection.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadDevSection.php @@ -43,12 +43,16 @@ public function apply(JsonFile $rootComposerJsonFile): JsonFile if (isset($rootAutoloadSection['psr-4'])) { $rootAutoloadSection['psr-4'] = array_unique($rootAutoloadSection['psr-4']); + ksort($rootAutoloadSection['psr-4']); } if (isset($rootAutoloadSection['exclude-from-classmap'])) { $rootAutoloadSection['exclude-from-classmap'] = array_unique($rootAutoloadSection['exclude-from-classmap']); + ksort($rootAutoloadSection['exclude-from-classmap']); } + ksort($rootAutoloadSection); + return $rootComposerJsonFile->setSection('autoload-dev', $rootAutoloadSection); } } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadSection.php index 90329fdf..0af2a253 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadSection.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateAutoloadSection.php @@ -47,12 +47,16 @@ public function apply(JsonFile $rootComposerJsonFile): JsonFile if (isset($rootAutoloadSection['psr-4'])) { $rootAutoloadSection['psr-4'] = array_unique($rootAutoloadSection['psr-4']); + ksort($rootAutoloadSection['psr-4']); } if (isset($rootAutoloadSection['exclude-from-classmap'])) { $rootAutoloadSection['exclude-from-classmap'] = array_unique($rootAutoloadSection['exclude-from-classmap']); + ksort($rootAutoloadSection['exclude-from-classmap']); } + ksort($rootAutoloadSection); + return $rootComposerJsonFile->setSection('autoload', $rootAutoloadSection); } } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateProvideSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateProvideSection.php index 7169454b..5f18b062 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateProvideSection.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateProvideSection.php @@ -27,6 +27,8 @@ public function apply(JsonFile $rootComposerJsonFile): JsonFile $rootProvideSection[$pkg] = $version; } + ksort($rootProvideSection); + return $rootComposerJsonFile->setSection('provide', $rootProvideSection); } } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateReplaceSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateReplaceSection.php index 290dd5ab..ef9deb2f 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateReplaceSection.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateReplaceSection.php @@ -20,6 +20,7 @@ public function apply(JsonFile $rootComposerJsonFile): JsonFile $pkgName = $this->pkgComposerJsonFile->getSection('name'); $rootReplace[$pkgName] = 'self.version'; + ksort($rootReplace); return $rootComposerJsonFile->setSection('replace', $rootReplace); } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireDevSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireDevSection.php index b8fb9749..e9b4f907 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireDevSection.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireDevSection.php @@ -53,6 +53,8 @@ public function apply(JsonFile $rootComposerJsonFile): JsonFile $rootRequireDev[$package] = $version; } + ksort($rootRequireDev); + return $rootComposerJsonFile->setSection('require-dev', $rootRequireDev); } } diff --git a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireSection.php b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireSection.php index 0b49fcbd..eee2891a 100644 --- a/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireSection.php +++ b/src/SonsOfPHP/Bard/src/Worker/File/Composer/Root/UpdateRequireSection.php @@ -35,6 +35,8 @@ public function apply(JsonFile $rootComposerJsonFile): JsonFile $rootRequire[$package] = $version; } + ksort($rootRequire); + return $rootComposerJsonFile->setSection('require', $rootRequire); } } diff --git a/src/SonsOfPHP/Component/Cache/composer.json b/src/SonsOfPHP/Component/Cache/composer.json index 4fbfa0aa..7fb9e02c 100644 --- a/src/SonsOfPHP/Component/Cache/composer.json +++ b/src/SonsOfPHP/Component/Cache/composer.json @@ -64,4 +64,4 @@ "url": "https://tidelift.com/subscription/pkg/packagist-sonsofphp-sonsofphp" } ] -} +} \ No newline at end of file