From 4ce251a8bc0c6186f144ae80aa7c495d55b041f4 Mon Sep 17 00:00:00 2001 From: Julien Rosset Date: Mon, 28 Oct 2024 11:12:34 +0100 Subject: [PATCH] Add command requirements support --- composer.json | 13 ++-- src/CliProgram/CliHelper.php | 41 ++++++++++++ src/CliProgram/Requirements/IRequirements.php | 24 +++++++ .../Requirements/TRequirementsApplication.php | 64 +++++++++++++++++++ tests/Application.php | 3 + tests/Commands/FailedHello.php | 23 +++++++ tests/Commands/Hello.php | 15 +++-- 7 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 src/CliProgram/CliHelper.php create mode 100644 src/CliProgram/Requirements/IRequirements.php create mode 100644 src/CliProgram/Requirements/TRequirementsApplication.php create mode 100644 tests/Commands/FailedHello.php diff --git a/composer.json b/composer.json index c113566..8d00dcf 100644 --- a/composer.json +++ b/composer.json @@ -15,12 +15,13 @@ "minimum-stability": "stable", "require": { - "php": "^7.4 || ^8.0.0", - "jrosset/betterphptoken": "^1.0", - "jrosset/extendedmonolog": "^1.1", - "psr/log": "^1.1", - "symfony/console": "^5.4", - "voku/arrayy": "^7.9" + "php": "^7.4 || ^8.0.0", + "jrosset/betterphptoken": "^1.0", + "jrosset/extendedmonolog": "^1.1", + "psr/log": "^1.1", + "symfony/console": "^5.4", + "symfony/event-dispatcher": "^5.4", + "voku/arrayy": "^7.9" }, "autoload": { "psr-4": { diff --git a/src/CliProgram/CliHelper.php b/src/CliProgram/CliHelper.php new file mode 100644 index 0000000..b4c6643 --- /dev/null +++ b/src/CliProgram/CliHelper.php @@ -0,0 +1,41 @@ +getErrorOutput() : $output; + } + + /** + * Get the name of a command class + * + * @param Application $application The application + * @param class-string $commandClass The command class + * + * @return string|null The command name ; Null if not found + */ + public static final function getCommandNameFromClass (Application $application, string $commandClass): ?string { + foreach ($application->all() as $possibleCommand) { + if (get_class($possibleCommand) == $commandClass) { + return $possibleCommand->getName(); + } + } + return null; + } +} \ No newline at end of file diff --git a/src/CliProgram/Requirements/IRequirements.php b/src/CliProgram/Requirements/IRequirements.php new file mode 100644 index 0000000..181e3af --- /dev/null +++ b/src/CliProgram/Requirements/IRequirements.php @@ -0,0 +1,24 @@ +addListener(ConsoleEvents::COMMAND, [$this, 'checkCommandRequirements']); + $this->setDispatcher($dispatcher); + } + + /** + * Check the requirements of a command + * + * @param ConsoleCommandEvent $event The command event + * + * @return void + */ + public function checkCommandRequirements (ConsoleCommandEvent $event): void { + $commandInput = $event->getInput(); + $commandOutput = $event->getOutput(); + try { + //region Check the command is valid + if (($command = $event->getCommand()) === null) { + return; + } + + $commandReflection = new ReflectionClass($command); + //endregion + //region Contrôle pré-requis (implémentation directe) + if ($command instanceof IRequirements) { + $command->checkRequirements($commandInput, $commandOutput); + } + //endregion + } + catch (Throwable $exception) { + $this->renderThrowable($exception, CliHelper::getErrorOutput($commandOutput)); + + $event->disableCommand(); + $event->stopPropagation(); + return; + } + } +} \ No newline at end of file diff --git a/tests/Application.php b/tests/Application.php index 16748cf..22e8e2a 100644 --- a/tests/Application.php +++ b/tests/Application.php @@ -6,12 +6,15 @@ use jrosset\CliProgram\ApplicationWithCommandMonolog; use jrosset\CliProgram\AutoDiscovery\AutoDiscoveryDirectory; use jrosset\CliProgram\AutoDiscovery\TAutoDiscoveryApplication; use jrosset\CliProgram\AutoPrefix\AutoPrefixNamespaceManager; +use jrosset\CliProgram\Requirements\TRequirementsApplication; class Application extends ApplicationWithCommandMonolog { use TAutoDiscoveryApplication; + use TRequirementsApplication; public function __construct (string $name = 'UNKNOWN', string $version = 'UNKNOWN') { parent::__construct(__DIR__ . '/logs/', $name, $version); + $this->registerCommandRequirementsListener(); $spot = new AutoDiscoveryDirectory(__DIR__ . '/Commands'); $spot->getAutoPrefixManagers()->prepend(new AutoPrefixNamespaceManager('\\jrosset\\Tests\\Commands', 'test')); diff --git a/tests/Commands/FailedHello.php b/tests/Commands/FailedHello.php new file mode 100644 index 0000000..8fb7606 --- /dev/null +++ b/tests/Commands/FailedHello.php @@ -0,0 +1,23 @@ +writeln('Command : ' . __CLASS__, OutputInterface::VERBOSITY_DEBUG); + $output->writeln('Command : ' . __CLASS__ . '', OutputInterface::VERBOSITY_DEBUG); $text = 'Hello'; $repeat = $input->getOption('repeat');