Commit 9713a825 authored by tatarbj's avatar tatarbj Committed by heddn
Browse files

Issue #3063131 by heddn, tatarbj: Backport MissingProjectInfo

parent 36f2c34b
<?php
/**
* Missing project info checker.
*/
class MissingProjectInfo implements ReadinessCheckerInterface {
/**
* {@inheritdoc}
*/
public static function run() {
return static::missingProjectInfoCheck();
}
/**
* Check for projects missing project info.
*
* @return array
* An array of translatable strings if any checks fail.
*/
protected static function missingProjectInfoCheck() {
$messages = [];
foreach (static::getInfos() as $extension_name => $info) {
if (static::isIgnoredPath($info['extension_uri'])) {
continue;
}
if (!static::getExtensionVersion($extension_name, $info)) {
$messages[] = t('The project "@extension" can not be updated because its version is either undefined or a dev release.', ['@extension' => $extension_name]);
}
}
return $messages;
}
/**
* Get the extension types.
*
* @return array
* The extension types.
*/
protected static function getExtensionsTypes() {
return ['modules', 'profiles', 'themes'];
}
/**
* Returns an array of info files information of available extensions.
*
* @return array
* An associative array of extension information arrays, keyed by extension
* name.
*/
protected static function getInfos() {
$infos = [];
// Find extensions.
$extensions = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'modules', $key = 'name', $min_depth = 1);
$extensions = array_merge($extensions, drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'themes', $key = 'name', $min_depth = 1));
foreach ($extensions as $extension) {
if (file_exists($info_file = dirname($extension->uri) . '/' . $extension->name . '.info')) {
// Get the .info file for the module or theme this file belongs to.
$infos[$extension->name] = drupal_parse_info_file($info_file);
$infos[$extension->name]['extension_uri'] = $extension->uri;
}
}
return $infos;
}
/**
* Get the extension version.
*
* @param string $extension_name
* The extension name.
* @param array $info
* The extension's info.
*
* @return string|null
* The version or NULL if undefined.
*/
protected static function getExtensionVersion($extension_name, array $info) {
if (isset($info['version']) && strpos($info['version'], '-dev') === FALSE) {
return $info['version'];
}
}
/**
* Check if the file path is ignored.
*
* @param string $file_path
* The file path.
*
* @return bool
* TRUE if file path is ignored, else FALSE.
*/
protected static function isIgnoredPath($file_path) {
$paths = variable_get('automatic_updates_ignored_paths', "sites/all/modules/custom/*\nsites/all/themes/custom/*");
if (drupal_match_path($file_path, $paths)) {
return TRUE;
}
}
}
......@@ -23,6 +23,7 @@ class ReadinessCheckerManager {
*/
protected static function getCheckers() {
static::$checkers['warning'][0][] = 'FileOwnership';
static::$checkers['warning'][0][] = 'MissingProjectInfo';
static::$checkers['warning'][0][] = 'ModifiedFiles';
static::$checkers['warning'][0][] = 'PhpSapi';
static::$checkers['error'][0][] = 'PhpSapi';
......
......@@ -33,7 +33,7 @@ function automatic_updates_admin_form() {
'#type' => 'textarea',
'#title' => t('Paths to ignore for readiness checks'),
'#description' => t('Paths relative to %drupal_root. One path per line.', ['%drupal_root' => DRUPAL_ROOT]),
'#default_value' => variable_get('automatic_updates_ignored_paths', "modules/custom/*\nthemes/custom/*\nprofiles/custom/*"),
'#default_value' => variable_get('automatic_updates_ignored_paths', "sites/all/modules/custom/*\nsites/all/themes/custom/*"),
'#states' => [
'visible' => [
':input[name="automatic_updates_enable_readiness_checks"]' => ['checked' => TRUE],
......
......@@ -10,6 +10,7 @@ files[] = ModifiedFilesService.php
files[] = ReadinessCheckers/ReadinessCheckerManager.php
files[] = ReadinessCheckers/ReadinessCheckerInterface.php
files[] = ReadinessCheckers/FileOwnership.php
files[] = ReadinessCheckers/MissingProjectInfo.php
files[] = ReadinessCheckers/ModifiedFiles.php
files[] = ReadinessCheckers/PhpSapi.php
files[] = ReadinessCheckers/ReadOnlyFilesystem.php
......@@ -55,10 +55,9 @@ function _automatic_updates_checker_requirements(array &$requirements) {
if (!empty($checker_results)) {
$requirements['automatic_updates_readiness']['severity'] = $error_results ? REQUIREMENT_ERROR : REQUIREMENT_WARNING;
$requirements['automatic_updates_readiness']['value'] = format_plural(count($checker_results), '@count check failed:', '@count checks failed:');
$requirements['automatic_updates_readiness']['description'] = [
'#theme' => 'item_list',
'#items' => $checker_results,
];
$requirements['automatic_updates_readiness']['description'] = theme('item_list', array(
'items' => $checker_results,
));
}
if (REQUEST_TIME > $last_check_timestamp + 3600 * 24) {
$requirements['automatic_updates_readiness']['severity'] = REQUIREMENT_ERROR;
......
......@@ -78,11 +78,15 @@ class AutomaticUpdatesTestCase extends DrupalWebTestCase {
public function testReadinessChecks() {
// Fabricate a readiness issue.
$this->drupalGet($this->getAbsoluteUrl('admin/config/system/automatic_updates'));
variable_set('automatic_updates.php_sapi', 'foo');
$this->clickLink('run the readiness checks');
$this->assertText('Your site does not pass some readiness checks for automatic updates. Depending on the nature of the failures, it might effect the eligibility for automatic updates.');
$this->assertText('PHP changed from running as');
$this->assertText('This can lead to inconsistent and misleading results.');
$this->assertText('The project "drupal_autoload_test" can not be updated because its version is either undefined or a dev release');
// Ignore certain folders for readiness checks.
variable_set('automatic_updates_ignored_paths', "sites/all/modules/custom/*\nsites/all/themes/custom/*");
$this->drupalGet($this->getAbsoluteUrl('admin/config/system/automatic_updates'));
$this->clickLink('run the readiness checks');
$this->assertText('No issues found. Your site is completely ready for automatic updates.');
}
}
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