3 namespace Drupal\Console\Command;
5 use Drupal\Console\Extension\Manager;
6 use Drupal\Console\Core\Utils\DrupalFinder;
7 use Symfony\Component\Console\Input\InputInterface;
8 use Symfony\Component\Console\Input\InputOption;
9 use Symfony\Component\Console\Output\OutputInterface;
10 use Drupal\Console\Core\Command\ContainerAwareCommand;
11 use Drupal\Component\Serialization\Json;
14 * Class ComposerizeCommand
16 * @package Drupal\Console\Command
18 class ComposerizeCommand extends ContainerAwareCommand
24 protected $corePackages = [];
29 protected $packages = [];
34 protected $dependencies = [];
39 protected $drupalFinder = null;
42 * @var Manager $extensionManager
44 protected $extensionManager = null;
49 protected function configure()
52 ->setName('composerize')
54 $this->trans('commands.composerize.description')
59 InputOption::VALUE_NONE,
60 $this->trans('commands.composerize.options.show-packages')
65 InputOption::VALUE_NONE,
66 $this->trans('commands.composerize.options.include-version')
68 ->setHelp($this->trans('commands.composerize.description'));
74 protected function execute(InputInterface $input, OutputInterface $output)
76 $includeVersion = $input->getOption('include-version');
77 $showPackages = $input->getOption('show-packages')?:false;
79 $this->drupalFinder = $this->get('console.drupal_finder');
81 $this->extensionManager = $this->get('console.extension_manager');
82 $this->extractCorePackages();
84 $this->processProfiles();
85 $this->processModules();
86 $this->processThemes();
94 $composerCommand = 'composer require ';
95 foreach ($types as $type) {
96 $packages = $this->packages[$type];
102 $this->getIo()->comment($this->trans('commands.composerize.messages.'.$type));
104 $this->trans('commands.composerize.messages.name'),
105 $this->trans('commands.composerize.messages.version'),
106 $this->trans('commands.composerize.messages.dependencies')
108 $this->getIo()->table($tableHeader, $packages);
110 foreach ($packages as $package) {
111 $module = str_replace('drupal/', '', $package['name']);
112 if (array_key_exists($module, $this->dependencies)) {
115 $composerCommand .= $package['name'];
116 if ($includeVersion) {
117 $composerCommand .= ':' . $package['version'];
119 $composerCommand .= ' ';
122 $this->getIo()->comment($this->trans('commands.composerize.messages.from'));
123 $this->getIo()->simple($this->drupalFinder->getComposerRoot());
124 $this->getIo()->newLine();
125 $this->getIo()->comment($this->trans('commands.composerize.messages.execute'));
126 $this->getIo()->simple($composerCommand);
127 $this->getIo()->newLine();
128 $this->getIo()->comment($this->trans('commands.composerize.messages.ignore'));
130 $webRoot = str_replace(
131 $this->drupalFinder->getComposerRoot() . '/',
133 $this->drupalFinder->getDrupalRoot() . '/'
136 $this->getIo()->writeln(
139 ' '.$webRoot.'modules/contrib',
140 ' '.$webRoot.'themes/contrib',
141 ' '.$webRoot.'profiles/contrib'
146 private function extractCorePackages()
148 $this->corePackages['module'] = $this->extensionManager->discoverModules()
154 $this->corePackages['theme'] = $this->extensionManager->discoverThemes()
160 $this->corePackages['profile'] = $this->extensionManager->discoverProfiles()
167 private function processProfiles()
170 $profiles = $this->extensionManager->discoverProfiles()
176 * @var \Drupal\Core\Extension\Extension[] $module
178 foreach ($profiles as $profile) {
179 if (!$this->isValidModule($profile)) {
183 $dependencies = $this->extractDependencies(
188 $this->packages[$type][] = [
189 'name' => sprintf('drupal/%s', $profile->getName()),
190 'version' => $this->calculateVersion($profile->info['version']),
191 'dependencies' => implode(PHP_EOL, array_values($dependencies))
194 $this->dependencies = array_merge(
196 $dependencies?$dependencies:[]
201 private function processModules()
204 $modules = $this->extensionManager->discoverModules()
210 * @var \Drupal\Core\Extension\Extension[] $module
212 foreach ($modules as $module) {
213 if (!$this->isValidModule($module)) {
217 $dependencies = $this->extractDependencies(
221 $this->packages[$type][] = [
222 'name' => sprintf('drupal/%s', $module->getName()),
223 'version' => $this->calculateVersion($module->info['version']),
224 'dependencies' => implode(PHP_EOL, array_values($dependencies))
227 $this->dependencies = array_merge(
229 $dependencies?$dependencies:[]
234 private function processThemes()
237 $themes = $this->extensionManager->discoverThemes()
242 * @var \Drupal\Core\Extension\Extension[] $module
244 foreach ($themes as $theme) {
245 if (!$this->isValidTheme($theme)) {
248 $this->packages[$type][] = [
249 'name' => sprintf('drupal/%s', $theme->getName()),
250 'version' => $this->calculateVersion($theme->info['version']),
260 private function isValidModule($module)
262 if (strpos($module->getPath(), 'modules/custom') === 0) {
266 if (!array_key_exists('project', $module->info)) {
270 if (!array_key_exists('project', $module->info)) {
274 return $module->info['project'] === $module->getName();
281 private function isValidTheme($module)
283 if (strpos($module->getPath(), 'themes/custom') === 0) {
290 private function isValidDependency($moduleDependency, $extension, $extensions)
292 if (in_array($moduleDependency, $this->corePackages['module'])) {
296 if ($extensions && !in_array($moduleDependency, $extensions)) {
300 if ($moduleDependency !== $extension->getName()) {
310 private function extractDependencies($extension, $extensions)
312 if (!array_key_exists('dependencies', $extension->info)) {
318 // Dependencies defined at info.yml
319 foreach ($extension->info['dependencies'] as $dependency) {
320 $dependencyExploded = explode(':', $dependency);
321 $moduleDependency = count($dependencyExploded)>1?$dependencyExploded[1]:$dependencyExploded[0];
323 if ($space = strpos($moduleDependency, ' ')) {
324 $moduleDependency = substr($moduleDependency, 0, $space);
327 if ($this->isValidDependency($moduleDependency, $extension, $extensions)) {
328 $dependencies[$moduleDependency] = 'drupal/'.$moduleDependency;
332 // Dependencies defined at composer.json
333 $composer = $this->readComposerFile($extension->getPath() . '/composer.json');
334 if (array_key_exists('require', $composer)) {
335 foreach (array_keys($composer['require']) as $package) {
336 if (strpos($package, 'drupal/') !== 0) {
339 $moduleDependency = str_replace('drupal/', '', $package);
340 if ($this->isValidDependency($moduleDependency, $extension, $extensions)) {
341 $dependencies[$moduleDependency] = $package;
346 return $dependencies;
349 protected function readComposerFile($file)
351 if (!file_exists($file)) {
355 return Json::decode(file_get_contents($file));
362 private function calculateVersion($version)
369 array_keys($replaceKeys),
370 array_values($replaceKeys),