default services conflit ?

This commit is contained in:
armansansd
2022-04-27 11:30:43 +02:00
parent 28190a5749
commit 8bb1064a3b
8132 changed files with 900138 additions and 426 deletions

View File

@@ -0,0 +1,14 @@
# deprecation-detector
/.rules
# Composer
composer.lock
/vendor
# Test
/phpunit.xml
# Project
extend.config.yml
extend.services.yml

View File

@@ -0,0 +1,8 @@
# Drupal Console Extend Plugin
Composer plugin to discover Drupal Console commands using a standard package/library.
### Install this project:
```
composer require drupal/console-extend-plugin
```

View File

@@ -0,0 +1,26 @@
{
"name": "drupal/console-extend-plugin",
"description": "Drupal Console Extend Plugin",
"license": "GPL-2.0+",
"authors": [
{
"name": "Jesus Manuel Olivas",
"email": "jesus.olivas@gmail.com"
}
],
"type": "composer-plugin",
"extra": {
"class": "Drupal\\Console\\Composer\\Plugin\\Extender"
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0",
"composer/installers": "^1.2",
"symfony/yaml": "~3.0|^4.4",
"symfony/finder": "~3.0|^4.4"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {"Drupal\\Console\\Composer\\Plugin\\": "src"}
}
}

View File

@@ -0,0 +1,69 @@
application:
method:
git:
enabled: true
exception: false
composer:
enabled: true
exception: false
analyzer:
parallel-lint:
enabled: true
exception: true
options:
e: 'php'
exclude: /vendor
arguments:
php-cs-fixer:
enabled: true
exception: false
options:
level: psr2
arguments:
prefixes:
- fix
postfixes:
phpcbf:
enabled: true
exception: false
options:
standard: PSR2
severity: 0
ignore: /vendor
arguments:
- '-n'
phpcs:
enabled: false
exception: false
options:
standard: PSR2
severity: 0
ignore: /vendor
arguments:
- '-n'
phpmd:
enabled: false
exception: false
options:
arguments:
prefixes:
postfixes:
- 'text'
- 'cleancode,codesize,unusedcode,naming,controversial,design'
phploc:
enabled: false
exception: false
phpcpd:
enabled: false
exception: false
phpdcd:
enabled: false
exception: false
phpunit:
enabled: true
exception: true
file:
configuration: phpunit.xml.dist
single-execution: true
options:
arguments:

View File

@@ -0,0 +1,19 @@
<?php
namespace Drupal\Console\Composer\Plugin;
use Composer\Installers\BaseInstaller;
/**
* Class DemoInstaller
*
* @package Composer\Installers
*/
class DrupalConsoleInstaller extends BaseInstaller
{
/**
* @var array
*/
protected $locations = array(
'console-library' => 'vendor/drupal/{$name}/',
);
}

View File

@@ -0,0 +1,179 @@
<?php
namespace Drupal\Console\Composer\Plugin;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Script\Event;
use Composer\Script\ScriptEvents;
use Composer\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Finder\Finder;
// Explicitly require ExtenderManager here.
// When this package is uninstalled, ExtenderManager needs to be available any
// time this class is available.
require_once __DIR__ . '/ExtenderManager.php';
class Extender implements PluginInterface, EventSubscriberInterface
{
/**
* @var Composer $composer
*/
protected $composer;
/**
* @var IOInterface $io
*/
protected $io;
/**
* Apply plugin modifications to composer
*
* @param Composer $composer
* @param IOInterface $io
*/
public function activate(Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->io = $io;
$installer = new Installer($io, $composer);
$composer->getInstallationManager()->addInstaller($installer);
}
/**
* Returns an array of event names this subscriber wants to listen to.
*/
public static function getSubscribedEvents()
{
return [
ScriptEvents::POST_INSTALL_CMD => "processPackages",
ScriptEvents::POST_UPDATE_CMD => "processPackages",
];
}
/**
* @param Event $event
* @throws \Exception
*/
public function processPackages(Event $event)
{
$extenderManager = new ExtenderManager();
$composer = $event->getComposer();
$installationManager = $composer->getInstallationManager();
$repositoryManager = $composer->getRepositoryManager();
$localRepository = $repositoryManager->getLocalRepository();
foreach ($localRepository->getPackages() as $package) {
if ($installationManager->isPackageInstalled($localRepository, $package)) {
if ($package->getType() === 'drupal-console-library') {
$extenderManager->addServicesFile($installationManager->getInstallPath($package) . '/console.services.yml');
$extenderManager->addConfigFile($installationManager->getInstallPath($package) . '/console.config.yml');
}
}
}
if ($consolePackage = $localRepository->findPackage('drupal/console', '*')) {
if ($localRepository->hasPackage($consolePackage)) {
$directory = $installationManager->getInstallPath($consolePackage);
}
}
if (empty($directory)) {
// cwd should be the project root. This is the same logic Symfony uses.
$directory = getcwd();
}
$configFile = $directory . '/extend.console.config.yml';
$servicesFile = $directory . '/extend.console.services.yml';
$servicesUninstallFile = $directory . '/extend.console.uninstall.services.yml';
if (file_exists($configFile)) {
unlink($configFile);
$this->io->write('<info>Removing config cache file:</info>');
$this->io->write($configFile);
}
if (file_exists($servicesFile)) {
unlink($servicesFile);
$this->io->write('<info>Removing packages services cache file:</info>');
$this->io->write($servicesFile);
}
if (file_exists($servicesUninstallFile)) {
unlink($servicesUninstallFile);
$this->io->write('<info>Removing packages services cache file:</info>');
$this->io->write($servicesUninstallFile);
}
if ($configData = $extenderManager->getConfigData()) {
file_put_contents(
$configFile,
Yaml::dump($configData, 6, 2)
);
$this->io->write('<info>Creating packages config cache file:</info>');
$this->io->write($configFile);
}
$servicesData = $extenderManager->getServicesData();
if ($servicesData && array_key_exists('install', $servicesData)) {
file_put_contents(
$servicesFile,
Yaml::dump($servicesData['install'], 4, 2)
);
$this->io->write('<info>Creating packages services cache file: </info>');
$this->io->write($servicesFile);
}
$servicesData = $extenderManager->getServicesData();
if ($servicesData && array_key_exists('uninstall', $servicesData)) {
file_put_contents(
$servicesUninstallFile,
Yaml::dump($servicesData['uninstall'], 4, 2)
);
$this->io->write('<info>Creating packages services cache file: </info>');
$this->io->write($servicesUninstallFile);
}
$this->removeCacheFiles($directory);
}
protected function removeCacheFiles($directory)
{
try {
$finder = new Finder();
$finder->files()
->in($directory)
->name('*-console.services.yml')
->ignoreUnreadableDirs();
foreach ($finder as $file) {
$this->io->write('<info>Removing site services cache file:</info>');
$this->io->write($file->getPathName());
unlink($file->getPathName());
}
} catch (\InvalidArgumentException $argumentException) {
$this->io->write('<info>Cache file can not be deleted</info>');
}
}
/**
* {@inheritdoc}
*/
public function deactivate(Composer $composer, IOInterface $io)
{
// Nothing to deactivate.
}
/**
* {@inheritdoc}
*/
public function uninstall(Composer $composer, IOInterface $io)
{
// Nothing to uninstall.
}
}

