Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -0,0 +1,12 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
/**
* Alter the result of a command after it has been processed.
* An alter result interface isa process result interface.
*
* @see HookManager::addAlterResult()
*/
interface AlterResultInterface extends ProcessResultInterface
{
}

View file

@ -0,0 +1,37 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Call hooks
*/
class CommandEventHookDispatcher extends HookDispatcher
{
/**
* @param ConsoleCommandEvent $event
*/
public function callCommandEventHooks(ConsoleCommandEvent $event)
{
$hooks = [
HookManager::PRE_COMMAND_EVENT,
HookManager::COMMAND_EVENT,
HookManager::POST_COMMAND_EVENT
];
$commandEventHooks = $this->getHooks($hooks);
foreach ($commandEventHooks as $commandEvent) {
if ($commandEvent instanceof EventDispatcherInterface) {
$commandEvent->dispatch(ConsoleEvents::COMMAND, $event);
}
if (is_callable($commandEvent)) {
$commandEvent($event);
}
}
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\Hooks\ExtractOutputInterface;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\OutputDataInterface;
/**
* Call hooks
*/
class ExtracterHookDispatcher extends HookDispatcher implements ExtractOutputInterface
{
/**
* Convert the result object to printable output in
* structured form.
*/
public function extractOutput($result)
{
if ($result instanceof OutputDataInterface) {
return $result->getOutputData();
}
$hooks = [
HookManager::EXTRACT_OUTPUT,
];
$extractors = $this->getHooks($hooks);
foreach ($extractors as $extractor) {
$structuredOutput = $this->callExtractor($extractor, $result);
if (isset($structuredOutput)) {
return $structuredOutput;
}
}
return $result;
}
protected function callExtractor($extractor, $result)
{
if ($extractor instanceof ExtractOutputInterface) {
return $extractor->extractOutput($result);
}
if (is_callable($extractor)) {
return $extractor($result);
}
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\AnnotationData;
/**
* Call hooks
*/
class HookDispatcher
{
/** var HookManager */
protected $hookManager;
protected $names;
public function __construct(HookManager $hookManager, $names)
{
$this->hookManager = $hookManager;
$this->names = $names;
}
public function getHooks($hooks, $annotationData = null)
{
return $this->hookManager->getHooks($this->names, $hooks, $annotationData);
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\Hooks\InitializeHookInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
/**
* Call hooks
*/
class InitializeHookDispatcher extends HookDispatcher implements InitializeHookInterface
{
public function initialize(
InputInterface $input,
AnnotationData $annotationData
) {
$hooks = [
HookManager::PRE_INITIALIZE,
HookManager::INITIALIZE,
HookManager::POST_INITIALIZE
];
$providers = $this->getHooks($hooks, $annotationData);
foreach ($providers as $provider) {
$this->callInitializeHook($provider, $input, $annotationData);
}
}
protected function callInitializeHook($provider, $input, AnnotationData $annotationData)
{
if ($provider instanceof InitializeHookInterface) {
return $provider->initialize($input, $annotationData);
}
if (is_callable($provider)) {
return $provider($input, $annotationData);
}
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\Hooks\InteractorInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Call hooks
*/
class InteractHookDispatcher extends HookDispatcher
{
public function interact(
InputInterface $input,
OutputInterface $output,
AnnotationData $annotationData
) {
$hooks = [
HookManager::PRE_INTERACT,
HookManager::INTERACT,
HookManager::POST_INTERACT
];
$interactors = $this->getHooks($hooks, $annotationData);
foreach ($interactors as $interactor) {
$this->callInteractor($interactor, $input, $output, $annotationData);
}
}
protected function callInteractor($interactor, $input, $output, AnnotationData $annotationData)
{
if ($interactor instanceof InteractorInterface) {
return $interactor->interact($input, $output, $annotationData);
}
if (is_callable($interactor)) {
return $interactor($input, $output, $annotationData);
}
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Symfony\Component\Console\Command\Command;
use Consolidation\AnnotatedCommand\AnnotatedCommand;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\Hooks\OptionHookInterface;
/**
* Call hooks
*/
class OptionsHookDispatcher extends HookDispatcher implements OptionHookInterface
{
public function getOptions(
Command $command,
AnnotationData $annotationData
) {
$hooks = [
HookManager::PRE_OPTION_HOOK,
HookManager::OPTION_HOOK,
HookManager::POST_OPTION_HOOK
];
$optionHooks = $this->getHooks($hooks, $annotationData);
foreach ($optionHooks as $optionHook) {
$this->callOptionHook($optionHook, $command, $annotationData);
}
$commandInfoList = $this->hookManager->getHookOptionsForCommand($command);
if ($command instanceof AnnotatedCommand) {
$command->optionsHookForHookAnnotations($commandInfoList);
}
}
protected function callOptionHook($optionHook, $command, AnnotationData $annotationData)
{
if ($optionHook instanceof OptionHookInterface) {
return $optionHook->getOptions($command, $annotationData);
}
if (is_callable($optionHook)) {
return $optionHook($command, $annotationData);
}
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\CommandData;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\Hooks\ProcessResultInterface;
/**
* Call hooks
*/
class ProcessResultHookDispatcher extends HookDispatcher implements ProcessResultInterface
{
/**
* Process result and decide what to do with it.
* Allow client to add transformation / interpretation
* callbacks.
*/
public function process($result, CommandData $commandData)
{
$hooks = [
HookManager::PRE_PROCESS_RESULT,
HookManager::PROCESS_RESULT,
HookManager::POST_PROCESS_RESULT,
HookManager::PRE_ALTER_RESULT,
HookManager::ALTER_RESULT,
HookManager::POST_ALTER_RESULT,
HookManager::POST_COMMAND_HOOK,
];
$processors = $this->getHooks($hooks, $commandData->annotationData());
foreach ($processors as $processor) {
$result = $this->callProcessor($processor, $result, $commandData);
}
return $result;
}
protected function callProcessor($processor, $result, CommandData $commandData)
{
$processed = null;
if ($processor instanceof ProcessResultInterface) {
$processed = $processor->process($result, $commandData);
}
if (is_callable($processor)) {
$processed = $processor($result, $commandData);
}
if (isset($processed)) {
return $processed;
}
return $result;
}
}

View file

@ -0,0 +1,66 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\CommandData;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
/**
* Call hooks.
*/
class ReplaceCommandHookDispatcher extends HookDispatcher implements LoggerAwareInterface
{
use LoggerAwareTrait;
/**
* @return int
*/
public function hasReplaceCommandHook()
{
return (bool) count($this->getReplaceCommandHooks());
}
/**
* @return \callable[]
*/
public function getReplaceCommandHooks()
{
$hooks = [
HookManager::REPLACE_COMMAND_HOOK,
];
$replaceCommandHooks = $this->getHooks($hooks);
return $replaceCommandHooks;
}
/**
* @param \Consolidation\AnnotatedCommand\CommandData $commandData
*
* @return callable
*/
public function getReplacementCommand(CommandData $commandData)
{
$replaceCommandHooks = $this->getReplaceCommandHooks();
// We only take the first hook implementation of "replace-command" as the replacement. Commands shouldn't have
// more than one replacement.
$replacementCommand = reset($replaceCommandHooks);
if ($this->logger && count($replaceCommandHooks) > 1) {
$command_name = $commandData->annotationData()->get('command', 'unknown');
$message = "Multiple implementations of the \"replace - command\" hook exist for the \"$command_name\" command.\n";
foreach ($replaceCommandHooks as $replaceCommandHook) {
$class = get_class($replaceCommandHook[0]);
$method = $replaceCommandHook[1];
$hook_name = "$class->$method";
$message .= " - $hook_name\n";
}
$this->logger->warning($message);
}
return $replacementCommand;
}
}

View file

@ -0,0 +1,51 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\ExitCodeInterface;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\Hooks\StatusDeterminerInterface;
/**
* Call hooks
*/
class StatusDeterminerHookDispatcher extends HookDispatcher implements StatusDeterminerInterface
{
/**
* Call all status determiners, and see if any of them
* know how to convert to a status code.
*/
public function determineStatusCode($result)
{
// If the result (post-processing) is an object that
// implements ExitCodeInterface, then we will ask it
// to give us the status code.
if ($result instanceof ExitCodeInterface) {
return $result->getExitCode();
}
$hooks = [
HookManager::STATUS_DETERMINER,
];
// If the result does not implement ExitCodeInterface,
// then we'll see if there is a determiner that can
// extract a status code from the result.
$determiners = $this->getHooks($hooks);
foreach ($determiners as $determiner) {
$status = $this->callDeterminer($determiner, $result);
if (isset($status)) {
return $status;
}
}
}
protected function callDeterminer($determiner, $result)
{
if ($determiner instanceof StatusDeterminerInterface) {
return $determiner->determineStatusCode($result);
}
if (is_callable($determiner)) {
return $determiner($result);
}
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks\Dispatchers;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\CommandData;
use Consolidation\AnnotatedCommand\CommandError;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Consolidation\AnnotatedCommand\Hooks\ValidatorInterface;
/**
* Call hooks
*/
class ValidateHookDispatcher extends HookDispatcher implements ValidatorInterface
{
public function validate(CommandData $commandData)
{
$hooks = [
HookManager::PRE_ARGUMENT_VALIDATOR,
HookManager::ARGUMENT_VALIDATOR,
HookManager::POST_ARGUMENT_VALIDATOR,
HookManager::PRE_COMMAND_HOOK,
HookManager::COMMAND_HOOK,
];
$validators = $this->getHooks($hooks, $commandData->annotationData());
foreach ($validators as $validator) {
$validated = $this->callValidator($validator, $commandData);
if ($validated === false) {
return new CommandError();
}
if (is_object($validated)) {
return $validated;
}
}
}
protected function callValidator($validator, CommandData $commandData)
{
if ($validator instanceof ValidatorInterface) {
return $validator->validate($commandData);
}
if (is_callable($validator)) {
return $validator($commandData);
}
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
/**
* Extract Output hooks are used to select the particular
* data elements of the result that should be printed as
* the command output -- perhaps after being formatted.
*
* @see HookManager::addOutputExtractor()
*/
interface ExtractOutputInterface
{
public function extractOutput($result);
}

View file

@ -0,0 +1,434 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Consolidation\AnnotatedCommand\ExitCodeInterface;
use Consolidation\AnnotatedCommand\OutputDataInterface;
use Consolidation\AnnotatedCommand\AnnotationData;
use Consolidation\AnnotatedCommand\CommandData;
use Consolidation\AnnotatedCommand\CommandError;
use Consolidation\AnnotatedCommand\Hooks\Dispatchers\CommandEventHookDispatcher;
/**
* Manage named callback hooks
*/
class HookManager implements EventSubscriberInterface
{
protected $hooks = [];
/** var CommandInfo[] */
protected $hookOptions = [];
const REPLACE_COMMAND_HOOK = 'replace-command';
const PRE_COMMAND_EVENT = 'pre-command-event';
const COMMAND_EVENT = 'command-event';
const POST_COMMAND_EVENT = 'post-command-event';
const PRE_OPTION_HOOK = 'pre-option';
const OPTION_HOOK = 'option';
const POST_OPTION_HOOK = 'post-option';
const PRE_INITIALIZE = 'pre-init';
const INITIALIZE = 'init';
const POST_INITIALIZE = 'post-init';
const PRE_INTERACT = 'pre-interact';
const INTERACT = 'interact';
const POST_INTERACT = 'post-interact';
const PRE_ARGUMENT_VALIDATOR = 'pre-validate';
const ARGUMENT_VALIDATOR = 'validate';
const POST_ARGUMENT_VALIDATOR = 'post-validate';
const PRE_COMMAND_HOOK = 'pre-command';
const COMMAND_HOOK = 'command';
const POST_COMMAND_HOOK = 'post-command';
const PRE_PROCESS_RESULT = 'pre-process';
const PROCESS_RESULT = 'process';
const POST_PROCESS_RESULT = 'post-process';
const PRE_ALTER_RESULT = 'pre-alter';
const ALTER_RESULT = 'alter';
const POST_ALTER_RESULT = 'post-alter';
const STATUS_DETERMINER = 'status';
const EXTRACT_OUTPUT = 'extract';
const ON_EVENT = 'on-event';
public function __construct()
{
}
public function getAllHooks()
{
return $this->hooks;
}
/**
* Add a hook
*
* @param mixed $callback The callback function to call
* @param string $hook The name of the hook to add
* @param string $name The name of the command to hook
* ('*' for all)
*/
public function add(callable $callback, $hook, $name = '*')
{
if (empty($name)) {
$name = static::getClassNameFromCallback($callback);
}
$this->hooks[$name][$hook][] = $callback;
return $this;
}
public function recordHookOptions($commandInfo, $name)
{
$this->hookOptions[$name][] = $commandInfo;
return $this;
}
public static function getNames($command, $callback)
{
return array_filter(
array_merge(
static::getNamesUsingCommands($command),
[static::getClassNameFromCallback($callback)]
)
);
}
protected static function getNamesUsingCommands($command)
{
return array_merge(
[$command->getName()],
$command->getAliases()
);
}
/**
* If a command hook does not specify any particular command
* name that it should be attached to, then it will be applied
* to every command that is defined in the same class as the hook.
* This is controlled by using the namespace + class name of
* the implementing class of the callback hook.
*/
protected static function getClassNameFromCallback($callback)
{
if (!is_array($callback)) {
return '';
}
$reflectionClass = new \ReflectionClass($callback[0]);
return $reflectionClass->getName();
}
/**
* Add a replace command hook
*
* @param type ReplaceCommandHookInterface $provider
* @param type string $command_name The name of the command to replace
*/
public function addReplaceCommandHook(ReplaceCommandHookInterface $replaceCommandHook, $name)
{
$this->hooks[$name][self::REPLACE_COMMAND_HOOK][] = $replaceCommandHook;
return $this;
}
public function addPreCommandEventDispatcher(EventDispatcherInterface $eventDispatcher, $name = '*')
{
$this->hooks[$name][self::PRE_COMMAND_EVENT][] = $eventDispatcher;
return $this;
}
public function addCommandEventDispatcher(EventDispatcherInterface $eventDispatcher, $name = '*')
{
$this->hooks[$name][self::COMMAND_EVENT][] = $eventDispatcher;
return $this;
}
public function addPostCommandEventDispatcher(EventDispatcherInterface $eventDispatcher, $name = '*')
{
$this->hooks[$name][self::POST_COMMAND_EVENT][] = $eventDispatcher;
return $this;
}
public function addCommandEvent(EventSubscriberInterface $eventSubscriber)
{
// Wrap the event subscriber in a dispatcher and add it
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber($eventSubscriber);
return $this->addCommandEventDispatcher($dispatcher);
}
/**
* Add an configuration provider hook
*
* @param type InitializeHookInterface $provider
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addInitializeHook(InitializeHookInterface $initializeHook, $name = '*')
{
$this->hooks[$name][self::INITIALIZE][] = $initializeHook;
return $this;
}
/**
* Add an option hook
*
* @param type ValidatorInterface $validator
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addOptionHook(OptionHookInterface $interactor, $name = '*')
{
$this->hooks[$name][self::INTERACT][] = $interactor;
return $this;
}
/**
* Add an interact hook
*
* @param type ValidatorInterface $validator
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addInteractor(InteractorInterface $interactor, $name = '*')
{
$this->hooks[$name][self::INTERACT][] = $interactor;
return $this;
}
/**
* Add a pre-validator hook
*
* @param type ValidatorInterface $validator
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addPreValidator(ValidatorInterface $validator, $name = '*')
{
$this->hooks[$name][self::PRE_ARGUMENT_VALIDATOR][] = $validator;
return $this;
}
/**
* Add a validator hook
*
* @param type ValidatorInterface $validator
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addValidator(ValidatorInterface $validator, $name = '*')
{
$this->hooks[$name][self::ARGUMENT_VALIDATOR][] = $validator;
return $this;
}
/**
* Add a pre-command hook. This is the same as a validator hook, except
* that it will run after all of the post-validator hooks.
*
* @param type ValidatorInterface $preCommand
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addPreCommandHook(ValidatorInterface $preCommand, $name = '*')
{
$this->hooks[$name][self::PRE_COMMAND_HOOK][] = $preCommand;
return $this;
}
/**
* Add a post-command hook. This is the same as a pre-process hook,
* except that it will run before the first pre-process hook.
*
* @param type ProcessResultInterface $postCommand
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addPostCommandHook(ProcessResultInterface $postCommand, $name = '*')
{
$this->hooks[$name][self::POST_COMMAND_HOOK][] = $postCommand;
return $this;
}
/**
* Add a result processor.
*
* @param type ProcessResultInterface $resultProcessor
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addResultProcessor(ProcessResultInterface $resultProcessor, $name = '*')
{
$this->hooks[$name][self::PROCESS_RESULT][] = $resultProcessor;
return $this;
}
/**
* Add a result alterer. After a result is processed
* by a result processor, an alter hook may be used
* to convert the result from one form to another.
*
* @param type AlterResultInterface $resultAlterer
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addAlterResult(AlterResultInterface $resultAlterer, $name = '*')
{
$this->hooks[$name][self::ALTER_RESULT][] = $resultAlterer;
return $this;
}
/**
* Add a status determiner. Usually, a command should return
* an integer on error, or a result object on success (which
* implies a status code of zero). If a result contains the
* status code in some other field, then a status determiner
* can be used to call the appropriate accessor method to
* determine the status code. This is usually not necessary,
* though; a command that fails may return a CommandError
* object, which contains a status code and a result message
* to display.
* @see CommandError::getExitCode()
*
* @param type StatusDeterminerInterface $statusDeterminer
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addStatusDeterminer(StatusDeterminerInterface $statusDeterminer, $name = '*')
{
$this->hooks[$name][self::STATUS_DETERMINER][] = $statusDeterminer;
return $this;
}
/**
* Add an output extractor. If a command returns an object
* object, by default it is passed directly to the output
* formatter (if in use) for rendering. If the result object
* contains more information than just the data to render, though,
* then an output extractor can be used to call the appopriate
* accessor method of the result object to get the data to
* rendered. This is usually not necessary, though; it is preferable
* to have complex result objects implement the OutputDataInterface.
* @see OutputDataInterface::getOutputData()
*
* @param type ExtractOutputInterface $outputExtractor
* @param type $name The name of the command to hook
* ('*' for all)
*/
public function addOutputExtractor(ExtractOutputInterface $outputExtractor, $name = '*')
{
$this->hooks[$name][self::EXTRACT_OUTPUT][] = $outputExtractor;
return $this;
}
public function getHookOptionsForCommand($command)
{
$names = $this->addWildcardHooksToNames($command->getNames(), $command->getAnnotationData());
return $this->getHookOptions($names);
}
/**
* @return CommandInfo[]
*/
public function getHookOptions($names)
{
$result = [];
foreach ($names as $name) {
if (isset($this->hookOptions[$name])) {
$result = array_merge($result, $this->hookOptions[$name]);
}
}
return $result;
}
/**
* Get a set of hooks with the provided name(s). Include the
* pre- and post- hooks, and also include the global hooks ('*')
* in addition to the named hooks provided.
*
* @param string|array $names The name of the function being hooked.
* @param string[] $hooks A list of hooks (e.g. [HookManager::ALTER_RESULT])
*
* @return callable[]
*/
public function getHooks($names, $hooks, $annotationData = null)
{
return $this->get($this->addWildcardHooksToNames($names, $annotationData), $hooks);
}
protected function addWildcardHooksToNames($names, $annotationData = null)
{
$names = array_merge(
(array)$names,
($annotationData == null) ? [] : array_map(function ($item) {
return "@$item";
}, $annotationData->keys())
);
$names[] = '*';
return array_unique($names);
}
/**
* Get a set of hooks with the provided name(s).
*
* @param string|array $names The name of the function being hooked.
* @param string[] $hooks The list of hook names (e.g. [HookManager::ALTER_RESULT])
*
* @return callable[]
*/
public function get($names, $hooks)
{
$result = [];
foreach ((array)$hooks as $hook) {
foreach ((array)$names as $name) {
$result = array_merge($result, $this->getHook($name, $hook));
}
}
return $result;
}
/**
* Get a single named hook.
*
* @param string $name The name of the hooked method
* @param string $hook The specific hook name (e.g. alter)
*
* @return callable[]
*/
public function getHook($name, $hook)
{
if (isset($this->hooks[$name][$hook])) {
return $this->hooks[$name][$hook];
}
return [];
}
/**
* Call the command event hooks.
*
* TODO: This should be moved to CommandEventHookDispatcher, which
* should become the class that implements EventSubscriberInterface.
* This change would break all clients, though, so postpone until next
* major release.
*
* @param ConsoleCommandEvent $event
*/
public function callCommandEventHooks(ConsoleCommandEvent $event)
{
/* @var Command $command */
$command = $event->getCommand();
$dispatcher = new CommandEventHookDispatcher($this, [$command->getName()]);
$dispatcher->callCommandEventHooks($event);
}
/**
* @{@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [ConsoleEvents::COMMAND => 'callCommandEventHooks'];
}
}

View file

@ -0,0 +1,15 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
use Consolidation\AnnotatedCommand\AnnotationData;
use Symfony\Component\Console\Input\InputInterface;
/**
* Non-interactively (e.g. via configuration files) apply configuration values to the Input object.
*
* @see HookManager::addInitializeHook()
*/
interface InitializeHookInterface
{
public function initialize(InputInterface $input, AnnotationData $annotationData);
}

View file

@ -0,0 +1,18 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
use Consolidation\AnnotatedCommand\AnnotationData;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Interactively supply values for missing required arguments for
* the current command. Note that this hook is not called if
* the --no-interaction flag is set.
*
* @see HookManager::addInteractor()
*/
interface InteractorInterface
{
public function interact(InputInterface $input, OutputInterface $output, AnnotationData $annotationData);
}

View file

@ -0,0 +1,16 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
use Consolidation\AnnotatedCommand\AnnotationData;
use Symfony\Component\Console\Command\Command;
/**
* Add options to a command.
*
* @see HookManager::addOptionHook()
* @see AnnotatedCommandFactory::addListener()
*/
interface OptionHookInterface
{
public function getOptions(Command $command, AnnotationData $annotationData);
}

View file

@ -0,0 +1,27 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
use Consolidation\AnnotatedCommand\CommandData;
/**
* A result processor takes a result object, processes it, and
* returns another result object. For example, if a result object
* represents a 'task', then a task-runner hook could run the
* task and return the result from that execution.
*
* @see HookManager::addResultProcessor()
*/
interface ProcessResultInterface
{
/**
* After a command has executed, if the result is something
* that needs to be processed, e.g. a collection of tasks to
* run, then execute it and return the new result.
*
* @param mixed $result Result to (potentially) be processed
* @param CommandData $commandData Reference to commandline arguments and options
*
* @return mixed $result
*/
public function process($result, CommandData $commandData);
}

View file

@ -0,0 +1,22 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
/**
* A StatusDeterminer maps from a result to a status exit code.
*
* @deprecated. Instead of using a Status Determiner hook, commands
* should simply return their exit code and result data separately
* using a CommandResult object.
*
* @see HookManager::addStatusDeterminer()
*/
interface StatusDeterminerInterface
{
/**
* Convert a result object into a status code, if
* possible. Return null if the result object is unknown.
*
* @return null|integer
*/
public function determineStatusCode($result);
}

View file

@ -0,0 +1,14 @@
<?php
namespace Consolidation\AnnotatedCommand\Hooks;
use Consolidation\AnnotatedCommand\CommandData;
/**
* Validate the arguments for the current command.
*
* @see HookManager::addValidator()
*/
interface ValidatorInterface
{
public function validate(CommandData $commandData);
}