namespace Drupal\Console\Core;
+use Drupal\Console\Core\EventSubscriber\RemoveMessagesListener;
+use Drupal\Console\Core\EventSubscriber\ShowGenerateCountCodeLinesListener;
use Drupal\Console\Core\Utils\TranslatorManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Application as BaseApplication;
+use Symfony\Component\Console\Input\ArrayInput;
use Drupal\Console\Core\EventSubscriber\DefaultValueEventListener;
use Drupal\Console\Core\EventSubscriber\ShowGenerateChainListener;
use Drupal\Console\Core\EventSubscriber\ShowTipsListener;
use Drupal\Console\Core\Style\DrupalStyle;
use Drupal\Console\Core\Utils\ChainDiscovery;
use Drupal\Console\Core\Command\Chain\ChainCustomCommand;
+use Drupal\Console\Core\Bootstrap\DrupalInterface;
/**
* Class Application
*/
protected $commandName;
+ /**
+ * @var DrupalInterface
+ */
+ protected $drupal;
+
+ /**
+ * @var bool
+ */
+ protected $eventRegistered;
+
/**
* ConsoleApplication constructor.
*
* @param string $version
*/
public function __construct(
- ContainerInterface$container,
+ ContainerInterface $container,
$name,
$version
) {
$this->container = $container;
+ $this->eventRegistered = false;
parent::__construct($name, $version);
$this->addOptions();
}
public function doRun(InputInterface $input, OutputInterface $output)
{
$io = new DrupalStyle($input, $output);
- if ($commandName = $this->getCommandName($input)) {
- $this->commandName = $commandName;
+ $messageManager = $this->container->get('console.message_manager');
+ $this->commandName = $this->getCommandName($input)?:'list';
+
+ $clear = $this->container->get('console.configuration_manager')
+ ->getConfiguration()
+ ->get('application.clear')?:false;
+ if ($clear === true || $clear === 'true') {
+ $output->write(sprintf("\033\143"));
}
- $this->registerEvents();
- $this->registerExtendCommands();
- $this->registerCommandsFromAutoWireConfiguration();
- $this->registerChainCommands();
+
+ $this->loadCommands();
/**
* @var ConfigurationManager $configurationManager
$configurationManager = $this->container
->get('console.configuration_manager');
- if ($commandName && !$this->has($commandName)) {
- $io->error(
- sprintf(
- $this->trans('application.errors.invalid-command'),
- $this->commandName
- )
- );
+ if (!$this->has($this->commandName)) {
+ $isValidCommand = false;
+ $config = $configurationManager->getConfiguration();
+ $mappings = $config->get('application.commands.mappings');
+
+ if (array_key_exists($this->commandName, $mappings)) {
+ $commandNameMap = $mappings[$this->commandName];
+ $messageManager->warning(
+ sprintf(
+ $this->trans('application.errors.renamed-command'),
+ $this->commandName,
+ $commandNameMap
+ )
+ );
+ $this->add(
+ $this->find($commandNameMap)->setAliases([$this->commandName])
+ );
+ $isValidCommand = true;
+ }
+
+ $drushCommand = $configurationManager->readDrushEquivalents($this->commandName);
+ if ($drushCommand) {
+ $this->add(
+ $this->find($drushCommand)->setAliases([$this->commandName])
+ );
+ $isValidCommand = true;
+ $messageManager->warning(
+ sprintf(
+ $this->trans('application.errors.drush-command'),
+ $this->commandName,
+ $drushCommand
+ )
+ );
+ }
+
+ $namespaces = $this->getNamespaces();
+ if (in_array($this->commandName, $namespaces)) {
+ $input = new ArrayInput(
+ [
+ 'command' => 'list',
+ 'namespace' => $this->commandName
+ ]
+ );
+ $this->commandName = 'list';
+ $isValidCommand = true;
+ }
+
+ if (!$isValidCommand) {
+ $io->error(
+ sprintf(
+ $this->trans('application.errors.invalid-command'),
+ $this->commandName
+ )
+ );
- return 1;
+ return 1;
+ }
}
$code = parent::doRun(
$output
);
- if ($this->commandName != 'init' && $configurationManager->getMissingConfigurationFiles()) {
- $io->warning($this->trans('application.site.errors.missing-config-file'));
- $io->listing($configurationManager->getMissingConfigurationFiles());
- $io->commentBlock(
- $this->trans('application.site.errors.missing-config-file-command')
- );
- }
+ // Propagate Drupal messages.
+ $this->addDrupalMessages($messageManager);
- if ($this->getCommandName($input) == 'list' && $this->container->hasParameter('console.warning')) {
- $io->warning(
- $this->trans($this->container->getParameter('console.warning'))
- );
+ if ($this->showMessages($input)) {
+ $messages = $messageManager->getMessages();
+
+ foreach ($messages as $message) {
+ $showBy = $message['showBy'];
+ if ($showBy!=='all' && $showBy!==$this->commandName) {
+ continue;
+ }
+ $type = $message['type'];
+ $io->$type($message['message']);
+ }
}
+
return $code;
}
+ public function loadCommands()
+ {
+ $this->registerGenerators();
+ $this->registerCommands();
+ $this->registerEvents();
+ $this->registerExtendCommands();
+
+ /**
+ * @var ConfigurationManager $configurationManager
+ */
+ $configurationManager = $this->container
+ ->get('console.configuration_manager');
+
+ $config = $configurationManager->getConfiguration()
+ ->get('application.extras.config')?:'true';
+ if ($config === 'true') {
+ $this->registerCommandsFromAutoWireConfiguration();
+ }
+
+ $chains = $configurationManager->getConfiguration()
+ ->get('application.extras.chains')?:'true';
+ if ($chains === 'true') {
+ $this->registerChainCommands();
+ }
+ }
+
+ /**
+ * @param InputInterface $input
+ *
+ * @return bool
+ */
+ private function showMessages(InputInterface $input)
+ {
+ $format = $input->hasOption('format')?$input->getOption('format'):'txt';
+
+ if ($format !== 'txt') {
+ return false;
+ }
+
+ return true;
+ }
+
/**
* registerEvents
*/
private function registerEvents()
{
- $dispatcher = new EventDispatcher();
- /* @todo Register listeners as services */
- $dispatcher->addSubscriber(
- new ValidateExecutionListener(
- $this->container->get('console.translator_manager'),
- $this->container->get('console.configuration_manager')
- )
- );
- $dispatcher->addSubscriber(
- new ShowWelcomeMessageListener(
- $this->container->get('console.translator_manager')
- )
- );
- $dispatcher->addSubscriber(
- new DefaultValueEventListener(
- $this->container->get('console.configuration_manager')
- )
- );
- $dispatcher->addSubscriber(
- new ShowTipsListener(
- $this->container->get('console.translator_manager')
- )
- );
- $dispatcher->addSubscriber(
- new CallCommandListener(
- $this->container->get('console.chain_queue')
- )
- );
- $dispatcher->addSubscriber(
- new ShowGeneratedFilesListener(
- $this->container->get('console.file_queue'),
- $this->container->get('console.show_file')
- )
- );
- $dispatcher->addSubscriber(
- new ShowGenerateInlineListener(
- $this->container->get('console.translator_manager')
- )
- );
- $dispatcher->addSubscriber(
- new ShowGenerateChainListener(
- $this->container->get('console.translator_manager')
- )
- );
+ if (!$this->eventRegistered) {
+ $dispatcher = new EventDispatcher();
+ $dispatcher->addSubscriber(
+ new ValidateExecutionListener(
+ $this->container->get('console.translator_manager'),
+ $this->container->get('console.configuration_manager')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new ShowWelcomeMessageListener(
+ $this->container->get('console.translator_manager')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new DefaultValueEventListener(
+ $this->container->get('console.configuration_manager')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new ShowTipsListener(
+ $this->container->get('console.translator_manager')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new CallCommandListener(
+ $this->container->get('console.chain_queue')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new ShowGeneratedFilesListener(
+ $this->container->get('console.file_queue'),
+ $this->container->get('console.show_file')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new ShowGenerateInlineListener(
+ $this->container->get('console.translator_manager')
+ )
+ );
+ $dispatcher->addSubscriber(
+ new ShowGenerateChainListener(
+ $this->container->get('console.translator_manager')
+ )
+ );
- $this->setDispatcher($dispatcher);
+ $dispatcher->addSubscriber(
+ new ShowGenerateCountCodeLinesListener(
+ $this->container->get('console.translator_manager'),
+ $this->container->get('console.count_code_lines')
+ )
+ );
+
+ $dispatcher->addSubscriber(
+ new RemoveMessagesListener(
+ $this->container->get('console.message_manager')
+ )
+ );
+
+ $this->setDispatcher($dispatcher);
+ $this->eventRegistered = true;
+ }
}
/**
*/
private function addOptions()
{
+ // Get the configuration from config.yml.
+ $env = $this->container
+ ->get('console.configuration_manager')
+ ->getConfiguration()
+ ->get('application.environment');
+
$this->getDefinition()->addOption(
new InputOption(
'--env',
'-e',
InputOption::VALUE_OPTIONAL,
- $this->trans('application.options.env'), 'prod'
+ $this->trans('application.options.env'),
+ !empty($env) ? $env : 'prod'
)
);
$this->getDefinition()->addOption(
}
/**
- * registerExtendCommands
+ * registerCommands
*/
- private function registerExtendCommands()
+ private function registerCommands()
{
- $this->container->get('console.configuration_manager')
- ->loadExtendConfiguration();
+ $consoleCommands = $this->container
+ ->findTaggedServiceIds('drupal.command');
+
+ $aliases = $this->container->get('console.configuration_manager')
+ ->getConfiguration()
+ ->get('application.commands.aliases')?:[];
+
+ $invalidCommands = [];
+ if ($this->container->has('console.key_value_storage')) {
+ $invalidCommands = $this->container
+ ->get('console.key_value_storage')
+ ->get('invalid_commands', []);
+ }
+
+ foreach ($consoleCommands as $name => $tags) {
+ if (in_array($name, $invalidCommands)) {
+ continue;
+ }
+
+ if (!$this->container->has($name)) {
+ continue;
+ }
+
+ try {
+ $command = $this->container->get($name);
+ } catch (\Exception $e) {
+ echo $name . ' - ' . $e->getMessage() . PHP_EOL;
+
+ continue;
+ }
+
+ if (!$command) {
+ continue;
+ }
+
+ if (method_exists($command, 'setTranslator')) {
+ $command->setTranslator(
+ $this->container->get('console.translator_manager')
+ );
+ }
+
+ if (method_exists($command, 'setContainer')) {
+ $command->setContainer(
+ $this->container->get('service_container')
+ );
+ }
+
+ if (array_key_exists($command->getName(), $aliases)) {
+ $commandAliases = $aliases[$command->getName()];
+ if (!is_array($commandAliases)) {
+ $commandAliases = [$commandAliases];
+ }
+ $commandAliases = array_merge(
+ $command->getAliases(),
+ $commandAliases
+ );
+ $command->setAliases($commandAliases);
+ }
+
+ $this->add($command);
+ }
+ }
+
+ /**
+ * registerGenerators
+ */
+ private function registerGenerators()
+ {
+ $consoleGenerators = $this->container
+ ->findTaggedServiceIds('drupal.generator');
+
+ foreach ($consoleGenerators as $name => $tags) {
+ if (!$this->container->has($name)) {
+ continue;
+ }
+
+ try {
+ $generator = $this->container->get($name);
+ } catch (\Exception $e) {
+ echo $name . ' - ' . $e->getMessage() . PHP_EOL;
+
+ continue;
+ }
+
+ if (!$generator) {
+ continue;
+ }
+ if (method_exists($generator, 'setRenderer')) {
+ $generator->setRenderer(
+ $this->container->get('console.renderer')
+ );
+ }
+
+ if (method_exists($generator, 'setFileQueue')) {
+ $generator->setFileQueue(
+ $this->container->get('console.file_queue')
+ );
+ }
+
+ if (method_exists($generator, 'setCountCodeLines')) {
+ $generator->setCountCodeLines(
+ $this->container->get('console.count_code_lines')
+ );
+ }
+
+ if (method_exists($generator, 'setDrupalFinder')) {
+ $generator->setDrupalFinder(
+ $this->container->get('console.drupal_finder')
+ );
+ }
+ }
}
/**
try {
$file = $chainCommand['file'];
$description = $chainCommand['description'];
- $command = new ChainCustomCommand($name, $description, $file);
+ $command = new ChainCustomCommand(
+ $name,
+ $description,
+ $file,
+ $chainDiscovery
+ );
$this->add($command);
} catch (\Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
}
+ /**
+ * registerExtendCommands
+ */
+ private function registerExtendCommands()
+ {
+ $this->container->get('console.configuration_manager')
+ ->loadExtendConfiguration();
+ }
+
+ public function getData()
+ {
+ $singleCommands = [
+ 'about',
+ 'chain',
+ 'check',
+ 'composerize',
+ 'exec',
+ 'help',
+ 'init',
+ 'list',
+ 'shell',
+ 'server'
+ ];
+
+ $languages = $this->container->get('console.configuration_manager')
+ ->getConfiguration()
+ ->get('application.languages');
+
+ $data = [];
+ foreach ($singleCommands as $singleCommand) {
+ $data['commands']['misc'][] = $this->commandData($singleCommand);
+ }
+
+ $namespaces = array_filter(
+ $this->getNamespaces(), function ($item) {
+ return (strpos($item, ':')<=0);
+ }
+ );
+ sort($namespaces);
+ array_unshift($namespaces, 'misc');
+
+ foreach ($namespaces as $namespace) {
+ $commands = $this->all($namespace);
+ usort(
+ $commands, function ($cmd1, $cmd2) {
+ return strcmp($cmd1->getName(), $cmd2->getName());
+ }
+ );
+
+ foreach ($commands as $command) {
+ if (method_exists($command, 'getModule')) {
+ if ($command->getModule() == 'Console') {
+ $data['commands'][$namespace][] = $this->commandData(
+ $command->getName()
+ );
+ }
+ } else {
+ $data['commands'][$namespace][] = $this->commandData(
+ $command->getName()
+ );
+ }
+ }
+ }
+
+ $input = $this->getDefinition();
+ $options = [];
+ foreach ($input->getOptions() as $option) {
+ $options[] = [
+ 'name' => $option->getName(),
+ 'description' => $this->trans('application.options.'.$option->getName())
+ ];
+ }
+ $arguments = [];
+ foreach ($input->getArguments() as $argument) {
+ $arguments[] = [
+ 'name' => $argument->getName(),
+ 'description' => $this->trans('application.arguments.'.$argument->getName())
+ ];
+ }
+
+ $data['application'] = [
+ 'namespaces' => $namespaces,
+ 'options' => $options,
+ 'arguments' => $arguments,
+ 'languages' => $languages,
+ 'messages' => [
+ 'title' => $this->trans('application.gitbook.messages.title'),
+ 'note' => $this->trans('application.gitbook.messages.note'),
+ 'note_description' => $this->trans('application.gitbook.messages.note-description'),
+ 'command' => $this->trans('application.gitbook.messages.command'),
+ 'options' => $this->trans('application.gitbook.messages.options'),
+ 'option' => $this->trans('application.gitbook.messages.option'),
+ 'details' => $this->trans('application.gitbook.messages.details'),
+ 'arguments' => $this->trans('application.gitbook.messages.arguments'),
+ 'argument' => $this->trans('application.gitbook.messages.argument'),
+ 'examples' => $this->trans('application.gitbook.messages.examples')
+ ],
+ 'examples' => []
+ ];
+
+ return $data;
+ }
+
+ private function commandData($commandName)
+ {
+ if (!$this->has($commandName)) {
+ return [];
+ }
+
+ $command = $this->find($commandName);
+
+ $input = $command->getDefinition();
+ $options = [];
+ foreach ($input->getOptions() as $option) {
+ $options[$option->getName()] = [
+ 'name' => $option->getName(),
+ 'description' => $this->trans($option->getDescription()),
+ ];
+ }
+
+ $arguments = [];
+ foreach ($input->getArguments() as $argument) {
+ $arguments[$argument->getName()] = [
+ 'name' => $argument->getName(),
+ 'description' => $this->trans($argument->getDescription()),
+ ];
+ }
+
+ $commandKey = str_replace(':', '.', $command->getName());
+
+ $examples = [];
+ for ($i = 0; $i < 5; $i++) {
+ $description = sprintf(
+ 'commands.%s.examples.%s.description',
+ $commandKey,
+ $i
+ );
+ $execution = sprintf(
+ 'commands.%s.examples.%s.execution',
+ $commandKey,
+ $i
+ );
+
+ if ($description != $this->trans($description)) {
+ $examples[] = [
+ 'description' => $this->trans($description),
+ 'execution' => $this->trans($execution)
+ ];
+ } else {
+ break;
+ }
+ }
+
+ $data = [
+ 'name' => $command->getName(),
+ 'description' => $command->getDescription(),
+ 'options' => $options,
+ 'arguments' => $arguments,
+ 'examples' => $examples,
+ 'aliases' => $command->getAliases(),
+ 'key' => $commandKey,
+ 'dashed' => str_replace(':', '-', $command->getName()),
+ 'messages' => [
+ 'usage' => $this->trans('application.gitbook.messages.usage'),
+ 'options' => $this->trans('application.gitbook.messages.options'),
+ 'option' => $this->trans('application.gitbook.messages.option'),
+ 'details' => $this->trans('application.gitbook.messages.details'),
+ 'arguments' => $this->trans('application.gitbook.messages.arguments'),
+ 'argument' => $this->trans('application.gitbook.messages.argument'),
+ 'examples' => $this->trans('application.gitbook.messages.examples')
+ ],
+ ];
+
+ return $data;
+ }
+
+ /**
+ * @return DrupalInterface
+ */
+ public function getDrupal()
+ {
+ return $this->drupal;
+ }
+
+ /**
+ * @param DrupalInterface $drupal
+ */
+ public function setDrupal($drupal)
+ {
+ $this->drupal = $drupal;
+ }
+
+ public function setContainer($container)
+ {
+ $this->container = $container;
+ }
+
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ /**
+ * Add Drupal system messages.
+ */
+ protected function addDrupalMessages($messageManager) {
+ if (function_exists('drupal_get_messages')) {
+ $drupalMessages = drupal_get_messages();
+ foreach ($drupalMessages as $type => $messages) {
+ foreach ($messages as $message) {
+ $method = $this->getMessageMethod($type);
+ $messageManager->{$method}((string)$message);
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets method name for MessageManager.
+ *
+ * @param string $type
+ * Type of the message.
+ *
+ * @return string
+ * Name of the method
+ */
+ protected function getMessageMethod($type) {
+ $methodName = 'info';
+ switch ($type) {
+ case 'error':
+ case 'warning':
+ $methodName = $type;
+ break;
+ }
+
+ return $methodName;
+ }
+
/**
* Finds a command by name or alias.
*