Browse Source

Drupal 9 / Drush 10.

Frederic G. MARAND 2 years ago
parent
commit
85ae4533ac
3 changed files with 207 additions and 144 deletions
  1. 194 0
      ComposerCheckCommands.php
  2. 13 14
      README.md
  3. 0 130
      composer_check.drush.inc

+ 194 - 0
ComposerCheckCommands.php

@@ -0,0 +1,194 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drush\Commands\composer_check;
+
+use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
+use Drush\Commands\DrushCommands;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * MagpjmCommands provides Drush 9 commands for the MAGPJ run time module.
+ */
+class ComposerCheckCommands extends DrushCommands {
+
+  /**
+   * The serialization.yaml service.
+   *
+   * @var \Symfony\Component\Yaml
+   */
+  private $yaml;
+
+  public function __construct() {
+    $this->yaml = new Yaml();
+  }
+
+  /**
+   * Command callback for composer-check.
+   *
+   * @param null|string $lockPath
+   *   Optional. The path to a composer.lock file.
+   */
+
+  /**
+   * Lists the packages requested in composer.json and the matching locked
+   * version.
+   *
+   * @param ?string $lockPath
+   *
+   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
+   *   The list of package versions, unless YAML encoding is used.
+   *
+   * @field-labels
+   *   name: Name
+   *   kind: Kind
+   *   req: Requirement
+   *   ver: Version
+   *
+   * @command composer:check
+   * @aliases cch
+   *
+   * @option all List all locked packages, even those not requested
+   * @option yaml Produce YAML output instead of a table
+   *
+   * @throws \Exception
+   */
+  public function composerCheck(string $lockPath = NULL) {
+    $lockPath = $this->validateLockPath($lockPath);
+    $jsonPath = $this->validateJsonPath($lockPath);
+
+    ['run' => $jrPack, 'dev' => $jdPack] = $this->decodeJsonPackages($jsonPath);
+    ['run' => $lrPack, 'dev' => $ldPack] = $this->decodeLockPackages($lockPath);
+
+    $all = !!$this->input()->getOption('all');
+    $yaml = !!$this->input()->getOption('yaml');
+
+    $packages = ['run' => [], 'dev' => []];
+
+    foreach ($jrPack as $package => $requirement) {
+      if ($all || !empty($requirement)) {
+        $package = mb_strtolower($package);
+        $packages['run'][$package]['requirement'] = $requirement;
+      }
+    }
+    foreach ($jdPack as $package => $requirement) {
+      if ($all || !empty($requirement)) {
+        $package = mb_strtolower($package);
+        $packages['dev'][$package]['requirement'] = $requirement;
+      }
+    }
+    foreach ($lrPack as $packageInfo) {
+      $package = mb_strtolower($packageInfo['name']);
+      if ($all || !empty($packages['run'][$package])) {
+        $version = $packageInfo['version'];
+        $packages['run'][$package]['version'] = $version;
+      }
+    }
+    foreach ($ldPack as $packageInfo) {
+      $package = mb_strtolower($packageInfo['name']);
+      if ($all || !empty($packages['dev'][$package])) {
+        $version = $packageInfo['version'];
+        $packages['dev'][$package]['version'] = $version;
+      }
+    }
+    ksort($packages['dev']);
+    ksort($packages['run']);
+
+    if ($yaml) {
+      $this->output()->writeln($this->yaml->dump($packages, 3, 2));
+      return NULL;
+    }
+
+    return $this->humanOutput($packages);
+  }
+
+  /**
+   * Display a package comparison as a text table.
+   *
+   * @param array $packages
+   *   A package comparison array.
+   *
+   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
+   *
+   */
+  protected function humanOutput($packages): RowsOfFields {
+    //$header = ['Name', 'Kind', 'Requirement', 'Version'];
+    $rows = [];
+    foreach ($packages as $kind => $kindPackages) {
+      foreach ($kindPackages as $package => $info) {
+        $rows["$package/$kind"] = [
+          'name' => $package,
+          'kind' => $kind,
+          'req' => $info['requirement'] ?? '',
+          'ver' => $info['version'] ?? '',
+        ];
+      }
+    }
+    ksort($rows);
+    return new RowsOfFields($rows);
+  }
+
+  /**
+   * @param string $jsonPath
+   *
+   * @return array
+   */
+  protected function decodeJsonPackages(string $jsonPath): array {
+    $json = json_decode(file_get_contents($jsonPath), TRUE);
+    $jsonPackages = $json['require'] ?? [];
+    $jsonDevPackages = $json['require-dev'] ?? [];
+    return ['run' => $jsonPackages, 'dev' => $jsonDevPackages];
+  }
+
+  protected function decodeLockPackages(string $lockPath): array {
+    $file = json_decode(file_get_contents($lockPath), TRUE);
+    $run = $file['packages'];
+    $dev = $file['packages-dev'];
+
+    $platform = $file['platform'];
+    array_walk($platform, function (&$requirement, $component) {
+      $requirement = [
+        'name' => $component,
+        'version' => $requirement,
+      ];
+    });
+    $run = array_merge($run, $platform);
+    $dev = array_merge($dev, $platform);
+
+    return ['run' => $run, 'dev' => $dev];
+  }
+
+  /**
+   * @param string $lockPath The lockPath command argument.
+   *
+   * @return string
+   *
+   * @throws \Exception
+   */
+  protected function validateJsonPath(string $lockPath): string {
+    $jsonPath = dirname($lockPath) . '/composer.json';
+    if (!is_file($jsonPath) && is_readable($jsonPath)) {
+      throw new \Exception("Cannot read composer.json file");
+    }
+    return $jsonPath;
+  }
+
+  /**
+   * @param string|null $lockPath The lockPath optional command argument.
+   *
+   * @return string|null The defaulted lock path.
+   *
+   * @throws \Exception If the defaulted lock path cannot be read.
+   */
+  protected function validateLockPath(?string $lockPath): ?string {
+    if (empty($lockPath)) {
+      $lockPath = dirname(DRUPAL_ROOT) . '/composer.lock';
+    }
+    if (!is_file($lockPath) && is_readable($lockPath)) {
+      throw new \Exception("Cannot read composer.lock file");
+    }
+    return $lockPath;
+  }
+
+}

+ 13 - 14
README.md

@@ -1,39 +1,38 @@
 # Drupal Composer check
 
-This Drush plugin provides a `composer-check` (alias `cck`) command, which 
+This Drush plugin provides a `composer:check` (alias `cch`) command, which
 compares the packages versions in `composer.lock` with those requested in the
-`composer.json` file of a Drupal 8 project.
+`composer.json` file of a Drupal 9 project.
 
 
 ## Syntax
 
-* Arguments:
-  * `composer.lock`: Optional. The path to the lock file. Defaults to the one in 
-    Drupal root.
-* Options:
+* Arguments :
+  * `composer.lock`: Optional. The path to the lock file. Defaults to the one
+    above the project root, which is the default in modern Composer layouts for
+    Drupal 9.
+* Options :
   * `--all`: List all locked packages, even those not requested
   * `--yaml`: Produce YAML output instead of a table
-* Aliases: `cck`
+* Aliases: `cch`
 
 
 # Composer / Packagist
 
-This package is available on [Packagist] as `fgm/composer-check`, but for now the 
-`config` section of your `composer.json` will need `"secure-http": false` 
-because this repo is not yet available over HTTPS.
+This package is available on [Packagist] as `fgm/composer-check`.
 
 [Packagist]: https://packagist.org/packages/fgm/composer-check
 
 
 # Examples
 
-* Default usage in a `drupal/drupal` project:
+* Default usage in a `drupal/core-recommended` or `drupal-composer/drupal-project` project :
 
-      drush cck
+      drush cch
 
-* Listing all packages in a `drupal-composer/drupal-project` project, in YAML format:
+* Listing all packages in a legacy `drupal/drupal` project, in YAML format :
 
-      drush cck --all --yaml $PWD/composer.lock
+      drush cch --all --yaml $PWD/composer.lock
 
 
 # License

+ 0 - 130
composer_check.drush.inc

@@ -1,130 +0,0 @@
-<?php
-
-/**
- * @file
- * A Drush plugin to compare composer.json and composer.lock.
- */
-
-use Drupal\Component\Utility\Unicode;
-use Symfony\Component\Yaml\Yaml;
-
-/**
- * Implements hook_drush_command().
- */
-function composer_check_drush_command() {
-  $cmds['composer-check'] = [
-    'aliases' => ['cck'],
-    'description' => 'Lists the packages requested in composer.json and the matching locked version.',
-    'arguments' => [
-      'composer.lock' => 'The path to the lock file. Defaults to the one in drupal root.',
-    ],
-    'options' => [
-      'all' => [
-        'description' => 'List all locked packages, even those not requested',
-        'required' => FALSE,
-      ],
-      'yaml' => 'Produce YAML output instead of a table',
-    ],
-  ];
-
-  return $cmds;
-}
-
-/**
- * Command callback for composer-check.
- *
- * @param null|string $lockPath
- *   Optional. The path to a composer.lock file.
- */
-function drush_composer_check($lockPath = NULL) {
-  if (empty($lockPath)) {
-    $lockPath = DRUPAL_ROOT . '/composer.lock';
-  }
-  if (!is_file($lockPath) && is_readable($lockPath)) {
-    drush_die("Cannot read lock file");
-  }
-
-  $jsonPath = dirname($lockPath) . '/composer.json';
-  if (!is_file($jsonPath) && is_readable($jsonPath)) {
-    drush_die("Cannot read json file");
-  }
-
-  $json = json_decode(file_get_contents($jsonPath), TRUE);
-  $jsonPackages = $json['require'] ?? [];
-  $jsonDevPackages = $json['require-dev'] ?? [];
-
-  $lockFile = json_decode(file_get_contents($lockPath), TRUE);
-  $lockPackages = $lockFile['packages'];
-  $lockDevPackages = $lockFile['packages-dev'];
-
-  $lockPlatform = $lockFile['platform'];
-  array_walk($lockPlatform, function (&$requirement, $component) {
-    $requirement = [
-      'name' => $component,
-      'version' => $requirement,
-    ];
-  });
-  $lockPackages = array_merge($lockPackages, $lockPlatform);
-  $lockDevPackages = array_merge($lockDevPackages, $lockPlatform);
-
-  $all = !!drush_get_option('all');
-  $packages = ['dev' => [], 'run' => []];
-  foreach ($jsonPackages as $package => $requirement) {
-    if ($all || !empty($requirement)) {
-      $package = Unicode::strtolower($package);
-      $packages['run'][$package]['requirement'] = $requirement;
-    }
-  }
-  foreach ($jsonDevPackages as $package => $requirement) {
-    if ($all || !empty($requirement)) {
-      $package = Unicode::strtolower($package);
-      $packages['dev'][$package]['requirement'] = $requirement;
-    }
-  }
-  foreach ($lockPackages as $packageInfo) {
-    $package = Unicode::strtolower($packageInfo['name']);
-    if ($all || !empty($packages['run'][$package])) {
-      $version = $packageInfo['version'];
-      $packages['run'][$package]['version'] = $version;
-    }
-  }
-  foreach ($lockDevPackages as $packageInfo) {
-    $package = Unicode::strtolower($packageInfo['name']);
-    if ($all || !empty($packages['dev'][$package])) {
-      $version = $packageInfo['version'];
-      $packages['dev'][$package]['version'] = $version;
-    }
-  }
-  ksort($packages['dev']);
-  ksort($packages['run']);
-
-  if (drush_get_option('yaml')) {
-    echo Yaml::dump($packages, 3);
-    return;
-  }
-
-  _composer_check_output_human($packages);
-}
-
-/**
- * Display a package comparison as a text table.
- *
- * @param array $packages
- *   A package comparison array.
- */
-function _composer_check_output_human($packages) {
-  $header = ['Name', 'Kind', 'Requirement', 'Version'];
-  $rows = [$header];
-  foreach ($packages as $kind => $kindPackages) {
-    foreach ($kindPackages as $package => $info) {
-      $rows["$package/$kind"] = [
-        $package,
-        $kind,
-        $info['requirement'] ?? '',
-        $info['version'] ?? '',
-      ];
-    }
-  }
-  ksort($rows);
-  drush_print_table($rows, FALSE);
-}