From 5274bdea5ace7d3ec2e75f0d9b554d32446399d3 Mon Sep 17 00:00:00 2001 From: Enea Date: Thu, 14 May 2026 15:41:37 +0200 Subject: [PATCH 01/13] chore(refactor): implements the Pipeline and new Empress packages to bootstrap the application --- bus/Bus.php | 45 ------- bus/DecorateBus.php | 25 ---- bus/HandlerInterface.php | 13 -- bus/MiddlewareInterface.php | 13 -- ecs.php | 1 - src/Application/Commands/DumpCommand.php | 76 ++++------- src/Application/Commands/InfoCommand.php | 14 +- src/Application/Commands/InitCommand.php | 67 +++------- .../Commands/Utils/RootFolderTrait.php | 3 + src/Application/Commands/ValidateCommand.php | 58 ++------- src/Application/InitMessage.php | 31 ----- .../{InfoMessage.php => Message.php} | 7 +- .../DeleteSchemaJson.php} | 9 +- .../Middlewares}/Dump.php | 66 ++++++++-- .../Middlewares}/Info.php | 15 ++- .../Middlewares}/Init.php | 59 ++++++++- .../SchemaJson.php} | 10 +- src/Application/Middlewares/Validate.php | 121 ++++++++++++++++++ src/Bootstrap.php | 75 ++++------- src/Domain/Output/Validate.php | 74 ----------- .../Filesystem}/DataFromJsonTrait.php | 2 +- src/Infrastructure/Filesystem/Path.php | 13 ++ src/Infrastructure/Handler/ConsoleHandler.php | 43 +++++++ src/ModuleApplication.php | 53 ++++++++ src/ModuleInfrastructure.php | 31 +++++ .../SchemaJsonTest.php} | 19 +-- tests/unit/Domain/Output/DumpTest.php | 2 +- tests/unit/Domain/Output/InitTest.php | 6 +- tests/unit/Domain/Output/ValidateTest.php | 2 +- 29 files changed, 489 insertions(+), 464 deletions(-) delete mode 100644 bus/Bus.php delete mode 100644 bus/DecorateBus.php delete mode 100644 bus/HandlerInterface.php delete mode 100644 bus/MiddlewareInterface.php delete mode 100644 src/Application/InitMessage.php rename src/Application/{InfoMessage.php => Message.php} (88%) rename src/Application/{Commands/Middleware/DeleteSchemaJsonMiddleware.php => Middlewares/DeleteSchemaJson.php} (68%) rename src/{Domain/Output => Application/Middlewares}/Dump.php (75%) rename src/{Domain/Output => Application/Middlewares}/Info.php (52%) rename src/{Domain/Output => Application/Middlewares}/Init.php (69%) rename src/Application/{Commands/Middleware/SchemaJsonMiddleware.php => Middlewares/SchemaJson.php} (79%) create mode 100644 src/Application/Middlewares/Validate.php delete mode 100644 src/Domain/Output/Validate.php rename src/{Application/Commands/Utils => Infrastructure/Filesystem}/DataFromJsonTrait.php (95%) create mode 100644 src/Infrastructure/Filesystem/Path.php create mode 100644 src/Infrastructure/Handler/ConsoleHandler.php create mode 100644 src/ModuleApplication.php create mode 100644 src/ModuleInfrastructure.php rename tests/unit/Application/{Commands/Middleware/SchemaJsonMiddlewareTest.php => Middlewares/SchemaJsonTest.php} (62%) diff --git a/bus/Bus.php b/bus/Bus.php deleted file mode 100644 index ca48418a..00000000 --- a/bus/Bus.php +++ /dev/null @@ -1,45 +0,0 @@ -handler = $handler; - } - - public function addMiddleware(MiddlewareInterface ...$middleware): void - { - $this->middleware = \array_merge($this->middleware, $middleware); - } - - public function handle(object $message) - { - if ($this->middleware === []) { - return $this->handler->handle($message); - } - - /** @var MiddlewareInterface $middleware */ - $middleware = array_shift($this->middleware); - return $middleware->process($message, $this); - } -} diff --git a/bus/DecorateBus.php b/bus/DecorateBus.php deleted file mode 100644 index caa98410..00000000 --- a/bus/DecorateBus.php +++ /dev/null @@ -1,25 +0,0 @@ -middleware = $middleware; - $this->nextHandler = $nextHandler; - } - - public function handle(object $message) - { - return $this->middleware->process($message, $this->nextHandler); - } -} diff --git a/bus/HandlerInterface.php b/bus/HandlerInterface.php deleted file mode 100644 index db84c8fe..00000000 --- a/bus/HandlerInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -paths([ - __DIR__ . '/bus', __DIR__ . '/src', __DIR__ . '/tests', __DIR__ . '/functions', diff --git a/src/Application/Commands/DumpCommand.php b/src/Application/Commands/DumpCommand.php index 8f3e376d..65c62890 100644 --- a/src/Application/Commands/DumpCommand.php +++ b/src/Application/Commands/DumpCommand.php @@ -4,12 +4,10 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; +use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Dump; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\GeneratedFile; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\GeneratingFile; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\NoFileFound; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -19,6 +17,7 @@ /** * @psalm-api */ +#[AsCommand(name: DumpCommand::NAME, description: DumpCommand::DESCRIPTION)] final class DumpCommand extends Command { use RootFolderTrait; @@ -28,6 +27,8 @@ final class DumpCommand extends Command */ public const NAME = 'dump'; + public const DESCRIPTION = 'Generate theme.json file'; + /** * @var string */ @@ -48,23 +49,19 @@ final class DumpCommand extends Command */ public const FILE = 'file'; - private Dump $dump; - - private \Symfony\Component\EventDispatcher\EventDispatcher $subscriber; + private HandlerInterface $handler; public function __construct( - \Symfony\Component\EventDispatcher\EventDispatcher $subscriber, - Dump $dump + HandlerInterface $handler ) { - $this->subscriber = $subscriber; - $this->dump = $dump; + $this->handler = $handler; parent::__construct(); } protected function configure(): void { $this->setName(self::NAME); - $this->setDescription('Generate theme.json file'); + $this->setDescription(self::DESCRIPTION); $this->setHelp('This command generate theme.json file'); $this->addOption( @@ -119,36 +116,6 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - - $this->subscriber->addListener( - GeneratingFile::class, - static function (GeneratingFile $event) use ($output): void { - $output->writeln(\sprintf( - 'Generating %s file', - $event->getFileName() - )); - } - ); - - $this->subscriber->addListener( - GeneratedFile ::class, - static function (GeneratedFile $event) use ($output): void { - $output->writeln(\sprintf( - 'Generated %s file', - $event->getFileName() - )); - $output->writeln('========================'); - } - ); - - $this->subscriber->addListener( - NoFileFound::class, - /** @psalm-suppress UnusedClosureParam */ - static function (NoFileFound $event) use ($output): void { - $output->writeln(NoFileFound::M_NO_FILE_FOUND); - } - ); - $rootFolder = $this->rootFolder((string)$input->getOption('path')); $message = new DumpMessage( @@ -158,17 +125,22 @@ static function (NoFileFound $event) use ($output): void { (string)$input->getOption(self::FILE) ); - $this->dump->handle($message); - - if ($input->getOption(ValidateCommand::NAME)) { - $process = new Process(['php', 'vendor/bin/theme-json', ValidateCommand::NAME]); - $process->run(); - - $output->write($process->getOutput()); - - return (int)$process->getExitCode(); + try { + return (int)$this->handler->handle($message); + } catch (\Exception $exception) { + $output->writeln('Error: ' . $exception->getMessage() . ''); + return Command::FAILURE; } - return Command::SUCCESS; +// if ($input->getOption(ValidateCommand::NAME)) { +// $process = new Process(['php', 'vendor/bin/theme-json', ValidateCommand::NAME]); +// $process->run(); +// +// $output->write($process->getOutput()); +// +// return (int)$process->getExitCode(); +// } + +// return Command::SUCCESS; } } diff --git a/src/Application/Commands/InfoCommand.php b/src/Application/Commands/InfoCommand.php index dd1b6a09..2c9c5aa0 100644 --- a/src/Application/Commands/InfoCommand.php +++ b/src/Application/Commands/InfoCommand.php @@ -4,8 +4,10 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; +use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; -use ItalyStrap\ThemeJsonGenerator\Application\InfoMessage; +use ItalyStrap\ThemeJsonGenerator\Application\Message; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -13,16 +15,18 @@ /** * @psalm-api */ +#[AsCommand(name: InfoCommand::NAME, description: InfoCommand::DESCRIPTION)] class InfoCommand extends Command { use RootFolderTrait; public const NAME = 'info'; + public const DESCRIPTION = 'Show info about JSON theme'; - private \ItalyStrap\Bus\HandlerInterface $handler; + private HandlerInterface $handler; public function __construct( - \ItalyStrap\Bus\HandlerInterface $handler + HandlerInterface $handler ) { $this->handler = $handler; parent::__construct(); @@ -31,14 +35,14 @@ public function __construct( protected function configure(): void { $this->setName(self::NAME); - $this->setDescription('Show info about JSON theme'); + $this->setDescription(self::DESCRIPTION); } protected function execute(InputInterface $input, OutputInterface $output): int { $rootFolder = $this->rootFolder(); - $message = new InfoMessage($rootFolder); + $message = new Message($rootFolder); try { return (int)$this->handler->handle($message); diff --git a/src/Application/Commands/InitCommand.php b/src/Application/Commands/InitCommand.php index db36fac9..f34d5463 100644 --- a/src/Application/Commands/InitCommand.php +++ b/src/Application/Commands/InitCommand.php @@ -4,13 +4,11 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; -use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\DataFromJsonTrait; +use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; -use ItalyStrap\ThemeJsonGenerator\Application\InitMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointCanNotBeCreated; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointCreated; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointDoesNotExist; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Init; +use ItalyStrap\ThemeJsonGenerator\Application\Message; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -18,6 +16,7 @@ /** * @psalm-api */ +#[AsCommand(name: InitCommand::NAME, description: InitCommand::DESCRIPTION)] class InitCommand extends Command { use RootFolderTrait; @@ -25,23 +24,21 @@ class InitCommand extends Command public const NAME = 'init'; - private Init $init; + public const DESCRIPTION = 'Initialize theme.json file'; - private \Symfony\Component\EventDispatcher\EventDispatcher $subscriber; + private HandlerInterface $handler; public function __construct( - \Symfony\Component\EventDispatcher\EventDispatcher $subscriber, - Init $init + HandlerInterface $handler, ) { - $this->subscriber = $subscriber; - $this->init = $init; + $this->handler = $handler; parent::__construct(); } protected function configure(): void { $this->setName(self::NAME); - $this->setDescription('Initialize theme.json file'); + $this->setDescription(self::DESCRIPTION); $this->addOption( 'styles', @@ -55,45 +52,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $rootFolder = $this->rootFolder(); - $this->subscriber->addListener( - EntryPointDoesNotExist::class, - static function (EntryPointDoesNotExist $event) use ($output): void { - $output->writeln(\sprintf( - 'Entry file does not exist, creating %s file', - $event->getFile() - )); - } - ); - - $this->subscriber->addListener( - EntryPointCreated::class, - static function (EntryPointCreated $event) use ($output): void { - $output->writeln(\sprintf( - 'Entry file %s created', - $event->getFile() - )); - } - ); - - $this->subscriber->addListener( - EntryPointCanNotBeCreated::class, - static function (EntryPointCanNotBeCreated $event) use ($output): void { - $output->writeln(\sprintf( - 'Entry file %s cannot be created because of %s', - $event->getFile(), - $event->getException()->getMessage() - )); - } - ); - - $message = new InitMessage($rootFolder, (string)$input->getOption('styles')); + $message = new Message($rootFolder); - if ($message->getStyleOption() !== '') { - throw new \RuntimeException('The option --styles is not yet implemented'); + try { + return (int)$this->handler->handle($message); + } catch (\Exception $exception) { + $output->writeln('Error: ' . $exception->getMessage() . ''); + return Command::FAILURE; } - - $this->init->handle($message); - - return Command::SUCCESS; } } diff --git a/src/Application/Commands/Utils/RootFolderTrait.php b/src/Application/Commands/Utils/RootFolderTrait.php index 45d13bcd..91cce765 100644 --- a/src/Application/Commands/Utils/RootFolderTrait.php +++ b/src/Application/Commands/Utils/RootFolderTrait.php @@ -4,6 +4,9 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils; +/** + * TODO: Move this logic into Infrastructure Filesystem layer + */ trait RootFolderTrait { private function rootFolder(string $path = ''): string diff --git a/src/Application/Commands/ValidateCommand.php b/src/Application/Commands/ValidateCommand.php index dd854058..edbd676a 100644 --- a/src/Application/Commands/ValidateCommand.php +++ b/src/Application/Commands/ValidateCommand.php @@ -4,12 +4,11 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; -use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\DataFromJsonTrait; +use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\ValidatedFails; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\ValidatingFile; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\ValidFile; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -18,22 +17,19 @@ /** * @psalm-api */ +#[AsCommand(name: ValidateCommand::NAME, description: ValidateCommand::DESCRIPTION)] class ValidateCommand extends Command { use RootFolderTrait; use DataFromJsonTrait; public const NAME = 'validate'; - - private \Symfony\Component\EventDispatcher\EventDispatcher $subscriber; - - private \ItalyStrap\Bus\HandlerInterface $handler; + public const DESCRIPTION = 'Validate theme.json file'; + private HandlerInterface $handler; public function __construct( - \Symfony\Component\EventDispatcher\EventDispatcher $subscriber, - \ItalyStrap\Bus\HandlerInterface $handler + HandlerInterface $handler ) { - $this->subscriber = $subscriber; $this->handler = $handler; parent::__construct(); } @@ -41,7 +37,7 @@ public function __construct( protected function configure(): void { $this->setName(self::NAME); - $this->setDescription('Validate theme.json file'); + $this->setDescription(self::DESCRIPTION); $this->addOption( 'force', @@ -59,44 +55,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $rootFolder = $this->rootFolder(); $schemaPath = $rootFolder . '/theme.schema.json'; - $this->subscriber->addListener( - ValidatingFile::class, - static function (ValidatingFile $event) use ($output): void { - $output->writeln('========================'); - $output->writeln(\sprintf( - 'Validating %s', - $event->getFile()->getFilename() - )); - } - ); - - $this->subscriber->addListener( - ValidFile::class, - static function (ValidFile $event) use ($output): void { - $output->writeln(\sprintf( - '%s is valid', - $event->getFile()->getFilename() - )); - } - ); - - $this->subscriber->addListener( - ValidatedFails::class, - static function (ValidatedFails $event) use ($output): void { - $output->writeln('# ' . $event->getFile()->getFilename() . ' file errors'); - /** - * @var array $error - */ - foreach ($event->getErrors() as $error) { - $output->writeln(\sprintf( - '- [%s] is not valid. %s', - $error['property'] ?? '', - $error['message'] ?? '' - )); - } - } - ); - $message = new ValidateMessage($rootFolder, $schemaPath, (bool)$input->getOption('force')); try { diff --git a/src/Application/InitMessage.php b/src/Application/InitMessage.php deleted file mode 100644 index 889cdd61..00000000 --- a/src/Application/InitMessage.php +++ /dev/null @@ -1,31 +0,0 @@ -rootFolder = $rootFolder; - $this->styleOption = $styleOption; - } - - public function getRootFolder(): string - { - return $this->rootFolder; - } - - public function getStyleOption(): string - { - return $this->styleOption; - } -} diff --git a/src/Application/InfoMessage.php b/src/Application/Message.php similarity index 88% rename from src/Application/InfoMessage.php rename to src/Application/Message.php index 24aca104..a085259d 100644 --- a/src/Application/InfoMessage.php +++ b/src/Application/Message.php @@ -4,10 +4,7 @@ namespace ItalyStrap\ThemeJsonGenerator\Application; -/** - * @psalm-api - */ -class InfoMessage +class Message { private string $rootFolder = ''; @@ -20,4 +17,4 @@ public function getRootFolder(): string { return $this->rootFolder; } -} +} \ No newline at end of file diff --git a/src/Application/Commands/Middleware/DeleteSchemaJsonMiddleware.php b/src/Application/Middlewares/DeleteSchemaJson.php similarity index 68% rename from src/Application/Commands/Middleware/DeleteSchemaJsonMiddleware.php rename to src/Application/Middlewares/DeleteSchemaJson.php index a0995f47..74905451 100644 --- a/src/Application/Commands/Middleware/DeleteSchemaJsonMiddleware.php +++ b/src/Application/Middlewares/DeleteSchemaJson.php @@ -2,12 +2,13 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Application\Commands\Middleware; +namespace ItalyStrap\ThemeJsonGenerator\Application\Middlewares; -use ItalyStrap\Bus\HandlerInterface; +use ItalyStrap\Pipeline\HandlerInterface; +use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; -class DeleteSchemaJsonMiddleware implements \ItalyStrap\Bus\MiddlewareInterface +class DeleteSchemaJson implements MiddlewareInterface { public function process(object $message, HandlerInterface $handler): int { @@ -19,4 +20,4 @@ public function process(object $message, HandlerInterface $handler): int return (int)$handler->handle($message); } -} +} \ No newline at end of file diff --git a/src/Domain/Output/Dump.php b/src/Application/Middlewares/Dump.php similarity index 75% rename from src/Domain/Output/Dump.php rename to src/Application/Middlewares/Dump.php index 0bd4f4b8..a8429cb2 100644 --- a/src/Domain/Output/Dump.php +++ b/src/Application/Middlewares/Dump.php @@ -2,11 +2,14 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Domain\Output; +namespace ItalyStrap\ThemeJsonGenerator\Application\Middlewares; +use ItalyStrap\Config\Config; use ItalyStrap\Config\ConfigInterface; -use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; +use ItalyStrap\Pipeline\HandlerInterface; +use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetsInterface; use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\DryRunMode; @@ -22,28 +25,26 @@ /** * @psalm-api */ -class Dump +class Dump implements MiddlewareInterface { public const JSON_FILE_SUFFIX = '.json'; - private ConfigInterface $config; - private FilesFinder $filesFinder; private EventDispatcherInterface $dispatcher; public function __construct( EventDispatcherInterface $dispatcher, - ConfigInterface $config, FilesFinder $filesFinder ) { - $this->config = $config; $this->filesFinder = $filesFinder; $this->dispatcher = $dispatcher; } - public function handle(DumpMessage $message): void + public function process(object $message, HandlerInterface $handler): int { + $this->needsRefactoringAddSubscriber($this->dispatcher); + $count = 0; /** * Let's test the new workflow @@ -77,6 +78,8 @@ public function handle(DumpMessage $message): void if ($count === 0) { $this->dispatcher->dispatch(new NoFileFound()); } + + return (int)$handler->handle($message); } private function generateJsonFile( @@ -104,12 +107,12 @@ private function generateScssFile(DumpMessage $message, string $fileName, ThemeJ } } - private function configureContainer(): \ItalyStrap\Empress\Injector + private function configureContainer(): \Auryn\Injector { - $injector = new \ItalyStrap\Empress\Injector(); + $injector = new \Auryn\Injector(); $injector->share($injector); - $container = $this->createContainer($injector, clone $this->config); + $container = $this->createContainer($injector, new Config()); $injector->alias(ContainerInterface::class, \get_class($container)); $injector->share($container); @@ -131,7 +134,7 @@ private function configureContainer(): \ItalyStrap\Empress\Injector } private function createContainer( - \ItalyStrap\Empress\Injector $injector, + \Auryn\Injector $injector, \ItalyStrap\Config\ConfigInterface $config ): ContainerInterface { return new class ($injector, $config) implements ContainerInterface { @@ -139,7 +142,7 @@ private function createContainer( private ConfigInterface $config; - public function __construct(\ItalyStrap\Empress\Injector $injector, ConfigInterface $config) + public function __construct(\Auryn\Injector $injector, ConfigInterface $config) { $this->injector = $injector; $this->config = $config; @@ -178,4 +181,41 @@ private function injectorHas(string $id): bool } }; } + + private function needsRefactoringAddSubscriber($subscriber): void + { + /** + * OutputInterface $output + */ + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + + $subscriber->addListener( + GeneratingFile::class, + static function (GeneratingFile $event) use ($output): void { + $output->writeln(\sprintf( + 'Generating %s file', + $event->getFileName() + )); + } + ); + + $subscriber->addListener( + GeneratedFile ::class, + static function (GeneratedFile $event) use ($output): void { + $output->writeln(\sprintf( + 'Generated %s file', + $event->getFileName() + )); + $output->writeln('========================'); + } + ); + + $subscriber->addListener( + NoFileFound::class, + /** @psalm-suppress UnusedClosureParam */ + static function (NoFileFound $event) use ($output): void { + $output->writeln(NoFileFound::M_NO_FILE_FOUND); + } + ); + } } diff --git a/src/Domain/Output/Info.php b/src/Application/Middlewares/Info.php similarity index 52% rename from src/Domain/Output/Info.php rename to src/Application/Middlewares/Info.php index be989e75..21126517 100644 --- a/src/Domain/Output/Info.php +++ b/src/Application/Middlewares/Info.php @@ -2,16 +2,19 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Domain\Output; +namespace ItalyStrap\ThemeJsonGenerator\Application\Middlewares; -use ItalyStrap\ThemeJsonGenerator\Application\InfoMessage; +use ItalyStrap\Pipeline\HandlerInterface; +use ItalyStrap\Pipeline\MiddlewareInterface; +use ItalyStrap\ThemeJsonGenerator\Application\Message; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; +use Symfony\Component\Console\Command\Command; /** * @psalm-api * @todo Implement the logic */ -class Info implements \ItalyStrap\Bus\HandlerInterface +class Info implements MiddlewareInterface { private FilesFinder $filesFinder; @@ -21,13 +24,13 @@ public function __construct( $this->filesFinder = $filesFinder; } - public function handle(object $message): int + public function process(object $message, HandlerInterface $handler): int { - /** @var InfoMessage $message */ + /** @var Message $message */ foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { echo $file->getBasename() . PHP_EOL; } - return 0; + return Command::SUCCESS; } } diff --git a/src/Domain/Output/Init.php b/src/Application/Middlewares/Init.php similarity index 69% rename from src/Domain/Output/Init.php rename to src/Application/Middlewares/Init.php index 4e33e4f9..755820d9 100644 --- a/src/Domain/Output/Init.php +++ b/src/Application/Middlewares/Init.php @@ -2,22 +2,23 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Domain\Output; +namespace ItalyStrap\ThemeJsonGenerator\Application\Middlewares; use Brick\VarExporter\VarExporter; -use ItalyStrap\ThemeJsonGenerator\Application\InitMessage; -use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\DataFromJsonTrait; +use ItalyStrap\Pipeline\HandlerInterface; +use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointCanNotBeCreated; use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointCreated; use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointDoesNotExist; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use PhpParser\Error; -use PhpParser\Node; use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\ClassConst; use PhpParser\NodeFinder; use PhpParser\ParserFactory; use Psr\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Console\Command\Command; use Webimpress\SafeWriter\Exception\ExceptionInterface as FileWriterException; use Webimpress\SafeWriter\FileWriter; use Webmozart\Assert\Assert; @@ -25,7 +26,7 @@ /** * @psalm-api */ -class Init +class Init implements MiddlewareInterface { use DataFromJsonTrait; @@ -63,11 +64,16 @@ public function __construct( $this->dispatcher = $dispatcher; } - public function handle(InitMessage $command): void + public function process(object $message, HandlerInterface $handler): int { - foreach ($this->filesFinder->find($command->getRootFolder(), 'json') as $file) { + // TODO: This should be refactored + $this->needsRefactoringAddSubscriber($this->dispatcher); + + foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { $this->generateEntryPointDataFile($file); } + + return Command::SUCCESS; } private function generateEntryPointDataFile( @@ -146,4 +152,43 @@ private function exportFromThemeJsonIfExists(\SplFileInfo $file): string return \str_replace($search, $replace, $dataExported); } + + private function needsRefactoringAddSubscriber($subscriber): void + { + /** + * OutputInterface $output + */ + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + + $subscriber->addListener( + EntryPointDoesNotExist::class, + static function (EntryPointDoesNotExist $event) use ($output): void { + $output->writeln(\sprintf( + 'Entry file does not exist, creating %s file', + $event->getFile() + )); + } + ); + + $subscriber->addListener( + EntryPointCreated::class, + static function (EntryPointCreated $event) use ($output): void { + $output->writeln(\sprintf( + 'Entry file %s created', + $event->getFile() + )); + } + ); + + $subscriber->addListener( + EntryPointCanNotBeCreated::class, + static function (EntryPointCanNotBeCreated $event) use ($output): void { + $output->writeln(\sprintf( + 'Entry file %s cannot be created because of %s', + $event->getFile(), + $event->getException()->getMessage() + )); + } + ); + } } diff --git a/src/Application/Commands/Middleware/SchemaJsonMiddleware.php b/src/Application/Middlewares/SchemaJson.php similarity index 79% rename from src/Application/Commands/Middleware/SchemaJsonMiddleware.php rename to src/Application/Middlewares/SchemaJson.php index 70643d80..c851fe77 100644 --- a/src/Application/Commands/Middleware/SchemaJsonMiddleware.php +++ b/src/Application/Middlewares/SchemaJson.php @@ -2,14 +2,16 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Application\Commands\Middleware; +namespace ItalyStrap\ThemeJsonGenerator\Application\Middlewares; +use ItalyStrap\Pipeline\HandlerInterface; +use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; use Webimpress\SafeWriter\FileWriter; -class SchemaJsonMiddleware implements \ItalyStrap\Bus\MiddlewareInterface +class SchemaJson implements MiddlewareInterface { - public function process(object $message, \ItalyStrap\Bus\HandlerInterface $handler): int + public function process(object $message, HandlerInterface $handler): int { /** @var ValidateMessage $message */ $schemaPath = $message->getSchemaPath(); @@ -39,4 +41,4 @@ private function createFileSchema(string $schemaPath): void FileWriter::writeFile($schemaPath, $schemaContent); } -} +} \ No newline at end of file diff --git a/src/Application/Middlewares/Validate.php b/src/Application/Middlewares/Validate.php new file mode 100644 index 00000000..8754b385 --- /dev/null +++ b/src/Application/Middlewares/Validate.php @@ -0,0 +1,121 @@ +validator = $validator; + $this->filesFinder = $filesFinder; + $this->dispatcher = $dispatcher; + $this->compiler = $compiler; + } + + public function process(object $message, HandlerInterface $handler): mixed + { + $this->needsRefactoringAddSubscriber($this->dispatcher); + + /** @var ValidateMessage $message */ + foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { + $this->dispatcher->dispatch(new ValidatingFile($file)); + $this->validateJsonFile($file, $message->getSchemaPath()); + $this->validator->reset(); + /** + * @todo Implementing scss validation + */ + $this->compiler->compileString(''); + } + + return (int)$handler->handle($message); + } + + private function validateJsonFile( + \SplFileInfo $file, + string $schemaPath + ): void { + $data = $this->objectFromPath((string)$file); + $this->validator->validate($data, (object)['$ref' => 'file://' . \realpath($schemaPath)]); + + if (!$this->validator->isValid()) { + $this->dispatcher->dispatch(new ValidatedFails($file, (array)$this->validator->getErrors())); + return; + } + + $this->dispatcher->dispatch(new ValidFile($file)); + } + + private function needsRefactoringAddSubscriber($subscriber): void + { + /** + * OutputInterface $output + */ + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); + + $subscriber->addListener( + ValidatingFile::class, + static function (ValidatingFile $event) use ($output): void { + $output->writeln('========================'); + $output->writeln(\sprintf( + 'Validating %s', + $event->getFile()->getFilename() + )); + } + ); + + $subscriber->addListener( + ValidFile::class, + static function (ValidFile $event) use ($output): void { + $output->writeln(\sprintf( + '%s is valid', + $event->getFile()->getFilename() + )); + } + ); + + $subscriber->addListener( + ValidatedFails::class, + static function (ValidatedFails $event) use ($output): void { + $output->writeln('# ' . $event->getFile()->getFilename() . ' file errors'); + /** + * @var array $error + */ + foreach ($event->getErrors() as $error) { + $output->writeln(\sprintf( + '- [%s] is not valid. %s', + $error['property'] ?? '', + $error['message'] ?? '' + )); + } + } + ); + } +} \ No newline at end of file diff --git a/src/Bootstrap.php b/src/Bootstrap.php index 01167d83..3b6172e2 100644 --- a/src/Bootstrap.php +++ b/src/Bootstrap.php @@ -4,68 +4,49 @@ namespace ItalyStrap\ThemeJsonGenerator; -use Symfony\Component\Console\Application; -use ItalyStrap\Bus\Bus; -use ItalyStrap\Config\Config; -use ItalyStrap\Config\ConfigInterface; -use ItalyStrap\Empress\Injector; -use ItalyStrap\Finder\Finder; -use ItalyStrap\Finder\FinderFactory; -use ItalyStrap\Finder\FinderInterface; +use ItalyStrap\Empress\ContainerBuilder; use ItalyStrap\ThemeJsonGenerator\Application\Commands\DumpCommand; use ItalyStrap\ThemeJsonGenerator\Application\Commands\InfoCommand; use ItalyStrap\ThemeJsonGenerator\Application\Commands\InitCommand; use ItalyStrap\ThemeJsonGenerator\Application\Commands\ValidateCommand; -use ItalyStrap\ThemeJsonGenerator\Application\Commands\Middleware\DeleteSchemaJsonMiddleware; -use ItalyStrap\ThemeJsonGenerator\Application\Commands\Middleware\SchemaJsonMiddleware; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Info; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Validate; -use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Container\ContainerInterface; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; /** * @psalm-api */ final class Bootstrap { + public function container(): ContainerInterface + { + $builder = new ContainerBuilder(); + + /** + * The order of the modules is important + */ +// $builder->addModule(new ModuleUI()); + $builder->addModule(new ModuleInfrastructure()); +// $builder->addModule(new ModuleDomain()); + $builder->addModule(new ModuleApplication()); + + return $builder->build(); + } public function run(): int { - $injector = new Injector(); - $injector->share($injector); - $injector->alias(ConfigInterface::class, Config::class); + $container = $this->container(); + + $application = new Application('Theme JSON Generator', '0.1.0'); - $injector->alias(FinderInterface::class, Finder::class); - $injector->delegate(Finder::class, static fn (): FinderInterface => (new FinderFactory())->make()); + $commandLoader = new ContainerCommandLoader($container, [ + InitCommand::NAME => InitCommand::class, + DumpCommand::NAME => DumpCommand::class, + ValidateCommand::NAME => ValidateCommand::class, + InfoCommand::NAME => InfoCommand::class, + ]); - $injector->alias( - EventDispatcherInterface::class, - \Symfony\Component\EventDispatcher\EventDispatcher::class - ); - $injector->share(EventDispatcherInterface::class); - $injector->share(\Symfony\Component\EventDispatcher\EventDispatcher::class); + $application->setCommandLoader($commandLoader); - $application = new Application(); - /** @psalm-suppress InvalidArgument */ - $application->add($injector->make(InitCommand::class)); - /** @psalm-suppress InvalidArgument */ - $application->add($injector->make(DumpCommand::class)); - /** @psalm-suppress InvalidArgument */ - $application->add($injector->make(ValidateCommand::class, [ - '+handler' => static function (string $named_param, Injector $injector): Bus { - $bus = new Bus( - $injector->make(Validate::class) - ); - $bus->addMiddleware( - new DeleteSchemaJsonMiddleware(), - new SchemaJsonMiddleware() - ); - return $bus; - }, - ])); - $application->add($injector->make(InfoCommand::class, [ - '+handler' => static fn(string $named_param, Injector $injector): Bus => new Bus( - $injector->make(Info::class) - ), - ])); return $application->run(); } } diff --git a/src/Domain/Output/Validate.php b/src/Domain/Output/Validate.php deleted file mode 100644 index a123f232..00000000 --- a/src/Domain/Output/Validate.php +++ /dev/null @@ -1,74 +0,0 @@ -validator = $validator; - $this->filesFinder = $filesFinder; - $this->dispatcher = $dispatcher; - $this->compiler = $compiler; - } - - public function handle(object $message): int - { - /** @var ValidateMessage $message */ - foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { - $this->dispatcher->dispatch(new ValidatingFile($file)); - $this->validateJsonFile($file, $message->getSchemaPath()); - $this->validator->reset(); - /** - * @todo Implementing scss validation - */ - $this->compiler->compileString(''); - } - - return 0; - } - - private function validateJsonFile( - \SplFileInfo $file, - string $schemaPath - ): void { - $data = $this->objectFromPath((string)$file); - $this->validator->validate($data, (object)['$ref' => 'file://' . \realpath($schemaPath)]); - - if (!$this->validator->isValid()) { - $this->dispatcher->dispatch(new ValidatedFails($file, (array)$this->validator->getErrors())); - return; - } - - $this->dispatcher->dispatch(new ValidFile($file)); - } -} diff --git a/src/Application/Commands/Utils/DataFromJsonTrait.php b/src/Infrastructure/Filesystem/DataFromJsonTrait.php similarity index 95% rename from src/Application/Commands/Utils/DataFromJsonTrait.php rename to src/Infrastructure/Filesystem/DataFromJsonTrait.php index 4bb9b56a..d3ad55dd 100644 --- a/src/Application/Commands/Utils/DataFromJsonTrait.php +++ b/src/Infrastructure/Filesystem/DataFromJsonTrait.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils; +namespace ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem; trait DataFromJsonTrait { diff --git a/src/Infrastructure/Filesystem/Path.php b/src/Infrastructure/Filesystem/Path.php new file mode 100644 index 00000000..4ce63deb --- /dev/null +++ b/src/Infrastructure/Filesystem/Path.php @@ -0,0 +1,13 @@ +pipeline = new Pipeline( + new CallbackHandler( + static fn (object $message): int => 1 + ), + ...$middleware, + ); + } + + public function handle(object $message): int + { + $result = $this->pipeline->handle($message); + + if (!is_int($result)) { + throw new \RuntimeException(\sprintf( + 'Expected middleware to return an int exit code, got %s', + get_debug_type($result), + )); + } + + return $result; + } +} diff --git a/src/ModuleApplication.php b/src/ModuleApplication.php new file mode 100644 index 00000000..01073ae3 --- /dev/null +++ b/src/ModuleApplication.php @@ -0,0 +1,53 @@ + [ + InitCommand::class => static function (ContainerInterface $container): InitCommand { + return new InitCommand(new ConsoleHandler( + $container->get(Init::class) + )); + }, + DumpCommand::class => static function (ContainerInterface $container): DumpCommand { + return new DumpCommand(new ConsoleHandler( + $container->get(Dump::class), + )); + }, + ValidateCommand::class => static function (ContainerInterface $container): ValidateCommand { + return new ValidateCommand(new ConsoleHandler( + new DeleteSchemaJson(), + new SchemaJson(), + $container->get(Validate::class) + )); + }, + InfoCommand::class => static function (ContainerInterface $container): InfoCommand { + return new InfoCommand(new ConsoleHandler( + $container->get(Info::class) + )); + }, + ], + ]; + } +} \ No newline at end of file diff --git a/src/ModuleInfrastructure.php b/src/ModuleInfrastructure.php new file mode 100644 index 00000000..4c716306 --- /dev/null +++ b/src/ModuleInfrastructure.php @@ -0,0 +1,31 @@ + [ + FinderInterface::class => Finder::class, + EventDispatcherInterface::class => \Symfony\Component\EventDispatcher\EventDispatcher::class, + ], + AurynConfig::SHARING => [ + EventDispatcherInterface::class, + \Symfony\Component\EventDispatcher\EventDispatcher::class + ], + AurynConfig::FACTORIES => [ + Finder::class => static fn (): FinderInterface => (new FinderFactory())->make(), + ], + ]; + } +} \ No newline at end of file diff --git a/tests/unit/Application/Commands/Middleware/SchemaJsonMiddlewareTest.php b/tests/unit/Application/Middlewares/SchemaJsonTest.php similarity index 62% rename from tests/unit/Application/Commands/Middleware/SchemaJsonMiddlewareTest.php rename to tests/unit/Application/Middlewares/SchemaJsonTest.php index 3fad09f8..ca03a44d 100644 --- a/tests/unit/Application/Commands/Middleware/SchemaJsonMiddlewareTest.php +++ b/tests/unit/Application/Middlewares/SchemaJsonTest.php @@ -2,22 +2,17 @@ declare(strict_types=1); -namespace ItalyStrap\Tests\Unit\Application\Commands\Middleware; +namespace ItalyStrap\Tests\Unit\Application\Middlewares; +use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Application\Commands\Middleware\SchemaJsonMiddleware; +use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\SchemaJson; -class SchemaJsonMiddlewareTest extends UnitTestCase +final class SchemaJsonTest extends UnitTestCase { - private function makeInstance(): SchemaJsonMiddleware + private function makeInstance(): SchemaJson { - return new SchemaJsonMiddleware(); - } - - public function testInstance() - { - $actual = $this->makeInstance(); - $this->assertInstanceOf(SchemaJsonMiddleware::class, $actual); + return new SchemaJson(); } public function testProcess() @@ -29,7 +24,7 @@ public function getSchemaPath(): string } }; - $handler = new class implements \ItalyStrap\Bus\HandlerInterface { + $handler = new class implements HandlerInterface { public function handle(object $message): int { return 1; diff --git a/tests/unit/Domain/Output/DumpTest.php b/tests/unit/Domain/Output/DumpTest.php index 905d6fb7..be445822 100644 --- a/tests/unit/Domain/Output/DumpTest.php +++ b/tests/unit/Domain/Output/DumpTest.php @@ -7,7 +7,7 @@ use ItalyStrap\Config\Config; use ItalyStrap\Tests\UnitTestCase; use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Dump; +use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Dump; use Prophecy\Argument; class DumpTest extends UnitTestCase diff --git a/tests/unit/Domain/Output/InitTest.php b/tests/unit/Domain/Output/InitTest.php index 5b9dd8a9..fa251d9b 100644 --- a/tests/unit/Domain/Output/InitTest.php +++ b/tests/unit/Domain/Output/InitTest.php @@ -5,8 +5,8 @@ namespace ItalyStrap\Tests\Unit\Domain\Output; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Application\InitMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Init; +use ItalyStrap\ThemeJsonGenerator\Application\Message; +use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Init; use Prophecy\Argument; class InitTest extends UnitTestCase @@ -26,6 +26,6 @@ public function testItShouldHandleButDoNothing(): void ->willReturn([]) ->shouldBeCalledOnce(); - $this->makeInstance()->handle(new InitMessage('', '')); +// $this->makeInstance()->process(new Message('')); } } diff --git a/tests/unit/Domain/Output/ValidateTest.php b/tests/unit/Domain/Output/ValidateTest.php index f9412cd1..cf6304a9 100644 --- a/tests/unit/Domain/Output/ValidateTest.php +++ b/tests/unit/Domain/Output/ValidateTest.php @@ -5,8 +5,8 @@ namespace ItalyStrap\Tests\Unit\Domain\Output; use ItalyStrap\Tests\UnitTestCase; +use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Validate; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Validate; use Prophecy\Argument; class ValidateTest extends UnitTestCase From 2a801c01f2e03f1a7bb581a207e70d1207e3ef9a Mon Sep 17 00:00:00 2001 From: Enea Date: Sat, 16 May 2026 14:11:06 +0200 Subject: [PATCH 02/13] chore(refactor): remove event-based system, replace with direct console output for improved simplicity and maintainability --- src/Application/Middlewares/Dump.php | 105 ++++++++---------- src/Application/Middlewares/Init.php | 70 +++--------- src/Application/Middlewares/Validate.php | 87 +++++---------- src/Domain/Output/Events/DryRunMode.php | 15 --- .../Events/EntryPointCanNotBeCreated.php | 31 ------ .../Output/Events/EntryPointCreated.php | 23 ---- .../Output/Events/EntryPointDoesNotExist.php | 23 ---- src/Domain/Output/Events/GeneratedFile.php | 23 ---- src/Domain/Output/Events/GeneratingFile.php | 23 ---- src/Domain/Output/Events/NoFileFound.php | 20 ---- src/Domain/Output/Events/ValidFile.php | 23 ---- src/Domain/Output/Events/ValidatedFails.php | 31 ------ src/Domain/Output/Events/ValidatingFile.php | 23 ---- tests/functional/CommandsCest.php | 4 +- 14 files changed, 95 insertions(+), 406 deletions(-) delete mode 100644 src/Domain/Output/Events/DryRunMode.php delete mode 100644 src/Domain/Output/Events/EntryPointCanNotBeCreated.php delete mode 100644 src/Domain/Output/Events/EntryPointCreated.php delete mode 100644 src/Domain/Output/Events/EntryPointDoesNotExist.php delete mode 100644 src/Domain/Output/Events/GeneratedFile.php delete mode 100644 src/Domain/Output/Events/GeneratingFile.php delete mode 100644 src/Domain/Output/Events/NoFileFound.php delete mode 100644 src/Domain/Output/Events/ValidFile.php delete mode 100644 src/Domain/Output/Events/ValidatedFails.php delete mode 100644 src/Domain/Output/Events/ValidatingFile.php diff --git a/src/Application/Middlewares/Dump.php b/src/Application/Middlewares/Dump.php index a8429cb2..71a078a6 100644 --- a/src/Application/Middlewares/Dump.php +++ b/src/Application/Middlewares/Dump.php @@ -12,38 +12,38 @@ use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetsInterface; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\DryRunMode; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\GeneratedFile; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\GeneratingFile; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\NoFileFound; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\ScssFileWriter; use Psr\Container\ContainerInterface; -use Psr\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Console\Output\OutputInterface; /** * @psalm-api */ class Dump implements MiddlewareInterface { + /** + * @var string + */ + public const M_NO_FILE_FOUND = 'No file found'; + public const JSON_FILE_SUFFIX = '.json'; private FilesFinder $filesFinder; - private EventDispatcherInterface $dispatcher; - public function __construct( - EventDispatcherInterface $dispatcher, FilesFinder $filesFinder ) { $this->filesFinder = $filesFinder; - $this->dispatcher = $dispatcher; } public function process(object $message, HandlerInterface $handler): int { - $this->needsRefactoringAddSubscriber($this->dispatcher); + /** + * OutputInterface $output + */ + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); $count = 0; /** @@ -67,43 +67,70 @@ public function process(object $message, HandlerInterface $handler): int // $dispatcher->dispatch($themeJson); if ($message->isDryRun()) { - $this->dispatcher->dispatch(new DryRunMode()); + $output->writeln(\sprintf( + 'Dry run mode enabled, skipping file generation for %s', + $fileName + )); continue; } - $this->generateJsonFile($message, $fileName, $file, $themeJson); - $this->generateScssFile($message, $fileName, $themeJson); + $this->generateJsonFile($output, $message, $fileName, $file, $themeJson); + $this->generateScssFile($output, $message, $fileName, $themeJson); } if ($count === 0) { - $this->dispatcher->dispatch(new NoFileFound()); + $output->writeln(self::M_NO_FILE_FOUND); } return (int)$handler->handle($message); } private function generateJsonFile( + OutputInterface $output, DumpMessage $message, string $fileName, \SplFileInfo $file, ThemeJson $themeJson ): void { - $this->dispatcher->dispatch(new GeneratingFile($fileName . self::JSON_FILE_SUFFIX)); + + $output->writeln(\sprintf( + 'Generating %s file', + $fileName . self::JSON_FILE_SUFFIX + )); (new JsonFileWriter($this->filesFinder->resolveJsonFile($file))) ->write($themeJson); - $this->dispatcher->dispatch(new GeneratedFile($fileName . self::JSON_FILE_SUFFIX)); + $output->writeln(\sprintf( + 'Generated %s file', + $fileName . self::JSON_FILE_SUFFIX + )); + $output->writeln('========================'); } - private function generateScssFile(DumpMessage $message, string $fileName, ThemeJson $themeJson): void + private function generateScssFile( + OutputInterface $output, + DumpMessage $message, + string $fileName, + ThemeJson $themeJson + ): void { $path_for_theme_sass = $message->getRootFolder() . DIRECTORY_SEPARATOR . $message->getSassFolder(); if ($message->getSassFolder() !== '' && \is_writable($path_for_theme_sass)) { - $this->dispatcher->dispatch(new GeneratingFile($fileName . '.scss')); + + $output->writeln(\sprintf( + 'Generating %s file', + $fileName . '.scss' + )); + (new ScssFileWriter($path_for_theme_sass . DIRECTORY_SEPARATOR . $fileName . '.scss')) ->write($themeJson); - $this->dispatcher->dispatch(new GeneratedFile($fileName . '.scss')); + + $output->writeln(\sprintf( + 'Generated %s file', + $fileName . '.scss' + )); + $output->writeln('========================'); } } @@ -119,9 +146,6 @@ private function configureContainer(): \Auryn\Injector $injector->alias(PresetsInterface::class, Presets::class); $injector->share(PresetsInterface::class); - $injector->alias(EventDispatcherInterface::class, \get_class($this->dispatcher)); - $injector->share(EventDispatcherInterface::class); - /** * Injector resolve to null if a param is nullable, so we need to be explicit and declare the param * I need this for all the classes under the Styles namespace @@ -181,41 +205,4 @@ private function injectorHas(string $id): bool } }; } - - private function needsRefactoringAddSubscriber($subscriber): void - { - /** - * OutputInterface $output - */ - $output = new \Symfony\Component\Console\Output\ConsoleOutput(); - - $subscriber->addListener( - GeneratingFile::class, - static function (GeneratingFile $event) use ($output): void { - $output->writeln(\sprintf( - 'Generating %s file', - $event->getFileName() - )); - } - ); - - $subscriber->addListener( - GeneratedFile ::class, - static function (GeneratedFile $event) use ($output): void { - $output->writeln(\sprintf( - 'Generated %s file', - $event->getFileName() - )); - $output->writeln('========================'); - } - ); - - $subscriber->addListener( - NoFileFound::class, - /** @psalm-suppress UnusedClosureParam */ - static function (NoFileFound $event) use ($output): void { - $output->writeln(NoFileFound::M_NO_FILE_FOUND); - } - ); - } } diff --git a/src/Application/Middlewares/Init.php b/src/Application/Middlewares/Init.php index 755820d9..6a902cb1 100644 --- a/src/Application/Middlewares/Init.php +++ b/src/Application/Middlewares/Init.php @@ -7,9 +7,6 @@ use Brick\VarExporter\VarExporter; use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Pipeline\MiddlewareInterface; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointCanNotBeCreated; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointCreated; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\EntryPointDoesNotExist; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use PhpParser\Error; @@ -19,6 +16,7 @@ use PhpParser\ParserFactory; use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Output\OutputInterface; use Webimpress\SafeWriter\Exception\ExceptionInterface as FileWriterException; use Webimpress\SafeWriter\FileWriter; use Webmozart\Assert\Assert; @@ -54,35 +52,38 @@ class Init implements MiddlewareInterface private FilesFinder $filesFinder; - private EventDispatcherInterface $dispatcher; - public function __construct( EventDispatcherInterface $dispatcher, FilesFinder $filesFinder ) { $this->filesFinder = $filesFinder; - $this->dispatcher = $dispatcher; } public function process(object $message, HandlerInterface $handler): int { - // TODO: This should be refactored - $this->needsRefactoringAddSubscriber($this->dispatcher); + /** + * OutputInterface $output + */ + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { - $this->generateEntryPointDataFile($file); + $this->generateEntryPointDataFile($output, $file); } return Command::SUCCESS; } private function generateEntryPointDataFile( + OutputInterface $output, \SplFileInfo $file ): void { $entryPointFileName = $file->getFilename() . self::ENTRY_POINT_EXTENSION; $entryPointRealPath = $file->getPath() . DIRECTORY_SEPARATOR . $entryPointFileName; if (!\file_exists($entryPointRealPath)) { - $this->dispatcher->dispatch(new EntryPointDoesNotExist($entryPointRealPath)); + $output->writeln(\sprintf( + 'Entry file does not exist, creating %s file', + $entryPointRealPath + )); $dataExported = $this->exportFromThemeJsonIfExists($file); $content = \sprintf( @@ -93,14 +94,18 @@ private function generateEntryPointDataFile( try { FileWriter::writeFile($entryPointRealPath, $content, 0666); } catch (FileWriterException $fileWriterException) { - $this->dispatcher->dispatch(new EntryPointCanNotBeCreated( + $output->writeln(\sprintf( + 'Entry file %s cannot be created because of %s', $entryPointRealPath, - $fileWriterException + $fileWriterException->getMessage() )); return; } - $this->dispatcher->dispatch(new EntryPointCreated($entryPointRealPath)); + $output->writeln(\sprintf( + 'Entry file %s created', + $entryPointRealPath + )); } } @@ -152,43 +157,4 @@ private function exportFromThemeJsonIfExists(\SplFileInfo $file): string return \str_replace($search, $replace, $dataExported); } - - private function needsRefactoringAddSubscriber($subscriber): void - { - /** - * OutputInterface $output - */ - $output = new \Symfony\Component\Console\Output\ConsoleOutput(); - - $subscriber->addListener( - EntryPointDoesNotExist::class, - static function (EntryPointDoesNotExist $event) use ($output): void { - $output->writeln(\sprintf( - 'Entry file does not exist, creating %s file', - $event->getFile() - )); - } - ); - - $subscriber->addListener( - EntryPointCreated::class, - static function (EntryPointCreated $event) use ($output): void { - $output->writeln(\sprintf( - 'Entry file %s created', - $event->getFile() - )); - } - ); - - $subscriber->addListener( - EntryPointCanNotBeCreated::class, - static function (EntryPointCanNotBeCreated $event) use ($output): void { - $output->writeln(\sprintf( - 'Entry file %s cannot be created because of %s', - $event->getFile(), - $event->getException()->getMessage() - )); - } - ); - } } diff --git a/src/Application/Middlewares/Validate.php b/src/Application/Middlewares/Validate.php index 8754b385..2ee5e85a 100644 --- a/src/Application/Middlewares/Validate.php +++ b/src/Application/Middlewares/Validate.php @@ -7,14 +7,11 @@ use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\ValidatedFails; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\ValidatingFile; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\ValidFile; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use JsonSchema\Validator; -use Psr\EventDispatcher\EventDispatcherInterface; use ScssPhp\ScssPhp\Compiler; +use Symfony\Component\Console\Output\OutputInterface; class Validate implements MiddlewareInterface { @@ -24,30 +21,35 @@ class Validate implements MiddlewareInterface private FilesFinder $filesFinder; - private EventDispatcherInterface $dispatcher; - private Compiler $compiler; public function __construct( - EventDispatcherInterface $dispatcher, Validator $validator, Compiler $compiler, FilesFinder $filesFinder ) { $this->validator = $validator; $this->filesFinder = $filesFinder; - $this->dispatcher = $dispatcher; $this->compiler = $compiler; } public function process(object $message, HandlerInterface $handler): mixed { - $this->needsRefactoringAddSubscriber($this->dispatcher); + /** + * OutputInterface $output + */ + $output = new \Symfony\Component\Console\Output\ConsoleOutput(); /** @var ValidateMessage $message */ foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { - $this->dispatcher->dispatch(new ValidatingFile($file)); - $this->validateJsonFile($file, $message->getSchemaPath()); + + $output->writeln('========================'); + $output->writeln(\sprintf( + 'Validating %s', + $file->getFilename() + )); + + $this->validateJsonFile($output, $file, $message->getSchemaPath()); $this->validator->reset(); /** * @todo Implementing scss validation @@ -59,6 +61,7 @@ public function process(object $message, HandlerInterface $handler): mixed } private function validateJsonFile( + OutputInterface $output, \SplFileInfo $file, string $schemaPath ): void { @@ -66,56 +69,24 @@ private function validateJsonFile( $this->validator->validate($data, (object)['$ref' => 'file://' . \realpath($schemaPath)]); if (!$this->validator->isValid()) { - $this->dispatcher->dispatch(new ValidatedFails($file, (array)$this->validator->getErrors())); - return; - } - - $this->dispatcher->dispatch(new ValidFile($file)); - } - - private function needsRefactoringAddSubscriber($subscriber): void - { - /** - * OutputInterface $output - */ - $output = new \Symfony\Component\Console\Output\ConsoleOutput(); - - $subscriber->addListener( - ValidatingFile::class, - static function (ValidatingFile $event) use ($output): void { - $output->writeln('========================'); + $output->writeln('# ' . $file->getFilename() . ' file errors'); + /** + * @var array $error + */ + foreach ((array)$this->validator->getErrors() as $error) { $output->writeln(\sprintf( - 'Validating %s', - $event->getFile()->getFilename() + '- [%s] is not valid. %s', + $error['property'] ?? '', + $error['message'] ?? '' )); } - ); - $subscriber->addListener( - ValidFile::class, - static function (ValidFile $event) use ($output): void { - $output->writeln(\sprintf( - '%s is valid', - $event->getFile()->getFilename() - )); - } - ); - - $subscriber->addListener( - ValidatedFails::class, - static function (ValidatedFails $event) use ($output): void { - $output->writeln('# ' . $event->getFile()->getFilename() . ' file errors'); - /** - * @var array $error - */ - foreach ($event->getErrors() as $error) { - $output->writeln(\sprintf( - '- [%s] is not valid. %s', - $error['property'] ?? '', - $error['message'] ?? '' - )); - } - } - ); + return; + } + + $output->writeln(\sprintf( + '%s is valid', + $file->getFilename() + )); } } \ No newline at end of file diff --git a/src/Domain/Output/Events/DryRunMode.php b/src/Domain/Output/Events/DryRunMode.php deleted file mode 100644 index e46f3066..00000000 --- a/src/Domain/Output/Events/DryRunMode.php +++ /dev/null @@ -1,15 +0,0 @@ -file = $file; - $this->exception = $exception; - } - - public function getFile(): string - { - return $this->file; - } - - public function getException(): \Throwable - { - return $this->exception; - } -} diff --git a/src/Domain/Output/Events/EntryPointCreated.php b/src/Domain/Output/Events/EntryPointCreated.php deleted file mode 100644 index 48993dc2..00000000 --- a/src/Domain/Output/Events/EntryPointCreated.php +++ /dev/null @@ -1,23 +0,0 @@ -file = $file; - } - - public function getFile(): string - { - return $this->file; - } -} diff --git a/src/Domain/Output/Events/EntryPointDoesNotExist.php b/src/Domain/Output/Events/EntryPointDoesNotExist.php deleted file mode 100644 index f499d840..00000000 --- a/src/Domain/Output/Events/EntryPointDoesNotExist.php +++ /dev/null @@ -1,23 +0,0 @@ -file = $file; - } - - public function getFile(): string - { - return $this->file; - } -} diff --git a/src/Domain/Output/Events/GeneratedFile.php b/src/Domain/Output/Events/GeneratedFile.php deleted file mode 100644 index f8a0119c..00000000 --- a/src/Domain/Output/Events/GeneratedFile.php +++ /dev/null @@ -1,23 +0,0 @@ -file = $file; - } - - public function getFileName(): string - { - return $this->file; - } -} diff --git a/src/Domain/Output/Events/GeneratingFile.php b/src/Domain/Output/Events/GeneratingFile.php deleted file mode 100644 index 1ce696ed..00000000 --- a/src/Domain/Output/Events/GeneratingFile.php +++ /dev/null @@ -1,23 +0,0 @@ -file = $file; - } - - public function getFileName(): string - { - return $this->file; - } -} diff --git a/src/Domain/Output/Events/NoFileFound.php b/src/Domain/Output/Events/NoFileFound.php deleted file mode 100644 index 16b3196e..00000000 --- a/src/Domain/Output/Events/NoFileFound.php +++ /dev/null @@ -1,20 +0,0 @@ -file = $file; - } - - public function getFile(): \SplFileInfo - { - return $this->file; - } -} diff --git a/src/Domain/Output/Events/ValidatedFails.php b/src/Domain/Output/Events/ValidatedFails.php deleted file mode 100644 index 9c4d060f..00000000 --- a/src/Domain/Output/Events/ValidatedFails.php +++ /dev/null @@ -1,31 +0,0 @@ -file = $file; - $this->errors = $errors; - } - - public function getFile(): \SplFileInfo - { - return $this->file; - } - - public function getErrors(): array - { - return $this->errors; - } -} diff --git a/src/Domain/Output/Events/ValidatingFile.php b/src/Domain/Output/Events/ValidatingFile.php deleted file mode 100644 index f74de399..00000000 --- a/src/Domain/Output/Events/ValidatingFile.php +++ /dev/null @@ -1,23 +0,0 @@ -file = $file; - } - - public function getFile(): \SplFileInfo - { - return $this->file; - } -} diff --git a/tests/functional/CommandsCest.php b/tests/functional/CommandsCest.php index 0bffbd09..ffde386d 100644 --- a/tests/functional/CommandsCest.php +++ b/tests/functional/CommandsCest.php @@ -6,7 +6,7 @@ use FunctionalTester; use ItalyStrap\Tests\FunctionalTestCase; -use ItalyStrap\ThemeJsonGenerator\Domain\Output\Events\NoFileFound; +use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Dump; class CommandsCest extends FunctionalTestCase { @@ -20,7 +20,7 @@ public function testDump(FunctionalTester $i): void // $i->runShellCommand('bin/theme-json dump --file="theme.json"'); // $i->runShellCommand('bin/theme-json dump --path="tests"'); // $i->runShellCommand('bin/theme-json dump --path="tests/_data/fixtures/themes/theme-flat/"'); - $i->dontSeeInShellOutput(NoFileFound::M_NO_FILE_FOUND); + $i->dontSeeInShellOutput(Dump::M_NO_FILE_FOUND); $i->seeResultCodeIs(0); } From 02bb2fe6be7fbca06b96725aa9b589035b989f79 Mon Sep 17 00:00:00 2001 From: Enea Date: Sat, 16 May 2026 22:00:57 +0200 Subject: [PATCH 03/13] chore(refactor): migrate ThemeJson and SectionNames to Domain namespace, remove TJGConfig, and update references across the codebase --- README.md | 2 ++ docs/01-basic-usage.md | 8 +++----- docs/02-advanced-usage.md | 12 ++++-------- docs/todo.md | 4 +--- namespace-bc-aliases.php | 2 +- src/Application/Config/TJGConfig.php | 18 ------------------ src/Application/Middlewares/Dump.php | 2 +- src/Application/Middlewares/Init.php | 3 +-- .../{Input => ThemeJson}/SectionNames.php | 2 +- .../Config => Domain/ThemeJson}/ThemeJson.php | 7 +++---- .../Filesystem}/ConvertCase.php | 2 +- tests/_data/fixtures/advanced-example.json.php | 4 ++-- tests/_data/fixtures/basic-example.json.php | 4 ++-- tests/_data/fixtures/input-data.php | 2 +- .../unit/Application/Config/ThemeJsonTest.php | 2 +- tests/unit/Domain/Input/Styles/CommonTests.php | 4 ++-- .../JsonFileWriterIntegrationTest.php | 4 ++-- .../Filesystem/JsonFileWriterTest.php | 3 +-- 18 files changed, 29 insertions(+), 56 deletions(-) delete mode 100644 src/Application/Config/TJGConfig.php rename src/Domain/{Input => ThemeJson}/SectionNames.php (93%) rename src/{Application/Config => Domain/ThemeJson}/ThemeJson.php (95%) rename src/{Helper => Infrastructure/Filesystem}/ConvertCase.php (88%) diff --git a/README.md b/README.md index 3cb33ca2..5c04432d 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ This package adheres to the [SemVer](http://semver.org/) specification and will Until the first stable version is released, BC breaks may occur. +`ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson` to `\ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson` + [🆙](#table-of-contents) ## Contributing diff --git a/docs/01-basic-usage.md b/docs/01-basic-usage.md index 96978d3c..367856e9 100644 --- a/docs/01-basic-usage.md +++ b/docs/01-basic-usage.md @@ -213,7 +213,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; return static function (ThemeJson $themeJson): void { // Your configuration code goes here @@ -229,7 +229,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; return static function (ThemeJson $themeJson): void { $themeJson->merge([ @@ -248,9 +248,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; -use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames;use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; return static function (ThemeJson $themeJson): void { $themeJson->merge([ diff --git a/docs/02-advanced-usage.md b/docs/02-advanced-usage.md index 58ccda5d..72982d77 100644 --- a/docs/02-advanced-usage.md +++ b/docs/02-advanced-usage.md @@ -43,8 +43,8 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; return static function (ThemeJson $themeJson, Presets $presets): void { // ... @@ -297,9 +297,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; -use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets;use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson;use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, Presets $presets, ContainerInterface $container): void { // ... @@ -444,8 +442,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson;use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, ContainerInterface $container): void { // Utilize the $themeJson and $container for your configuration @@ -465,8 +462,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson;use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, ContainerInterface $container): void { /** @var SomeService $someService */ diff --git a/docs/todo.md b/docs/todo.md index 8fbf84a3..c06b5a8c 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -160,9 +160,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; -use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; return static function (ThemeJson $themeJson, PresetsInterface $presets): void { diff --git a/namespace-bc-aliases.php b/namespace-bc-aliases.php index 020cec11..168aa55a 100644 --- a/namespace-bc-aliases.php +++ b/namespace-bc-aliases.php @@ -18,6 +18,6 @@ }); \class_alias( - '\ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson', + '\ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson', '\ItalyStrap\ThemeJsonGenerator\Application\Config\Blueprint' ); diff --git a/src/Application/Config/TJGConfig.php b/src/Application/Config/TJGConfig.php deleted file mode 100644 index 59be5341..00000000 --- a/src/Application/Config/TJGConfig.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @psalm-suppress DeprecatedInterface - */ -class TJGConfig extends Config -{ -} diff --git a/src/Application/Middlewares/Dump.php b/src/Application/Middlewares/Dump.php index 71a078a6..871b5d3f 100644 --- a/src/Application/Middlewares/Dump.php +++ b/src/Application/Middlewares/Dump.php @@ -8,10 +8,10 @@ use ItalyStrap\Config\ConfigInterface; use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Pipeline\MiddlewareInterface; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetsInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\ScssFileWriter; diff --git a/src/Application/Middlewares/Init.php b/src/Application/Middlewares/Init.php index 6a902cb1..195ee317 100644 --- a/src/Application/Middlewares/Init.php +++ b/src/Application/Middlewares/Init.php @@ -36,9 +36,8 @@ class Init implements MiddlewareInterface declare(strict_types=1); -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetsInterface; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; use Psr\Container\ContainerInterface; return static function (ContainerInterface $container, PresetsInterface $presets, ThemeJson $themeJson) { diff --git a/src/Domain/Input/SectionNames.php b/src/Domain/ThemeJson/SectionNames.php similarity index 93% rename from src/Domain/Input/SectionNames.php rename to src/Domain/ThemeJson/SectionNames.php index 884a05e3..b7aeac22 100644 --- a/src/Domain/Input/SectionNames.php +++ b/src/Domain/ThemeJson/SectionNames.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Domain\Input; +namespace ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson; /** * @psalm-api diff --git a/src/Application/Config/ThemeJson.php b/src/Domain/ThemeJson/ThemeJson.php similarity index 95% rename from src/Application/Config/ThemeJson.php rename to src/Domain/ThemeJson/ThemeJson.php index 0b07dc4d..79904f11 100644 --- a/src/Application/Config/ThemeJson.php +++ b/src/Domain/ThemeJson/ThemeJson.php @@ -2,16 +2,15 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Application\Config; +namespace ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson; use ItalyStrap\Config\Config; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Shadow; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetsInterface; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Duotone; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Gradient; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Palette; +use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Shadow; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Custom\Custom; +use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetsInterface; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\FontFamily; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\FontSize; diff --git a/src/Helper/ConvertCase.php b/src/Infrastructure/Filesystem/ConvertCase.php similarity index 88% rename from src/Helper/ConvertCase.php rename to src/Infrastructure/Filesystem/ConvertCase.php index 55690b10..a345a156 100644 --- a/src/Helper/ConvertCase.php +++ b/src/Infrastructure/Filesystem/ConvertCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace ItalyStrap\ThemeJsonGenerator\Helper; +namespace ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem; use function preg_replace; use function strtolower; diff --git a/tests/_data/fixtures/advanced-example.json.php b/tests/_data/fixtures/advanced-example.json.php index 607a37ab..6c4b6495 100644 --- a/tests/_data/fixtures/advanced-example.json.php +++ b/tests/_data/fixtures/advanced-example.json.php @@ -4,8 +4,6 @@ namespace ItalyStrap\Tests; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Duotone; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Gradient; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Palette; @@ -19,6 +17,8 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\FontFamily; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\FontSize; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, Presets $presets, ContainerInterface $container): void { diff --git a/tests/_data/fixtures/basic-example.json.php b/tests/_data/fixtures/basic-example.json.php index 68e0e834..573d7c88 100644 --- a/tests/_data/fixtures/basic-example.json.php +++ b/tests/_data/fixtures/basic-example.json.php @@ -4,8 +4,8 @@ namespace ItalyStrap\Tests; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; return static function (ThemeJson $themeJson): void { $themeJson->merge([ diff --git a/tests/_data/fixtures/input-data.php b/tests/_data/fixtures/input-data.php index 777fdc21..1ba4ea61 100644 --- a/tests/_data/fixtures/input-data.php +++ b/tests/_data/fixtures/input-data.php @@ -4,7 +4,7 @@ namespace ItalyStrap\Tests; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames; return [ SectionNames::VERSION => 1, diff --git a/tests/unit/Application/Config/ThemeJsonTest.php b/tests/unit/Application/Config/ThemeJsonTest.php index 74b5bd17..d1b0ca97 100644 --- a/tests/unit/Application/Config/ThemeJsonTest.php +++ b/tests/unit/Application/Config/ThemeJsonTest.php @@ -5,7 +5,7 @@ namespace ItalyStrap\Tests\Unit\Application\Config; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; class ThemeJsonTest extends UnitTestCase { diff --git a/tests/unit/Domain/Input/Styles/CommonTests.php b/tests/unit/Domain/Input/Styles/CommonTests.php index 7be76aca..756c0db9 100644 --- a/tests/unit/Domain/Input/Styles/CommonTests.php +++ b/tests/unit/Domain/Input/Styles/CommonTests.php @@ -4,9 +4,9 @@ namespace ItalyStrap\Tests\Unit\Domain\Input\Styles; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\SectionNames; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles\CommonTrait; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; trait CommonTests { diff --git a/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php b/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php index 52bdc1ff..eba49c05 100644 --- a/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php +++ b/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php @@ -5,13 +5,13 @@ namespace ItalyStrap\Tests\Unit\Infrastructure\Filesystem; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Palette; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities\Color; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities\ColorModifier; +use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles\Color as StylesColor; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles\Typography; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; class JsonFileWriterIntegrationTest extends UnitTestCase diff --git a/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php b/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php index 778349e7..b33caa21 100644 --- a/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php +++ b/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php @@ -4,9 +4,8 @@ namespace ItalyStrap\Tests\Unit\Infrastructure\Filesystem; -use ItalyStrap\Config\Config; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Application\Config\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; class JsonFileWriterTest extends UnitTestCase From d972dc9af206bc60f3a28e54bbbc86d0233724df Mon Sep 17 00:00:00 2001 From: Enea Date: Sat, 16 May 2026 22:01:19 +0200 Subject: [PATCH 04/13] chore(refactor): remove unused ConvertCase dependency from ScssFileWriter --- src/Infrastructure/Filesystem/ScssFileWriter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Infrastructure/Filesystem/ScssFileWriter.php b/src/Infrastructure/Filesystem/ScssFileWriter.php index 7d2ccae3..49ac8ffb 100644 --- a/src/Infrastructure/Filesystem/ScssFileWriter.php +++ b/src/Infrastructure/Filesystem/ScssFileWriter.php @@ -5,7 +5,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem; use ItalyStrap\Config\ConfigInterface; -use ItalyStrap\ThemeJsonGenerator\Helper\ConvertCase; use Webimpress\SafeWriter; class ScssFileWriter implements FileWriter From e65d1afc3ab6cccd626d6fb159e14548d9c8bb6d Mon Sep 17 00:00:00 2001 From: Enea Date: Sat, 16 May 2026 22:01:40 +0200 Subject: [PATCH 05/13] chore(refactor): remove unused `bus` directory, update PHP requirement to 8.2, and adjust dependencies in composer configuration --- composer.json | 9 +++++---- phpcs.xml | 1 - psalm.xml | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 6a005202..d073189f 100644 --- a/composer.json +++ b/composer.json @@ -15,12 +15,13 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php" : ">=7.4", + "php" : ">=8.2", "ext-json": "*", "italystrap/config": "^2.4", - "italystrap/empress": "^2.0", + "italystrap/empress": "dev-modularized as 2.0.x-dev", "italystrap/finder": "dev-master", + "italystrap/pipeline": "dev-main", "mexitek/phpcolors": "^1.0", "spatie/color": "~1.5.0", @@ -36,7 +37,8 @@ "symfony/process": "^v5.4", "symfony/polyfill-php80": "^1.22", "symfony/event-dispatcher": "^5.4", - "webmozart/assert": "^1.11" + "webmozart/assert": "^1.11", + "overclokk/auryn": "dev-master" }, "require-dev": { "lucatume/wp-browser": "<3.5", @@ -68,7 +70,6 @@ }, "autoload": { "psr-4": { - "ItalyStrap\\Bus\\": "bus/", "ItalyStrap\\ThemeJsonGenerator\\": "src/" }, "files": [ diff --git a/phpcs.xml b/phpcs.xml index c279cb99..d4c9b56d 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -16,7 +16,6 @@ ./bin/ - ./bus/ ./functions/ ./src/ ./tests/ diff --git a/psalm.xml b/psalm.xml index 955e3ecb..bd590bbf 100644 --- a/psalm.xml +++ b/psalm.xml @@ -11,7 +11,6 @@ > - From 714eb0a22629574db387902ef3c7b7db573afec8 Mon Sep 17 00:00:00 2001 From: Enea Date: Sun, 17 May 2026 11:20:41 +0200 Subject: [PATCH 06/13] chore(refactor): remove unused unit tests, update dependencies, and improve Docker/Codeception configuration for compatibility with PHP 8.2 and lucatume/wp-browser ^4.5 --- .docker/.env | 4 +- .docker/docker-compose.yml | 11 +- .docker/wordpress/Dockerfile | 9 +- codeception.dist.yml | 20 ++- composer.json | 12 +- src/Infrastructure/Handler/ConsoleHandler.php | 2 +- tests/.env | 4 +- tests/integration.suite.yml | 11 +- tests/src/IntegrationTestCase.php | 4 +- tests/unit/Bus/BusHandlerProviderTest.php | 136 ------------------ tests/unit/Bus/BusTest.php | 78 ---------- tests/unit/Bus/DecorateBusTest.php | 43 ------ tests/unit/Domain/Output/DumpTest.php | 16 ++- tests/unit/Domain/Output/InitTest.php | 8 +- tests/unit/Domain/Output/ValidateTest.php | 9 +- 15 files changed, 69 insertions(+), 298 deletions(-) delete mode 100644 tests/unit/Bus/BusHandlerProviderTest.php delete mode 100644 tests/unit/Bus/BusTest.php delete mode 100644 tests/unit/Bus/DecorateBusTest.php diff --git a/.docker/.env b/.docker/.env index b1cbae62..8bbb1634 100644 --- a/.docker/.env +++ b/.docker/.env @@ -1,7 +1,7 @@ # Docker only PROJECT_NAME="theme-json-generator" -PHP_VERSION="7.4" -WP_VERSION="6.0" +PHP_VERSION="8.2" +WP_VERSION="6" WP_PORT=8888 DB_PORT=8889 diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index d76891fa..4ef25bf5 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -21,7 +21,8 @@ services: - ../tests/_output/:/var/www/html/wp-content/plugins/${PROJECT_NAME:-wordpress}/tests/_output/ - ./mu-plugins/:/var/www/html/wp-content/mu-plugins/ depends_on: - - mysql + mysql: + condition: service_healthy networks: integration_test_networks: @@ -37,12 +38,18 @@ services: MYSQL_PASSWORD: ${DB_PASSWORD:-root} #MYSQL_RANDOM_ROOT_PASSWORD: '1' MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-root} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p${DB_PASSWORD:-root}"] + interval: 5s + timeout: 5s + retries: 30 networks: - integration_test_networks phpmyadmin: depends_on: - - mysql + mysql: + condition: service_healthy image: phpmyadmin/phpmyadmin:${PMA_VERSION:-latest} container_name: ${PROJECT_NAME}_phpmyadmin_test restart: always diff --git a/.docker/wordpress/Dockerfile b/.docker/wordpress/Dockerfile index f2014b35..4e5757ed 100644 --- a/.docker/wordpress/Dockerfile +++ b/.docker/wordpress/Dockerfile @@ -21,7 +21,10 @@ RUN set -eux; \ apt-get update && apt-get install -y \ git \ nano \ - less # Needed for the WP-CLI \ + less \ + unzip \ + zip \ + ; \ rm -rf /var/lib/apt/lists/* # Git add safe directory for the working directory @@ -32,7 +35,9 @@ RUN set -eux; \ RUN docker-php-ext-install \ pdo_mysql -COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer +RUN curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php && \ + php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer && \ + rm /tmp/composer-setup.php RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \ chmod +x wp-cli.phar && \ diff --git a/codeception.dist.yml b/codeception.dist.yml index a3aa5ab9..7d264085 100644 --- a/codeception.dist.yml +++ b/codeception.dist.yml @@ -9,13 +9,19 @@ extensions: enabled: - Codeception\Extension\RunFailed commands: - - Codeception\Command\GenerateWPUnit - - Codeception\Command\GenerateWPRestApi - - Codeception\Command\GenerateWPRestController - - Codeception\Command\GenerateWPRestPostTypeController - - Codeception\Command\GenerateWPAjax - - Codeception\Command\GenerateWPCanonical - - Codeception\Command\GenerateWPXMLRPC + - lucatume\WPBrowser\Command\RunOriginal + - lucatume\WPBrowser\Command\RunAll + - lucatume\WPBrowser\Command\DbExport + - lucatume\WPBrowser\Command\DbImport + - lucatume\WPBrowser\Command\MonkeyCachePath + - lucatume\WPBrowser\Command\MonkeyCacheClear + - lucatume\WPBrowser\Command\GenerateWPUnit + - lucatume\WPBrowser\Command\GenerateWPRestApi + - lucatume\WPBrowser\Command\GenerateWPRestController + - lucatume\WPBrowser\Command\GenerateWPRestPostTypeController + - lucatume\WPBrowser\Command\GenerateWPAjax + - lucatume\WPBrowser\Command\GenerateWPCanonical + - lucatume\WPBrowser\Command\GenerateWPXMLRPC params: - tests/.env coverage: diff --git a/composer.json b/composer.json index d073189f..68b20332 100644 --- a/composer.json +++ b/composer.json @@ -41,14 +41,14 @@ "overclokk/auryn": "dev-master" }, "require-dev": { - "lucatume/wp-browser": "<3.5", + "lucatume/wp-browser": "^4.5", "phpspec/prophecy-phpunit": "^2.0", - "codeception/module-asserts": "^1.0", - "codeception/module-phpbrowser": "^1.0", - "codeception/module-db": "^1.0", - "codeception/module-filesystem": "^1.0", - "codeception/module-cli": "^1.0", + "codeception/module-asserts": "^3.0", + "codeception/module-phpbrowser": "^3.0", + "codeception/module-db": "^3.0", + "codeception/module-filesystem": "^3.0", + "codeception/module-cli": "^2.0", "codeception/util-universalframework": "^1.0", "squizlabs/php_codesniffer": "*", diff --git a/src/Infrastructure/Handler/ConsoleHandler.php b/src/Infrastructure/Handler/ConsoleHandler.php index f14dd3e0..c5dc3f04 100644 --- a/src/Infrastructure/Handler/ConsoleHandler.php +++ b/src/Infrastructure/Handler/ConsoleHandler.php @@ -21,7 +21,7 @@ public function __construct(MiddlewareInterface ...$middleware) { $this->pipeline = new Pipeline( new CallbackHandler( - static fn (object $message): int => 1 + static fn (object $message): int => self::SUCCESS ), ...$middleware, ); diff --git a/tests/.env b/tests/.env index 78484b7c..d5f17d0c 100644 --- a/tests/.env +++ b/tests/.env @@ -1,7 +1,7 @@ # Codeception configuration file ROOT_FOLDER="../../../" -DB_HOST="localhost" +DB_HOST="mysql" DB_NAME="test" DB_USER="root" DB_PASSWORD="root" @@ -9,4 +9,4 @@ DB_PASSWORD="root" TABLE_PREFIX="wp_" DOMAIN="localhost" -ADMIN_EMAIL="admin@localhost.test" \ No newline at end of file +ADMIN_EMAIL="admin@localhost.test" diff --git a/tests/integration.suite.yml b/tests/integration.suite.yml index 4155150b..83657c16 100644 --- a/tests/integration.suite.yml +++ b/tests/integration.suite.yml @@ -2,16 +2,13 @@ actor: IntegrationTester modules: enabled: - Asserts - - WPLoader + - lucatume\WPBrowser\Module\WPLoader - \Helper\Integration config: - WPLoader: + lucatume\WPBrowser\Module\WPLoader: wpRootFolder: "%ROOT_FOLDER%" - dbName: "%DB_NAME%" - dbHost: "%DB_HOST%" - dbUser: "%DB_USER%" - dbPassword: "%DB_PASSWORD%" + dbUrl: "mysql://%DB_USER%:%DB_PASSWORD%@%DB_HOST%/%DB_NAME%" tablePrefix: "%TABLE_PREFIX%" domain: "%DOMAIN%" adminEmail: "%ADMIN_EMAIL%" - title: "Test" \ No newline at end of file + title: "Test" diff --git a/tests/src/IntegrationTestCase.php b/tests/src/IntegrationTestCase.php index f931c3a7..52be6099 100644 --- a/tests/src/IntegrationTestCase.php +++ b/tests/src/IntegrationTestCase.php @@ -4,11 +4,11 @@ namespace ItalyStrap\Tests; -use Codeception\TestCase\WPTestCase; +use lucatume\WPBrowser\TestCase\WPTestCase; class IntegrationTestCase extends WPTestCase { - protected \IntegrationTester $tester; + protected $tester; protected function setUp(): void { diff --git a/tests/unit/Bus/BusHandlerProviderTest.php b/tests/unit/Bus/BusHandlerProviderTest.php deleted file mode 100644 index 52d513d9..00000000 --- a/tests/unit/Bus/BusHandlerProviderTest.php +++ /dev/null @@ -1,136 +0,0 @@ -getMessage(); - } - }; - } - - private function makeMessage2(): object - { - static $message; - if ($message) { - return $message; - } - - $message = new class { - public function getMessage(): string - { - return 'World'; - } - }; - - return $message; - } - - private function makeHandler2(): HandlerInterface - { - return new class implements HandlerInterface { - public function handle(object $message): string - { - return $message->getMessage(); - } - }; - } - - private function makeHandlerProvider(): HandlerInterface - { - return new class implements HandlerInterface { - private array $handlers = []; - - /** - * @param class-string $messageName - */ - public function addHandler(HandlerInterface $handler, string $messageName): void - { - $this->handlers[$messageName] = $handler; - } - - public function getHandlerForCommand(object $message): HandlerInterface - { - $messageClass = \get_class($message); - if (\array_key_exists($messageClass, $this->handlers)) { - return $this->handlers[$messageClass]; - } - - throw new \InvalidArgumentException(\sprintf( - 'No handler for message %s', - $messageClass - )); - } - - /** - * @return mixed - */ - public function handle(object $message) - { - return $this->getHandlerForCommand($message)->handle($message); - } - }; - } - - private array $handlers = []; - - private function makeInstance(): Bus - { - $handlerProvider = $this->makeHandlerProvider(); - foreach ($this->handlers as $messageName => $handler) { - $handlerProvider->addHandler($handler, $messageName); - } - - return new Bus($handlerProvider); - } - - public function testMessage1(): void - { - $this->handlers[\get_class($this->makeMessage1())] = $this->makeHandler1(); - - $sut = $this->makeInstance(); - - $result = $sut->handle($this->makeMessage1()); - - $this->assertSame('Hello', $result); - } - - public function testMessage2(): void - { - $this->handlers[\get_class($this->makeMessage2())] = $this->makeHandler2(); - - $sut = $this->makeInstance(); - - $result = $sut->handle($this->makeMessage2()); - - $this->assertSame('World', $result); - } -} diff --git a/tests/unit/Bus/BusTest.php b/tests/unit/Bus/BusTest.php deleted file mode 100644 index 14643506..00000000 --- a/tests/unit/Bus/BusTest.php +++ /dev/null @@ -1,78 +0,0 @@ -getMessage(); - return 1; - } - }); - } - - public function testItShouldDoSomething(): void - { - $sut = $this->makeInstance(); - - $order = []; - $sut->addMiddleware(new class ($order) implements MiddlewareInterface { - private array $order; - - public function __construct(array &$order) - { - $this->order = &$order; - } - - public function process(object $message, HandlerInterface $handler) - { - $this->order[] = 'Generate'; - return $handler->handle($message); - } - }); - - $sut->addMiddleware(new class ($order) implements MiddlewareInterface { - private array $order; - - public function __construct(array &$order) - { - $this->order = &$order; - } - - public function process(object $message, HandlerInterface $handler) - { - $this->order[] = 'Validate'; - return $handler->handle($message); - } - }); - - $result = $sut->handle(new class ($order) { - private array $order; - - public function __construct(array &$order) - { - $this->order = &$order; - } - - public function getMessage(): string - { - $this->order[] = 'Handler called'; - return 'Hello World'; - } - }); - - $this->assertSame(1, $result); - $this->assertSame(['Generate', 'Validate', 'Handler called'], $order); - } -} diff --git a/tests/unit/Bus/DecorateBusTest.php b/tests/unit/Bus/DecorateBusTest.php deleted file mode 100644 index 9896b5f4..00000000 --- a/tests/unit/Bus/DecorateBusTest.php +++ /dev/null @@ -1,43 +0,0 @@ -getMessage() === 'Hello') { - return $handler->handle($message); - } - - return 0; - } - }, - new class implements \ItalyStrap\Bus\HandlerInterface { - public function handle(object $message): int - { - return 1; - } - } - )); - - $result = $sut->handle(new class { - public function getMessage(): string - { - return 'Hello'; - } - }); - - $this->assertSame(1, $result); - } -} diff --git a/tests/unit/Domain/Output/DumpTest.php b/tests/unit/Domain/Output/DumpTest.php index be445822..f85b4d10 100644 --- a/tests/unit/Domain/Output/DumpTest.php +++ b/tests/unit/Domain/Output/DumpTest.php @@ -4,7 +4,7 @@ namespace ItalyStrap\Tests\Unit\Domain\Output; -use ItalyStrap\Config\Config; +use ItalyStrap\Pipeline\CallbackHandler; use ItalyStrap\Tests\UnitTestCase; use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Dump; @@ -15,13 +15,15 @@ class DumpTest extends UnitTestCase private function makeInstance(): Dump { return new Dump( - $this->makeDispatcher(), - // $this->makeConfig(), - new Config(), $this->makeFilesFinder(), ); } + private function makeHandler(): CallbackHandler + { + return new CallbackHandler(static fn (object $message): int => 0); + } + public function testItShouldHandleButDoNothing(): void { $this->filesFinder @@ -29,7 +31,7 @@ public function testItShouldHandleButDoNothing(): void ->willReturn([]) ->shouldBeCalledOnce(); - $this->makeInstance()->handle(new DumpMessage('', '', false, '')); + $this->makeInstance()->process(new DumpMessage('', '', false, ''), $this->makeHandler()); } public function testItShouldBasicExample(): void @@ -45,7 +47,7 @@ public function testItShouldBasicExample(): void ->resolveJsonFile($basicExample) ->willReturn(\codecept_data_dir('fixtures/basic-example.json')); - $this->makeInstance()->handle(new DumpMessage('', '', false, '')); + $this->makeInstance()->process(new DumpMessage('', '', false, ''), $this->makeHandler()); $generatedFile = new \SplFileInfo(\codecept_data_dir('fixtures/basic-example.json')); $this->assertFileExists($generatedFile->getPathname(), 'The file was not generated'); @@ -66,7 +68,7 @@ public function testItShouldAdvancedExample(): void ->resolveJsonFile($advancedExample) ->willReturn(\codecept_data_dir('fixtures/advanced-example.json')); - $this->makeInstance()->handle(new DumpMessage('', '', false, '')); + $this->makeInstance()->process(new DumpMessage('', '', false, ''), $this->makeHandler()); $generatedFile = new \SplFileInfo(\codecept_data_dir('fixtures/advanced-example.json')); $this->assertFileExists($generatedFile->getPathname(), 'The file was not generated'); diff --git a/tests/unit/Domain/Output/InitTest.php b/tests/unit/Domain/Output/InitTest.php index fa251d9b..093b4914 100644 --- a/tests/unit/Domain/Output/InitTest.php +++ b/tests/unit/Domain/Output/InitTest.php @@ -4,6 +4,7 @@ namespace ItalyStrap\Tests\Unit\Domain\Output; +use ItalyStrap\Pipeline\CallbackHandler; use ItalyStrap\Tests\UnitTestCase; use ItalyStrap\ThemeJsonGenerator\Application\Message; use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Init; @@ -19,6 +20,11 @@ private function makeInstance(): Init ); } + private function makeHandler(): CallbackHandler + { + return new CallbackHandler(static fn (object $message): int => 0); + } + public function testItShouldHandleButDoNothing(): void { $this->filesFinder @@ -26,6 +32,6 @@ public function testItShouldHandleButDoNothing(): void ->willReturn([]) ->shouldBeCalledOnce(); -// $this->makeInstance()->process(new Message('')); + $this->makeInstance()->process(new Message(''), $this->makeHandler()); } } diff --git a/tests/unit/Domain/Output/ValidateTest.php b/tests/unit/Domain/Output/ValidateTest.php index cf6304a9..f1edabd7 100644 --- a/tests/unit/Domain/Output/ValidateTest.php +++ b/tests/unit/Domain/Output/ValidateTest.php @@ -4,6 +4,7 @@ namespace ItalyStrap\Tests\Unit\Domain\Output; +use ItalyStrap\Pipeline\CallbackHandler; use ItalyStrap\Tests\UnitTestCase; use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Validate; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; @@ -14,13 +15,17 @@ class ValidateTest extends UnitTestCase private function makeInstance(): Validate { return new Validate( - $this->makeDispatcher(), $this->makeValidator(), $this->makeCompiler(), $this->makeFilesFinder() ); } + private function makeHandler(): CallbackHandler + { + return new CallbackHandler(static fn (object $message): int => 0); + } + public function testItShouldHandleButDoNothing(): void { $this->filesFinder @@ -28,6 +33,6 @@ public function testItShouldHandleButDoNothing(): void ->willReturn([]) ->shouldBeCalledOnce(); - $this->makeInstance()->handle(new ValidateMessage('', '')); + $this->makeInstance()->process(new ValidateMessage('', ''), $this->makeHandler()); } } From 11e61b8722b8988195af944edec9d8e5f76e729b Mon Sep 17 00:00:00 2001 From: Enea Date: Sun, 17 May 2026 11:28:43 +0200 Subject: [PATCH 07/13] chore(ci): update workflows to support PHP 8.2, replace outdated dependencies, and refine configuration for improved consistency --- .github/workflows/lint.yml | 8 ++++---- .github/workflows/static-analysis.yml | 8 ++++---- .github/workflows/test.yml | 17 ++++++++++------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6e39329a..cd0ae64a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,12 +18,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.2' - name: Validate composer.json and composer.lock run: composer validate --strict @@ -31,7 +31,7 @@ jobs: - name: Validate php files run: find ./src/ ./tests/ -type f -name '*.php' -print0 | xargs -0 -L 1 -P 4 -- php -l - - uses: ramsey/composer-install@v2 + - uses: ramsey/composer-install@v3 - name: Coding standard - run: composer run cs \ No newline at end of file + run: composer run cs diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index fe814ae9..082d67b6 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -18,14 +18,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 7.4 + php-version: '8.2' - - uses: ramsey/composer-install@v2 + - uses: ramsey/composer-install@v3 - name: Psalm - run: vendor/bin/psalm \ No newline at end of file + run: vendor/bin/psalm diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 98a08e26..26ed382b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: CI env: PROJECT_KIND: plugins - DB_HOST: localhost + DB_HOST: 127.0.0.1 DB_NAME: test DB_USER: root DB_PASSWORD: root @@ -28,19 +28,18 @@ on: jobs: tests: - name: 🐘 Tests on PHP ${{matrix.php_versions}} & APP version ${{matrix.app_versions}} + name: Tests on PHP ${{ matrix.php_versions }} & WordPress ${{ matrix.app_versions }} strategy: matrix: - php_versions: ['7.4', '8.0'] - app_versions: ['6.0'] + php_versions: ['8.2'] + app_versions: ['6'] runs-on: ubuntu-latest - continue-on-error: ${{ matrix.php_versions == '8.0' }} if: "!contains(github.event.head_commit.message, '--skip ci') && !github.event.pull_request.draft" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -74,7 +73,7 @@ jobs: pwd ls -la ${{env.APP_FOLDER_PATH}}/wp-includes - - uses: "ramsey/composer-install@v2" + - uses: "ramsey/composer-install@v3" with: working-directory: "${{env.APP_FOLDER_PATH}}/wp-content/${{env.PROJECT_KIND}}/${{ github.event.repository.name }}" @@ -92,6 +91,10 @@ jobs: - name: Verify MySQL is Running run: sudo systemctl status mysql.service + - name: Configure Codeception database host + working-directory: ${{env.APP_FOLDER_PATH}}/wp-content/${{env.PROJECT_KIND}}/${{ github.event.repository.name }} + run: sed -i 's/DB_HOST="mysql"/DB_HOST="${{ env.DB_HOST }}"/' tests/.env + - name: Build codeception working-directory: ${{env.APP_FOLDER_PATH}}/wp-content/${{env.PROJECT_KIND}}/${{ github.event.repository.name }} run: ./vendor/bin/codecept build From b2a67c33b3943c14bcf447924a905ec1fd432159 Mon Sep 17 00:00:00 2001 From: Enea Date: Sun, 17 May 2026 11:34:43 +0200 Subject: [PATCH 08/13] chore: update to PHP 8.2 compatibility, fix code style issues, and ensure proper file endings throughout the codebase --- phpcs.xml | 2 +- src/Application/Message.php | 2 +- src/Application/Middlewares/DeleteSchemaJson.php | 2 +- src/Application/Middlewares/Dump.php | 4 +--- src/Application/Middlewares/SchemaJson.php | 2 +- src/Application/Middlewares/Validate.php | 3 +-- src/Infrastructure/Filesystem/Path.php | 2 +- src/ModuleApplication.php | 2 +- src/ModuleInfrastructure.php | 2 +- 9 files changed, 9 insertions(+), 12 deletions(-) diff --git a/phpcs.xml b/phpcs.xml index d4c9b56d..ca4933e3 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -13,7 +13,7 @@ - + ./bin/ ./functions/ diff --git a/src/Application/Message.php b/src/Application/Message.php index a085259d..ee2f460b 100644 --- a/src/Application/Message.php +++ b/src/Application/Message.php @@ -17,4 +17,4 @@ public function getRootFolder(): string { return $this->rootFolder; } -} \ No newline at end of file +} diff --git a/src/Application/Middlewares/DeleteSchemaJson.php b/src/Application/Middlewares/DeleteSchemaJson.php index 74905451..e2540810 100644 --- a/src/Application/Middlewares/DeleteSchemaJson.php +++ b/src/Application/Middlewares/DeleteSchemaJson.php @@ -20,4 +20,4 @@ public function process(object $message, HandlerInterface $handler): int return (int)$handler->handle($message); } -} \ No newline at end of file +} diff --git a/src/Application/Middlewares/Dump.php b/src/Application/Middlewares/Dump.php index 871b5d3f..3036bbf9 100644 --- a/src/Application/Middlewares/Dump.php +++ b/src/Application/Middlewares/Dump.php @@ -113,11 +113,9 @@ private function generateScssFile( DumpMessage $message, string $fileName, ThemeJson $themeJson - ): void - { + ): void { $path_for_theme_sass = $message->getRootFolder() . DIRECTORY_SEPARATOR . $message->getSassFolder(); if ($message->getSassFolder() !== '' && \is_writable($path_for_theme_sass)) { - $output->writeln(\sprintf( 'Generating %s file', $fileName . '.scss' diff --git a/src/Application/Middlewares/SchemaJson.php b/src/Application/Middlewares/SchemaJson.php index c851fe77..1124d04e 100644 --- a/src/Application/Middlewares/SchemaJson.php +++ b/src/Application/Middlewares/SchemaJson.php @@ -41,4 +41,4 @@ private function createFileSchema(string $schemaPath): void FileWriter::writeFile($schemaPath, $schemaContent); } -} \ No newline at end of file +} diff --git a/src/Application/Middlewares/Validate.php b/src/Application/Middlewares/Validate.php index 2ee5e85a..a2301027 100644 --- a/src/Application/Middlewares/Validate.php +++ b/src/Application/Middlewares/Validate.php @@ -42,7 +42,6 @@ public function process(object $message, HandlerInterface $handler): mixed /** @var ValidateMessage $message */ foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { - $output->writeln('========================'); $output->writeln(\sprintf( 'Validating %s', @@ -89,4 +88,4 @@ private function validateJsonFile( $file->getFilename() )); } -} \ No newline at end of file +} diff --git a/src/Infrastructure/Filesystem/Path.php b/src/Infrastructure/Filesystem/Path.php index 4ce63deb..ae59afb8 100644 --- a/src/Infrastructure/Filesystem/Path.php +++ b/src/Infrastructure/Filesystem/Path.php @@ -10,4 +10,4 @@ private function cwd(): string { return (string)\getcwd(); } -} \ No newline at end of file +} diff --git a/src/ModuleApplication.php b/src/ModuleApplication.php index 01073ae3..20a2ff93 100644 --- a/src/ModuleApplication.php +++ b/src/ModuleApplication.php @@ -50,4 +50,4 @@ public function __invoke(): array ], ]; } -} \ No newline at end of file +} diff --git a/src/ModuleInfrastructure.php b/src/ModuleInfrastructure.php index 4c716306..a59b5064 100644 --- a/src/ModuleInfrastructure.php +++ b/src/ModuleInfrastructure.php @@ -28,4 +28,4 @@ public function __invoke(): array ], ]; } -} \ No newline at end of file +} From 41c8e2668886d54fcb8a35cb858c16552cf6ae75 Mon Sep 17 00:00:00 2001 From: Enea Date: Sun, 17 May 2026 11:36:56 +0200 Subject: [PATCH 09/13] chore(ci): rename workflow from "CI" to "Test" for clarity --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 26ed382b..2cd19c67 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: CI +name: Test env: PROJECT_KIND: plugins From 04859fd9590c2024640b5f0713f4936362bc7401 Mon Sep 17 00:00:00 2001 From: Enea Date: Sun, 17 May 2026 11:39:16 +0200 Subject: [PATCH 10/13] chore(ci): update app version matrix to include 6.9 in test workflow --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2cd19c67..47244e27 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: strategy: matrix: php_versions: ['8.2'] - app_versions: ['6'] + app_versions: ['6.9'] runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, '--skip ci') && !github.event.pull_request.draft" From a6f449858d8026690dc442d768b2c7770c2a85b5 Mon Sep 17 00:00:00 2001 From: Enea Date: Sun, 17 May 2026 12:22:05 +0200 Subject: [PATCH 11/13] chore(refactor): fixed 5 PHP 8.4 nullable warnings by making nullable parameters explicit --- src/Domain/Input/Settings/Color/Utilities/Color.php | 4 ++-- src/Domain/Input/Settings/Color/Utilities/ColorModifier.php | 2 +- src/Domain/Input/Styles/CommonTrait.php | 2 +- src/Domain/Input/Styles/Css.php | 2 +- src/Domain/Input/Styles/Scss.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Domain/Input/Settings/Color/Utilities/Color.php b/src/Domain/Input/Settings/Color/Utilities/Color.php index eb990a9b..ac693975 100644 --- a/src/Domain/Input/Settings/Color/Utilities/Color.php +++ b/src/Domain/Input/Settings/Color/Utilities/Color.php @@ -170,7 +170,7 @@ public function toHsl(): self return new self((string) $this->spatieColor->toHsl()); } - public function toHsla(float $alpha = null): self + public function toHsla(?float $alpha = null): self { $alpha = $alpha ?? $this->fromHexToFloat($this->alpha); return new self((string) $this->spatieColor->toHsla($alpha)); @@ -181,7 +181,7 @@ public function toRgb(): self return new self((string) $this->spatieColor->toRgb()); } - public function toRgba(float $alpha = null): self + public function toRgba(?float $alpha = null): self { $alpha = $alpha ?? $this->fromHexToFloat($this->alpha); return new self((string) $this->spatieColor->toRgba($alpha)); diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php b/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php index fc3c54a7..59d932c6 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php @@ -20,7 +20,7 @@ final class ColorModifier implements ColorModifierInterface /** * @throws Exception */ - public function __construct(ColorInterface $color, ColorFactoryInterface $factory = null) + public function __construct(ColorInterface $color, ?ColorFactoryInterface $factory = null) { $this->color = $color; $this->color_factory = $factory ?? new ColorFactory(); diff --git a/src/Domain/Input/Styles/CommonTrait.php b/src/Domain/Input/Styles/CommonTrait.php index e8219cfa..46975302 100644 --- a/src/Domain/Input/Styles/CommonTrait.php +++ b/src/Domain/Input/Styles/CommonTrait.php @@ -21,7 +21,7 @@ trait CommonTrait * @param array $properties */ public function __construct( - PresetsInterface $presets = null, + ?PresetsInterface $presets = null, array $properties = [] ) { $this->presets = $presets ?? new NullPresets(); diff --git a/src/Domain/Input/Styles/Css.php b/src/Domain/Input/Styles/Css.php index b8fbfa50..05668b9f 100644 --- a/src/Domain/Input/Styles/Css.php +++ b/src/Domain/Input/Styles/Css.php @@ -27,7 +27,7 @@ class Css implements CssInterface private bool $shouldResolveVariables = true; public function __construct( - PresetsInterface $presets = null + ?PresetsInterface $presets = null ) { $this->presets = $presets ?? new NullPresets(); } diff --git a/src/Domain/Input/Styles/Scss.php b/src/Domain/Input/Styles/Scss.php index a33f8cb8..ef8e876d 100644 --- a/src/Domain/Input/Styles/Scss.php +++ b/src/Domain/Input/Styles/Scss.php @@ -28,7 +28,7 @@ class Scss implements CssInterface public function __construct( Css $css, Compiler $compiler, - PresetsInterface $presets = null + ?PresetsInterface $presets = null ) { $this->css = $css; $this->compiler = $compiler; From 4b4c68cd61789f7590385d628d084d2a202d2edb Mon Sep 17 00:00:00 2001 From: Enea Date: Mon, 18 May 2026 05:55:59 +0200 Subject: [PATCH 12/13] chore(refactor): move `ThemeJson` and `SectionNames` to `Api` namespace, update references across codebase, and remove outdated namespace aliases --- docs/01-basic-usage.md | 6 +++--- docs/02-advanced-usage.md | 9 ++++----- docs/todo.md | 2 +- namespace-bc-aliases.php | 20 ------------------- .../ThemeJson => Api}/SectionNames.php | 2 +- src/{Domain/ThemeJson => Api}/ThemeJson.php | 2 +- src/Application/Middlewares/Dump.php | 2 +- src/Application/Middlewares/Init.php | 2 +- .../_data/fixtures/advanced-example.json.php | 4 ++-- tests/_data/fixtures/basic-example.json.php | 4 ++-- tests/_data/fixtures/input-data.php | 2 +- .../Config => Api}/ThemeJsonTest.php | 4 ++-- .../unit/Domain/Input/Styles/CommonTests.php | 4 ++-- .../JsonFileWriterIntegrationTest.php | 2 +- .../Filesystem/JsonFileWriterTest.php | 2 +- 15 files changed, 23 insertions(+), 44 deletions(-) rename src/{Domain/ThemeJson => Api}/SectionNames.php (93%) rename src/{Domain/ThemeJson => Api}/ThemeJson.php (97%) rename tests/unit/{Application/Config => Api}/ThemeJsonTest.php (95%) diff --git a/docs/01-basic-usage.md b/docs/01-basic-usage.md index 367856e9..aee2b396 100644 --- a/docs/01-basic-usage.md +++ b/docs/01-basic-usage.md @@ -213,7 +213,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; return static function (ThemeJson $themeJson): void { // Your configuration code goes here @@ -229,7 +229,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; return static function (ThemeJson $themeJson): void { $themeJson->merge([ @@ -248,7 +248,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames;use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\SectionNames;use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; return static function (ThemeJson $themeJson): void { $themeJson->merge([ diff --git a/docs/02-advanced-usage.md b/docs/02-advanced-usage.md index 72982d77..528bf277 100644 --- a/docs/02-advanced-usage.md +++ b/docs/02-advanced-usage.md @@ -43,8 +43,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson;use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; return static function (ThemeJson $themeJson, Presets $presets): void { // ... @@ -297,7 +296,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets;use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson;use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson;use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets;use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, Presets $presets, ContainerInterface $container): void { // ... @@ -442,7 +441,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson;use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson;use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, ContainerInterface $container): void { // Utilize the $themeJson and $container for your configuration @@ -462,7 +461,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson;use Psr\Container\ContainerInterface; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson;use Psr\Container\ContainerInterface; return static function (ThemeJson $themeJson, ContainerInterface $container): void { /** @var SomeService $someService */ diff --git a/docs/todo.md b/docs/todo.md index c06b5a8c..2b5af7d1 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -160,7 +160,7 @@ declare(strict_types=1); namespace YourVendor\YourProject; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; return static function (ThemeJson $themeJson, PresetsInterface $presets): void { diff --git a/namespace-bc-aliases.php b/namespace-bc-aliases.php index 168aa55a..174d7fd7 100644 --- a/namespace-bc-aliases.php +++ b/namespace-bc-aliases.php @@ -1,23 +1,3 @@ merge([ diff --git a/tests/_data/fixtures/input-data.php b/tests/_data/fixtures/input-data.php index 1ba4ea61..1639b21b 100644 --- a/tests/_data/fixtures/input-data.php +++ b/tests/_data/fixtures/input-data.php @@ -4,7 +4,7 @@ namespace ItalyStrap\Tests; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Api\SectionNames; return [ SectionNames::VERSION => 1, diff --git a/tests/unit/Application/Config/ThemeJsonTest.php b/tests/unit/Api/ThemeJsonTest.php similarity index 95% rename from tests/unit/Application/Config/ThemeJsonTest.php rename to tests/unit/Api/ThemeJsonTest.php index d1b0ca97..0d0413e0 100644 --- a/tests/unit/Application/Config/ThemeJsonTest.php +++ b/tests/unit/Api/ThemeJsonTest.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace ItalyStrap\Tests\Unit\Application\Config; +namespace ItalyStrap\Tests\Unit\Api; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; class ThemeJsonTest extends UnitTestCase { diff --git a/tests/unit/Domain/Input/Styles/CommonTests.php b/tests/unit/Domain/Input/Styles/CommonTests.php index 756c0db9..d2b65860 100644 --- a/tests/unit/Domain/Input/Styles/CommonTests.php +++ b/tests/unit/Domain/Input/Styles/CommonTests.php @@ -4,9 +4,9 @@ namespace ItalyStrap\Tests\Unit\Domain\Input\Styles; +use ItalyStrap\ThemeJsonGenerator\Api\SectionNames; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles\CommonTrait; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\SectionNames; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; trait CommonTests { diff --git a/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php b/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php index eba49c05..c42c0eaf 100644 --- a/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php +++ b/tests/unit/Infrastructure/Filesystem/JsonFileWriterIntegrationTest.php @@ -5,13 +5,13 @@ namespace ItalyStrap\Tests\Unit\Infrastructure\Filesystem; use ItalyStrap\Tests\UnitTestCase; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Palette; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities\Color; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities\ColorModifier; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Presets; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles\Color as StylesColor; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles\Typography; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; class JsonFileWriterIntegrationTest extends UnitTestCase diff --git a/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php b/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php index b33caa21..b694455a 100644 --- a/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php +++ b/tests/unit/Infrastructure/Filesystem/JsonFileWriterTest.php @@ -5,7 +5,7 @@ namespace ItalyStrap\Tests\Unit\Infrastructure\Filesystem; use ItalyStrap\Tests\UnitTestCase; -use ItalyStrap\ThemeJsonGenerator\Domain\ThemeJson\ThemeJson; +use ItalyStrap\ThemeJsonGenerator\Api\ThemeJson; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; class JsonFileWriterTest extends UnitTestCase From bf9a33c1dbef0be15df4a73a7901a49869435e69 Mon Sep 17 00:00:00 2001 From: Enea Scerba Date: Mon, 18 May 2026 09:32:58 +0200 Subject: [PATCH 13/13] Replace psalm with phpstan --- .github/workflows/static-analysis.yml | 6 +-- Makefile | 22 +++++------ bin/theme-json.php | 1 - composer.json | 10 ++--- phpstan.neon | 13 +++++++ psalm.xml | 21 ---------- src/Api/SectionNames.php | 3 -- src/Api/ThemeJson.php | 15 ++++++-- src/Application/Commands/DumpCommand.php | 20 +++++----- src/Application/Commands/InfoCommand.php | 11 ++---- src/Application/Commands/InitCommand.php | 11 ++---- src/Application/Commands/ValidateCommand.php | 13 +++---- src/Application/DumpMessage.php | 3 -- .../Middlewares/DeleteSchemaJson.php | 8 +++- src/Application/Middlewares/Dump.php | 29 +++++++++++--- src/Application/Middlewares/Info.php | 5 ++- src/Application/Middlewares/Init.php | 9 ++--- src/Application/Middlewares/SchemaJson.php | 8 +++- src/Application/Middlewares/Validate.php | 8 +++- src/Application/ValidateMessage.php | 3 -- src/Bootstrap.php | 3 -- src/Domain/Input/Settings/Color/Duotone.php | 3 -- src/Domain/Input/Settings/Color/Gradient.php | 3 -- src/Domain/Input/Settings/Color/Palette.php | 3 -- src/Domain/Input/Settings/Color/Shadow.php | 3 -- .../AchromaticColorsExperimental.php | 3 -- .../Utilities/AnalogousColorsExperimental.php | 3 -- .../Settings/Color/Utilities/BoxShadow.php | 3 -- .../Input/Settings/Color/Utilities/Color.php | 21 +++++----- .../Settings/Color/Utilities/ColorFactory.php | 3 -- .../Color/Utilities/ColorFactoryInterface.php | 3 -- .../Color/Utilities/ColorInterface.php | 3 -- .../Color/Utilities/ColorModifier.php | 11 +----- .../Utilities/ColorModifierInterface.php | 3 -- .../Color/Utilities/ColorsGenerator.php | 3 -- .../ComplementaryColorsExperimental.php | 3 -- .../Color/Utilities/GradientInterface.php | 3 -- .../Color/Utilities/LinearGradient.php | 3 -- .../MonochromaticColorsExperimental.php | 3 -- .../SplitComplementaryColorsExperimental.php | 3 -- .../Utilities/SquareColorsExperimental.php | 3 -- .../Utilities/TriadicColorsExperimental.php | 3 -- src/Domain/Input/Settings/Custom/Custom.php | 3 -- .../Input/Settings/Custom/CustomToPresets.php | 12 ++++-- src/Domain/Input/Settings/NullPresets.php | 6 ++- src/Domain/Input/Settings/PresetInterface.php | 5 +-- src/Domain/Input/Settings/PresetTrait.php | 3 -- src/Domain/Input/Settings/Presets.php | 19 +++++++--- .../Input/Settings/PresetsInterface.php | 8 ++-- .../Input/Settings/Typography/FontFamily.php | 3 -- .../Input/Settings/Typography/FontSize.php | 6 +-- .../Settings/Typography/Utilities/Fluid.php | 3 -- .../Typography/Utilities/FontFace.php | 11 ++++-- .../Settings/Utilities/CalcExperimental.php | 3 -- .../Settings/Utilities/ClampExperimental.php | 3 -- .../Utilities/DimensionExperimental.php | 1 - .../Utilities/SupportedUnitsExperimental.php | 3 -- .../Utilities/UnitInterfaceExperimental.php | 3 -- .../Input/Styles/ArrayableInterface.php | 3 -- src/Domain/Input/Styles/Border.php | 3 -- src/Domain/Input/Styles/Color.php | 3 -- src/Domain/Input/Styles/CommonTrait.php | 15 ++++++-- src/Domain/Input/Styles/Css.php | 3 +- src/Domain/Input/Styles/CssInterface.php | 3 -- src/Domain/Input/Styles/Outline.php | 3 -- src/Domain/Input/Styles/Scss.php | 1 - src/Domain/Input/Styles/Spacing.php | 6 +-- src/Domain/Input/Styles/Typography.php | 3 -- .../Filesystem/DataFromJsonTrait.php | 3 ++ src/Infrastructure/Filesystem/FileWriter.php | 1 + .../Filesystem/FilesExtension.php | 3 -- src/Infrastructure/Filesystem/FilesFinder.php | 9 +++-- .../Filesystem/JsonFileWriter.php | 1 + src/Infrastructure/Filesystem/Path.php | 13 ------- .../Filesystem/ScssFileWriter.php | 5 ++- src/ModuleApplication.php | 38 +++++++++++++++---- src/ModuleInfrastructure.php | 3 ++ stubs/auryn-injector.stub | 18 +++++++++ .../Middlewares/SchemaJsonTest.php | 17 ++++----- tests/unit/Domain/Output/InitTest.php | 1 - 80 files changed, 256 insertions(+), 302 deletions(-) create mode 100644 phpstan.neon delete mode 100644 psalm.xml delete mode 100644 src/Infrastructure/Filesystem/Path.php create mode 100644 stubs/auryn-injector.stub diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 082d67b6..69c9e843 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -6,7 +6,7 @@ on: paths: - '**workflows/static-analysis.yml' - '**.php' - - '**psalm.xml' + - '**phpstan.neon' - '**composer.json' jobs: @@ -27,5 +27,5 @@ jobs: - uses: ramsey/composer-install@v3 - - name: Psalm - run: vendor/bin/psalm + - name: PHPStan + run: composer stan diff --git a/Makefile b/Makefile index 4ee3e968..21dfe3a9 100644 --- a/Makefile +++ b/Makefile @@ -94,12 +94,12 @@ cs/fix: up ### Run the code sniffer and fix the errors @$(DOCKER_DIR) ./composer cs:fix @$(FILES_OWNERSHIP) -# Psalm commands - -.PHONY: psalm -psalm: up ### Run the psalm - @echo "Running the psalm" - @$(DOCKER_DIR) ./composer psalm +# PHPStan commands + +.PHONY: stan +stan: up ### Run PHPStan + @echo "Running PHPStan" + @$(DOCKER_DIR) ./composer stan # Codeception commands @@ -137,8 +137,8 @@ acceptance: up ### Run the acceptance tests .PHONY: tests tests: unit integration functional ### Run unit and integration tests -.PHONY: qa -qa: cs psalm unit integration functional ### Run all the tests +.PHONY: qa +qa: cs stan unit integration functional ### Run all the tests # Infection commands @@ -180,9 +180,9 @@ docker/metrics: ### Run the phpmetrics # PhpMetrics commands from composer .PHONY: metrics -metrics: up ### Run the composer/metrics - @echo "Running the psalm" - @$(DOCKER_DIR) ./composer metrics +metrics: up ### Run the composer/metrics + @echo "Running phpmetrics" + @$(DOCKER_DIR) ./composer metrics # Generate commands diff --git a/bin/theme-json.php b/bin/theme-json.php index e8e3389f..4a87ccb6 100644 --- a/bin/theme-json.php +++ b/bin/theme-json.php @@ -8,7 +8,6 @@ namespace ItalyStrap\ThemeJsonGenerator; -/** @psalm-suppress UnresolvableInclude */ require $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php'; $bootstrap = new Bootstrap(); diff --git a/composer.json b/composer.json index 68b20332..04155d25 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ "phpcompatibility/php-compatibility": "*", "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "vimeo/psalm": "^5.6", + "phpstan/phpstan": "^1.12", "phpbench/phpbench": "^1.2", "phpmetrics/phpmetrics": "^2.8", @@ -97,8 +97,8 @@ "cs:fix": [ "@php ./vendor/bin/phpcbf -p" ], - "psalm": [ - "@php ./vendor/bin/psalm --no-cache" + "stan": [ + "@php ./vendor/bin/phpstan analyse --debug --no-progress" ], "unit": [ "@php ./vendor/bin/codecept run unit" @@ -125,7 +125,7 @@ ], "qa": [ "@cs", - "@psalm", + "@stan", "@rector", "@unit" ], @@ -145,7 +145,7 @@ "scripts-descriptions": { "cs": "Run Code Sniffer", "cs:fix": "Run Code Sniffer and fix errors", - "psalm": "Run Psalm", + "stan": "Run PHPStan", "unit": "Run Unit tests", "integration": "Run Integration tests", "infection": "Run Infection", diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..85808fdd --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,13 @@ +parameters: + level: 9 + paths: + - bin + - functions + - src + stubFiles: + - stubs/auryn-injector.stub + excludePaths: + analyse: + - src/**/*Experimental*.php + parallel: + maximumNumberOfProcesses: 1 diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index bd590bbf..00000000 --- a/psalm.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Api/SectionNames.php b/src/Api/SectionNames.php index f0c64b79..7ce2a01c 100644 --- a/src/Api/SectionNames.php +++ b/src/Api/SectionNames.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Api; -/** - * @psalm-api - */ final class SectionNames { /** diff --git a/src/Api/ThemeJson.php b/src/Api/ThemeJson.php index e1c27d8d..d3093d10 100644 --- a/src/Api/ThemeJson.php +++ b/src/Api/ThemeJson.php @@ -15,11 +15,9 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\FontSize; /** - * @psalm-api * @template TKey as array-key * @template TValue * @template-extends Config - * @psalm-suppress DeprecatedInterface */ final class ThemeJson extends Config implements \JsonSerializable { @@ -34,16 +32,25 @@ public function appendGlobalCss(string $css): bool return $this->set(SectionNames::STYLES . '.css', $currentCss . $css); } + /** + * @param array $config + */ public function setElementStyle(string $elementName, array $config): bool { return $this->set(SectionNames::STYLES . '.elements.' . $elementName, $config); } + /** + * @param array $config + */ public function setBlockSettings(string $blockName, array $config): bool { return $this->set(SectionNames::SETTINGS . '.blocks.' . $blockName, $config); } + /** + * @param array $config + */ public function setBlockStyle(string $blockName, array $config): bool { return $this->set(SectionNames::STYLES . '.blocks.' . $blockName, $config); @@ -68,7 +75,6 @@ public function setPresets(PresetsInterface $presets): bool foreach ($keys as $key => $value) { try { - /** @psalm-suppress UndefinedInterfaceMethod */ $this->set($key, $presets->toArrayByCategory($value)); } catch (\Exception $e) { continue; @@ -78,6 +84,9 @@ public function setPresets(PresetsInterface $presets): bool return true; } + /** + * @return array + */ public function jsonSerialize(): array { return $this->getArrayCopy(); diff --git a/src/Application/Commands/DumpCommand.php b/src/Application/Commands/DumpCommand.php index 65c62890..e8cae02c 100644 --- a/src/Application/Commands/DumpCommand.php +++ b/src/Application/Commands/DumpCommand.php @@ -4,9 +4,9 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; -use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; use ItalyStrap\ThemeJsonGenerator\Application\DumpMessage; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -14,9 +14,6 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Process; -/** - * @psalm-api - */ #[AsCommand(name: DumpCommand::NAME, description: DumpCommand::DESCRIPTION)] final class DumpCommand extends Command { @@ -49,10 +46,10 @@ final class DumpCommand extends Command */ public const FILE = 'file'; - private HandlerInterface $handler; + private ConsoleHandler $handler; public function __construct( - HandlerInterface $handler + ConsoleHandler $handler ) { $this->handler = $handler; parent::__construct(); @@ -116,17 +113,20 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $rootFolder = $this->rootFolder((string)$input->getOption('path')); + $path = $input->getOption('path'); + $file = $input->getOption(self::FILE); + + $rootFolder = $this->rootFolder(\is_string($path) ? $path : ''); $message = new DumpMessage( $rootFolder, '', - (bool)$input->getOption('dry-run'), - (string)$input->getOption(self::FILE) + $input->getOption('dry-run') === true, + \is_string($file) ? $file : '' ); try { - return (int)$this->handler->handle($message); + return $this->handler->handle($message); } catch (\Exception $exception) { $output->writeln('Error: ' . $exception->getMessage() . ''); return Command::FAILURE; diff --git a/src/Application/Commands/InfoCommand.php b/src/Application/Commands/InfoCommand.php index 2c9c5aa0..1a9e3a69 100644 --- a/src/Application/Commands/InfoCommand.php +++ b/src/Application/Commands/InfoCommand.php @@ -4,17 +4,14 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; -use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; use ItalyStrap\ThemeJsonGenerator\Application\Message; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -/** - * @psalm-api - */ #[AsCommand(name: InfoCommand::NAME, description: InfoCommand::DESCRIPTION)] class InfoCommand extends Command { @@ -23,10 +20,10 @@ class InfoCommand extends Command public const NAME = 'info'; public const DESCRIPTION = 'Show info about JSON theme'; - private HandlerInterface $handler; + private ConsoleHandler $handler; public function __construct( - HandlerInterface $handler + ConsoleHandler $handler ) { $this->handler = $handler; parent::__construct(); @@ -45,7 +42,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $message = new Message($rootFolder); try { - return (int)$this->handler->handle($message); + return $this->handler->handle($message); } catch (\Exception $exception) { $output->writeln('Error: ' . $exception->getMessage() . ''); return Command::FAILURE; diff --git a/src/Application/Commands/InitCommand.php b/src/Application/Commands/InitCommand.php index f34d5463..3cd494bd 100644 --- a/src/Application/Commands/InitCommand.php +++ b/src/Application/Commands/InitCommand.php @@ -4,18 +4,15 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; -use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; use ItalyStrap\ThemeJsonGenerator\Application\Message; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -/** - * @psalm-api - */ #[AsCommand(name: InitCommand::NAME, description: InitCommand::DESCRIPTION)] class InitCommand extends Command { @@ -26,10 +23,10 @@ class InitCommand extends Command public const DESCRIPTION = 'Initialize theme.json file'; - private HandlerInterface $handler; + private ConsoleHandler $handler; public function __construct( - HandlerInterface $handler, + ConsoleHandler $handler, ) { $this->handler = $handler; parent::__construct(); @@ -55,7 +52,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $message = new Message($rootFolder); try { - return (int)$this->handler->handle($message); + return $this->handler->handle($message); } catch (\Exception $exception) { $output->writeln('Error: ' . $exception->getMessage() . ''); return Command::FAILURE; diff --git a/src/Application/Commands/ValidateCommand.php b/src/Application/Commands/ValidateCommand.php index edbd676a..9a5fadd9 100644 --- a/src/Application/Commands/ValidateCommand.php +++ b/src/Application/Commands/ValidateCommand.php @@ -4,19 +4,16 @@ namespace ItalyStrap\ThemeJsonGenerator\Application\Commands; -use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\ThemeJsonGenerator\Application\Commands\Utils\RootFolderTrait; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -/** - * @psalm-api - */ #[AsCommand(name: ValidateCommand::NAME, description: ValidateCommand::DESCRIPTION)] class ValidateCommand extends Command { @@ -25,10 +22,10 @@ class ValidateCommand extends Command public const NAME = 'validate'; public const DESCRIPTION = 'Validate theme.json file'; - private HandlerInterface $handler; + private ConsoleHandler $handler; public function __construct( - HandlerInterface $handler + ConsoleHandler $handler ) { $this->handler = $handler; parent::__construct(); @@ -55,10 +52,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $rootFolder = $this->rootFolder(); $schemaPath = $rootFolder . '/theme.schema.json'; - $message = new ValidateMessage($rootFolder, $schemaPath, (bool)$input->getOption('force')); + $message = new ValidateMessage($rootFolder, $schemaPath, $input->getOption('force') === true); try { - return (int)$this->handler->handle($message); + return $this->handler->handle($message); } catch (\Exception $exception) { $output->writeln('Error: ' . $exception->getMessage() . ''); return Command::FAILURE; diff --git a/src/Application/DumpMessage.php b/src/Application/DumpMessage.php index 24b3bc1b..8213928e 100644 --- a/src/Application/DumpMessage.php +++ b/src/Application/DumpMessage.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Application; -/** - * @psalm-api - */ class DumpMessage { private string $rootFolder = ''; diff --git a/src/Application/Middlewares/DeleteSchemaJson.php b/src/Application/Middlewares/DeleteSchemaJson.php index e2540810..98dade27 100644 --- a/src/Application/Middlewares/DeleteSchemaJson.php +++ b/src/Application/Middlewares/DeleteSchemaJson.php @@ -7,17 +7,21 @@ use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; class DeleteSchemaJson implements MiddlewareInterface { + /** + * @phpstan-param ValidateMessage $message + * @phpstan-param ConsoleHandler $handler + */ public function process(object $message, HandlerInterface $handler): int { - /** @var ValidateMessage $message */ $schemaPath = $message->getSchemaPath(); if ($message->shouldRecreate() && \file_exists($schemaPath)) { \unlink($schemaPath); } - return (int)$handler->handle($message); + return $handler->handle($message); } } diff --git a/src/Application/Middlewares/Dump.php b/src/Application/Middlewares/Dump.php index 3a65111e..c67193b6 100644 --- a/src/Application/Middlewares/Dump.php +++ b/src/Application/Middlewares/Dump.php @@ -15,12 +15,10 @@ use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\JsonFileWriter; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\ScssFileWriter; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use Psr\Container\ContainerInterface; use Symfony\Component\Console\Output\OutputInterface; -/** - * @psalm-api - */ class Dump implements MiddlewareInterface { /** @@ -38,6 +36,10 @@ public function __construct( $this->filesFinder = $filesFinder; } + /** + * @phpstan-param DumpMessage $message + * @phpstan-param ConsoleHandler $handler + */ public function process(object $message, HandlerInterface $handler): int { /** @@ -53,10 +55,10 @@ public function process(object $message, HandlerInterface $handler): int */ foreach ($this->filesFinder->find($message->getRootFolder(), 'php') as $fileName => $file) { $injector = $this->configureContainer(); - /** @psalm-suppress UnresolvableInclude */ $injector->execute(require $file); $presets = $injector->make(PresetsInterface::class); $themeJson = $injector->make(ThemeJson::class); + $themeJson->setPresets($presets); $count++; @@ -82,9 +84,12 @@ public function process(object $message, HandlerInterface $handler): int $output->writeln(self::M_NO_FILE_FOUND); } - return (int)$handler->handle($message); + return $handler->handle($message); } + /** + * @param ThemeJson $themeJson + */ private function generateJsonFile( OutputInterface $output, DumpMessage $message, @@ -108,6 +113,9 @@ private function generateJsonFile( $output->writeln('========================'); } + /** + * @param ThemeJson $themeJson + */ private function generateScssFile( OutputInterface $output, DumpMessage $message, @@ -155,15 +163,24 @@ private function configureContainer(): \Auryn\Injector return $injector; } + /** + * @param ConfigInterface $config + */ private function createContainer( \Auryn\Injector $injector, - \ItalyStrap\Config\ConfigInterface $config + ConfigInterface $config ): ContainerInterface { return new class ($injector, $config) implements ContainerInterface { private \Auryn\Injector $injector; + /** + * @var ConfigInterface + */ private ConfigInterface $config; + /** + * @param ConfigInterface $config + */ public function __construct(\Auryn\Injector $injector, ConfigInterface $config) { $this->injector = $injector; diff --git a/src/Application/Middlewares/Info.php b/src/Application/Middlewares/Info.php index 21126517..a7a60023 100644 --- a/src/Application/Middlewares/Info.php +++ b/src/Application/Middlewares/Info.php @@ -11,7 +11,6 @@ use Symfony\Component\Console\Command\Command; /** - * @psalm-api * @todo Implement the logic */ class Info implements MiddlewareInterface @@ -24,9 +23,11 @@ public function __construct( $this->filesFinder = $filesFinder; } + /** + * @phpstan-param Message $message + */ public function process(object $message, HandlerInterface $handler): int { - /** @var Message $message */ foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { echo $file->getBasename() . PHP_EOL; } diff --git a/src/Application/Middlewares/Init.php b/src/Application/Middlewares/Init.php index ba975609..837de744 100644 --- a/src/Application/Middlewares/Init.php +++ b/src/Application/Middlewares/Init.php @@ -7,6 +7,7 @@ use Brick\VarExporter\VarExporter; use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Pipeline\MiddlewareInterface; +use ItalyStrap\ThemeJsonGenerator\Application\Message; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; use PhpParser\Error; @@ -14,16 +15,12 @@ use PhpParser\Node\Stmt\ClassConst; use PhpParser\NodeFinder; use PhpParser\ParserFactory; -use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\OutputInterface; use Webimpress\SafeWriter\Exception\ExceptionInterface as FileWriterException; use Webimpress\SafeWriter\FileWriter; use Webmozart\Assert\Assert; -/** - * @psalm-api - */ class Init implements MiddlewareInterface { use DataFromJsonTrait; @@ -52,12 +49,14 @@ class Init implements MiddlewareInterface private FilesFinder $filesFinder; public function __construct( - EventDispatcherInterface $dispatcher, FilesFinder $filesFinder ) { $this->filesFinder = $filesFinder; } + /** + * @phpstan-param Message $message + */ public function process(object $message, HandlerInterface $handler): int { /** diff --git a/src/Application/Middlewares/SchemaJson.php b/src/Application/Middlewares/SchemaJson.php index 1124d04e..e4c5e618 100644 --- a/src/Application/Middlewares/SchemaJson.php +++ b/src/Application/Middlewares/SchemaJson.php @@ -7,19 +7,23 @@ use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Pipeline\MiddlewareInterface; use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use Webimpress\SafeWriter\FileWriter; class SchemaJson implements MiddlewareInterface { + /** + * @phpstan-param ValidateMessage $message + * @phpstan-param ConsoleHandler $handler + */ public function process(object $message, HandlerInterface $handler): int { - /** @var ValidateMessage $message */ $schemaPath = $message->getSchemaPath(); if (!\file_exists($schemaPath) || $this->isFileSchemaOlderThanOneWeek($schemaPath)) { $this->createFileSchema($schemaPath); } - return (int)$handler->handle($message); + return $handler->handle($message); } private function isFileSchemaOlderThanOneWeek(string $schemaPath): bool diff --git a/src/Application/Middlewares/Validate.php b/src/Application/Middlewares/Validate.php index a2301027..3723accd 100644 --- a/src/Application/Middlewares/Validate.php +++ b/src/Application/Middlewares/Validate.php @@ -9,6 +9,7 @@ use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\DataFromJsonTrait; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem\FilesFinder; +use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; use JsonSchema\Validator; use ScssPhp\ScssPhp\Compiler; use Symfony\Component\Console\Output\OutputInterface; @@ -33,6 +34,10 @@ public function __construct( $this->compiler = $compiler; } + /** + * @phpstan-param ValidateMessage $message + * @phpstan-param ConsoleHandler $handler + */ public function process(object $message, HandlerInterface $handler): mixed { /** @@ -40,7 +45,6 @@ public function process(object $message, HandlerInterface $handler): mixed */ $output = new \Symfony\Component\Console\Output\ConsoleOutput(); - /** @var ValidateMessage $message */ foreach ($this->filesFinder->find($message->getRootFolder(), 'json') as $file) { $output->writeln('========================'); $output->writeln(\sprintf( @@ -56,7 +60,7 @@ public function process(object $message, HandlerInterface $handler): mixed $this->compiler->compileString(''); } - return (int)$handler->handle($message); + return $handler->handle($message); } private function validateJsonFile( diff --git a/src/Application/ValidateMessage.php b/src/Application/ValidateMessage.php index a4f62d0d..19f52ed4 100644 --- a/src/Application/ValidateMessage.php +++ b/src/Application/ValidateMessage.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Application; -/** - * @psalm-api - */ class ValidateMessage { private string $rootFolder; diff --git a/src/Bootstrap.php b/src/Bootstrap.php index 3b6172e2..6548fb9f 100644 --- a/src/Bootstrap.php +++ b/src/Bootstrap.php @@ -13,9 +13,6 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; -/** - * @psalm-api - */ final class Bootstrap { public function container(): ContainerInterface diff --git a/src/Domain/Input/Settings/Color/Duotone.php b/src/Domain/Input/Settings/Color/Duotone.php index 465b759e..b6aca50c 100644 --- a/src/Domain/Input/Settings/Color/Duotone.php +++ b/src/Domain/Input/Settings/Color/Duotone.php @@ -7,9 +7,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetTrait; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; -/** - * @psalm-api - */ class Duotone implements PresetInterface { use PresetTrait; diff --git a/src/Domain/Input/Settings/Color/Gradient.php b/src/Domain/Input/Settings/Color/Gradient.php index 621edf56..a6059f58 100644 --- a/src/Domain/Input/Settings/Color/Gradient.php +++ b/src/Domain/Input/Settings/Color/Gradient.php @@ -8,9 +8,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetTrait; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; -/** - * @psalm-api - */ class Gradient implements PresetInterface { use PresetTrait; diff --git a/src/Domain/Input/Settings/Color/Palette.php b/src/Domain/Input/Settings/Color/Palette.php index 5fdd867d..f7398c09 100644 --- a/src/Domain/Input/Settings/Color/Palette.php +++ b/src/Domain/Input/Settings/Color/Palette.php @@ -8,9 +8,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetTrait; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; -/** - * @psalm-api - */ class Palette implements PresetInterface { use PresetTrait; diff --git a/src/Domain/Input/Settings/Color/Shadow.php b/src/Domain/Input/Settings/Color/Shadow.php index 65183d85..ad885d4f 100644 --- a/src/Domain/Input/Settings/Color/Shadow.php +++ b/src/Domain/Input/Settings/Color/Shadow.php @@ -8,9 +8,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetTrait; -/** - * @psalm-api - */ class Shadow implements PresetInterface { use PresetTrait; diff --git a/src/Domain/Input/Settings/Color/Utilities/AchromaticColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/AchromaticColorsExperimental.php index 2f2e8259..4b845b86 100644 --- a/src/Domain/Input/Settings/Color/Utilities/AchromaticColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/AchromaticColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class AchromaticColorsExperimental implements ColorsGenerator { public function generate(): array diff --git a/src/Domain/Input/Settings/Color/Utilities/AnalogousColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/AnalogousColorsExperimental.php index 314842ae..310f6857 100644 --- a/src/Domain/Input/Settings/Color/Utilities/AnalogousColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/AnalogousColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class AnalogousColorsExperimental implements ColorsGenerator { private ColorModifierInterface $colorModifier; diff --git a/src/Domain/Input/Settings/Color/Utilities/BoxShadow.php b/src/Domain/Input/Settings/Color/Utilities/BoxShadow.php index 3633f050..949873c5 100644 --- a/src/Domain/Input/Settings/Color/Utilities/BoxShadow.php +++ b/src/Domain/Input/Settings/Color/Utilities/BoxShadow.php @@ -6,9 +6,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Palette; -/** - * @psalm-api - */ class BoxShadow { private bool $inset = false; diff --git a/src/Domain/Input/Settings/Color/Utilities/Color.php b/src/Domain/Input/Settings/Color/Utilities/Color.php index ac693975..e0423a4d 100644 --- a/src/Domain/Input/Settings/Color/Utilities/Color.php +++ b/src/Domain/Input/Settings/Color/Utilities/Color.php @@ -8,9 +8,6 @@ use Spatie\Color\Factory as ColorFactory; use Spatie\Color\Hsla; -/** - * @psalm-api - */ final class Color implements ColorInterface { private SpatieColor $spatieColor; @@ -39,10 +36,15 @@ public function __construct(string $color) if ($reflected->hasProperty('alpha')) { $reflectionProperty = $reflected->getProperty('alpha'); $reflectionProperty->setAccessible(true); - /** - * @psalm-suppress MixedAssignment - */ - $this->alpha = $reflectionProperty->getValue($this->spatieColor); + $alpha = $reflectionProperty->getValue($this->spatieColor); + if (!\is_string($alpha) && !\is_float($alpha) && !\is_int($alpha)) { + throw new \RuntimeException(\sprintf( + 'Expected alpha to be string, float, or int, got %s.', + \get_debug_type($alpha) + )); + } + + $this->alpha = \is_int($alpha) ? (float)$alpha : $alpha; $reflectionProperty->setAccessible(false); } @@ -192,10 +194,7 @@ public function __toString(): string return (string)$this->spatieColor; } - /** - * @param mixed $alpha - */ - private function fromHexToFloat($alpha): float + private function fromHexToFloat(string|int|float $alpha): float { return \is_string($alpha) ? \hexdec($alpha) / 255 : (float)$alpha; } diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorFactory.php b/src/Domain/Input/Settings/Color/Utilities/ColorFactory.php index e078caee..620ddbb0 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorFactory.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorFactory.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ final class ColorFactory implements ColorFactoryInterface { /** diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorFactoryInterface.php b/src/Domain/Input/Settings/Color/Utilities/ColorFactoryInterface.php index 418bc006..b4a8fd18 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorFactoryInterface.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorFactoryInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ interface ColorFactoryInterface { /** diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorInterface.php b/src/Domain/Input/Settings/Color/Utilities/ColorInterface.php index 4fd15496..a6d8ece7 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorInterface.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ // phpcs:ignore PHPCompatibility.Interfaces.NewInterfaces.stringableFound interface ColorInterface extends \Stringable { diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php b/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php index 59d932c6..54351346 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorModifier.php @@ -6,9 +6,6 @@ use Exception; -/** - * @psalm-api - */ final class ColorModifier implements ColorModifierInterface { private ColorInterface $color; @@ -137,10 +134,6 @@ private function createNewColorWithChangedContrast(int $amount): ColorInterface ); } - /** - * @psalm-suppress MixedInferredReturnType - * @psalm-suppress MixedReturnStatement - */ private function createNewColorFrom( string $hue, string $saturation, @@ -161,8 +154,6 @@ private function createNewColorFrom( /** * @todo Is it a good idea to make it public? * Evaluate possible side effects. - * @psalm-suppress MixedInferredReturnType - * @psalm-suppress MixedReturnStatement */ private function mixWith(string $color_string, float $weight = 0): ColorInterface { @@ -211,7 +202,7 @@ private function sanitizeFromFloatToInteger(float $value): int /** * @param ColorInterface $newColor - * @return mixed + * @return ColorInterface * @throws Exception */ private function callMethodOnColorObject(ColorInterface $newColor): ColorInterface diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorModifierInterface.php b/src/Domain/Input/Settings/Color/Utilities/ColorModifierInterface.php index 48b9a33a..58a6d16f 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorModifierInterface.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorModifierInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ interface ColorModifierInterface { public function tint(float $weight = 0): ColorInterface; diff --git a/src/Domain/Input/Settings/Color/Utilities/ColorsGenerator.php b/src/Domain/Input/Settings/Color/Utilities/ColorsGenerator.php index 48d9c84a..43b2d09f 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ColorsGenerator.php +++ b/src/Domain/Input/Settings/Color/Utilities/ColorsGenerator.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ interface ColorsGenerator { /** diff --git a/src/Domain/Input/Settings/Color/Utilities/ComplementaryColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/ComplementaryColorsExperimental.php index 10c8cd0e..65dc9381 100644 --- a/src/Domain/Input/Settings/Color/Utilities/ComplementaryColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/ComplementaryColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class ComplementaryColorsExperimental implements ColorsGenerator { private ColorModifierInterface $color; diff --git a/src/Domain/Input/Settings/Color/Utilities/GradientInterface.php b/src/Domain/Input/Settings/Color/Utilities/GradientInterface.php index 3311c5d2..9aee6da6 100644 --- a/src/Domain/Input/Settings/Color/Utilities/GradientInterface.php +++ b/src/Domain/Input/Settings/Color/Utilities/GradientInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ // phpcs:ignore PHPCompatibility.Interfaces.NewInterfaces.stringableFound interface GradientInterface extends \Stringable { diff --git a/src/Domain/Input/Settings/Color/Utilities/LinearGradient.php b/src/Domain/Input/Settings/Color/Utilities/LinearGradient.php index 4873bc3b..451d47c6 100644 --- a/src/Domain/Input/Settings/Color/Utilities/LinearGradient.php +++ b/src/Domain/Input/Settings/Color/Utilities/LinearGradient.php @@ -6,9 +6,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Palette; -/** - * @psalm-api - */ class LinearGradient implements GradientInterface { private string $direction = ''; diff --git a/src/Domain/Input/Settings/Color/Utilities/MonochromaticColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/MonochromaticColorsExperimental.php index 0ef44567..25a3d1dc 100644 --- a/src/Domain/Input/Settings/Color/Utilities/MonochromaticColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/MonochromaticColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class MonochromaticColorsExperimental implements ColorsGenerator { private ColorModifierInterface $colorModifier; diff --git a/src/Domain/Input/Settings/Color/Utilities/SplitComplementaryColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/SplitComplementaryColorsExperimental.php index 8a710780..81813ba4 100644 --- a/src/Domain/Input/Settings/Color/Utilities/SplitComplementaryColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/SplitComplementaryColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class SplitComplementaryColorsExperimental implements ColorsGenerator { private ColorModifierInterface $colorModifier; diff --git a/src/Domain/Input/Settings/Color/Utilities/SquareColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/SquareColorsExperimental.php index 2415c2a9..5ccc94e1 100644 --- a/src/Domain/Input/Settings/Color/Utilities/SquareColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/SquareColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class SquareColorsExperimental implements ColorsGenerator { private ColorModifierInterface $colorModifier; diff --git a/src/Domain/Input/Settings/Color/Utilities/TriadicColorsExperimental.php b/src/Domain/Input/Settings/Color/Utilities/TriadicColorsExperimental.php index 887cbfd4..2905b733 100644 --- a/src/Domain/Input/Settings/Color/Utilities/TriadicColorsExperimental.php +++ b/src/Domain/Input/Settings/Color/Utilities/TriadicColorsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Color\Utilities; -/** - * @psalm-api - */ class TriadicColorsExperimental implements ColorsGenerator { private ColorModifierInterface $colorModifier; diff --git a/src/Domain/Input/Settings/Custom/Custom.php b/src/Domain/Input/Settings/Custom/Custom.php index 318b6bd2..81e5327a 100644 --- a/src/Domain/Input/Settings/Custom/Custom.php +++ b/src/Domain/Input/Settings/Custom/Custom.php @@ -7,9 +7,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetTrait; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; -/** - * @psalm-api - */ class Custom implements PresetInterface { use PresetTrait; diff --git a/src/Domain/Input/Settings/Custom/CustomToPresets.php b/src/Domain/Input/Settings/Custom/CustomToPresets.php index a9754e21..e1f5adee 100644 --- a/src/Domain/Input/Settings/Custom/CustomToPresets.php +++ b/src/Domain/Input/Settings/Custom/CustomToPresets.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Custom; -/** - * @psalm-api - */ class CustomToPresets { /** @@ -23,17 +20,24 @@ public function __construct( $this->customs = $customs; } + /** + * @return Custom[] + */ public function toArray(): array { return $this->presetsToFlat($this->customs); } + /** + * @param array $presets + * @return Custom[] + */ private function presetsToFlat(array $presets, string $prefix = ''): array { $processed = []; /** - * @var string|array|\Stringable $value + * @var string|array|\Stringable $value */ foreach ($presets as $key => $value) { $fullKey = (string)($prefix === '' ? $key : $prefix . '.' . $key); diff --git a/src/Domain/Input/Settings/NullPresets.php b/src/Domain/Input/Settings/NullPresets.php index 7e659276..011d4668 100644 --- a/src/Domain/Input/Settings/NullPresets.php +++ b/src/Domain/Input/Settings/NullPresets.php @@ -6,7 +6,6 @@ /** * @infection-ignore-all - * @psalm-api */ class NullPresets implements PresetsInterface { @@ -29,4 +28,9 @@ public function parse(string $content): string { return $content; } + + public function toArrayByCategory(string $category): array + { + return []; + } } diff --git a/src/Domain/Input/Settings/PresetInterface.php b/src/Domain/Input/Settings/PresetInterface.php index ea7f0378..c31058e3 100644 --- a/src/Domain/Input/Settings/PresetInterface.php +++ b/src/Domain/Input/Settings/PresetInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings; -/** - * @psalm-api - */ // phpcs:ignore PHPCompatibility.Interfaces.NewInterfaces.stringableFound interface PresetInterface extends \Stringable { @@ -23,7 +20,7 @@ public function var(string $fallback = ''): string; public function __toString(): string; /** - * @return array + * @return array|object> */ public function toArray(): array; } diff --git a/src/Domain/Input/Settings/PresetTrait.php b/src/Domain/Input/Settings/PresetTrait.php index daf4aca3..ad711061 100644 --- a/src/Domain/Input/Settings/PresetTrait.php +++ b/src/Domain/Input/Settings/PresetTrait.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings; -/** - * @psalm-api - */ trait PresetTrait { public function type(): string diff --git a/src/Domain/Input/Settings/Presets.php b/src/Domain/Input/Settings/Presets.php index b064e496..093cae85 100644 --- a/src/Domain/Input/Settings/Presets.php +++ b/src/Domain/Input/Settings/Presets.php @@ -10,7 +10,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Custom\Custom; /** - * @psalm-api * @see PresetsTest * @see PresetsIntegrationTest */ @@ -35,7 +34,6 @@ public function add(PresetInterface $item): self $this->assertIsUnique($key, $item); - /** @psalm-suppress MixedPropertyTypeCoercion */ $this->insertValue( $this->collection, \explode('.', $key), @@ -114,6 +112,9 @@ public function field(string $field): self return $this; } + /** + * @return array + */ public function toArray(): array { $field = $this->field; @@ -129,7 +130,8 @@ public function toArray(): array return $this->processCustomCollection($fetched); } - return $this->processPresetCollection($fetched); + /** @var PresetInterface[] $fetched */ + return $this->processPresetCollection(...$fetched); } /** @@ -141,7 +143,11 @@ public function toArrayByCategory(string $category): array return $this->toArray(); } - private function processPresetCollection(array $collection): array + /** + * @param PresetInterface ...$collection + * @return array> + */ + private function processPresetCollection(PresetInterface ...$collection): array { return \array_values(\array_map( function (PresetInterface $item): array { @@ -162,7 +168,7 @@ function (PresetInterface $item): array { /** * @param array $collection - * @param array-key|string $prefix + * @param string $prefix * @return array */ private function processCustomCollection(array $collection, string $prefix = ''): array @@ -196,6 +202,9 @@ private function assertIsUnique(string $key, PresetInterface $item): void } } + /** + * @return array + */ public function jsonSerialize(): array { return $this->toArray(); diff --git a/src/Domain/Input/Settings/PresetsInterface.php b/src/Domain/Input/Settings/PresetsInterface.php index 92e6921e..9194550e 100644 --- a/src/Domain/Input/Settings/PresetsInterface.php +++ b/src/Domain/Input/Settings/PresetsInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings; -/** - * @psalm-api - */ interface PresetsInterface { public function add(PresetInterface $item): self; @@ -23,4 +20,9 @@ public function addMultiple(array $items): self; public function get(string $key, $default = null); public function parse(string $content): string; + + /** + * @return array + */ + public function toArrayByCategory(string $category): array; } diff --git a/src/Domain/Input/Settings/Typography/FontFamily.php b/src/Domain/Input/Settings/Typography/FontFamily.php index f0efac9b..44cbaad6 100644 --- a/src/Domain/Input/Settings/Typography/FontFamily.php +++ b/src/Domain/Input/Settings/Typography/FontFamily.php @@ -7,9 +7,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetTrait; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; -/** - * @psalm-api - */ class FontFamily implements PresetInterface { use PresetTrait; diff --git a/src/Domain/Input/Settings/Typography/FontSize.php b/src/Domain/Input/Settings/Typography/FontSize.php index d2dfc421..b3968be4 100644 --- a/src/Domain/Input/Settings/Typography/FontSize.php +++ b/src/Domain/Input/Settings/Typography/FontSize.php @@ -8,9 +8,6 @@ use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\PresetInterface; use ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\Utilities\Fluid; -/** - * @psalm-api - */ class FontSize implements PresetInterface { use PresetTrait; @@ -36,6 +33,9 @@ public function __construct(string $slug, string $name, string $size, ?Fluid $fl $this->fluid = $fluid; } + /** + * @return array{slug: string, name: string, size: string, fluid?: Fluid} + */ public function toArray(): array { return \array_filter([ diff --git a/src/Domain/Input/Settings/Typography/Utilities/Fluid.php b/src/Domain/Input/Settings/Typography/Utilities/Fluid.php index 69001aac..9a2947fa 100644 --- a/src/Domain/Input/Settings/Typography/Utilities/Fluid.php +++ b/src/Domain/Input/Settings/Typography/Utilities/Fluid.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\Utilities; -/** - * @psalm-api - */ class Fluid { /** diff --git a/src/Domain/Input/Settings/Typography/Utilities/FontFace.php b/src/Domain/Input/Settings/Typography/Utilities/FontFace.php index a20686f0..fca02c70 100644 --- a/src/Domain/Input/Settings/Typography/Utilities/FontFace.php +++ b/src/Domain/Input/Settings/Typography/Utilities/FontFace.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Typography\Utilities; -/** - * @psalm-api - */ class FontFace { private string $fontFamily; @@ -17,8 +14,14 @@ class FontFace private string $fontStretch; + /** + * @var string[] + */ private array $src; + /** + * @param string[] $src + */ public function __construct( string $fontFamily, string $fontWeight, @@ -34,7 +37,7 @@ public function __construct( } /** - * @return array{fontFamily: string, fontWeight: string, fontStyle: string, fontStretch: string, src: mixed[]} + * @return array{fontFamily: string, fontWeight: string, fontStyle: string, fontStretch: string, src: string[]} */ public function toArray(): array { diff --git a/src/Domain/Input/Settings/Utilities/CalcExperimental.php b/src/Domain/Input/Settings/Utilities/CalcExperimental.php index 831da7ea..75a438cc 100644 --- a/src/Domain/Input/Settings/Utilities/CalcExperimental.php +++ b/src/Domain/Input/Settings/Utilities/CalcExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Utilities; -/** - * @psalm-api - */ class CalcExperimental { private string $value; diff --git a/src/Domain/Input/Settings/Utilities/ClampExperimental.php b/src/Domain/Input/Settings/Utilities/ClampExperimental.php index 0aeb4bae..4190deb3 100644 --- a/src/Domain/Input/Settings/Utilities/ClampExperimental.php +++ b/src/Domain/Input/Settings/Utilities/ClampExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Utilities; -/** - * @psalm-api - */ class ClampExperimental { private string $value; diff --git a/src/Domain/Input/Settings/Utilities/DimensionExperimental.php b/src/Domain/Input/Settings/Utilities/DimensionExperimental.php index 0d8f3962..38e55c0a 100644 --- a/src/Domain/Input/Settings/Utilities/DimensionExperimental.php +++ b/src/Domain/Input/Settings/Utilities/DimensionExperimental.php @@ -9,7 +9,6 @@ * https://github.com/pimlie/php-unit-conversion * https://github.com/PhpUnitsOfMeasure/php-units-of-measure * https://wiki.php.net/rfc/clamp - * @psalm-api */ final class DimensionExperimental { diff --git a/src/Domain/Input/Settings/Utilities/SupportedUnitsExperimental.php b/src/Domain/Input/Settings/Utilities/SupportedUnitsExperimental.php index f8cedace..a2b64930 100644 --- a/src/Domain/Input/Settings/Utilities/SupportedUnitsExperimental.php +++ b/src/Domain/Input/Settings/Utilities/SupportedUnitsExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Utilities; -/** - * @psalm-api - */ class SupportedUnitsExperimental implements UnitInterfaceExperimental { private array $units; diff --git a/src/Domain/Input/Settings/Utilities/UnitInterfaceExperimental.php b/src/Domain/Input/Settings/Utilities/UnitInterfaceExperimental.php index b661ce99..8f1900fc 100644 --- a/src/Domain/Input/Settings/Utilities/UnitInterfaceExperimental.php +++ b/src/Domain/Input/Settings/Utilities/UnitInterfaceExperimental.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Settings\Utilities; -/** - * @psalm-api - */ interface UnitInterfaceExperimental { /** diff --git a/src/Domain/Input/Styles/ArrayableInterface.php b/src/Domain/Input/Styles/ArrayableInterface.php index 08c18822..86dda03f 100644 --- a/src/Domain/Input/Styles/ArrayableInterface.php +++ b/src/Domain/Input/Styles/ArrayableInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ interface ArrayableInterface { /** diff --git a/src/Domain/Input/Styles/Border.php b/src/Domain/Input/Styles/Border.php index ef9893ed..ebbeb358 100644 --- a/src/Domain/Input/Styles/Border.php +++ b/src/Domain/Input/Styles/Border.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ final class Border implements ArrayableInterface, \JsonSerializable { use CommonTrait; diff --git a/src/Domain/Input/Styles/Color.php b/src/Domain/Input/Styles/Color.php index 14fac358..9046f3ce 100644 --- a/src/Domain/Input/Styles/Color.php +++ b/src/Domain/Input/Styles/Color.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ final class Color implements ArrayableInterface, \JsonSerializable { use CommonTrait; diff --git a/src/Domain/Input/Styles/CommonTrait.php b/src/Domain/Input/Styles/CommonTrait.php index 46975302..817258b5 100644 --- a/src/Domain/Input/Styles/CommonTrait.php +++ b/src/Domain/Input/Styles/CommonTrait.php @@ -66,17 +66,21 @@ public function property(string $property, string $value): self */ private function setProperty(string $key, string $value): self { - /** - * @var PresetInterface|mixed $value - */ $value = $this->presets->get($value, $value); if ($value instanceof PresetInterface) { $value = $value->var(); } + if (!\is_scalar($value) && !$value instanceof \Stringable) { + throw new \RuntimeException(\sprintf( + 'Expected style value to be stringable, got %s.', + \get_debug_type($value) + )); + } + /** - * This prevents to return a string with the placeholder like this: + * This prevents returning a string with the placeholder like this: * {{color.base}} * instead we want to return the value of the placeholder like this: * var(--wp--preset--color--base) @@ -102,6 +106,9 @@ public function toArray(): array return $result; } + /** + * @return array + */ public function jsonSerialize(): array { return $this->toArray(); diff --git a/src/Domain/Input/Styles/Css.php b/src/Domain/Input/Styles/Css.php index 05668b9f..72b53f4d 100644 --- a/src/Domain/Input/Styles/Css.php +++ b/src/Domain/Input/Styles/Css.php @@ -17,7 +17,6 @@ * @link https://www.google.it/search?q=php+inline+css+content&sca_esv=596560865&ei=mAicZaTCGp3Axc8Pq7yT8AQ&ved=0ahUKEwik7p-Rgs6DAxUdYPEDHSveBE4Q4dUDCBA&uact=5&oq=php+inline+css+content&gs_lp=Egxnd3Mtd2l6LXNlcnAiFnBocCBpbmxpbmUgY3NzIGNvbnRlbnQyBRAhGKABMgUQIRigATIIECEYFhgeGB0yCBAhGBYYHhgdMggQIRgWGB4YHUjvogFQmgdYwJcBcAF4AZABAJgBsQGgAZkSqgEEMC4xOLgBA8gBAPgBAcICChAAGEcY1gQYsAPCAgoQABiABBiKBRhDwgIFEAAYgATCAgYQABgWGB7CAgcQABiABBgTwgIIEAAYFhgeGBPiAwQYACBBiAYBkAYI&sclient=gws-wiz-serp#ip=1 * @link https://github.com/topics/inline-css?l=php * - * @psalm-api * @see CssTest */ class Css implements CssInterface @@ -158,7 +157,7 @@ private function duplicateRulesForSelectorList(string $css): string $pattern = '/\{(.*)}/s'; \preg_match($pattern, $css, $matches); - if (!isset($matches[1])) { + if (!isset($matches[0], $matches[1])) { return $css; } diff --git a/src/Domain/Input/Styles/CssInterface.php b/src/Domain/Input/Styles/CssInterface.php index ec55bbf5..ac3405a4 100644 --- a/src/Domain/Input/Styles/CssInterface.php +++ b/src/Domain/Input/Styles/CssInterface.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ interface CssInterface { public const M_AMPERSAND_MUST_NOT_BE_AT_THE_BEGINNING = 'CSS cannot begin with an ampersand (&)'; diff --git a/src/Domain/Input/Styles/Outline.php b/src/Domain/Input/Styles/Outline.php index ce42c3fe..ff80abcb 100644 --- a/src/Domain/Input/Styles/Outline.php +++ b/src/Domain/Input/Styles/Outline.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ class Outline implements ArrayableInterface, \JsonSerializable { use CommonTrait; diff --git a/src/Domain/Input/Styles/Scss.php b/src/Domain/Input/Styles/Scss.php index ef8e876d..3af4d1db 100644 --- a/src/Domain/Input/Styles/Scss.php +++ b/src/Domain/Input/Styles/Scss.php @@ -11,7 +11,6 @@ use ScssPhp\ScssPhp\OutputStyle; /** - * @psalm-api * @see ScssTest */ class Scss implements CssInterface diff --git a/src/Domain/Input/Styles/Spacing.php b/src/Domain/Input/Styles/Spacing.php index 52d9ddd3..2711cbbb 100644 --- a/src/Domain/Input/Styles/Spacing.php +++ b/src/Domain/Input/Styles/Spacing.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ final class Spacing implements ArrayableInterface, \JsonSerializable { use CommonTrait; @@ -60,6 +57,9 @@ public function left(string $value): self * Three values => 10px auto 0px => 10px auto 0px auto * Four values => 1px 2px 3px 4px => 1px 2px 3px 4px */ + /** + * @param string[] $values + */ public function shorthand(array $values): self { switch (\count($values)) { diff --git a/src/Domain/Input/Styles/Typography.php b/src/Domain/Input/Styles/Typography.php index e9ea1048..fb8b3f40 100644 --- a/src/Domain/Input/Styles/Typography.php +++ b/src/Domain/Input/Styles/Typography.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Domain\Input\Styles; -/** - * @psalm-api - */ final class Typography implements ArrayableInterface, \JsonSerializable { use CommonTrait; diff --git a/src/Infrastructure/Filesystem/DataFromJsonTrait.php b/src/Infrastructure/Filesystem/DataFromJsonTrait.php index d3ad55dd..70e76dc1 100644 --- a/src/Infrastructure/Filesystem/DataFromJsonTrait.php +++ b/src/Infrastructure/Filesystem/DataFromJsonTrait.php @@ -6,6 +6,9 @@ trait DataFromJsonTrait { + /** + * @return array + */ private function associativeFromPath(string $path): array { return (array)$this->fromPath($path, true); diff --git a/src/Infrastructure/Filesystem/FileWriter.php b/src/Infrastructure/Filesystem/FileWriter.php index c076d937..cf795e13 100644 --- a/src/Infrastructure/Filesystem/FileWriter.php +++ b/src/Infrastructure/Filesystem/FileWriter.php @@ -9,6 +9,7 @@ interface FileWriter { /** + * @param ConfigInterface $data * @throws \Exception */ public function write(ConfigInterface $data): void; diff --git a/src/Infrastructure/Filesystem/FilesExtension.php b/src/Infrastructure/Filesystem/FilesExtension.php index 965a75b8..252f8a01 100644 --- a/src/Infrastructure/Filesystem/FilesExtension.php +++ b/src/Infrastructure/Filesystem/FilesExtension.php @@ -4,9 +4,6 @@ namespace ItalyStrap\ThemeJsonGenerator\Infrastructure\Filesystem; -/** - * @psalm-api - */ final class FilesExtension { public const PHP = '.php'; diff --git a/src/Infrastructure/Filesystem/FilesFinder.php b/src/Infrastructure/Filesystem/FilesFinder.php index 1a028e80..f51c0e67 100644 --- a/src/Infrastructure/Filesystem/FilesFinder.php +++ b/src/Infrastructure/Filesystem/FilesFinder.php @@ -6,9 +6,6 @@ use ItalyStrap\Finder\FinderInterface; -/** - * @psalm-api - */ class FilesFinder { public const ROOT_FILE_NAME = 'theme'; @@ -71,7 +68,7 @@ public function find( public function resolveJsonFile(\SplFileInfo $file): string { $fileName = $this->extractFileName($file); - $themeRoot = \getcwd(); + $themeRoot = (string)\getcwd(); $stylesFolder = ''; if ($fileName !== self::ROOT_FILE_NAME) { $stylesFolder = self::STYLES_FOLDER; @@ -87,6 +84,10 @@ public function resolveJsonFile(\SplFileInfo $file): string } $styleCssContent = \file_get_contents($styleCss); + if ($styleCssContent === false) { + throw new \RuntimeException('Unable to read the style.css file'); + } + if (\strpos($styleCssContent, 'Theme Name:') === false) { throw new \RuntimeException('The style.css file is not a valid WordPress theme'); } diff --git a/src/Infrastructure/Filesystem/JsonFileWriter.php b/src/Infrastructure/Filesystem/JsonFileWriter.php index 90d60381..a4ba15a0 100644 --- a/src/Infrastructure/Filesystem/JsonFileWriter.php +++ b/src/Infrastructure/Filesystem/JsonFileWriter.php @@ -20,6 +20,7 @@ public function __construct(string $path) } /** + * @param ConfigInterface $data * @throws \Exception */ public function write(ConfigInterface $data): void diff --git a/src/Infrastructure/Filesystem/Path.php b/src/Infrastructure/Filesystem/Path.php deleted file mode 100644 index ae59afb8..00000000 --- a/src/Infrastructure/Filesystem/Path.php +++ /dev/null @@ -1,13 +0,0 @@ -path = $path; } + /** + * @param ConfigInterface $data + */ public function write(ConfigInterface $data): void { if (\count($data) === 0) { @@ -35,7 +38,7 @@ public function write(ConfigInterface $data): void } /** - * @param ConfigInterface $data + * @param ConfigInterface $data * @return string */ private function generateScssContent(ConfigInterface $data): string diff --git a/src/ModuleApplication.php b/src/ModuleApplication.php index 20a2ff93..f11de8d4 100644 --- a/src/ModuleApplication.php +++ b/src/ModuleApplication.php @@ -17,37 +17,59 @@ use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\SchemaJson; use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\Validate; use ItalyStrap\ThemeJsonGenerator\Infrastructure\Handler\ConsoleHandler; +use ItalyStrap\Pipeline\MiddlewareInterface; use Psr\Container\ContainerInterface; class ModuleApplication implements ModuleInterface { + /** + * @return array> + */ public function __invoke(): array { return [ AurynConfig::FACTORIES => [ - InitCommand::class => static function (ContainerInterface $container): InitCommand { + InitCommand::class => function (ContainerInterface $container): InitCommand { return new InitCommand(new ConsoleHandler( - $container->get(Init::class) + $this->middleware($container, Init::class) )); }, - DumpCommand::class => static function (ContainerInterface $container): DumpCommand { + DumpCommand::class => function (ContainerInterface $container): DumpCommand { return new DumpCommand(new ConsoleHandler( - $container->get(Dump::class), + $this->middleware($container, Dump::class), )); }, - ValidateCommand::class => static function (ContainerInterface $container): ValidateCommand { + ValidateCommand::class => function (ContainerInterface $container): ValidateCommand { return new ValidateCommand(new ConsoleHandler( new DeleteSchemaJson(), new SchemaJson(), - $container->get(Validate::class) + $this->middleware($container, Validate::class) )); }, - InfoCommand::class => static function (ContainerInterface $container): InfoCommand { + InfoCommand::class => function (ContainerInterface $container): InfoCommand { return new InfoCommand(new ConsoleHandler( - $container->get(Info::class) + $this->middleware($container, Info::class) )); }, ], ]; } + + /** + * @param class-string $id + */ + private function middleware(ContainerInterface $container, string $id): MiddlewareInterface + { + $middleware = $container->get($id); + if (!$middleware instanceof MiddlewareInterface) { + throw new \RuntimeException(\sprintf( + 'Expected container entry %s to be an instance of %s, got %s.', + $id, + MiddlewareInterface::class, + \get_debug_type($middleware) + )); + } + + return $middleware; + } } diff --git a/src/ModuleInfrastructure.php b/src/ModuleInfrastructure.php index a59b5064..84bd9990 100644 --- a/src/ModuleInfrastructure.php +++ b/src/ModuleInfrastructure.php @@ -12,6 +12,9 @@ class ModuleInfrastructure implements \ItalyStrap\Empress\ModuleInterface { + /** + * @return array + */ public function __invoke(): array { return [ diff --git a/stubs/auryn-injector.stub b/stubs/auryn-injector.stub new file mode 100644 index 00000000..cec6213d --- /dev/null +++ b/stubs/auryn-injector.stub @@ -0,0 +1,18 @@ + $args + * @return ($name is class-string ? T : mixed) + */ + public function make($name, array $args = array()) + { + } +} diff --git a/tests/unit/Application/Middlewares/SchemaJsonTest.php b/tests/unit/Application/Middlewares/SchemaJsonTest.php index ca03a44d..6f02f45c 100644 --- a/tests/unit/Application/Middlewares/SchemaJsonTest.php +++ b/tests/unit/Application/Middlewares/SchemaJsonTest.php @@ -7,6 +7,7 @@ use ItalyStrap\Pipeline\HandlerInterface; use ItalyStrap\Tests\UnitTestCase; use ItalyStrap\ThemeJsonGenerator\Application\Middlewares\SchemaJson; +use ItalyStrap\ThemeJsonGenerator\Application\ValidateMessage; final class SchemaJsonTest extends UnitTestCase { @@ -17,12 +18,8 @@ private function makeInstance(): SchemaJson public function testProcess() { - $message = new class { - public function getSchemaPath(): string - { - return \codecept_output_dir('theme.schema.json'); - } - }; + $schemaPath = \codecept_output_dir('theme.schema.json'); + $message = new ValidateMessage('', $schemaPath); $handler = new class implements HandlerInterface { public function handle(object $message): int @@ -31,15 +28,15 @@ public function handle(object $message): int } }; - if (\file_exists($message->getSchemaPath())) { - $this->tester->deleteFile($message->getSchemaPath()); + if (\file_exists($schemaPath)) { + $this->tester->deleteFile($schemaPath); } - $this->tester->writeToFile($message->getSchemaPath(), '{}'); + $this->tester->writeToFile($schemaPath, '{}'); $actual = $this->makeInstance(); $this->assertIsInt($actual->process($message, $handler)); $this->assertSame(1, $actual->process($message, $handler)); - $this->tester->deleteFile($message->getSchemaPath()); + $this->tester->deleteFile($schemaPath); } } diff --git a/tests/unit/Domain/Output/InitTest.php b/tests/unit/Domain/Output/InitTest.php index 093b4914..10ea58c8 100644 --- a/tests/unit/Domain/Output/InitTest.php +++ b/tests/unit/Domain/Output/InitTest.php @@ -15,7 +15,6 @@ class InitTest extends UnitTestCase private function makeInstance(): Init { return new Init( - $this->makeDispatcher(), $this->makeFilesFinder(), ); }