View File

@@ -0,0 +1,218 @@
<?php
namespace Drupal\Console\Composer\Plugin;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Finder\Finder;
class ExtenderManager
{
/**
* @var array
*/
protected $configData = [];
/**
* @var array
*/
protected $servicesData = [];
/**
* ExtendExtensionManager constructor.
*/
public function __construct()
{
$this->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->configData = array_merge_recursive(
$configData,
$this->configData
);
}
}
/**
* @param string $servicesFile
*/
public function addServicesFile($servicesFile)
{
$consoleTags = [
'drupal.command',
'drupal.generator'
];
$servicesData = $this->parseData($servicesFile);
if ($this->isValidServicesData($servicesData)) {
foreach ($servicesData['services'] as $key => $definition) {
if (!array_key_exists('tags', $definition)) {
continue;
}
$bootstrap = 'install';
foreach ($definition['tags'] as $tags) {
if (!array_key_exists('name', $tags)) {
$bootstrap = null;
continue;
}
if (array_search($tags['name'], $consoleTags) === false) {
$bootstrap = null;
continue;
}
if (array_key_exists('bootstrap', $tags)) {
$bootstrap = $tags['bootstrap'];
}
}
if ($bootstrap) {
$this->servicesData[$bootstrap]['services'][$key] = $definition;
}
}
}
}
/**
* init
*/
private function init()
{
$this->configData = [];
$this->servicesData = [];
}
/**
* @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)
->ignoreUnreadableDirs();
foreach ($finder as $file) {
$this->processComposerFile($file->getPathName());
}
}
/**
* @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;
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Drupal\Console\Composer\Plugin;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\Installers\Installer as BaseInstaller;
class Installer extends BaseInstaller
{
/**
* Package types to installer class map
*
* @var array
*/
private $supportedTypes = array(
'drupal' => 'DrupalConsoleInstaller'
);
/**
* {@inheritDoc}
*/
public function getInstallPath(PackageInterface $package)
{
$type = $package->getType();
$frameworkType = $this->findFrameworkType($type);
if ($frameworkType === false) {
throw new \InvalidArgumentException(
'Sorry the package type of this package is not yet supported.'
);
}
$class = 'Drupal\\Console\\Composer\\Plugin\\' . $this->supportedTypes[$frameworkType];
$installer = new $class($package, $this->composer, $this->getIO());
return $installer->getInstallPath($package, $frameworkType);
}
/**
* Get the second part of the regular expression to check for support of a
* package type
*
* @param string $frameworkType
* @return string
*/
protected function getLocationPattern($frameworkType)
{
$pattern = false;
if (!empty($this->supportedTypes[$frameworkType])) {
$frameworkClass = 'Drupal\\Console\\Composer\\Plugin\\' . $this->supportedTypes[$frameworkType];
/** @var BaseInstaller $framework */
$framework = new $frameworkClass(null, $this->composer, $this->getIO());
$locations = array_keys($framework->getLocations());
$pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
}
return $pattern ? : '(\w+)';
}
/**
* Get I/O object
*
* @return IOInterface
*/
private function getIO()
{
return $this->io;
}
}