From 2ed05069536bbef744ea769129367e9e29c3604c Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Sun, 5 Feb 2017 10:32:57 -0800 Subject: [PATCH] Update compile services file. (#3157) --- bin/drupal.php | 2 + services.yml | 2 + src/Bootstrap/AddServicesCompilerPass.php | 56 +++-- src/Bootstrap/Drupal.php | 22 ++ src/Utils/ExtendExtensionManager.php | 241 ++++++++++++++++++++++ src/Utils/Site.php | 42 ++++ 6 files changed, 353 insertions(+), 12 deletions(-) create mode 100644 src/Utils/ExtendExtensionManager.php diff --git a/bin/drupal.php b/bin/drupal.php index d73c44267..35c172344 100644 --- a/bin/drupal.php +++ b/bin/drupal.php @@ -8,6 +8,8 @@ set_time_limit(0); +$autoloaders = []; + if (file_exists(__DIR__ . '/../autoload.local.php')) { include_once __DIR__ . '/../autoload.local.php'; } else { diff --git a/services.yml b/services.yml index 32e03500b..4d50f0ebc 100644 --- a/services.yml +++ b/services.yml @@ -29,3 +29,5 @@ services: console.annotation_validator: class: Drupal\Console\Utils\AnnotationValidator arguments: ['@console.annotation_command_reader', '@console.extension_manager'] + console.extend_extension_manager: + class: Drupal\Console\Utils\ExtendExtensionManager diff --git a/src/Bootstrap/AddServicesCompilerPass.php b/src/Bootstrap/AddServicesCompilerPass.php index 580d9ba9d..19f7c8b14 100644 --- a/src/Bootstrap/AddServicesCompilerPass.php +++ b/src/Bootstrap/AddServicesCompilerPass.php @@ -2,15 +2,16 @@ namespace Drupal\Console\Bootstrap; -use Drupal\Console\Extension\Extension; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; use Symfony\Component\Finder\Finder; use Symfony\Component\Yaml\Yaml; -use Drupal\Console\Extension\Manager; +use Drupal\Console\Utils\ExtendExtensionManager; use Drupal\Console\Utils\TranslatorManager; +use Drupal\Console\Extension\Extension; +use Drupal\Console\Extension\Manager; /** * FindCommandsCompilerPass @@ -56,13 +57,21 @@ public function process(ContainerBuilder $container) new FileLocator($this->root) ); - $loader->load($this->root. DRUPAL_CONSOLE_CORE . 'services.yml'); - $loader->load($this->root. DRUPAL_CONSOLE . 'services-drupal-install.yml'); - $loader->load($this->root. DRUPAL_CONSOLE . 'services.yml'); + $loader->load($this->root. DRUPAL_CONSOLE_CORE . 'services.yml'); + $loader->load($this->root. DRUPAL_CONSOLE . 'services-drupal-install.yml'); + $loader->load($this->root. DRUPAL_CONSOLE . 'services.yml'); - $consoleServicesFile = $this->root.DRUPAL_CONSOLE.'services-console.yml'; + $basePath = $container->get('console.site')->getCacheDirectory(); + $consoleServicesFile = $basePath.'/console.services.yml'; + $consoleExtendServicesFile = $basePath.'/extend.console.services.yml'; + $consoleExtendConfigFile = $basePath.'/extend.console.config.yml'; - if ($this->rebuild || !file_exists($consoleServicesFile)) { + if ($basePath && !$this->rebuild && file_exists($consoleServicesFile)) { + $loader->load($consoleServicesFile); + if (file_exists($consoleExtendServicesFile)) { + $loader->load($consoleExtendServicesFile); + } + } else { $finder = new Finder(); $finder->files() ->name('*.yml') @@ -139,14 +148,37 @@ public function process(ContainerBuilder $container) } } - if ($servicesData) { + if ($servicesData && is_writable($basePath)) { file_put_contents( $consoleServicesFile, Yaml::dump($servicesData, 4, 2) ); } - } else { - $loader->load($consoleServicesFile); + + /** + * @var ExtendExtensionManager $extendExtensionManager + */ + $extendExtensionManager = $container->get('console.extend_extension_manager'); + $extendExtensionManager->processProjectPackages($this->root); + $configData = $extendExtensionManager->getConfigData(); + if ($configData && is_writable($basePath)) { + file_put_contents( + $consoleExtendConfigFile, + Yaml::dump($configData, 6, 2) + ); + } + $servicesData = $extendExtensionManager->getServicesData(); + if ($servicesData && is_writable($basePath)) { + file_put_contents( + $consoleExtendServicesFile, + Yaml::dump($servicesData, 4, 2) + ); + } + + $servicesFiles = $extendExtensionManager->getServicesFiles(); + foreach ($servicesFiles as $servicesFile) { + $loader->load($servicesFile); + } } $configurationManager = $container->get('console.configuration_manager'); diff --git a/src/Bootstrap/Drupal.php b/src/Bootstrap/Drupal.php index edbccfe2b..9501e5f39 100644 --- a/src/Bootstrap/Drupal.php +++ b/src/Bootstrap/Drupal.php @@ -9,6 +9,7 @@ use Drupal\Console\Core\Style\DrupalStyle; use Drupal\Console\Core\Utils\ArgvInputReader; use Drupal\Console\Core\Bootstrap\DrupalConsoleCore; +use Drupal\Console\Utils\ExtendExtensionManager; class Drupal { @@ -129,6 +130,27 @@ public function boot($debug) $this->root ); + $basePath = $container->get('console.site')->getCacheDirectory(); + $consoleExtendConfigFile = $basePath.'/extend.console.config.yml'; + + if ($basePath && file_exists($consoleExtendConfigFile)) { + $container->get('console.configuration_manager') + ->importConfigurationFile($consoleExtendConfigFile); + } else { + /** + * @var ExtendExtensionManager $extendExtensionManager + */ + $extendExtensionManager = $container->get('console.extend_extension_manager'); + if (!$extendExtensionManager->isProcessed()) { + $extendExtensionManager->processProjectPackages($this->root); + } + $configFiles = $extendExtensionManager->getConfigFiles(); + foreach ($configFiles as $configFile) { + $container->get('console.configuration_manager') + ->importConfigurationFile($configFile); + } + } + $container->get('console.renderer') ->setSkeletonDirs( [ diff --git a/src/Utils/ExtendExtensionManager.php b/src/Utils/ExtendExtensionManager.php new file mode 100644 index 000000000..d3f1ee373 --- /dev/null +++ b/src/Utils/ExtendExtensionManager.php @@ -0,0 +1,241 @@ +init(); + } + + /** + * @param string $composerFile + * + * @return bool + */ + public function isValidPackageType($composerFile) + { + if (!is_file($composerFile)) { + return false; + } + + $composerContent = json_decode(file_get_contents($composerFile), true); + if (!$composerContent) { + return false; + } + + if (!array_key_exists('type', $composerContent)) { + return false; + } + + return $composerContent['type'] === 'drupal-console-library'; + } + + /** + * @param string $configFile + */ + public function addConfigFile($configFile) + { + $configData = $this->parseData($configFile); + if ($this->isValidConfigData($configData)) { + $this->configFiles[] = $configFile; + $this->configData = array_merge_recursive( + $configData, + $this->configData + ); + } + } + + /** + * @param string $servicesFile + */ + public function addServicesFile($servicesFile) + { + $servicesData = $this->parseData($servicesFile); + if ($this->isValidServicesData($servicesData)) { + $this->servicesFiles[] = $servicesFile; + $this->servicesData = array_merge_recursive( + $servicesData, + $this->servicesData + ); + } + } + + /** + * init + */ + private function init() + { + $this->configData = []; + $this->servicesData = []; + $this->configFiles = []; + $this->servicesFiles = []; + $this->processed = false; + } + + /** + * @param $file + * @return array|mixed + */ + private function parseData($file) + { + if (!file_exists($file)) { + return []; + } + + $data = Yaml::parse( + file_get_contents($file) + ); + + if (!$data) { + return []; + } + + return $data; + } + + public function processProjectPackages($directory) + { + $finder = new Finder(); + $finder->files() + ->name('composer.json') + ->contains('drupal-console-library') + ->in($directory); + + foreach ($finder as $file) { + $this->processComposerFile($file->getPathName()); + } + + $this->processed = true; + } + + /** + * @param $composerFile + */ + private function processComposerFile($composerFile) + { + $packageDirectory = dirname($composerFile); + + $configFile = $packageDirectory.'/console.config.yml'; + $this->addConfigFile($configFile); + + $servicesFile = $packageDirectory.'/console.services.yml'; + $this->addServicesFile($servicesFile); + } + + /** + * @param array $configData + * + * @return boolean + */ + private function isValidConfigData($configData) + { + if (!$configData) { + return false; + } + + if (!array_key_exists('application', $configData)) { + return false; + } + + if (!array_key_exists('autowire', $configData['application'])) { + return false; + } + + if (!array_key_exists('commands', $configData['application']['autowire'])) { + return false; + } + + return true; + } + + /** + * @param array $servicesData + * + * @return boolean + */ + private function isValidServicesData($servicesData) + { + if (!$servicesData) { + return false; + } + + if (!array_key_exists('services', $servicesData)) { + return false; + } + + return true; + } + + /** + * @return array + */ + public function getConfigData() + { + return $this->configData; + } + + /** + * @return array + */ + public function getServicesData() + { + return $this->servicesData; + } + + /** + * @return array + */ + public function getConfigFiles() + { + return $this->configFiles; + } + + /** + * @return array + */ + public function getServicesFiles() + { + return $this->servicesFiles; + } + + /** + * @return bool + */ + public function isProcessed() + { + return $this->processed; + } +} diff --git a/src/Utils/Site.php b/src/Utils/Site.php index 58285bfc1..dee4d3b91 100644 --- a/src/Utils/Site.php +++ b/src/Utils/Site.php @@ -3,6 +3,7 @@ namespace Drupal\Console\Utils; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Logger\LoggerChannelFactory; @@ -183,4 +184,45 @@ public function validMultisite($uri) return false; } + + public function getCacheDirectory() + { + $configFactory = \Drupal::configFactory(); + $basePath = $configFactory->get('system.file') + ->get('path.temporary'); + $siteId = $configFactory->get('system.site') + ->get('uuid'); + $basePath = $this->validateDirectory( + $basePath . '/console/cache/' . $siteId . '/' + ); + + if (!$basePath) { + if (function_exists('posix_getuid')) { + $homeDir = posix_getpwuid(posix_getuid())['dir']; + } else { + $homeDir = realpath(rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\')); + } + + $basePath = sprintf('%s/.console/cache/%s/', $homeDir, $siteId); + + $basePath = $this->validateDirectory($basePath); + } + + return $basePath; + } + + private function validateDirectory($path) + { + $fileSystem = new Filesystem(); + if ($fileSystem->exists($path)) { + return $path; + } + try { + $fileSystem->mkdir($path); + + return $path; + } catch (\Exception $e) { + return null; + } + } }