From e5d8457dece96d3dcb664fa0c2df0d42613f27f7 Mon Sep 17 00:00:00 2001 From: phenaproxima <phenaproxima@205645.no-reply.drupal.org> Date: Tue, 21 Sep 2021 15:59:39 +0000 Subject: [PATCH] Issue #3232959 by phenaproxima: Make it possible to choose which file copier to use --- .../config/schema/package_manager.schema.yml | 7 ++ package_manager/package_manager.services.yml | 3 +- package_manager/src/FileCopierFactory.php | 84 +++++++++++++++++++ .../src/Kernel/FileCopierFactoryTest.php | 66 +++++++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 package_manager/config/schema/package_manager.schema.yml create mode 100644 package_manager/src/FileCopierFactory.php create mode 100644 package_manager/tests/src/Kernel/FileCopierFactoryTest.php diff --git a/package_manager/config/schema/package_manager.schema.yml b/package_manager/config/schema/package_manager.schema.yml new file mode 100644 index 0000000000..53cac8d50d --- /dev/null +++ b/package_manager/config/schema/package_manager.schema.yml @@ -0,0 +1,7 @@ +package_manager.settings: + type: config_object + label: 'Package Manager settings' + mapping: + file_copier: + type: string + label: 'Which file copier to use, or NULL to auto-detect' diff --git a/package_manager/package_manager.services.yml b/package_manager/package_manager.services.yml index 3c0d4d8c28..2b4c19f733 100644 --- a/package_manager/package_manager.services.yml +++ b/package_manager/package_manager.services.yml @@ -44,11 +44,12 @@ services: - '@package_manager.symfony_finder' - '@package_manager.symfony_finder' package_manager.file_copier.factory: - class: PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\FileCopierFactory + class: Drupal\package_manager\FileCopierFactory arguments: - '@package_manager.symfony_executable_finder' - '@package_manager.file_copier.php' - '@package_manager.file_copier.rsync' + - '@config.factory' package_manager.file_copier: class: PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\FileCopierInterface factory: ['@package_manager.file_copier.factory', 'create'] diff --git a/package_manager/src/FileCopierFactory.php b/package_manager/src/FileCopierFactory.php new file mode 100644 index 0000000000..27f26ef219 --- /dev/null +++ b/package_manager/src/FileCopierFactory.php @@ -0,0 +1,84 @@ +<?php + +namespace Drupal\package_manager; + +use Drupal\Core\Config\ConfigFactoryInterface; +use PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\FileCopierFactory as StagerFileCopierFactory; +use PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\FileCopierFactoryInterface; +use PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\FileCopierInterface; +use PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\PhpFileCopierInterface; +use PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\RsyncFileCopierInterface; +use Symfony\Component\Process\ExecutableFinder; + +/** + * A file copier factory which returns file copiers according to configuration. + */ +class FileCopierFactory implements FileCopierFactoryInterface { + + /** + * The decorated file copier factory. + * + * @var \PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\FileCopierFactoryInterface + */ + protected $decorated; + + /** + * The PHP file copier service. + * + * @var \PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\PhpFileCopierInterface + */ + protected $phpFileCopier; + + /** + * The rsync file copier service. + * + * @var \PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\RsyncFileCopierInterface + */ + protected $rsyncFileCopier; + + /** + * The config factory service. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * Constructs a FileCopierFactory object. + * + * @param \Symfony\Component\Process\ExecutableFinder $executable_finder + * The Symfony executable finder. + * @param \PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\PhpFileCopierInterface $php_file_copier + * The PHP file copier service. + * @param \PhpTuf\ComposerStager\Infrastructure\Process\FileCopier\RsyncFileCopierInterface $rsync_file_copier + * The rsync file copier service. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory service. + */ + public function __construct(ExecutableFinder $executable_finder, PhpFileCopierInterface $php_file_copier, RsyncFileCopierInterface $rsync_file_copier, ConfigFactoryInterface $config_factory) { + $this->decorated = new StagerFileCopierFactory($executable_finder, $php_file_copier, $rsync_file_copier); + $this->phpFileCopier = $php_file_copier; + $this->rsyncFileCopier = $rsync_file_copier; + $this->configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public function create(): FileCopierInterface { + $copier = $this->configFactory->get('package_manager.settings') + ->get('file_copier'); + + switch ($copier) { + case 'rsync': + return $this->rsyncFileCopier; + + case 'php': + return $this->phpFileCopier; + + default: + return $this->decorated->create(); + } + } + +} diff --git a/package_manager/tests/src/Kernel/FileCopierFactoryTest.php b/package_manager/tests/src/Kernel/FileCopierFactoryTest.php new file mode 100644 index 0000000000..b992ebc1c1 --- /dev/null +++ b/package_manager/tests/src/Kernel/FileCopierFactoryTest.php @@ -0,0 +1,66 @@ +<?php + +namespace Drupal\Tests\package_manager\Kernel; + +use Drupal\KernelTests\KernelTestBase; + +/** + * @covers \Drupal\package_manager\FileCopierFactory + * + * @group package_manager + */ +class FileCopierFactoryTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['package_manager']; + + /** + * Data provider for ::testFactory(). + * + * @return mixed[][] + * Sets of arguments to pass to the test method. + */ + public function providerFactory(): array { + return [ + ['rsync'], + ['php'], + [NULL], + ]; + } + + /** + * Tests creating a file copier using our specialized factory class. + * + * @param string|null $configured_copier + * The copier to use, as configured in automatic_updates.settings. Can be + * 'rsync', 'php', or NULL. + * + * @dataProvider providerFactory + */ + public function testFactory(?string $configured_copier): void { + $factory = $this->container->get('package_manager.file_copier.factory'); + + switch ($configured_copier) { + case 'rsync': + $expected_copier = $this->container->get('package_manager.file_copier.rsync'); + break; + + case 'php': + $expected_copier = $this->container->get('package_manager.file_copier.php'); + break; + + default: + $expected_copier = $factory->create(); + break; + } + + $this->config('package_manager.settings') + ->set('file_copier', $configured_copier) + ->save(); + + $this->assertSame($expected_copier, $factory->create()); + } + +} -- GitLab