validate-split-packages.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/php -q
  2. <?php
  3. declare(strict_types=1);
  4. /*
  5. * Compare split packages' composer.json with ROOT composer.json in regard to dependency constraints.
  6. */
  7. use Cake\Utility\Inflector;
  8. $options = [
  9. __DIR__ . '/../vendor/autoload.php',
  10. __DIR__ . '/vendor/autoload.php',
  11. ];
  12. if (!empty($_SERVER['PWD'])) {
  13. array_unshift($options, $_SERVER['PWD'] . '/vendor/autoload.php');
  14. }
  15. foreach ($options as $file) {
  16. if (file_exists($file)) {
  17. define('COMPOSER_INSTALL', $file);
  18. break;
  19. }
  20. }
  21. require COMPOSER_INSTALL;
  22. $path = dirname(__DIR__) . DS . 'src' . DS;
  23. $di = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
  24. $iterator = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::LEAVES_ONLY);
  25. /** @var array<\SplFileInfo> $iterator */
  26. $iterator = new RegexIterator($iterator, '~/src/\w+/composer.json$~');
  27. $packages = [];
  28. $code = 0;
  29. foreach ($iterator as $file) {
  30. $filePath = $file->getPath();
  31. $package = substr($filePath, strrpos($filePath, '/') + 1);
  32. if ($package === 'ORM') {
  33. $fullName = 'cakephp/orm';
  34. } else {
  35. $fullName = 'cakephp/' . Inflector::dasherize($package);
  36. }
  37. $packages[$fullName] = $package;
  38. }
  39. ksort($packages);
  40. $mainJsonContent = file_get_contents(dirname(__FILE__, 2) . DS . 'composer.json');
  41. $mainJson = json_decode($mainJsonContent, true);
  42. $mainReplace = $mainJson['replace'];
  43. $missing = [];
  44. foreach ($packages as $fullPackageName => $package) {
  45. if (!empty($mainReplace[$fullPackageName])) {
  46. unset($mainReplace[$fullPackageName]);
  47. continue;
  48. }
  49. $missing[] = $package;
  50. }
  51. if ($mainReplace) {
  52. echo "\033[31m" . ' * Missing "replace" statement in ROOT composer.json for package `' . $package . '`' . "\033[0m" . PHP_EOL;
  53. $code = 1;
  54. }
  55. if ($missing) {
  56. echo "\033[31m" . ' * Extra "replace" statement in ROOT composer.json for non-existent package(s) `' . implode(', ', $missing) . '`' . "\033[0m" . PHP_EOL;
  57. $code = 1;
  58. }
  59. $mainRequire = $mainJson['require'];
  60. $issues = [];
  61. foreach ($packages as $fullPackageName => $package) {
  62. $content = file_get_contents($path . $package . DS . 'composer.json');
  63. $json = json_decode($content, true);
  64. $require = $json['require'] ?? [];
  65. foreach ($require as $packageName => $constraint) {
  66. if (isset($packages[$packageName])) {
  67. continue;
  68. }
  69. if (!isset($mainRequire[$packageName])) {
  70. $issues[$package][] = 'Missing package requirement `' . $packageName . ': ' . $constraint . '` in ROOT composer.json';
  71. continue;
  72. }
  73. if ($mainRequire[$packageName] !== $constraint) {
  74. $issues[$package][] = 'Package requirement `' . $packageName . ': ' . $constraint . '` does not match the one in ROOT composer.json (`' . $mainRequire[$packageName] . '`)';
  75. }
  76. }
  77. }
  78. if ($issues) {
  79. foreach ($issues as $packageName => $packageIssues) {
  80. echo "\033[31m" . $packageName . ':' . "\033[0m" . PHP_EOL;
  81. foreach ($packageIssues as $issue) {
  82. echo "\033[31m" . ' - ' . $issue . "\033[0m" . PHP_EOL;
  83. $code = 1;
  84. }
  85. }
  86. }
  87. exit($code);