Skip to content
Snippets Groups Projects
Commit e375b0fe authored by Lucas Hedding's avatar Lucas Hedding Committed by Lucas Hedding
Browse files

Issue #3054006 by heddn, eiriksm, catch: Add method to ignore certain paths...

Issue #3054006 by heddn, eiriksm, catch: Add method to ignore certain paths (custom modules, themes, etc) for the modified code checker
parent f1f29b26
No related branches found
No related tags found
No related merge requests found
...@@ -7,3 +7,4 @@ notify: true ...@@ -7,3 +7,4 @@ notify: true
check_frequency: 43200 check_frequency: 43200
enable_readiness_checks: true enable_readiness_checks: true
download_uri: 'https://ftp.drupal.org/files/projects' download_uri: 'https://ftp.drupal.org/files/projects'
ignored_paths: "modules/custom/*\nthemes/custom/*\nprofiles/custom/*"
...@@ -20,3 +20,6 @@ automatic_updates.settings: ...@@ -20,3 +20,6 @@ automatic_updates.settings:
download_uri: download_uri:
type: string type: string
label: 'Endpoint URI for file hashes and quasi patch files' label: 'Endpoint URI for file hashes and quasi patch files'
ignored_paths:
type: string
label: 'List of files paths to ignore when running readiness checks'
...@@ -25,6 +25,13 @@ class SettingsForm extends ConfigFormBase { ...@@ -25,6 +25,13 @@ class SettingsForm extends ConfigFormBase {
*/ */
protected $dateFormatter; protected $dateFormatter;
/**
* Drupal root path.
*
* @var string
*/
protected $drupalRoot;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -32,6 +39,9 @@ class SettingsForm extends ConfigFormBase { ...@@ -32,6 +39,9 @@ class SettingsForm extends ConfigFormBase {
$instance = parent::create($container); $instance = parent::create($container);
$instance->checker = $container->get('automatic_updates.readiness_checker'); $instance->checker = $container->get('automatic_updates.readiness_checker');
$instance->dateFormatter = $container->get('date.formatter'); $instance->dateFormatter = $container->get('date.formatter');
$drupal_finder = $container->get('automatic_updates.drupal_finder');
$drupal_finder->locateRoot(getcwd());
$instance->drupalRoot = $drupal_finder->getDrupalRoot();
return $instance; return $instance;
} }
...@@ -82,6 +92,17 @@ class SettingsForm extends ConfigFormBase { ...@@ -82,6 +92,17 @@ class SettingsForm extends ConfigFormBase {
'@link' => Url::fromRoute('automatic_updates.update_readiness')->toString(), '@link' => Url::fromRoute('automatic_updates.update_readiness')->toString(),
]); ]);
} }
$form['ignored_paths'] = [
'#type' => 'textarea',
'#title' => $this->t('Paths to ignore for readiness checks'),
'#description' => $this->t('Paths relative to %drupal_root. One path per line.', ['%drupal_root' => $this->drupalRoot]),
'#default_value' => $config->get('ignored_paths'),
'#states' => [
'visible' => [
':input[name="enable_readiness_checks"]' => ['checked' => TRUE],
],
],
];
return parent::buildForm($form, $form_state); return parent::buildForm($form, $form_state);
} }
......
<?php
namespace Drupal\automatic_updates;
/**
* Provide a helper to check if file paths are ignored.
*/
trait IgnoredPathsTrait {
/**
* 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 function isIgnoredPath($file_path) {
$paths = $this->getConfigFactory()->get('automatic_updates.settings')->get('ignored_paths');
if ($this->getPathMatcher()->matchPath($file_path, $paths)) {
return TRUE;
}
}
/**
* Gets the config factory.
*
* @return \Drupal\Core\Config\ConfigFactoryInterface
* The config factory.
*/
protected function getConfigFactory() {
if (isset($this->configFactory)) {
return $this->configFactory;
}
return \Drupal::configFactory();
}
/**
* Get the path matcher service.
*
* @return \Drupal\Core\Path\PathMatcherInterface
* The path matcher.
*/
protected function getPathMatcher() {
if (isset($this->pathMatcher)) {
return $this->pathMatcher;
}
return \Drupal::service('path.matcher');
}
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\automatic_updates\ReadinessChecker; namespace Drupal\automatic_updates\ReadinessChecker;
use Drupal\automatic_updates\IgnoredPathsTrait;
use Drupal\Core\Extension\ExtensionList; use Drupal\Core\Extension\ExtensionList;
use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\StringTranslationTrait;
use DrupalFinder\DrupalFinder; use DrupalFinder\DrupalFinder;
...@@ -10,6 +11,7 @@ use DrupalFinder\DrupalFinder; ...@@ -10,6 +11,7 @@ use DrupalFinder\DrupalFinder;
* Missing project info checker. * Missing project info checker.
*/ */
class MissingProjectInfo extends Filesystem { class MissingProjectInfo extends Filesystem {
use IgnoredPathsTrait;
use StringTranslationTrait; use StringTranslationTrait;
/** /**
...@@ -69,6 +71,9 @@ class MissingProjectInfo extends Filesystem { ...@@ -69,6 +71,9 @@ class MissingProjectInfo extends Filesystem {
$messages = []; $messages = [];
foreach ($this->getExtensionsTypes() as $extension_type) { foreach ($this->getExtensionsTypes() as $extension_type) {
foreach ($this->getInfos($extension_type) as $extension_name => $info) { foreach ($this->getInfos($extension_type) as $extension_name => $info) {
if ($this->isIgnoredPath(drupal_get_path($info['type'], $extension_name))) {
continue;
}
if (empty($info['version'])) { 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]); $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]);
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\automatic_updates\Services; namespace Drupal\automatic_updates\Services;
use Drupal\automatic_updates\IgnoredPathsTrait;
use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use DrupalFinder\DrupalFinder; use DrupalFinder\DrupalFinder;
...@@ -14,6 +15,7 @@ use Psr\Log\LoggerInterface; ...@@ -14,6 +15,7 @@ use Psr\Log\LoggerInterface;
* Modified files service. * Modified files service.
*/ */
class ModifiedFiles implements ModifiedFilesInterface { class ModifiedFiles implements ModifiedFilesInterface {
use IgnoredPathsTrait;
/** /**
* The logger. * The logger.
...@@ -100,6 +102,9 @@ class ModifiedFiles implements ModifiedFilesInterface { ...@@ -100,6 +102,9 @@ class ModifiedFiles implements ModifiedFilesInterface {
$this->logger->error('@hash or @file is empty; the hash file is malformed for this line.', ['@hash' => $hash, '@file' => $file]); $this->logger->error('@hash or @file is empty; the hash file is malformed for this line.', ['@hash' => $hash, '@file' => $file]);
continue; continue;
} }
if ($this->isIgnoredPath($file)) {
continue;
}
$file_path = $this->drupalFinder->getDrupalRoot() . DIRECTORY_SEPARATOR . $file; $file_path = $this->drupalFinder->getDrupalRoot() . DIRECTORY_SEPARATOR . $file;
if (!file_exists($file_path) || hash_file('sha512', $file_path) !== $hash) { if (!file_exists($file_path) || hash_file('sha512', $file_path) !== $hash) {
$modified_files[] = $file_path; $modified_files[] = $file_path;
......
...@@ -62,7 +62,7 @@ class AutomaticUpdatesTest extends BrowserTestBase { ...@@ -62,7 +62,7 @@ class AutomaticUpdatesTest extends BrowserTestBase {
$this->assertSession()->pageTextContains('3 urgent announcements require your attention:'); $this->assertSession()->pageTextContains('3 urgent announcements require your attention:');
// Test cache. // Test cache.
$end_point = 'http://localhost/automatic_updates/test-json-denied'; $end_point = $this->buildUrl(Url::fromRoute('test_automatic_updates.json_test_denied_controller'));
$this->config('automatic_updates.settings') $this->config('automatic_updates.settings')
->set('psa_endpoint', $end_point) ->set('psa_endpoint', $end_point)
->save(); ->save();
...@@ -72,7 +72,7 @@ class AutomaticUpdatesTest extends BrowserTestBase { ...@@ -72,7 +72,7 @@ class AutomaticUpdatesTest extends BrowserTestBase {
// Test transmit errors with JSON endpoint. // Test transmit errors with JSON endpoint.
drupal_flush_all_caches(); drupal_flush_all_caches();
$this->drupalGet(Url::fromRoute('system.admin')); $this->drupalGet(Url::fromRoute('system.admin'));
$this->assertSession()->pageTextContains('Drupal PSA endpoint http://localhost/automatic_updates/test-json-denied is unreachable.'); $this->assertSession()->pageTextContains("Drupal PSA endpoint $end_point is unreachable.");
// Test disabling PSAs. // Test disabling PSAs.
$end_point = $this->buildUrl(Url::fromRoute('test_automatic_updates.json_test_controller')); $end_point = $this->buildUrl(Url::fromRoute('test_automatic_updates.json_test_controller'));
...@@ -91,12 +91,17 @@ class AutomaticUpdatesTest extends BrowserTestBase { ...@@ -91,12 +91,17 @@ class AutomaticUpdatesTest extends BrowserTestBase {
* Tests manually running readiness checks. * Tests manually running readiness checks.
*/ */
public function testReadinessChecks() { public function testReadinessChecks() {
// Test manually running readiness checks. // Test manually running readiness checks. A few warnings will occur.
$url = $this->buildUrl('<front>') . '/automatic_updates';
$this->config('automatic_updates.settings')->set('download_uri', $url);
$this->drupalGet(Url::fromRoute('automatic_updates.settings')); $this->drupalGet(Url::fromRoute('automatic_updates.settings'));
$this->clickLink('run the readiness checks'); $this->clickLink('run the readiness checks');
$this->assertSession()->pageTextContains('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->assertSession()->pageTextContains('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.');
// Ignore specific file paths to see no readiness issues.
$this->config('automatic_updates.settings')->set('ignored_paths', "core/*\nmodules/*\nthemes/*\nprofiles/*")
->save();
$this->drupalGet(Url::fromRoute('automatic_updates.settings'));
$this->clickLink('run the readiness checks');
$this->assertSession()->pageTextContains('No issues found. Your site is completely ready for automatic updates.');
} }
} }
...@@ -21,6 +21,14 @@ class MissingProjectInfoTest extends KernelTestBase { ...@@ -21,6 +21,14 @@ class MissingProjectInfoTest extends KernelTestBase {
'automatic_updates', 'automatic_updates',
]; ];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installConfig(['automatic_updates']);
}
/** /**
* Tests pending db updates readiness checks. * Tests pending db updates readiness checks.
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment