DependencyChecker.php 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Composer;
  7. use Composer\Console\Application;
  8. use Magento\Framework\App\Filesystem\DirectoryList;
  9. use Symfony\Component\Console\Input\ArrayInput;
  10. use Symfony\Component\Console\Output\BufferedOutput;
  11. /**
  12. * A class to check if there are any dependency to package(s) that exists in the codebase, regardless of package type
  13. */
  14. class DependencyChecker
  15. {
  16. /**
  17. * @var Application
  18. */
  19. private $composerApp;
  20. /**
  21. * @var DirectoryList
  22. */
  23. private $directoryList;
  24. /**
  25. * Constructor
  26. *
  27. * @param Application $composerApp
  28. * @param DirectoryList $directoryList
  29. */
  30. public function __construct(Application $composerApp, DirectoryList $directoryList)
  31. {
  32. $this->composerApp = $composerApp;
  33. $this->directoryList = $directoryList;
  34. }
  35. /**
  36. * Checks dependencies to package(s), returns array of dependencies in the format of
  37. * 'package A' => [array of package names depending on package A]
  38. * If $excludeSelf is set to true, items in $packages will be excluded in all
  39. * "array of package names depending on package A"
  40. *
  41. * @param string[] $packages
  42. * @param bool $excludeSelf
  43. * @return string[]
  44. */
  45. public function checkDependencies(array $packages, $excludeSelf = false)
  46. {
  47. $this->composerApp->setAutoExit(false);
  48. $dependencies = [];
  49. foreach ($packages as $package) {
  50. $buffer = new BufferedOutput();
  51. $this->composerApp->resetComposer();
  52. $this->composerApp->run(
  53. new ArrayInput(
  54. ['command' => 'depends', '--working-dir' => $this->directoryList->getRoot(), 'package' => $package]
  55. ),
  56. $buffer
  57. );
  58. $dependingPackages = $this->parseComposerOutput($buffer->fetch());
  59. if ($excludeSelf === true) {
  60. $dependingPackages = array_values(array_diff($dependingPackages, $packages));
  61. }
  62. $dependencies[$package] = $dependingPackages;
  63. }
  64. return $dependencies;
  65. }
  66. /**
  67. * Parse output from running composer remove command into an array of depending packages
  68. *
  69. * @param string $output
  70. * @return string[]
  71. */
  72. private function parseComposerOutput($output)
  73. {
  74. $rawLines = explode(PHP_EOL, $output);
  75. $packages = [];
  76. foreach ($rawLines as $rawLine) {
  77. $parts = explode(' ', $rawLine);
  78. if (count(explode('/', $parts[0])) == 2) {
  79. if (strpos($parts[0], 'magento/project-') === false) {
  80. $packages[] = $parts[0];
  81. }
  82. }
  83. }
  84. return $packages;
  85. }
  86. }