parent
0a9a99f13c
commit
4ce251a8bc
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Application;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper methods
|
||||||
|
*/
|
||||||
|
abstract class CliHelper {
|
||||||
|
/**
|
||||||
|
* Get the “error” output if exists, else the output itself
|
||||||
|
*
|
||||||
|
* @param OutputInterface $output The output
|
||||||
|
*
|
||||||
|
* @return OutputInterface The “error” output if exists, else the output itself
|
||||||
|
*/
|
||||||
|
public static final function getErrorOutput (OutputInterface $output): OutputInterface {
|
||||||
|
return $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of a command class
|
||||||
|
*
|
||||||
|
* @param Application $application The application
|
||||||
|
* @param class-string<Command> $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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram\Requirements;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for a command requirements
|
||||||
|
*/
|
||||||
|
interface IRequirements {
|
||||||
|
/**
|
||||||
|
* Check the requirements
|
||||||
|
*
|
||||||
|
* @param InputInterface $input The command input
|
||||||
|
* @param OutputInterface $output The command output
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws Throwable If a requirement failed
|
||||||
|
*/
|
||||||
|
public function checkRequirements (InputInterface $input, OutputInterface $output): void;
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\CliProgram\Requirements;
|
||||||
|
|
||||||
|
use jrosset\CliProgram\CliHelper;
|
||||||
|
use ReflectionClass;
|
||||||
|
use Symfony\Component\Console\ConsoleEvents;
|
||||||
|
use Symfony\Component\Console\Event\ConsoleCommandEvent;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||||
|
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An application with command requirements checking
|
||||||
|
*
|
||||||
|
* @see IRequirements
|
||||||
|
*/
|
||||||
|
trait TRequirementsApplication {
|
||||||
|
/**
|
||||||
|
* Register the listener for command requirements
|
||||||
|
*
|
||||||
|
* @param EventDispatcherInterface|null $dispatcher The event dispatcher is already existing
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected final function registerCommandRequirementsListener (?EventDispatcherInterface $dispatcher = null): void {
|
||||||
|
$dispatcher ??= new EventDispatcher();
|
||||||
|
$dispatcher->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace jrosset\Tests\Commands;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class FailedHello extends Hello {
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function __construct () {
|
||||||
|
parent::__construct('failedHello');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function checkRequirements (InputInterface $input, OutputInterface $output): void {
|
||||||
|
throw new LogicException('The "foo" requirement failed');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue