diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index f59cf6531b717d139cf60a79cdd6d64588529ffb..b8aaad354bf61cdc2f31c9a5e0aa334b095462f3 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -23,6 +23,7 @@ services: automatic_updates.updater: class: Drupal\automatic_updates\Updater arguments: + - '@package_manager.composer_inspector' - '@package_manager.path_locator' - '@package_manager.beginner' - '@package_manager.stager' @@ -43,6 +44,7 @@ services: - '@automatic_updates.status_check_mailer' - '@state' - '@config.factory' + - '@package_manager.composer_inspector' - '@package_manager.path_locator' - '@package_manager.beginner' - '@package_manager.stager' diff --git a/package_manager/src/ComposerInspector.php b/package_manager/src/ComposerInspector.php index cf92a7a5072ba434f7eb6c199b780b391b0ac1d0..c8643142932568d20296da1876235bc5476d2680 100644 --- a/package_manager/src/ComposerInspector.php +++ b/package_manager/src/ComposerInspector.php @@ -287,6 +287,7 @@ class ComposerInspector { // Composer requirement accordingly. $lock_content = file_get_contents($working_dir . DIRECTORY_SEPARATOR . 'composer.lock'); $lock_data = json_decode($lock_content, TRUE, 512, JSON_THROW_ON_ERROR); + $lock_packages = array_merge($lock_data['packages'] ?? [], $lock_data['packages-dev'] ?? []); foreach ($lock_packages as $lock_package) { $name = $lock_package['name']; @@ -302,6 +303,22 @@ class ComposerInspector { return $list; } + /** + * Returns the output of `composer show --self` in a directory. + * + * @param string $working_dir + * The directory in which to run Composer. + * + * @return array + * The parsed output of `composer show --self`. + */ + public function getRootPackageInfo(string $working_dir): array { + $this->validate($working_dir); + + $this->runner->run(['show', '--self', '--format=json', "--working-dir={$working_dir}"], $this->jsonCallback); + return $this->jsonCallback->getOutputData(); + } + /** * Gets the installed packages data from running `composer show`. * diff --git a/package_manager/tests/src/Kernel/ComposerInspectorTest.php b/package_manager/tests/src/Kernel/ComposerInspectorTest.php index 3c42bc149dfa26c762d1df5dc3292aa72efca0a6..e4a5375c85ba52f38be4e21bd35bbd05f48826b1 100644 --- a/package_manager/tests/src/Kernel/ComposerInspectorTest.php +++ b/package_manager/tests/src/Kernel/ComposerInspectorTest.php @@ -265,4 +265,16 @@ class ComposerInspectorTest extends PackageManagerKernelTestBase { ->validate($project_root); } + /** + * @covers ::getRootPackageInfo + */ + public function testRootPackageInfo(): void { + $project_root = $this->container->get('package_manager.path_locator') + ->getProjectRoot(); + + $info = $this->container->get('package_manager.composer_inspector') + ->getRootPackageInfo($project_root); + $this->assertSame('fake/site', $info['name']); + } + } diff --git a/src/Updater.php b/src/Updater.php index cca31265087e157bd224f3cf1520efbf6087484c..bb08bb525a122c0f5e874355086a3fb68fb386ce 100644 --- a/src/Updater.php +++ b/src/Updater.php @@ -5,6 +5,7 @@ declare(strict_types = 1); namespace Drupal\automatic_updates; use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\package_manager\ComposerInspector; use Drupal\package_manager\Stage; /** @@ -17,6 +18,18 @@ use Drupal\package_manager\Stage; */ class Updater extends Stage { + /** + * Constructs a new Updater object. + * + * @param \Drupal\package_manager\ComposerInspector $composerInspector + * The Composer inspector service. + * @param mixed ...$arguments + * Additional arguments to pass to the parent constructor. + */ + public function __construct(protected ComposerInspector $composerInspector, mixed ...$arguments) { + parent::__construct(...$arguments); + } + /** * Begins the update. * @@ -38,18 +51,16 @@ class Updater extends Stage { throw new \InvalidArgumentException("Currently only updates to Drupal core are supported."); } - $composer = $this->getActiveComposer(); $package_versions = [ 'production' => [], 'dev' => [], ]; - $require_dev = $composer->getComposer() - ->getPackage() - ->getDevRequires(); - foreach (array_keys($composer->getCorePackages()) as $package) { - $group = array_key_exists($package, $require_dev) ? 'dev' : 'production'; - $package_versions[$group][$package] = $project_versions['drupal']; + $project_root = $this->pathLocator->getProjectRoot(); + $info = $this->composerInspector->getRootPackageInfo($project_root); + foreach ($this->composerInspector->getInstalledPackagesList($project_root)->getCorePackages() as $package) { + $group = isset($info['devRequires'][$package->name]) ? 'dev' : 'production'; + $package_versions[$group][$package->name] = $project_versions['drupal']; } // Ensure that package versions are available to pre-create event