composer_check.drush.inc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * @file
  4. * A Drush plugin to compare composer.json and composer.lock.
  5. */
  6. use Drupal\Component\Utility\Unicode;
  7. use Symfony\Component\Yaml\Yaml;
  8. /**
  9. * Implements hook_drush_command().
  10. */
  11. function composer_check_drush_command() {
  12. $cmds['composer-check'] = [
  13. 'aliases' => ['cck'],
  14. 'description' => 'Lists the packages requested in composer.json and the matching locked version.',
  15. 'arguments' => [
  16. 'composer.lock' => 'The path to the lock file. Defaults to the one in drupal root.',
  17. ],
  18. 'options' => [
  19. 'all' => [
  20. 'description' => 'List all locked packages, even those not requested',
  21. 'required' => FALSE,
  22. ],
  23. 'yaml' => 'Produce YAML output instead of a table',
  24. ],
  25. ];
  26. return $cmds;
  27. }
  28. /**
  29. * Command callback for composer-check.
  30. *
  31. * @param null|string $lockPath
  32. * Optional. The path to a composer.lock file.
  33. */
  34. function drush_composer_check($lockPath = NULL) {
  35. if (empty($lockPath)) {
  36. $lockPath = DRUPAL_ROOT . '/composer.lock';
  37. }
  38. if (!is_file($lockPath) && is_readable($lockPath)) {
  39. drush_die("Cannot read lock file");
  40. }
  41. $jsonPath = dirname($lockPath) . '/composer.json';
  42. if (!is_file($jsonPath) && is_readable($jsonPath)) {
  43. drush_die("Cannot read json file");
  44. }
  45. $json = json_decode(file_get_contents($jsonPath), TRUE);
  46. $jsonPackages = $json['require'] ?? [];
  47. $jsonDevPackages = $json['require-dev'] ?? [];
  48. $lockFile = json_decode(file_get_contents($lockPath), TRUE);
  49. $lockPackages = $lockFile['packages'];
  50. $lockDevPackages = $lockFile['packages-dev'];
  51. $lockPlatform = $lockFile['platform'];
  52. array_walk($lockPlatform, function (&$requirement, $component) {
  53. $requirement = [
  54. 'name' => $component,
  55. 'version' => $requirement,
  56. ];
  57. });
  58. $lockPackages = array_merge($lockPackages, $lockPlatform);
  59. $lockDevPackages = array_merge($lockDevPackages, $lockPlatform);
  60. $all = !!drush_get_option('all');
  61. $packages = ['dev' => [], 'run' => []];
  62. foreach ($jsonPackages as $package => $requirement) {
  63. if ($all || !empty($requirement)) {
  64. $package = Unicode::strtolower($package);
  65. $packages['run'][$package]['requirement'] = $requirement;
  66. }
  67. }
  68. foreach ($jsonDevPackages as $package => $requirement) {
  69. if ($all || !empty($requirement)) {
  70. $package = Unicode::strtolower($package);
  71. $packages['dev'][$package]['requirement'] = $requirement;
  72. }
  73. }
  74. foreach ($lockPackages as $packageInfo) {
  75. $package = Unicode::strtolower($packageInfo['name']);
  76. if ($all || !empty($packages['run'][$package])) {
  77. $version = $packageInfo['version'];
  78. $packages['run'][$package]['version'] = $version;
  79. }
  80. }
  81. foreach ($lockDevPackages as $packageInfo) {
  82. $package = Unicode::strtolower($packageInfo['name']);
  83. if ($all || !empty($packages['dev'][$package])) {
  84. $version = $packageInfo['version'];
  85. $packages['dev'][$package]['version'] = $version;
  86. }
  87. }
  88. ksort($packages['dev']);
  89. ksort($packages['run']);
  90. if (drush_get_option('yaml')) {
  91. echo Yaml::dump($packages, 3);
  92. return;
  93. }
  94. _composer_check_output_human($packages);
  95. }
  96. /**
  97. * Display a package comparison as a text table.
  98. *
  99. * @param array $packages
  100. * A package comparison array.
  101. */
  102. function _composer_check_output_human($packages) {
  103. $header = ['Name', 'Kind', 'Requirement', 'Version'];
  104. $rows = [$header];
  105. foreach ($packages as $kind => $kindPackages) {
  106. foreach ($kindPackages as $package => $info) {
  107. $rows["$package/$kind"] = [
  108. $package,
  109. $kind,
  110. $info['requirement'] ?? '',
  111. $info['version'] ?? '',
  112. ];
  113. }
  114. }
  115. ksort($rows);
  116. drush_print_table($rows, FALSE);
  117. }