diff --git a/services.yml b/services.yml index 3a3918f..08c060a 100644 --- a/services.yml +++ b/services.yml @@ -31,6 +31,8 @@ services: class: Drupal\Console\Core\Utils\CountCodeLines console.message_manager: class: Drupal\Console\Core\Utils\MessageManager + console.drupal_finder: + class: Drupal\Console\Core\Utils\DrupalFinder # DrupalConsoleCore Commands console.about: class: Drupal\Console\Core\Command\AboutCommand @@ -88,13 +90,22 @@ services: arguments: ['@console.configuration_manager'] tags: - { name: drupal.command } + console.drush: + class: Drupal\Console\Core\Command\DrushCommand + arguments: ['@console.configuration_manager', '@console.chain_queue'] + tags: + - { name: drupal.command } + console.generate_site_alias: + class: Drupal\Console\Core\Command\Generate\SiteAliasCommand + arguments: ['@console.site_alias_generator', '@console.configuration_manager', '@console.drupal_finder'] + tags: + - { name: drupal.command } # DrupalConsoleCore Generators console.init_generator: class: Drupal\Console\Core\Generator\InitGenerator tags: - { name: drupal.generator } - console.drush: - class: Drupal\Console\Core\Command\DrushCommand - arguments: ['@console.configuration_manager', '@console.chain_queue'] + console.site_alias_generator: + class: Drupal\Console\Core\Generator\SiteAliasGenerator tags: - - { name: drupal.command } + - { name: drupal.generator } diff --git a/src/Application.php b/src/Application.php index c11936b..27882cb 100644 --- a/src/Application.php +++ b/src/Application.php @@ -175,8 +175,8 @@ public function doRun(InputInterface $input, OutputInterface $output) if (in_array($this->commandName, $namespaces)) { $input = new ArrayInput( [ - 'command' => 'list', - 'namespace' => $this->commandName + 'command' => 'list', + 'namespace' => $this->commandName ] ); $this->commandName = 'list'; @@ -480,6 +480,12 @@ private function registerGenerators() $this->container->get('console.count_code_lines') ); } + + if (method_exists($generator, 'setDrupalFinder')) { + $generator->setDrupalFinder( + $this->container->get('console.drupal_finder') + ); + } } } diff --git a/src/Command/Chain/ChainCommand.php b/src/Command/Chain/ChainCommand.php index 8f1e162..68e767b 100644 --- a/src/Command/Chain/ChainCommand.php +++ b/src/Command/Chain/ChainCommand.php @@ -212,11 +212,11 @@ protected function execute(InputInterface $input, OutputInterface $output) } $parser = new Parser(); - $configData = $parser->parse($chainContent); + $chainData = $parser->parse($chainContent); $commands = []; - if (array_key_exists('commands', $configData)) { - $commands = $configData['commands']; + if (array_key_exists('commands', $chainData)) { + $commands = $chainData['commands']; } $chainInlineOptions = $input->getOptions(); diff --git a/src/Command/Debug/SiteCommand.php b/src/Command/Debug/SiteCommand.php index 4241dd9..4aa8cc1 100644 --- a/src/Command/Debug/SiteCommand.php +++ b/src/Command/Debug/SiteCommand.php @@ -70,7 +70,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); - $sites = array_keys($this->configurationManager->getSites()); + $sites = $this->configurationManager->getSites(); if (!$sites) { $io->error($this->trans('commands.debug.site.messages.invalid-sites')); @@ -78,15 +78,22 @@ protected function execute(InputInterface $input, OutputInterface $output) return 1; } - - // --target argument $target = $input->getArgument('target'); if (!$target) { - $tableHeader =[ - $this->trans('commands.debug.site.messages.site'), - ]; - - $io->table($tableHeader, $sites); + foreach ($sites as $key => $site) { + $environments = array_keys($site); + unset($environments[0]); + + $environments = array_map( + function ($element) use ($key) { + return $key . '.' . $element; + }, + $environments + ); + + $io->info($key); + $io->listing($environments); + } return 0; } @@ -114,7 +121,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $io->info($target); $dumper = new Dumper(); - $io->writeln($dumper->dump($targetConfig, 2)); + $io->writeln($dumper->dump($targetConfig, 4, 2)); return 0; } diff --git a/src/Command/Generate/SiteAliasCommand.php b/src/Command/Generate/SiteAliasCommand.php new file mode 100644 index 0000000..3e0a508 --- /dev/null +++ b/src/Command/Generate/SiteAliasCommand.php @@ -0,0 +1,298 @@ + [ + 'none' => '', + 'vagrant' => '-o PasswordAuthentication=no -i ~/.vagrant.d/insecure_private_key', + ], + 'container' => [ + 'none' => '', + 'drupal4docker' => 'docker-compose exec --user=82 php' + ] + ]; + + public function __construct( + SiteAliasGenerator $generator, + ConfigurationManager $configurationManager, + DrupalFinder $drupalFinder + ) { + $this->generator = $generator; + $this->configurationManager = $configurationManager; + $this->drupalFinder = $drupalFinder; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('generate:site:alias') + ->setDescription( + $this->trans('commands.generate.site.alias.description') + ) + ->setHelp($this->trans('commands.generate.site.alias.help')) + ->addOption( + 'name', + null, + InputOption::VALUE_REQUIRED, + $this->trans('commands.generate.site.alias.options.name') + ) + ->addOption( + 'environment', + null, + InputOption::VALUE_REQUIRED, + $this->trans('commands.generate.site.alias.options.environment') + ) + ->addOption( + 'type', + null, + InputOption::VALUE_REQUIRED, + $this->trans('commands.generate.site.alias.options.type') + ) + ->addOption( + 'composer-root', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.site.alias.options.composer-root') + ) + ->addOption( + 'site-uri', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.site.alias.options.site-uri') + ) + ->addOption( + 'host', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.site.alias.options.host') + ) + ->addOption( + 'user', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.site.alias.options.user') + ) + ->addOption( + 'port', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.site.alias.options.port') + ) + ->addOption( + 'extra-options', + null, + InputOption::VALUE_OPTIONAL, + $this->trans('commands.generate.site.alias.options.extra-options') + ) + ->addOption( + 'directory', + null, + InputOption::VALUE_REQUIRED, + $this->trans('commands.generate.site.alias.options.directory') + ) + ->setAliases(['gsa']); + } + + /** + * {@inheritdoc} + */ + protected function interact( + InputInterface $input, + OutputInterface $output + ) { + $name = $input->getOption('name'); + if (!$name) { + $sites = array_keys($this->configurationManager->getSites()); + + $name = $this->getIo()->choiceNoList( + $this->trans('commands.generate.site.alias.questions.name'), + $sites, + current($sites), + true + ); + + if (is_numeric($name)) { + $name = $sites[$name]; + } + + $input->setOption('name', $name); + } + + $environment = $input->getOption('environment'); + if (!$environment) { + $environment = $this->getIo()->ask( + $this->trans('commands.generate.site.alias.questions.environment'), + null + ); + + $input->setOption('environment', $environment); + } + + $type = $input->getOption('type'); + if (!$type) { + $type = $this->getIo()->choiceNoList( + $this->trans('commands.generate.site.alias.questions.type'), + $this->types + ); + + $input->setOption('type', $type); + } + + $composerRoot = $input->getOption('composer-root'); + if (!$composerRoot) { + $root = $this->drupalFinder->getComposerRoot(); + if ($type === 'container') { + $root = '/var/www/html'; + } + if ($type === 'ssh') { + $root = '/var/www/'.$name; + } + $composerRoot = $this->getIo()->ask( + $this->trans('commands.generate.site.alias.questions.composer-root'), + $root + ); + + $input->setOption('composer-root', $composerRoot); + } + + $siteUri = $input->getOption('site-uri'); + if (!$siteUri) { + $uri = explode('.', $environment); + if (count($uri)>1) { + $uri = $uri[1]; + } else { + $uri = 'default'; + } + $siteUri = $this->getIo()->askEmpty( + $this->trans('commands.generate.site.alias.questions.site-uri'), + $uri + ); + + $input->setOption('site-uri', $siteUri); + } + + if ($type !== 'local') { + $extraOptions = $input->getOption('extra-options'); + if (!$extraOptions) { + $options = array_values($this->extraOptions[$type]); + + $extraOptions = $this->getIo()->choiceNoList( + $this->trans( + 'commands.generate.site.alias.questions.extra-options' + ), + $options, + current($options) + ); + + $input->setOption('extra-options', $extraOptions); + } + + $host = $input->getOption('host'); + if (!$host) { + $host = $this->getIo()->askEmpty( + $this->trans('commands.generate.site.alias.questions.host') + ); + + $input->setOption('host', $host); + } + + $user = $input->getOption('user'); + if (!$user) { + $user = $this->getIo()->askEmpty( + $this->trans('commands.generate.site.alias.questions.user') + ); + + $input->setOption('user', $user); + } + + $port = $input->getOption('port'); + if (!$port) { + $port = $this->getIo()->askEmpty( + $this->trans('commands.generate.site.alias.questions.port') + ); + + $input->setOption('port', $port); + } + } + + $directory = $input->getOption('directory'); + if (!$directory) { + $directory = $this->getIo()->choice( + $this->trans('commands.generate.site.alias.questions.directory'), + $this->configurationManager->getConfigurationDirectories() + ); + + $input->setOption('directory', $directory); + } + } + + /** + * {@inheritdoc} + */ + protected function execute( + InputInterface $input, + OutputInterface $output + ) { + $this->generator->generate( + [ + 'name' => $input->getOption('name'), + 'environment' => $input->getOption('environment'), + 'type' => $input->getOption('type'), + 'extra_options' => $input->getOption('extra-options'), + 'root' => $input->getOption('composer-root'), + 'uri' => $input->getOption('site-uri'), + 'port' => $input->getOption('port'), + 'user' => $input->getOption('user'), + 'host' => $input->getOption('host'), + 'directory' => $input->getOption('directory') + ] + ); + } +} diff --git a/src/Generator/Generator.php b/src/Generator/Generator.php index 8092f2d..de0826e 100644 --- a/src/Generator/Generator.php +++ b/src/Generator/Generator.php @@ -10,6 +10,7 @@ use Drupal\Console\Core\Utils\TwigRenderer; use Drupal\Console\Core\Utils\FileQueue; use Drupal\Console\Core\Utils\CountCodeLines; +use Drupal\Console\Core\Utils\DrupalFinder; /** * Class Generator @@ -33,6 +34,11 @@ abstract class Generator */ protected $countCodeLines; + /** + * @var DrupalFinder + */ + protected $drupalFinder; + /** * @param $renderer */ @@ -57,6 +63,14 @@ public function setCountCodeLines(CountCodeLines $countCodeLines) $this->countCodeLines = $countCodeLines; } + /** + * @param DrupalFinder $drupalFinder + */ + public function setDrupalFinder($drupalFinder) + { + $this->drupalFinder = $drupalFinder; + } + /** * @param string $template * @param string $target diff --git a/src/Generator/GeneratorInterface.php b/src/Generator/GeneratorInterface.php new file mode 100644 index 0000000..984a34e --- /dev/null +++ b/src/Generator/GeneratorInterface.php @@ -0,0 +1,22 @@ +renderFile( + 'sites/alias.yml.twig', + $parameters['directory'].'/sites/'.$parameters['name'].'.yml', + $parameters, + FILE_APPEND + ); + } +} diff --git a/src/Style/DrupalStyle.php b/src/Style/DrupalStyle.php index ce2cd8e..75c3d99 100644 --- a/src/Style/DrupalStyle.php +++ b/src/Style/DrupalStyle.php @@ -40,16 +40,16 @@ public function __construct(InputInterface $input, OutputInterface $output) * @param string $question * @param array $choices * @param mixed $default - * @param bool $allowEmpty + * @param bool $skipValidation * * @return string */ - public function choiceNoList($question, array $choices, $default = null, $allowEmpty = false) - { - if ($allowEmpty) { - $default = ' '; - } - + public function choiceNoList( + $question, + array $choices, + $default = null, + $skipValidation = false + ) { if (is_null($default)) { $default = current($choices); } @@ -63,7 +63,16 @@ public function choiceNoList($question, array $choices, $default = null, $allowE $default = $values[$default]; } - return trim($this->askChoiceQuestion(new ChoiceQuestion($question, $choices, $default))); + $choiceQuestion = new ChoiceQuestion($question, $choices, $default); + if ($skipValidation) { + $choiceQuestion->setValidator( + function ($answer) { + return $answer; + } + ); + } + + return trim($this->askChoiceQuestion($choiceQuestion)); } /** @@ -107,21 +116,26 @@ public function askChoiceQuestion(ChoiceQuestion $question) */ public function askHiddenEmpty($question) { - $question = new Question($question, ' '); + $question = new Question($question, ''); $question->setHidden(true); + $question->setValidator( + function ($answer) { + return $answer; + } + ); return trim($this->askQuestion($question)); } /** - * @param string $question - * @param null|callable $validator + * @param string $question + * @param string $default * * @return string */ - public function askEmpty($question, $validator = null) + public function askEmpty($question, $default = '') { - $question = new Question($question, ''); + $question = new Question($question, $default); $question->setValidator( function ($answer) { return $answer; diff --git a/src/Utils/ConfigurationManager.php b/src/Utils/ConfigurationManager.php index 329ee0a..723c768 100644 --- a/src/Utils/ConfigurationManager.php +++ b/src/Utils/ConfigurationManager.php @@ -94,7 +94,7 @@ public function getConfiguration() return $this->configuration; } - public function readSite($siteFile) + private function readSite($siteFile) { if (!file_exists($siteFile)) { return []; @@ -110,20 +110,30 @@ public function readSite($siteFile) */ public function readTarget($target) { - if (!array_key_exists($target, $this->sites)) { + $site = $target; + $environment = null; + $exploded = explode('.', $target, 2); + + if (count($exploded)>1) { + $site = $exploded[0]; + $environment = $exploded[1]; + } + + if (!array_key_exists($site, $this->sites)) { return []; } - $targetInformation = $this->sites[$target]; + $targetInformation = $this->sites[$site]; + + if ($environment) { + if (!array_key_exists($environment, $this->sites[$site])) { + return []; + } - if (array_key_exists('host', $targetInformation) && $targetInformation['host'] != 'local') { - $targetInformation['remote'] = true; + $targetInformation = $this->sites[$site][$environment]; } - return array_merge( - $this->configuration->get('application.remote'), - $targetInformation - ); + return $targetInformation; } /** @@ -398,9 +408,23 @@ public function getSites() continue; } + $this->sites[$siteName] = [ + 'file' => $site->getRealPath() + ]; + foreach ($environments as $environment => $config) { - $site = $siteName . '.' . $environment; - $this->sites[$site] = $config; + if ($config['type'] !== 'local') { + if (array_key_exists('host', $config)) { + $targetInformation['remote'] = true; + } + + $config = array_merge( + $this->configuration->get('application.remote')?:[], + $config + ); + } + + $this->sites[$siteName][$environment] = $config; } } diff --git a/templates/core/sites/alias.yml.twig b/templates/core/sites/alias.yml.twig new file mode 100644 index 0000000..b17302b --- /dev/null +++ b/templates/core/sites/alias.yml.twig @@ -0,0 +1,22 @@ +{{ environment }}: + type: {{ type }} + root: {{ root }} +{% if host %} + host: {{ host }} +{% endif %} +{% if port %} + port: {{ port }} +{% endif %} +{% if user %} + user: {{ user }} +{% endif %} +{% if uri %} + options: + uri: {{ uri }} +{% else %} +# options: +{% endif %} +# arguments: +{% if extra_options %} + extra-options: '{{ extra_options }}' +{% endif %}