Commit c1c1f899 authored by Gábor Hojtsy's avatar Gábor Hojtsy
Browse files

Issue #3201336 by Gábor Hojtsy, andypost: Update Upgrade Status UI for Drupal 9 to 10 support

parent 4a5e158d
......@@ -347,7 +347,7 @@ final class DeprecationAnalyzer {
$result['data']['totals']['file_errors']++;
}
// Assume this project is Drupal 9 ready unless proven otherwise.
// Assume this project is ready for the next major core version unless proven otherwise.
$result['data']['totals']['upgrade_status_split']['declared_ready'] = TRUE;
$info_files = $this->getSubExtensionInfoFiles($project_dir);
......@@ -372,9 +372,9 @@ final class DeprecationAnalyzer {
$result['data']['totals']['file_errors']++;
$result['data']['totals']['upgrade_status_split']['declared_ready'] = FALSE;
}
elseif (!ProjectCollector::isDrupal9CompatibleConstraint($info['core_version_requirement'])) {
elseif (!ProjectCollector::isCompatibleWithNextMajorDrupal($info['core_version_requirement'])) {
$result['data']['files'][$error_path]['messages'][] = [
'message' => "Value of core_version_requirement: {$info['core_version_requirement']} is not compatible with Drupal 9. See https://drupal.org/node/3070687.",
'message' => "Value of core_version_requirement: {$info['core_version_requirement']} is not compatible with the next major version of Drupal core. See https://drupal.org/node/3070687.",
'line' => 0,
];
$result['data']['totals']['errors']++;
......@@ -397,16 +397,16 @@ final class DeprecationAnalyzer {
$composer_json = json_decode(file_get_contents($project_dir . '/composer.json'));
if (empty($composer_json) || !is_object($composer_json)) {
$result['data']['files'][$extension->getPath() . '/composer.json']['messages'][] = [
'message' => "Parse error in composer.json. Having a composer.json is not a requirement for Drupal 9 compatibility but if there is one, it should be valid. See https://drupal.org/node/2514612.",
'message' => "Parse error in composer.json. Having a composer.json is not a requirement in general, but if there is one, it should be valid. See https://drupal.org/node/2514612.",
'line' => 0,
];
$result['data']['totals']['errors']++;
$result['data']['totals']['file_errors']++;
$result['data']['totals']['upgrade_status_split']['declared_ready'] = FALSE;
}
elseif (!empty($composer_json->require->{'drupal/core'}) && !projectCollector::isDrupal9CompatibleConstraint($composer_json->require->{'drupal/core'})) {
elseif (!empty($composer_json->require->{'drupal/core'}) && !projectCollector::isCompatibleWithNextMajorDrupal($composer_json->require->{'drupal/core'})) {
$result['data']['files'][$extension->getPath() . '/composer.json']['messages'][] = [
'message' => "The drupal/core requirement is not Drupal 9 compatible. Either remove it or update it to be compatible with Drupal 9. See https://drupal.org/node/2514612#s-drupal-9-compatibility.",
'message' => "The drupal/core requirement is not compatible with the next major version of Drupal. Either remove it or update it to be compatible. See https://drupal.org/node/2514612#s-drupal-9-compatibility.",
'line' => 0,
];
$result['data']['totals']['errors']++;
......@@ -440,8 +440,8 @@ final class DeprecationAnalyzer {
// Sum up the error based on the category it ended up in. Split the
// categories into two high level buckets needing attention now or
// later for Drupal 9 compatibility. Issues in the 'ignore' category
// are intentionally not counted in either.
// later for compatibility with the next major version. Issues in the
// 'ignore' category are intentionally not counted in either.
@$result['data']['totals']['upgrade_status_category'][$category]++;
if (in_array($category, ['safe', 'old', 'rector'])) {
@$result['data']['totals']['upgrade_status_split']['error']++;
......@@ -452,7 +452,7 @@ final class DeprecationAnalyzer {
}
}
// For contributed projects, attempt to grab Drupal 9 plan information.
// For contributed projects, attempt to grab upgrade plan information.
if (!empty($extension->info['project'])) {
try {
/** @var \Psr\Http\Message\ResponseInterface $response */
......
......@@ -95,6 +95,13 @@ class UpgradeStatusForm extends FormBase {
*/
protected $destination;
/**
* The next Drupal core major version.
*
* @var int
*/
protected $nextMajor;
/**
* {@inheritdoc}
*/
......@@ -159,6 +166,7 @@ class UpgradeStatusForm extends FormBase {
$this->state = $state;
$this->dateFormatter = $date_formatter;
$this->destination = $destination;
$this->nextMajor = ProjectCollector::getDrupalCoreMajorVersion() + 1;
}
/**
......@@ -193,12 +201,14 @@ class UpgradeStatusForm extends FormBase {
$environment = $this->buildEnvironmentChecks();
$form['summary'] = $this->buildResultSummary($environment['status']);
$environment_description = $environment['description'];
unset($environment['status']);
unset($environment['description']);
$form['environment'] = [
'#type' => 'details',
'#title' => $this->t('Drupal core and hosting environment'),
'#description' => $this->t('<a href=":upgrade">Upgrades to Drupal 9 are supported from Drupal 8.8.x and Drupal 8.9.x</a>. It is suggested to update to the latest Drupal 8 version available. <a href=":platform">Several hosting platform requirements have been raised for Drupal 9</a>.', [':upgrade' => 'https://www.drupal.org/docs/9/how-to-prepare-your-drupal-7-or-8-site-for-drupal-9/upgrading-a-drupal-8-site-to-drupal-9', ':platform' => 'https://www.drupal.org/docs/9/how-drupal-9-is-made-and-what-is-included/environment-requirements-of-drupal-9']),
'#description' => $environment_description,
'#open' => TRUE,
'#attributes' => ['class' => ['upgrade-status-summary-environment']],
'data' => $environment,
......@@ -270,10 +280,10 @@ class UpgradeStatusForm extends FormBase {
'type' => ['data' => $this->t('Type'), 'class' => 'type-label'],
'status' => ['data' => $this->t('Status'), 'class' => 'status-label'],
'version' => ['data' => $this->t('Local version'), 'class' => 'version-label'],
'ready' => ['data' => $this->t('Local 9-ready'), 'class' => 'ready-label'],
'ready' => ['data' => $this->t('Local ' . $this->nextMajor . '-ready'), 'class' => 'ready-label'],
'result' => ['data' => $this->t('Local scan result'), 'class' => 'scan-info'],
'updatev' => ['data' => $this->t('Drupal.org version'), 'class' => 'updatev-info'],
'update9' => ['data' => $this->t('Drupal.org 9-ready'), 'class' => 'update9-info'],
'update9' => ['data' => $this->t('Drupal.org ' . $this->nextMajor . '-ready'), 'class' => 'update9-info'],
'issues' => ['data' => $this->t('Drupal.org issues'), 'class' => 'issue-info'],
'plan' => ['data' => $this->t('Plan'), 'class' => 'plan-info'],
];
......@@ -327,11 +337,11 @@ class UpgradeStatusForm extends FormBase {
]
];
$option['ready'] = [
'class' => 'status-info ' . (!empty($extension->info['upgrade_status_9_compatible']) ? 'status-info-compatible' : 'status-info-incompatible'),
'class' => 'status-info ' . (!empty($extension->info['upgrade_status_next_major_compatible']) ? 'status-info-compatible' : 'status-info-incompatible'),
'data' => [
'label' => [
'#type' => 'markup',
'#markup' => !empty($extension->info['upgrade_status_9_compatible']) ? $this->t('Compatible') : $this->t('Incompatible'),
'#markup' => !empty($extension->info['upgrade_status_next_major_compatible']) ? $this->t('Compatible') : $this->t('Incompatible'),
],
]
];
......@@ -458,7 +468,7 @@ class UpgradeStatusForm extends FormBase {
'#type' => 'markup',
// Use the project name from the info array instead of $key.
// $key is the local name, not necessarily the project name.
'#markup' => '<a href="https://drupal.org/project/issues/' . $extension->info['project'] . '?text=Drupal+9&status=All">' . $this->t('Issues', [], ['context' => 'Drupal.org issues']) . '</a>',
'#markup' => '<a href="https://drupal.org/project/issues/' . $extension->info['project'] . '?text=Drupal+' . $this->nextMajor . '&status=All">' . $this->t('Issues', [], ['context' => 'Drupal.org issues']) . '</a>',
],
]
];
......@@ -481,8 +491,9 @@ class UpgradeStatusForm extends FormBase {
/**
* Build a result summary table for quick overview display to users.
*
* @param bool $environment_status
* The status of the environment. Whether to put it into the Fix or Relax columns.
* @param bool|null $environment_status
* The status of the environment. Whether to put it into the Fix or Relax
* columns or omit it.
*
* @return array
* Render array.
......@@ -552,7 +563,7 @@ class UpgradeStatusForm extends FormBase {
// Add available update info.
$cell_items[] = $update_time;
}
if (($key == ProjectCollector::SUMMARY_ACT) && !$environment_status) {
if (($key == ProjectCollector::SUMMARY_ACT) && !is_null($environment_status) && !$environment_status) {
$cell_items[] = [
'#markup' => '<a href="#edit-environment" class="upgrade-status-summary-label">' . $this->t('Environment is incompatible') . '</a>',
];
......@@ -598,14 +609,11 @@ class UpgradeStatusForm extends FormBase {
</div>
MARKUP
];
if ($environment_status) {
if (!empty($environment_status)) {
$cell_items[] = [
'#markup' => '<a href="#edit-environment" class="upgrade-status-summary-label">' . $this->t('Environment checks passed') . '</a>',
];
}
$cell_items[] = [
'#markup' => 'Once entirely compatible, make sure to remove Upgrade Status from the site before updating to Drupal 9',
];
}
if (count($cell_items)) {
$build['#rows'][0]['data'][$key]['data'][] = [
......@@ -627,10 +635,19 @@ MARKUP
* Builds a list of environment checks.
*
* @return array
* Build array. The overall environment status (TRUE or FALSE) is indicated
* in the 'status' key.
* Build array. The overall environment status (TRUE, FALSE or NULL) is
* indicated in the 'status' key, while a 'description' key explains the
* environment requirements on a high level.
*/
protected function buildEnvironmentChecks() {
if ($this->nextMajor == 10) {
// @todo update this as the situation develops.
return [
'status' => NULL,
'description' => $this->t('<a href=":environment">Drupal 10 environment requirements are still to be defined. Expect a minimum requirement of PHP 8.</a> Unfortunately the <a href=":support">dependencies of Upgrade Status do not yet support PHP 8, support is needed</a>.', [':support' => 'https://mglaman.dev/blog/drupal-check-and-phpstan-drupal-indefinite-development-hiatus', ':environment' => 'https://www.drupal.org/project/drupal/issues/3118147']),
];
}
$status = TRUE;
$header = [
'requirement' => ['data' => $this->t('Requirement'), 'class' => 'requirement-label'],
......@@ -641,6 +658,7 @@ MARKUP
'#header' => $header,
'#rows' => [],
];
$build['description'] = $this->t('<a href=":upgrade">Upgrades to Drupal 9 are supported from Drupal 8.8.x and Drupal 8.9.x</a>. It is suggested to update to the latest Drupal 8 version available. <a href=":platform">Several hosting platform requirements have been raised for Drupal 9</a>.', [':upgrade' => 'https://www.drupal.org/docs/9/how-to-prepare-your-drupal-7-or-8-site-for-drupal-9/upgrading-a-drupal-8-site-to-drupal-9', ':platform' => 'https://www.drupal.org/docs/9/how-drupal-9-is-made-and-what-is-included/environment-requirements-of-drupal-9']);
// Check Drupal version. Link to update if available.
$core_version_info = [
......
......@@ -206,12 +206,12 @@ class ProjectCollector {
// If the existing project was already Drupal 9 compatible, consider
// this subcomponent as well. If this component was enabled, it would
// affect how we consider the Drupal 9 compatibility.
if (!empty($projects[$project]->info['upgrade_status_9_compatible']) && !empty($extension->status)) {
if (!empty($projects[$project]->info['upgrade_status_next_major_compatible']) && !empty($extension->status)) {
// Overwrite compatibility. If this is still compatible, it will
// keep being TRUE, otherwise FALSE.
$projects[$project]->info['upgrade_status_9_compatible'] =
$projects[$project]->info['upgrade_status_next_major_compatible'] =
isset($extension->info['core_version_requirement']) &&
self::isDrupal9CompatibleConstraint($extension->info['core_version_requirement']);
self::isCompatibleWithNextMajorDrupal($extension->info['core_version_requirement']);
}
continue;
}
......@@ -251,9 +251,9 @@ class ProjectCollector {
// extension information elsewhere.
$extdata = clone $extension;
$extdata->info['upgrade_status_type'] = $type;
$extdata->info['upgrade_status_9_compatible'] =
$extdata->info['upgrade_status_next_major_compatible'] =
isset($extdata->info['core_version_requirement']) &&
self::isDrupal9CompatibleConstraint($extdata->info['core_version_requirement']);
self::isCompatibleWithNextMajorDrupal($extdata->info['core_version_requirement']);
// Save this as a possible project to consider.
$projects[$key] = $extdata;
......@@ -282,7 +282,7 @@ class ProjectCollector {
// Add Drupal 9 compatibility info from the update's data.
$latest_release = reset($project_update['releases']);
$projects[$name]->info['upgrade_status_update_compatible'] = FALSE;
if (!empty($latest_release['core_compatibility']) && self::isDrupal9CompatibleConstraint($latest_release['core_compatibility'])) {
if (!empty($latest_release['core_compatibility']) && self::isCompatibleWithNextMajorDrupal($latest_release['core_compatibility'])) {
$projects[$name]->info['upgrade_status_update_compatible'] = TRUE;
}
// Denormalize update info into the extension info for our own use.
......@@ -303,7 +303,7 @@ class ProjectCollector {
$scan_result = $this->getResults($name);
// Pick a suggested next step for this project.
if ($extension->info['upgrade_status_9_compatible'] && $extension->info['upgrade_status_type'] == self::TYPE_CONTRIB) {
if ($extension->info['upgrade_status_next_major_compatible'] && $extension->info['upgrade_status_type'] == self::TYPE_CONTRIB) {
// If the project was contrib and already Drupal 9 compatible, relax.
$extension->info['upgrade_status_next'] = self::NEXT_RELAX;
}
......@@ -364,12 +364,12 @@ class ProjectCollector {
// If the existing project was already Drupal 9 compatible, consider
// this subcomponent as well. If this component was enabled, it would
// affect how we consider the Drupal 9 compatibility.
if (!empty($extensions[$name_a]->info['upgrade_status_9_compatible']) && !empty($extension_b->status)) {
if (!empty($extensions[$name_a]->info['upgrade_status_next_major_compatible']) && !empty($extension_b->status)) {
// Overwrite compatibility. If this is still compatible, it will
// keep being TRUE, otherwise FALSE.
$extensions[$name_a]->info['upgrade_status_9_compatible'] =
$extensions[$name_a]->info['upgrade_status_next_major_compatible'] =
isset($extension_b->info['core_version_requirement']) &&
self::isDrupal9CompatibleConstraint($extension_b->info['core_version_requirement']);
self::isCompatibleWithNextMajorDrupal($extension_b->info['core_version_requirement']);
}
// Remove the subextension.
......@@ -462,7 +462,7 @@ class ProjectCollector {
],
ProjectCollector::NEXT_UPDATE => [
$this->t('Update'),
$this->t('There is an update available. Even if that is not fully Drupal 9 compatible, it may be more compatible than what you have, so best to start with updating first.'),
$this->t('There is an update available. Even if that is not fully compatible with the next major Drupal core, it may be more compatible than what you have, so best to start with updating first.'),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_SCAN => [
......@@ -472,7 +472,7 @@ class ProjectCollector {
],
ProjectCollector::NEXT_COLLABORATE => [
$this->t('Collaborate with maintainers'),
$this->t('There are likely Drupal.org issues by contributors or even <a href=":drupal-bot">the Project Update Bot</a>. Work with the maintainer to get them committed, provide feedback if they worked.', [':drupal-bot' => 'https://www.drupal.org/u/project-update-bot']),
$this->t('There may be Drupal.org issues by contributors or even <a href=":drupal-bot">the Project Update Bot</a>. Work with the maintainer to get them committed, provide feedback if they worked.', [':drupal-bot' => 'https://www.drupal.org/u/project-update-bot']),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_RECTOR => [
......@@ -486,7 +486,7 @@ class ProjectCollector {
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_RELAX => [
$this->t('Drupal 9 compatible'),
$this->t('Compatible with next major Drupal core version'),
$this->t('Well done. Congrats! Let\'s get everything else here!'),
ProjectCollector::SUMMARY_RELAX,
],
......@@ -494,7 +494,7 @@ class ProjectCollector {
}
/**
* Checks whether the given constraints are Drupal 9 compatible.
* Checks constraint compatibility with the next major Drupal core version.
*
* A customized version of Semver::satisfies(), since that only works for
* a == condition.
......@@ -505,9 +505,9 @@ class ProjectCollector {
*
* @return bool
*/
public static function isDrupal9CompatibleConstraint(string $constraints) {
public static function isCompatibleWithNextMajorDrupal(string $constraints) {
$version_parser = new VersionParser();
$provider = new Constraint('>=', $version_parser->normalize('9.0.0'));
$provider = new Constraint('>=', $version_parser->normalize((self::getDrupalCoreMajorVersion() + 1) . '.0.0'));
$parsed_constraints = $version_parser->parseConstraints($constraints);
return $parsed_constraints->matches($provider);
}
......@@ -526,6 +526,7 @@ class ProjectCollector {
case 9:
return '9.0';
}
return '';
}
/**
......
name: 'Upgrade status test 10 compatible'
type: module
description: 'Support module for upgrade status module testing.'
package: Testing
version: VERSION
core_version_requirement: ^8 || ^9 || ^10
name: 'Upgrade status test no error'
name: 'Upgrade status test 9 compatible'
type: module
description: 'Support module for upgrade status module testing.'
package: Testing
......
name: 'Upgrade status test contrib no error'
name: 'Upgrade status test contrib 9 compatible'
type: module
description: 'Support module for upgrade status module testing.'
package: Testing
......@@ -6,4 +6,5 @@ version: VERSION
# Intentionally using a requirement that is slightly more specific to
# test handling of this case.
core_version_requirement: ^8 || ^9.1
project: 'upgrade_status_test_contributed_no_error'
# Project name intentionally different from module name for testing.
project: 'upgrade_status_test_contributed_9_compatible'
......@@ -18,11 +18,12 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
// Check if the project has scan result in the keyValueStorage.
$this->assertTrue($key_value->has('upgrade_status_test_error'));
$this->assertTrue($key_value->has('upgrade_status_test_no_error'));
$this->assertTrue($key_value->has('upgrade_status_test_9_compatible'));
$this->assertTrue($key_value->has('upgrade_status_test_10_compatible'));
$this->assertTrue($key_value->has('upgrade_status_test_submodules'));
$this->assertTrue($key_value->has('upgrade_status_test_submodules_with_error'));
$this->assertTrue($key_value->has('upgrade_status_test_contrib_error'));
$this->assertTrue($key_value->has('upgrade_status_test_contrib_no_error'));
$this->assertTrue($key_value->has('upgrade_status_test_contrib_9_compatible'));
$this->assertTrue($key_value->has('upgrade_status_test_twig'));
$this->assertTrue($key_value->has('upgrade_status_test_theme'));
$this->assertTrue($key_value->has('upgrade_status_test_library'));
......@@ -57,7 +58,31 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$this->assertEquals("Add core_version_requirement: ^8 || ^9 to designate that the module is compatible with Drupal 9. See https://drupal.org/node/3070687.", $message['message']);
$this->assertEquals(0, $message['line']);
$report = $key_value->get('upgrade_status_test_no_error');
// The Drupal 9 compatible test modules are not Drupal 10 compatible.
$test_9_compatibles = [
'upgrade_status_test_9_compatible' => '^8 || ^9',
'upgrade_status_test_contrib_9_compatible' => '^8 || ^9.1',
];
foreach ($test_9_compatibles as $name => $version_requirement) {
$report = $key_value->get($name);
$this->assertNotEmpty($report);
if ($this->getDrupalCoreMajorVersion() < 9) {
$this->assertEquals(0, $report['data']['totals']['file_errors']);
$this->assertCount(0, $report['data']['files']);
}
else {
$this->assertEquals(1, $report['data']['totals']['file_errors']);
$this->assertCount(1, $report['data']['files']);
$file = reset($report['data']['files']);
$this->assertEquals($name . '.info.yml', basename(key($report['data']['files'])));
$message = $file['messages'][0];
$this->assertEquals("Value of core_version_requirement: $version_requirement is not compatible with the next major version of Drupal core. See https://drupal.org/node/3070687.", $message['message']);
$this->assertEquals(0, $message['line']);
}
}
// The Drupal 10 compatible test module is also Drupal 9 compatible.
$report = $key_value->get('upgrade_status_test_10_compatible');
$this->assertNotEmpty($report);
$this->assertEquals(0, $report['data']['totals']['file_errors']);
$this->assertCount(0, $report['data']['files']);
......@@ -67,6 +92,7 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$this->assertEquals(5, $report['data']['totals']['file_errors']);
$this->assertCount(2, $report['data']['files']);
$file = reset($report['data']['files']);
$this->assertEquals('UpgradeStatusTestContribErrorController.php', basename(key($report['data']['files'])));
$message = $file['messages'][0];
$this->assertEquals("Call to deprecated function upgrade_status_test_contrib_error_function_8_to_9(). Deprecated in drupal:8.6.0 and is removed from drupal:9.0.0. Use the replacement instead.", $message['message']);
$this->assertEquals(13, $message['line']);
......@@ -83,11 +109,20 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$this->assertEquals("Call to deprecated function upgrade_status_test_contrib_error_function_9_to_11(). Deprecated in drupal:9.0.0 and is removed from drupal:11.0.0. Use the replacement instead.", $message['message']);
$this->assertEquals(16, $message['line']);
$this->assertEquals('ignore', $message['upgrade_status_category']);
$file = next($report['data']['files']);
$this->assertEquals('upgrade_status_test_contrib_error.info.yml', basename(key($report['data']['files'])));
$message = $file['messages'][0];
$this->assertEquals("Add core_version_requirement: ^8 || ^9 to designate that the module is compatible with Drupal 9. See https://drupal.org/node/3070687.", $message['message']);
$this->assertEquals(0, $message['line']);
$this->assertEquals('uncategorized', $message['upgrade_status_category']);
// On at least Drupal 9, these modules will not be ready for the next major.
$base_info_error = (int) ($this->getDrupalCoreMajorVersion() >= 9);
$report = $key_value->get('upgrade_status_test_twig');
$this->assertNotEmpty($report);
$this->assertEquals(3, $report['data']['totals']['file_errors']);
$this->assertCount(1, $report['data']['files']);
$this->assertEquals(3 + $base_info_error, $report['data']['totals']['file_errors']);
$this->assertCount(1 + $base_info_error, $report['data']['files']);
$file = reset($report['data']['files']);
$this->assertEquals('Twig Filter "deprecatedfilter" is deprecated. See https://drupal.org/node/3071078.', $file['messages'][0]['message']);
$this->assertEquals(10, $file['messages'][0]['line']);
......@@ -98,8 +133,8 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$report = $key_value->get('upgrade_status_test_theme');
$this->assertNotEmpty($report);
$this->assertEquals(5, $report['data']['totals']['file_errors']);
$this->assertCount(3, $report['data']['files']);
$this->assertEquals(5 + $base_info_error, $report['data']['totals']['file_errors']);
$this->assertCount(3 + $base_info_error, $report['data']['files']);
$file = reset($report['data']['files']);
foreach ([0 => 2, 1 => 4] as $index => $line) {
$message = $file['messages'][$index];
......@@ -117,8 +152,8 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$report = $key_value->get('upgrade_status_test_theme_functions');
$this->assertNotEmpty($report);
$this->assertEquals(3, $report['data']['totals']['file_errors']);
$this->assertCount(1, $report['data']['files']);
$this->assertEquals(3 + $base_info_error, $report['data']['totals']['file_errors']);
$this->assertCount(1 + $base_info_error, $report['data']['files']);
$file = reset($report['data']['files']);
$this->assertEquals('The module is defining "upgrade_status_test_theme_function" theme function. Theme functions are deprecated. For more info, see https://www.drupal.org/node/2575445.', $file['messages'][0]['message']);
$this->assertEquals(9, $file['messages'][0]['line']);
......@@ -129,8 +164,8 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$report = $key_value->get('upgrade_status_test_library');
$this->assertNotEmpty($report);
$this->assertEquals(4, $report['data']['totals']['file_errors']);
$this->assertCount(2, $report['data']['files']);
$this->assertEquals(4 + $base_info_error, $report['data']['totals']['file_errors']);
$this->assertCount(2 + $base_info_error, $report['data']['files']);
$file = reset($report['data']['files']);
$this->assertEquals("The 'library' library is depending on a deprecated library. The \"upgrade_status_test_library/deprecated_library\" asset library is deprecated for testing.", $file['messages'][0]['message']);
$this->assertEquals(0, $file['messages'][0]['line']);
......@@ -144,8 +179,8 @@ class UpgradeStatusAnalyzeTest extends UpgradeStatusTestBase {
$report = $key_value->get('upgrade_status_test_library_exception');
$this->assertNotEmpty($report);
$this->assertEquals(1, $report['data']['totals']['file_errors']);
$this->assertCount(1, $report['data']['files']);
$this->assertEquals(1 + $base_info_error, $report['data']['totals']['file_errors']);
$this->assertCount(1 + $base_info_error, $report['data']['files']);
$file = reset($report['data']['files']);
$this->assertEquals("Incomplete library definition for definition 'library_exception' in extension 'upgrade_status_test_library_exception'", $file['messages'][0]['message']);
......
......@@ -20,11 +20,12 @@ abstract class UpgradeStatusTestBase extends BrowserTestBase {
protected static $modules = [
'upgrade_status',
'upgrade_status_test_error',
'upgrade_status_test_no_error',
'upgrade_status_test_9_compatible',
'upgrade_status_test_10_compatible',
'upgrade_status_test_submodules_a',
'upgrade_status_test_submodules_with_error',
'upgrade_status_test_contrib_error',
'upgrade_status_test_contrib_no_error',
'upgrade_status_test_contrib_9_compatible',
'upgrade_status_test_theme_functions',
'upgrade_status_test_twig',
'upgrade_status_test_library',
......@@ -46,7 +47,8 @@ abstract class UpgradeStatusTestBase extends BrowserTestBase {
protected function runFullScan() {
$edit = [
'scan[data][list][upgrade_status_test_error]' => TRUE,
'scan[data][list][upgrade_status_test_no_error]' => TRUE,
'scan[data][list][upgrade_status_test_9_compatible]' => TRUE,
'scan[data][list][upgrade_status_test_10_compatible]' => TRUE,
'scan[data][list][upgrade_status_test_submodules]' => TRUE,
'scan[data][list][upgrade_status_test_submodules_with_error]' => TRUE,
'scan[data][list][upgrade_status_test_twig]' => TRUE,
......@@ -54,12 +56,9 @@ abstract class UpgradeStatusTestBase extends BrowserTestBase {
'scan[data][list][upgrade_status_test_theme_functions]' => TRUE,
'scan[data][list][upgrade_status_test_library]' => TRUE,
'scan[data][list][upgrade_status_test_library_exception]' => TRUE,
// Due to the automated core compatibility assignment of test modules,
// the category of this module may be different based on major Drupal
// version.
($this->getDrupalCoreMajorVersion() < 9 ? 'collaborate' : 'relax') . '[data][list][upgrade_status_test_contrib_error]' => TRUE,
'relax[data][list][upgrade_status]' => TRUE,
'relax[data][list][upgrade_status_test_contrib_no_error]' => TRUE,
'collaborate[data][list][upgrade_status_test_contrib_error]' => TRUE,
($this->getDrupalCoreMajorVersion() < 9 ? 'relax' : 'collaborate') . '[data][list][upgrade_status]' => TRUE,
($this->getDrupalCoreMajorVersion() < 9 ? 'relax' : 'collaborate') . '[data][list][upgrade_status_test_contrib_9_compatible]' => TRUE,
];
$this->drupalPostForm('admin/reports/upgrade-status', $edit, 'Scan selected');
}
......
......@@ -51,17 +51,19 @@ class UpgradeStatusUiTest extends UpgradeStatusTestBase {
// Error and no-error test module results should show.
$this->assertSame('4 problems', strip_tags($page->find('css', 'tr.project-upgrade_status_test_error td.scan-result')->getHtml()));
$this->assertSame('No problems found', strip_tags($page->find('css', 'tr.project-upgrade_status_test_no_error td.scan-result')->getHtml()));
$this->assertSame($this->getDrupalCoreMajorVersion() < 9 ? 'No problems found' : '1 problem', strip_tags($page->find('css', 'tr.project-upgrade_status_test_9_compatible td.scan-result')->getHtml()));
$this->assertSame('No problems found', strip_tags($page->find('css', 'tr.project-upgrade_status_test_10_compatible td.scan-result')->getHtml()));
// Parent module should show up without errors and submodule should not appear.
$this->assertSame('No problems found', strip_tags($page->find('css', 'tr.project-upgrade_status_test_submodules td.scan-result')->getHtml()));
$this->assertSame($this->getDrupalCoreMajorVersion() < 9 ? 'No problems found' : '2 problems', strip_tags($page->find('css', 'tr.project-upgrade_status_test_submodules td.scan-result')->getHtml()));
$this->assertEmpty($page->find('css', 'tr.upgrade_status_test_submodules_a'));
// Contrib test modules should show with results.
$this->assertSame('5 problems', strip_tags($page->find('css', 'tr.project-upgrade_status_test_contrib_error td.scan-result')->getHtml()));
$this->assertSame('No problems found', strip_tags($page->find('css', 'tr.project-upgrade_status_test_contrib_no_error td.scan-result')->getHtml()));
$this->assertSame($this->getDrupalCoreMajorVersion() < 9 ? 'No problems found' : '1 problem', strip_tags($page->find('css', 'tr.project-upgrade_status_test_contrib_9_compatible td.scan-result')->getHtml()));
// This contrib module has a different project name. Ensure the drupal.org link used that.
$this->assertSession()->linkByHrefExists('https://drupal.org/project/issues/upgrade_status_test_contributed_no_error?text=Drupal+9&status=All');
$next_major = $this->getDrupalCoreMajorVersion() + 1;
$this->assertSession()->linkByHrefExists('https://drupal.org/project/issues/upgrade_status_test_contributed_9_compatible?text=Drupal+' . $next_major . '&status=All');
// Click the first '4 problems' link. Should be the custom project.
$this->clickLink('4 problems');
......@@ -92,11 +94,8 @@ class UpgradeStatusUiTest extends UpgradeStatusTestBase {
// Run partial export of multiple projects.
$edit = [
'manual[data][list][upgrade_status_test_error]' => TRUE,
'relax[data][list][upgrade_status_test_no_error]' => TRUE,
// Due to the automated core compatibility assignment of test modules,
// the category of this module may be different based on major Drupal
// version.
($this->getDrupalCoreMajorVersion() < 9 ? 'collaborate' : 'relax') . '[data][list][upgrade_status_test_contrib_error]' => TRUE,
($this->getDrupalCoreMajorVersion() < 9 ? 'relax' : 'manual') . '[data][list][upgrade_status_test_9_compatible]' => TRUE,
'collaborate[data][list][upgrade_status_test_contrib_error]' => TRUE,
];
$expected = [
'Export selected as HTML' => ['Contributed projects', 'Custom projects'],
......@@ -107,10 +106,10 @@ class UpgradeStatusUiTest extends UpgradeStatusTestBase {
$this->assertText($assert[0]);
$this->assertText($assert[1]);
$this->assertText('Upgrade status test contrib error ' . \Drupal::VERSION);
$this->assertText('Upgrade status test no error ' . \Drupal::VERSION);
$this->assertText('Upgrade status test 9 compatible ' . \Drupal::VERSION);
$this->assertText('Upgrade status test error ' . \Drupal::VERSION);
$this->assertNoText('Upgrade status test root module');
$this->assertNoText('Upgrade status test contrib no error');
$this->assertNoText('Upgrade status test contrib 9 compatbile');
$this->assertText('2 errors found. 2 warnings found.');
$this->assertText('Syntax error, unexpected T_STRING on line 3');
}
......
upgrade_status.report:
title: 'Upgrade status'
description: 'Review current status of known Drupal 9 incompatibilities on the site.'
description: 'Review Drupal major upgrade readiness of the environment and components of the site.'
route_name: upgrade_status.report
parent: system.admin_reports
......@@ -8,7 +8,13 @@ use Drupal\Core\Extension\Extension;
*/
function upgrade_status_help($route_name, RouteMatchInterface $route_match) {
if ($route_name == 'upgrade_status.report') {
return '<p>' . t('Analyze your site\'s Drupal 9 readiness. Run the report to find out if there are detectable compatibility errors with the modules and themes installed on your site. <a href=":prepare">Read more about preparing your site for Drupal 9</a>.', [':prepare' => 'https://www.drupal.org/docs/9/how-to-prepare-your-drupal-7-or-8-site-for-drupal-9/prepare-a-drupal-8-site-for-drupal-9']) . '</p>';
$help = '<p>' . t('Analyze your site\'s readiness for the next major Drupal version. Run the report to find out if there are detectable compatibility errors with the modules and themes installed on your site.');
// @todo Link to a relevant page for the Drupal 9 to 10 process when available.
if ((int) \Drupal::VERSION < 9) {
$help .= t('<a href=":prepare">Read more about preparing your site for Drupal 9</a>.', [':prepare' => 'https://www.drupal.org/docs/9/how-to-prepare-your-drupal-7-or-8-site-for-drupal-9/prepare-a-drupal-8-site-for-drupal-9']);
}
$help .= '</p>';
return $help;
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment