From 111c3cd8d0af1866a36aea9946fa6bb018f7fa30 Mon Sep 17 00:00:00 2001 From: lucashedding <lucashedding@1463982.no-reply.drupal.org> Date: Tue, 28 May 2019 10:19:44 -0500 Subject: [PATCH] Issue #3054005 by heddn, catch: Checker: warn for projects that don't have packing info added --- automatic_updates.module | 2 +- automatic_updates.services.yml | 9 ++ src/Controller/ReadinessCheckerController.php | 2 +- src/ReadinessChecker/MissingProjectInfo.php | 107 ++++++++++++++++++ tests/src/Functional/AutomaticUpdatesTest.php | 2 +- .../MissingProjectInfoTest.php | 69 +++++++++++ 6 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 src/ReadinessChecker/MissingProjectInfo.php create mode 100644 tests/src/Kernel/ReadinessChecker/MissingProjectInfoTest.php diff --git a/automatic_updates.module b/automatic_updates.module index cb65f4a4b0..9f389b04f7 100644 --- a/automatic_updates.module +++ b/automatic_updates.module @@ -55,7 +55,7 @@ function automatic_updates_page_top(array &$page_top) { } $results = $checker->getResults('warning'); if ($results) { - \Drupal::messenger()->addWarning(t('Your site does not pass some readiness checks for automatic updates. It might not be eligible for <a href="@readiness_checks">automatic updates</a>.', ['@readiness_checks' => 'https://www.drupal.org/docs/8/update/automatic-updates#readiness-checks'])); + \Drupal::messenger()->addWarning(t('Your site does not pass some readiness checks for automatic updates. It might not be completely eligible for <a href="@readiness_checks">automatic updates</a>.', ['@readiness_checks' => 'https://www.drupal.org/docs/8/update/automatic-updates#readiness-checks'])); foreach ($results as $message) { \Drupal::messenger()->addWarning($message); } diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index 5dc14c723a..ba47c91629 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -73,3 +73,12 @@ services: class: Drupal\automatic_updates\ReadinessChecker\PendingDbUpdates tags: - { name: readiness_checker, category: error} + automatic_updates.missing_project_info: + class: Drupal\automatic_updates\ReadinessChecker\MissingProjectInfo + arguments: + - '@automatic_updates.drupal_finder' + - '@extension.list.module' + - '@extension.list.profile' + - '@extension.list.theme' + tags: + - { name: readiness_checker, category: warning} diff --git a/src/Controller/ReadinessCheckerController.php b/src/Controller/ReadinessCheckerController.php index b5872cf747..29f253d0c4 100644 --- a/src/Controller/ReadinessCheckerController.php +++ b/src/Controller/ReadinessCheckerController.php @@ -54,7 +54,7 @@ class ReadinessCheckerController extends ControllerBase { $messages = array_merge($this->checker->run($category), $messages); } if (empty($messages)) { - $this->messenger()->addStatus($this->t('No issues found. Your site is ready to for <a href="@readiness_checks">automatic updates</a>.', ['@readiness_checks' => 'https://www.drupal.org/docs/8/update/automatic-updates#readiness-checks'])); + $this->messenger()->addStatus($this->t('No issues found. Your site is completely ready for <a href="@readiness_checks">automatic updates</a>.', ['@readiness_checks' => 'https://www.drupal.org/docs/8/update/automatic-updates#readiness-checks'])); } return $this->redirect('automatic_updates.settings'); } diff --git a/src/ReadinessChecker/MissingProjectInfo.php b/src/ReadinessChecker/MissingProjectInfo.php new file mode 100644 index 0000000000..9b202732ba --- /dev/null +++ b/src/ReadinessChecker/MissingProjectInfo.php @@ -0,0 +1,107 @@ +<?php + +namespace Drupal\automatic_updates\ReadinessChecker; + +use Drupal\Core\Extension\ExtensionList; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use DrupalFinder\DrupalFinder; + +/** + * Missing project info checker. + */ +class MissingProjectInfo extends Filesystem { + use StringTranslationTrait; + + /** + * The module extension list. + * + * @var \Drupal\Core\Extension\ExtensionList + */ + protected $modules; + + /** + * The profile extension list. + * + * @var \Drupal\Core\Extension\ExtensionList + */ + protected $profiles; + + /** + * The theme extension list. + * + * @var \Drupal\Core\Extension\ExtensionList + */ + protected $themes; + + /** + * MissingProjectInfo constructor. + * + * @param \DrupalFinder\DrupalFinder $drupal_finder + * The Drupal finder. + * @param \Drupal\Core\Extension\ExtensionList $modules + * The module extension list. + * @param \Drupal\Core\Extension\ExtensionList $profiles + * The profile extension list. + * @param \Drupal\Core\Extension\ExtensionList $themes + * The theme extension list. + */ + public function __construct(DrupalFinder $drupal_finder, ExtensionList $modules, ExtensionList $profiles, ExtensionList $themes) { + $this->drupalFinder = $drupal_finder; + $this->modules = $modules; + $this->profiles = $profiles; + $this->themes = $themes; + } + + /** + * {@inheritdoc} + */ + protected function doCheck() { + return $this->missingProjectInfoCheck(); + } + + /** + * Check for projects missing project info. + * + * @return array + * An array of translatable strings if any checks fail. + */ + protected function missingProjectInfoCheck() { + $messages = []; + foreach ($this->getExtensionsTypes() as $extension_type) { + foreach ($this->getInfos($extension_type) as $extension_name => $info) { + if (empty($info['version'])) { + $messages[] = $this->t('The project "@extension" will not be updated because it is missing the "version" key in the @extension.info.yml file.', ['@extension' => $extension_name]); + } + if (empty($info['project'])) { + $messages[] = $this->t('The project "@extension" will not be updated because it is missing the "project" key in the @extension.info.yml file.', ['@extension' => $extension_name]); + } + } + } + return $messages; + } + + /** + * Get the extension types. + * + * @return array + * The extension types. + */ + protected function getExtensionsTypes() { + return ['modules', 'profiles', 'themes']; + } + + /** + * Returns an array of info files information of available extensions. + * + * @param string $extension_type + * The extension type. + * + * @return array + * An associative array of extension information arrays, keyed by extension + * name. + */ + protected function getInfos($extension_type) { + return $this->{$extension_type}->getAllAvailableInfo(); + } + +} diff --git a/tests/src/Functional/AutomaticUpdatesTest.php b/tests/src/Functional/AutomaticUpdatesTest.php index a416154170..1ce69e985b 100644 --- a/tests/src/Functional/AutomaticUpdatesTest.php +++ b/tests/src/Functional/AutomaticUpdatesTest.php @@ -94,7 +94,7 @@ class AutomaticUpdatesTest extends BrowserTestBase { // Test manually running readiness checks. $this->drupalGet(Url::fromRoute('automatic_updates.settings')); $this->clickLink('run the readiness checks'); - $this->assertSession()->pageTextContains('No issues found. Your site is ready to for automatic updates.'); + $this->assertSession()->pageTextContains('Your site does not pass some readiness checks for automatic updates. It might not be completely eligible for automatic updates.'); } } diff --git a/tests/src/Kernel/ReadinessChecker/MissingProjectInfoTest.php b/tests/src/Kernel/ReadinessChecker/MissingProjectInfoTest.php new file mode 100644 index 0000000000..e5ac3b3f1c --- /dev/null +++ b/tests/src/Kernel/ReadinessChecker/MissingProjectInfoTest.php @@ -0,0 +1,69 @@ +<?php + +namespace Drupal\Tests\automatic_updates\Kernel\ReadinessChecker; + +use Drupal\automatic_updates\ReadinessChecker\MissingProjectInfo; +use DrupalFinder\DrupalFinder; +use Drupal\Core\Extension\ExtensionList; +use Drupal\KernelTests\KernelTestBase; + +/** + * Tests missing project info readiness checking. + * + * @group automatic_updates + */ +class MissingProjectInfoTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'automatic_updates', + ]; + + /** + * Tests pending db updates readiness checks. + */ + public function testMissingProjectInfo() { + // The checker should always have messages on the testbot, since project + // info is added by the packager. + $messages = $this->container->get('automatic_updates.missing_project_info')->run(); + $this->assertNotEmpty($messages); + + // Now test with a some dummy info data that won't cause any issues. + $drupal_finder = new DrupalFinder(); + $extension_list = $this->createMock(ExtensionList::class); + $messages = (new TestMissingProjectInfo($drupal_finder, $extension_list, $extension_list, $extension_list))->run(); + $this->assertEmpty($messages); + } + +} + +/** + * Class TestMissingProjectInfo. + */ +class TestMissingProjectInfo extends MissingProjectInfo { + + /** + * {@inheritdoc} + */ + protected function getInfos($extension_type) { + $infos = []; + if ($extension_type === 'modules') { + $infos['system'] = [ + 'name' => 'System', + 'type' => 'module', + 'description' => 'Handles general site configuration for administrators.', + 'package' => 'Core', + 'version' => 'VERSION', + 'project' => 'drupal', + 'core' => '8.x', + 'required' => 'true', + 'configure' => 'system.admin_config_system', + 'dependencies' => [], + ]; + } + return $infos; + } + +} -- GitLab