From 648f8901f7be12170fc7a32167ee7c789f15d718 Mon Sep 17 00:00:00 2001 From: phenaproxima <phenaproxima@205645.no-reply.drupal.org> Date: Mon, 23 Aug 2021 19:20:46 +0000 Subject: [PATCH] Issue #3229485 by phenaproxima, tedbow: Clean up some exclusion code --- automatic_updates.services.yml | 2 +- src/Updater.php | 65 ++++++++++++++++------ tests/src/Functional/ExclusionsTest.php | 74 +++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 tests/src/Functional/ExclusionsTest.php diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index c5638b40d3..d1ab120bd3 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -4,7 +4,7 @@ services: arguments: ['@keyvalue.expirable', '@datetime.time', 24] automatic_updates.updater: class: Drupal\automatic_updates\Updater - arguments: ['@state', '@string_translation','@automatic_updates.beginner', '@automatic_updates.stager', '@automatic_updates.cleaner', '@automatic_updates.committer' , '@file_system', '@event_dispatcher'] + arguments: ['@state', '@string_translation','@automatic_updates.beginner', '@automatic_updates.stager', '@automatic_updates.cleaner', '@automatic_updates.committer' , '@file_system', '@event_dispatcher', '%app.root%', '%site.path%'] automatic_updates.staged_package_validator: class: Drupal\automatic_updates\Validation\StagedProjectsValidation arguments: ['@string_translation', '@automatic_updates.updater' ] diff --git a/src/Updater.php b/src/Updater.php index 7c2c351038..65f908bbdf 100644 --- a/src/Updater.php +++ b/src/Updater.php @@ -79,6 +79,20 @@ class Updater { */ protected $eventDispatcher; + /** + * The Drupal root. + * + * @var string + */ + protected $appRoot; + + /** + * The current site directory, relative to the Drupal root. + * + * @var string + */ + protected $sitePath; + /** * Constructs an Updater object. * @@ -98,8 +112,12 @@ class Updater { * The file system service. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher * The event dispatcher service. + * @param string $app_root + * The Drupal root. + * @param string $site_path + * The current site directory, relative to the Drupal root. */ - public function __construct(StateInterface $state, TranslationInterface $translation, BeginnerInterface $beginner, StagerInterface $stager, CleanerInterface $cleaner, CommitterInterface $committer, FileSystemInterface $file_system, EventDispatcherInterface $event_dispatcher) { + public function __construct(StateInterface $state, TranslationInterface $translation, BeginnerInterface $beginner, StagerInterface $stager, CleanerInterface $cleaner, CommitterInterface $committer, FileSystemInterface $file_system, EventDispatcherInterface $event_dispatcher, string $app_root, string $site_path) { $this->state = $state; $this->beginner = $beginner; $this->stager = $stager; @@ -108,6 +126,8 @@ class Updater { $this->setStringTranslation($translation); $this->fileSystem = $file_system; $this->eventDispatcher = $event_dispatcher; + $this->appRoot = $app_root; + $this->sitePath = $site_path; } /** @@ -171,34 +191,43 @@ class Updater { * Gets the paths that should be excluded from the staging area. * * @return string[] - * The paths relative to the active directory to exclude. + * The paths to exclude, relative to the active directory. */ - private function getExclusions(): array { + protected function getExclusions(): array { $exclusions = []; - $make_relative = function ($path) { - return str_replace(static::getActiveDirectory() . '/', '', $path); - }; if ($public = $this->fileSystem->realpath('public://')) { - $exclusions[] = $make_relative($public); + $exclusions[] = $public; } if ($private = $this->fileSystem->realpath('private://')) { - $exclusions[] = $make_relative($private); + $exclusions[] = $private; } - /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ - $module_handler = \Drupal::service('module_handler'); - $module_path = $this->fileSystem->realpath($module_handler->getModule('automatic_updates')->getPath()); - if (is_dir("$module_path/.git")) { - // If the current module is git clone. Don't copy it. - $exclusions[] = $make_relative($module_path); + // If this module is a git clone, exclude it. + if (is_dir(__DIR__ . '/../.git')) { + $exclusions[] = $this->fileSystem->realpath(__DIR__ . '/..'); } - $settings_files = ['settings.php', 'settings.local.php', 'services.yml']; + + // Exclude site-specific settings files. + $settings_files = [ + 'settings.php', + 'settings.local.php', + 'services.yml', + ]; foreach ($settings_files as $settings_file) { - $file_path = "sites/default/$settings_file"; + $file_path = implode(DIRECTORY_SEPARATOR, [ + $this->appRoot, + $this->sitePath, + $settings_file, + ]); + $file_path = $this->fileSystem->realpath($file_path); if (file_exists($file_path)) { - $exclusions[] = $make_relative($this->fileSystem->realpath("sites/default/$settings_file")); + $exclusions[] = $file_path; } } - return $exclusions; + + $make_relative = function (string $path): string { + return str_replace($this->getActiveDirectory() . '/', '', $path); + }; + return array_map($make_relative, $exclusions); } /** diff --git a/tests/src/Functional/ExclusionsTest.php b/tests/src/Functional/ExclusionsTest.php new file mode 100644 index 0000000000..8d0832eb8c --- /dev/null +++ b/tests/src/Functional/ExclusionsTest.php @@ -0,0 +1,74 @@ +<?php + +namespace Drupal\Tests\automatic_updates\Functional; + +use Drupal\Tests\BrowserTestBase; + +/** + * Tests exclusion of certain files and directories from the staging area. + * + * @group automatic_updates + */ +class ExclusionsTest extends BrowserTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['automatic_updates']; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * The names of site-specific settings files to mock. + * + * @var string[] + */ + private const SETTINGS_FILES = [ + 'settings.php', + 'settings.local.php', + 'services.yml', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + foreach (static::SETTINGS_FILES as $settings_file) { + $settings_file = "$this->siteDirectory/$settings_file"; + touch($settings_file); + $this->assertFileExists($settings_file); + } + } + + /** + * Tests that certain files and directories are not staged. + * + * @covers \Drupal\automatic_updates\Updater::getExclusions + */ + public function testExclusions(): void { + /** @var \Drupal\automatic_updates\Updater $updater */ + $updater = $this->container->get('automatic_updates.updater'); + + $reflector = new \ReflectionObject($updater); + $method = $reflector->getMethod('getExclusions'); + $method->setAccessible(TRUE); + $exclusions = $method->invoke($updater); + + $this->assertContains("$this->siteDirectory/files", $exclusions); + $this->assertContains("$this->siteDirectory/private", $exclusions); + foreach (static::SETTINGS_FILES as $settings_file) { + $this->assertContains("$this->siteDirectory/$settings_file", $exclusions); + } + if (is_dir(__DIR__ . '/../../../.git')) { + $module_path = $this->container->get('extension.list.module') + ->getPath('automatic_updates'); + $this->assertContains($module_path, $exclusions); + } + } + +} -- GitLab