Composer.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Utils;
  12. use Composer\Autoload\ClassLoader;
  13. class Composer
  14. {
  15. /**
  16. * @var null|Collection
  17. */
  18. private static $content;
  19. /**
  20. * @var null|Collection
  21. */
  22. private static $json;
  23. /**
  24. * @var array
  25. */
  26. private static $extra = [];
  27. /**
  28. * @var array
  29. */
  30. private static $scripts = [];
  31. /**
  32. * @var array
  33. */
  34. private static $versions = [];
  35. /**
  36. * @var null|ClassLoader
  37. */
  38. private static $classLoader;
  39. /**
  40. * @throws \RuntimeException When composer.lock does not exist.
  41. */
  42. public static function getLockContent(): Collection
  43. {
  44. if (! self::$content) {
  45. $path = self::discoverLockFile();
  46. if (! $path) {
  47. throw new \RuntimeException('composer.lock not found.');
  48. }
  49. self::$content = collect(json_decode(file_get_contents($path), true));
  50. $packages = self::$content->offsetGet('packages') ?? [];
  51. $packagesDev = self::$content->offsetGet('packages-dev') ?? [];
  52. foreach (array_merge($packages, $packagesDev) as $package) {
  53. $packageName = '';
  54. foreach ($package ?? [] as $key => $value) {
  55. if ($key === 'name') {
  56. $packageName = $value;
  57. continue;
  58. }
  59. switch ($key) {
  60. case 'extra':
  61. $packageName && self::$extra[$packageName] = $value;
  62. break;
  63. case 'scripts':
  64. $packageName && self::$scripts[$packageName] = $value;
  65. break;
  66. case 'version':
  67. $packageName && self::$versions[$packageName] = $value;
  68. break;
  69. }
  70. }
  71. }
  72. }
  73. return self::$content;
  74. }
  75. public static function getJsonContent(): Collection
  76. {
  77. if (! self::$json) {
  78. $path = BASE_PATH . '/composer.json';
  79. if (! is_readable($path)) {
  80. throw new \RuntimeException('composer.json is not readable.');
  81. }
  82. self::$json = collect(json_decode(file_get_contents($path), true));
  83. }
  84. return self::$json;
  85. }
  86. public static function discoverLockFile(): string
  87. {
  88. $path = '';
  89. if (is_readable(BASE_PATH . '/composer.lock')) {
  90. $path = BASE_PATH . '/composer.lock';
  91. }
  92. return $path;
  93. }
  94. public static function getMergedExtra(string $key = null)
  95. {
  96. if (! self::$extra) {
  97. self::getLockContent();
  98. }
  99. if ($key === null) {
  100. return self::$extra;
  101. }
  102. $extra = [];
  103. foreach (self::$extra ?? [] as $project => $config) {
  104. foreach ($config ?? [] as $configKey => $item) {
  105. if ($key === $configKey && $item) {
  106. foreach ($item ?? [] as $k => $v) {
  107. if (is_array($v)) {
  108. $extra[$k] = array_merge($extra[$k] ?? [], $v);
  109. } else {
  110. $extra[$k][] = $v;
  111. }
  112. }
  113. }
  114. }
  115. }
  116. return $extra;
  117. }
  118. public static function getLoader(): ClassLoader
  119. {
  120. if (! self::$classLoader) {
  121. self::$classLoader = self::findLoader();
  122. }
  123. return self::$classLoader;
  124. }
  125. public static function setLoader(ClassLoader $classLoader): ClassLoader
  126. {
  127. self::$classLoader = $classLoader;
  128. return $classLoader;
  129. }
  130. private static function findLoader(): ClassLoader
  131. {
  132. $composerClass = '';
  133. foreach (get_declared_classes() as $declaredClass) {
  134. if (strpos($declaredClass, 'ComposerAutoloaderInit') === 0 && method_exists($declaredClass, 'getLoader')) {
  135. $composerClass = $declaredClass;
  136. break;
  137. }
  138. }
  139. if (! $composerClass) {
  140. throw new \RuntimeException('Composer loader not found.');
  141. }
  142. return $composerClass::getLoader();
  143. }
  144. }