Skip to content
Snippets Groups Projects
Commit ab57f234 authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3277229 by phenaproxima: Auto-wire Composer Stager into Package Manager

parent 02041b35
No related branches found
No related tags found
1 merge request!297Issue #3277229: Auto-wire Composer Stager into Package Manager
services: services:
# Underlying Symfony utilities. # Underlying Symfony utilities for Composer Stager.
package_manager.symfony_file_system: Symfony\Component\Filesystem\Filesystem:
class: Symfony\Component\Filesystem\Filesystem public: false
package_manager.symfony_executable_finder: Symfony\Component\Process\ExecutableFinder:
class: Symfony\Component\Process\ExecutableFinder public: false
# Basic infrastructure services. # Basic infrastructure services for Composer Stager.
package_manager.process_factory: Drupal\package_manager\ProcessFactory:
class: Drupal\package_manager\ProcessFactory
arguments: arguments:
- '@file_system' - '@file_system'
- '@config.factory' - '@config.factory'
package_manager.file_system: public: false
class: PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem:
arguments: autowire: true
- '@package_manager.symfony_file_system' public: false
package_manager.executable_finder: Drupal\package_manager\ExecutableFinder:
class: Drupal\package_manager\ExecutableFinder arguments:
arguments: $config_factory: '@config.factory'
- '@package_manager.symfony_executable_finder' autowire: true
- '@config.factory' public: false
PhpTuf\ComposerStager\Infrastructure\Process\ProcessFactoryInterface:
alias: 'Drupal\package_manager\ProcessFactory'
PhpTuf\ComposerStager\Domain\Filesystem\FilesystemInterface:
alias: 'PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem'
PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface:
alias: 'Drupal\package_manager\ExecutableFinder'
# Executable runners. # Executable runners for Composer Stager.
package_manager.rsync_runner: PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner:
class: PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner autowire: true
arguments: public: false
- '@package_manager.executable_finder' PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner:
- '@package_manager.process_factory' autowire: true
package_manager.composer_runner: public: false
class: PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner PhpTuf\ComposerStager\Domain\Process\Runner\RsyncRunnerInterface:
arguments: alias: 'PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner'
- '@package_manager.executable_finder' PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface:
- '@package_manager.process_factory' alias: 'PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner'
# File syncers. # File syncers for Composer Stager.
package_manager.file_syncer.rsync: PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer:
class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer autowire: true
arguments: PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer:
- '@package_manager.file_system' autowire: true
- '@package_manager.rsync_runner' Drupal\package_manager\FileSyncerFactory:
package_manager.file_syncer.php: arguments:
class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer $config_factory: '@config.factory'
arguments: autowire: true
- '@package_manager.file_system' public: false
package_manager.file_syncer.factory: PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface:
class: Drupal\package_manager\FileSyncerFactory factory: ['@Drupal\package_manager\FileSyncerFactory', 'create']
arguments:
- '@package_manager.symfony_executable_finder'
- '@package_manager.file_syncer.php'
- '@package_manager.file_syncer.rsync'
- '@config.factory'
package_manager.file_syncer:
class: PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
factory: ['@package_manager.file_syncer.factory', 'create']
# Domain services. # Services provided to Drupal by Package Manager.
package_manager.beginner: package_manager.beginner:
class: PhpTuf\ComposerStager\Domain\Beginner class: PhpTuf\ComposerStager\Domain\Beginner
arguments: autowire: true
- '@package_manager.file_syncer'
- '@package_manager.file_system'
package_manager.stager: package_manager.stager:
class: PhpTuf\ComposerStager\Domain\Stager class: PhpTuf\ComposerStager\Domain\Stager
arguments: autowire: true
- '@package_manager.composer_runner'
- '@package_manager.file_system'
package_manager.committer: package_manager.committer:
class: PhpTuf\ComposerStager\Domain\Committer class: PhpTuf\ComposerStager\Domain\Committer
arguments: autowire: true
- '@package_manager.file_syncer'
- '@package_manager.file_system'
package_manager.path_locator: package_manager.path_locator:
class: Drupal\package_manager\PathLocator class: Drupal\package_manager\PathLocator
arguments: arguments:
...@@ -79,7 +70,7 @@ services: ...@@ -79,7 +70,7 @@ services:
package_manager.validator.composer_executable: package_manager.validator.composer_executable:
class: Drupal\package_manager\Validator\ComposerExecutableValidator class: Drupal\package_manager\Validator\ComposerExecutableValidator
arguments: arguments:
- '@package_manager.composer_runner' - '@PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface'
- '@module_handler' - '@module_handler'
- '@string_translation' - '@string_translation'
tags: tags:
...@@ -143,11 +134,11 @@ services: ...@@ -143,11 +134,11 @@ services:
package_manager.site_files_excluder: package_manager.site_files_excluder:
class: Drupal\package_manager\PathExcluder\SiteFilesExcluder class: Drupal\package_manager\PathExcluder\SiteFilesExcluder
arguments: arguments:
- '@package_manager.path_locator' $path_locator: '@package_manager.path_locator'
- '@stream_wrapper_manager' $stream_wrapper_manager: '@stream_wrapper_manager'
- '@package_manager.symfony_file_system'
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
autowire: true
package_manager.sqlite_excluder: package_manager.sqlite_excluder:
class: Drupal\package_manager\PathExcluder\SqliteDatabaseExcluder class: Drupal\package_manager\PathExcluder\SqliteDatabaseExcluder
arguments: arguments:
......
...@@ -6,6 +6,8 @@ use Drupal\Core\Config\ConfigFactoryInterface; ...@@ -6,6 +6,8 @@ use Drupal\Core\Config\ConfigFactoryInterface;
use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface; use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface;
use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface; use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerFactory as StagerFileSyncerFactory; use PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerFactory as StagerFileSyncerFactory;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer;
use Symfony\Component\Process\ExecutableFinder; use Symfony\Component\Process\ExecutableFinder;
/** /**
...@@ -23,14 +25,14 @@ class FileSyncerFactory implements FileSyncerFactoryInterface { ...@@ -23,14 +25,14 @@ class FileSyncerFactory implements FileSyncerFactoryInterface {
/** /**
* The PHP file syncer service. * The PHP file syncer service.
* *
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface * @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer
*/ */
protected $phpFileSyncer; protected $phpFileSyncer;
/** /**
* The rsync file syncer service. * The rsync file syncer service.
* *
* @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface * @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer
*/ */
protected $rsyncFileSyncer; protected $rsyncFileSyncer;
...@@ -46,14 +48,14 @@ class FileSyncerFactory implements FileSyncerFactoryInterface { ...@@ -46,14 +48,14 @@ class FileSyncerFactory implements FileSyncerFactoryInterface {
* *
* @param \Symfony\Component\Process\ExecutableFinder $executable_finder * @param \Symfony\Component\Process\ExecutableFinder $executable_finder
* The Symfony executable finder. * The Symfony executable finder.
* @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $php_file_syncer * @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer $php_file_syncer
* The PHP file syncer service. * The PHP file syncer service.
* @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $rsync_file_syncer * @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer $rsync_file_syncer
* The rsync file syncer service. * The rsync file syncer service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service. * The config factory service.
*/ */
public function __construct(ExecutableFinder $executable_finder, FileSyncerInterface $php_file_syncer, FileSyncerInterface $rsync_file_syncer, ConfigFactoryInterface $config_factory) { public function __construct(ExecutableFinder $executable_finder, PhpFileSyncer $php_file_syncer, RsyncFileSyncer $rsync_file_syncer, ConfigFactoryInterface $config_factory) {
$this->decorated = new StagerFileSyncerFactory($executable_finder, $php_file_syncer, $rsync_file_syncer); $this->decorated = new StagerFileSyncerFactory($executable_finder, $php_file_syncer, $rsync_file_syncer);
$this->phpFileSyncer = $php_file_syncer; $this->phpFileSyncer = $php_file_syncer;
$this->rsyncFileSyncer = $rsync_file_syncer; $this->rsyncFileSyncer = $rsync_file_syncer;
......
...@@ -18,9 +18,11 @@ class PackageManagerBypassServiceProvider extends ServiceProviderBase { ...@@ -18,9 +18,11 @@ class PackageManagerBypassServiceProvider extends ServiceProviderBase {
parent::alter($container); parent::alter($container);
$container->getDefinition('package_manager.beginner') $container->getDefinition('package_manager.beginner')
->setClass(Beginner::class); ->setClass(Beginner::class)
->setArguments([]);
$container->getDefinition('package_manager.stager') $container->getDefinition('package_manager.stager')
->setClass(Stager::class); ->setClass(Stager::class)
->setArguments([]);
$container->register('package_manager_bypass.committer') $container->register('package_manager_bypass.committer')
->setClass(Committer::class) ->setClass(Committer::class)
......
...@@ -3,6 +3,6 @@ services: ...@@ -3,6 +3,6 @@ services:
class: Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager class: Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager
arguments: arguments:
- '@state' - '@state'
- '@package_manager.symfony_file_system' - '@Symfony\Component\Filesystem\Filesystem'
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
namespace Drupal\Tests\package_manager\Kernel; namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Validator\ComposerExecutableValidator; use Drupal\package_manager\Validator\ComposerExecutableValidator;
use Drupal\package_manager\ValidationResult; use Drupal\package_manager\ValidationResult;
use PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface;
use PhpTuf\ComposerStager\Exception\IOException; use PhpTuf\ComposerStager\Exception\IOException;
use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface;
use Prophecy\Argument; use Prophecy\Argument;
/** /**
...@@ -17,19 +18,42 @@ use Prophecy\Argument; ...@@ -17,19 +18,42 @@ use Prophecy\Argument;
*/ */
class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase { class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
/**
* The mocked Composer runner.
*
* @var \Prophecy\Prophecy\ObjectProphecy|\PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface
*/
private $composerRunner;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
$this->composerRunner = $this->prophesize(ComposerRunnerInterface::class);
parent::setUp();
}
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$container->getDefinition('package_manager.validator.composer_executable')
->setArgument('$composer', $this->composerRunner->reveal());
}
/** /**
* Tests that an error is raised if the Composer executable isn't found. * Tests that an error is raised if the Composer executable isn't found.
*/ */
public function testErrorIfComposerNotFound(): void { public function testErrorIfComposerNotFound(): void {
$exception = new IOException("This is your regularly scheduled error."); $exception = new IOException("This is your regularly scheduled error.");
// The executable finder throws an exception if it can't find the requested // If the Composer executable isn't found, the executable finder will throw
// executable. // an exception, which will not be caught by the Composer runner.
$exec_finder = $this->prophesize(ExecutableFinderInterface::class); $this->composerRunner->run(Argument::cetera())
$exec_finder->find('composer')
->willThrow($exception) ->willThrow($exception)
->shouldBeCalled(); ->shouldBeCalled();
$this->container->set('package_manager.executable_finder', $exec_finder->reveal());
// The validator should translate that exception into an error. // The validator should translate that exception into an error.
$error = ValidationResult::createError([ $error = ValidationResult::createError([
...@@ -38,7 +62,6 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase { ...@@ -38,7 +62,6 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
$this->assertResults([$error], PreCreateEvent::class); $this->assertResults([$error], PreCreateEvent::class);
$this->enableModules(['help']); $this->enableModules(['help']);
$this->container->set('package_manager.executable_finder', $exec_finder->reveal());
$this->assertResultsWithHelp([$error], PreCreateEvent::class); $this->assertResultsWithHelp([$error], PreCreateEvent::class);
} }
...@@ -122,10 +145,7 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase { ...@@ -122,10 +145,7 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
// Mock the output of `composer --version`, will be passed to the validator, // Mock the output of `composer --version`, will be passed to the validator,
// which is itself a callback function that gets called repeatedly as // which is itself a callback function that gets called repeatedly as
// Composer produces output. // Composer produces output.
/** @var \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface|\Prophecy\Prophecy\ObjectProphecy $runner */ $this->composerRunner->run(['--version'], Argument::type(ComposerExecutableValidator::class))
$runner = $this->prophesize('\PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface');
$runner->run(['--version'], Argument::type(ComposerExecutableValidator::class))
// Whatever is passed to ::run() will be passed to this mock callback in // Whatever is passed to ::run() will be passed to this mock callback in
// $arguments, and we know exactly what that will contain: an array of // $arguments, and we know exactly what that will contain: an array of
// command arguments for Composer, and the validator object. // command arguments for Composer, and the validator object.
...@@ -137,14 +157,12 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase { ...@@ -137,14 +157,12 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
// recognized, supported version number out of this output. // recognized, supported version number out of this output.
$validator($validator::OUT, "Composer version $reported_version"); $validator($validator::OUT, "Composer version $reported_version");
}); });
$this->container->set('package_manager.composer_runner', $runner->reveal());
// If the validator can't find a recognized, supported version of Composer, // If the validator can't find a recognized, supported version of Composer,
// it should produce errors. // it should produce errors.
$this->assertResults($expected_results, PreCreateEvent::class); $this->assertResults($expected_results, PreCreateEvent::class);
$this->enableModules(['help']); $this->enableModules(['help']);
$this->container->set('package_manager.composer_runner', $runner->reveal());
$this->assertResultsWithHelp($expected_results, PreCreateEvent::class); $this->assertResultsWithHelp($expected_results, PreCreateEvent::class);
} }
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
namespace Drupal\Tests\package_manager\Kernel; namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\package_manager\ExecutableFinder;
use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface;
use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder;
/** /**
...@@ -12,10 +15,11 @@ use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; ...@@ -12,10 +15,11 @@ use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder;
class ExecutableFinderTest extends PackageManagerKernelTestBase { class ExecutableFinderTest extends PackageManagerKernelTestBase {
/** /**
* Tests that the executable finder looks for paths in configuration. * {@inheritdoc}
*/ */
public function testCheckConfigurationForExecutablePath(): void { public function register(ContainerBuilder $container) {
$symfony_executable_finder = new class () extends SymfonyExecutableFinder { // Mock a Symfony executable finder that always returns /dev/null.
$symfony_executable_finder = new class extends SymfonyExecutableFinder {
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -25,13 +29,19 @@ class ExecutableFinderTest extends PackageManagerKernelTestBase { ...@@ -25,13 +29,19 @@ class ExecutableFinderTest extends PackageManagerKernelTestBase {
} }
}; };
$this->container->set('package_manager.symfony_executable_finder', $symfony_executable_finder); $container->getDefinition(ExecutableFinder::class)
->setArgument('$symfony_executable_finder', $symfony_executable_finder);
}
/**
* Tests that the executable finder looks for paths in configuration.
*/
public function testCheckConfigurationForExecutablePath(): void {
$this->config('package_manager.settings') $this->config('package_manager.settings')
->set('executables.composer', '/path/to/composer') ->set('executables.composer', '/path/to/composer')
->save(); ->save();
$executable_finder = $this->container->get('package_manager.executable_finder'); $executable_finder = $this->container->get(ExecutableFinderInterface::class);
$this->assertSame('/path/to/composer', $executable_finder->find('composer')); $this->assertSame('/path/to/composer', $executable_finder->find('composer'));
$this->assertSame('/dev/null', $executable_finder->find('rsync')); $this->assertSame('/dev/null', $executable_finder->find('rsync'));
} }
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
namespace Drupal\Tests\package_manager\Kernel; namespace Drupal\Tests\package_manager\Kernel;
use Drupal\KernelTests\KernelTestBase; use Drupal\KernelTests\KernelTestBase;
use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer;
/** /**
* @covers \Drupal\package_manager\FileSyncerFactory * @covers \Drupal\package_manager\FileSyncerFactory
...@@ -40,19 +43,17 @@ class FileSyncerFactoryTest extends KernelTestBase { ...@@ -40,19 +43,17 @@ class FileSyncerFactoryTest extends KernelTestBase {
* @dataProvider providerFactory * @dataProvider providerFactory
*/ */
public function testFactory(?string $configured_syncer): void { public function testFactory(?string $configured_syncer): void {
$factory = $this->container->get('package_manager.file_syncer.factory');
switch ($configured_syncer) { switch ($configured_syncer) {
case 'rsync': case 'rsync':
$expected_syncer = $this->container->get('package_manager.file_syncer.rsync'); $expected_syncer = RsyncFileSyncer::class;
break; break;
case 'php': case 'php':
$expected_syncer = $this->container->get('package_manager.file_syncer.php'); $expected_syncer = PhpFileSyncer::class;
break; break;
default: default:
$expected_syncer = $factory->create(); $expected_syncer = FileSyncerInterface::class;
break; break;
} }
...@@ -60,7 +61,7 @@ class FileSyncerFactoryTest extends KernelTestBase { ...@@ -60,7 +61,7 @@ class FileSyncerFactoryTest extends KernelTestBase {
->set('file_syncer', $configured_syncer) ->set('file_syncer', $configured_syncer)
->save(); ->save();
$this->assertSame($expected_syncer, $factory->create()); $this->assertInstanceOf($expected_syncer, $this->container->get(FileSyncerInterface::class));
} }
} }
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