From 7c5e93ad4679faf005aed5de0f446226f5d3ee86 Mon Sep 17 00:00:00 2001 From: phenaproxima <phenaproxima@205645.no-reply.drupal.org> Date: Tue, 7 Jun 2022 20:03:13 +0000 Subject: [PATCH] Issue #3277211 by phenaproxima: Update Composer Stager to 0.5.0 --- automatic_updates.services.yml | 2 + .../automatic_updates_extensions.services.yml | 1 + composer.json | 2 +- package_manager/package_manager.install | 2 +- package_manager/package_manager.services.yml | 103 +++++++++++++++--- package_manager/src/ExecutableFinder.php | 6 +- package_manager/src/FileSyncerFactory.php | 21 ++-- .../src/PackageManagerUninstallValidator.php | 4 +- package_manager/src/ProcessFactory.php | 6 +- package_manager/src/Stage.php | 53 +++++---- .../Validator/ComposerExecutableValidator.php | 12 +- .../package_manager_bypass/src/Beginner.php | 9 +- .../package_manager_bypass/src/Committer.php | 33 +----- .../package_manager_bypass/src/Stager.php | 8 +- .../src/ApiController.php | 4 +- .../ComposerExecutableValidatorTest.php | 6 +- .../tests/src/Kernel/ExecutableFinderTest.php | 2 +- .../src/Kernel/FileSyncerFactoryTest.php | 6 +- .../Kernel/PackageManagerKernelTestBase.php | 46 +++++++- 19 files changed, 220 insertions(+), 106 deletions(-) diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index a5e5545c3a..5d0fc38d79 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -26,6 +26,7 @@ services: - '@event_dispatcher' - '@tempstore.shared' - '@datetime.time' + - '@PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface' automatic_updates.cron_updater: class: Drupal\automatic_updates\CronUpdater arguments: @@ -40,6 +41,7 @@ services: - '@event_dispatcher' - '@tempstore.shared' - '@datetime.time' + - '@PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface' automatic_updates.staged_projects_validator: class: Drupal\automatic_updates\Validator\StagedProjectsValidator arguments: diff --git a/automatic_updates_extensions/automatic_updates_extensions.services.yml b/automatic_updates_extensions/automatic_updates_extensions.services.yml index dea4d1ff45..2e4867dab5 100644 --- a/automatic_updates_extensions/automatic_updates_extensions.services.yml +++ b/automatic_updates_extensions/automatic_updates_extensions.services.yml @@ -11,6 +11,7 @@ services: - '@event_dispatcher' - '@tempstore.shared' - '@datetime.time' + - '@PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface' automatic_updates_extensions.validator.target_release: class: Drupal\automatic_updates_extensions\Validator\UpdateReleaseValidator tags: diff --git a/composer.json b/composer.json index 1d6b9da4c2..5027023d50 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "require": { "ext-json": "*", "drupal/core": "^9.2", - "php-tuf/composer-stager": "0.3.0", + "php-tuf/composer-stager": "0.5.0", "composer/composer": "^2.2.12 || ^2.3.5", "composer-runtime-api": "^2.0.9" }, diff --git a/package_manager/package_manager.install b/package_manager/package_manager.install index c4fb7265e2..a533010e3c 100644 --- a/package_manager/package_manager.install +++ b/package_manager/package_manager.install @@ -11,7 +11,7 @@ function package_manager_requirements(string $phase) { $requirements = []; - if (!class_exists('PhpTuf\ComposerStager\Domain\Beginner')) { + if (!class_exists('\PhpTuf\ComposerStager\Domain\Core\Beginner\Beginner')) { $requirements['package_manager_composer_dependencies'] = [ 'title' => 'Missing dependency', 'description' => t('External dependencies for Package Manager are not available. Composer must be used to download the module with dependencies.'), diff --git a/package_manager/package_manager.services.yml b/package_manager/package_manager.services.yml index 31701a6b04..60f7142c4a 100644 --- a/package_manager/package_manager.services.yml +++ b/package_manager/package_manager.services.yml @@ -11,7 +11,7 @@ services: - '@file_system' - '@config.factory' public: false - PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem: + PhpTuf\ComposerStager\Infrastructure\Service\Filesystem\Filesystem: autowire: true public: false Drupal\package_manager\ExecutableFinder: @@ -19,47 +19,114 @@ services: $config_factory: '@config.factory' autowire: true public: false - PhpTuf\ComposerStager\Infrastructure\Process\ProcessFactoryInterface: + PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactory: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface: alias: 'Drupal\package_manager\ProcessFactory' - PhpTuf\ComposerStager\Domain\Filesystem\FilesystemInterface: - alias: 'PhpTuf\ComposerStager\Infrastructure\Filesystem\Filesystem' - PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface: + PhpTuf\ComposerStager\Domain\Service\Filesystem\FilesystemInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Filesystem\Filesystem' + PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface: alias: 'Drupal\package_manager\ExecutableFinder' + PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactory' # Executable runners for Composer Stager. - PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner: + PhpTuf\ComposerStager\Infrastructure\Service\ProcessRunner\RsyncRunner: autowire: true public: false - PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner: + PhpTuf\ComposerStager\Infrastructure\Service\ProcessRunner\ComposerRunner: autowire: true public: false - PhpTuf\ComposerStager\Domain\Process\Runner\RsyncRunnerInterface: - alias: 'PhpTuf\ComposerStager\Infrastructure\Process\Runner\RsyncRunner' - PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface: - alias: 'PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunner' + PhpTuf\ComposerStager\Domain\Service\ProcessRunner\RsyncRunnerInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\ProcessRunner\RsyncRunner' + PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\ProcessRunner\ComposerRunner' # File syncers for Composer Stager. - PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer: + PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer: autowire: true - PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer: + PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer: autowire: true Drupal\package_manager\FileSyncerFactory: arguments: $config_factory: '@config.factory' autowire: true public: false - PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface: + PhpTuf\ComposerStager\Domain\Service\FileSyncer\FileSyncerInterface: factory: ['@Drupal\package_manager\FileSyncerFactory', 'create'] + # Composer Stager preconditions. + PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\CommonPreconditions: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\BeginnerPreconditions: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\StagerPreconditions: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\CommitterPreconditions: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\StagingDirIsReady: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ComposerIsAvailable: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ActiveDirExists: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ActiveDirIsWritable: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ActiveAndStagingDirsAreDifferent: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirExists: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirIsWritable: + autowire: true + public: false + PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirDoesNotExist: + autowire: true + public: false + PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\CommitterPreconditionsInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\CommitterPreconditions' + PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\BeginnerPreconditionsInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\BeginnerPreconditions' + PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\StagerPreconditionsInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\StagerPreconditions' + PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\CommonPreconditionsInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\CommonPreconditions' + PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\StagingDirIsReadyInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Aggregate\PreconditionsTree\StagingDirIsReady' + PhpTuf\ComposerStager\Domain\Service\Precondition\ComposerIsAvailableInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ComposerIsAvailable' + PhpTuf\ComposerStager\Domain\Service\Precondition\ActiveDirExistsInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ActiveDirExists' + PhpTuf\ComposerStager\Domain\Service\Precondition\ActiveDirIsWritableInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ActiveDirIsWritable' + PhpTuf\ComposerStager\Domain\Service\Precondition\ActiveAndStagingDirsAreDifferentInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\ActiveAndStagingDirsAreDifferent' + PhpTuf\ComposerStager\Domain\Service\Precondition\StagingDirExistsInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirExists' + PhpTuf\ComposerStager\Domain\Service\Precondition\StagingDirIsWritableInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirIsWritable' + PhpTuf\ComposerStager\Domain\Service\Precondition\StagingDirDoesNotExistInterface: + alias: 'PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirDoesNotExist' + # Services provided to Drupal by Package Manager. package_manager.beginner: - class: PhpTuf\ComposerStager\Domain\Beginner + class: PhpTuf\ComposerStager\Domain\Core\Beginner\Beginner autowire: true package_manager.stager: - class: PhpTuf\ComposerStager\Domain\Stager + class: PhpTuf\ComposerStager\Domain\Core\Stager\Stager autowire: true package_manager.committer: - class: PhpTuf\ComposerStager\Domain\Committer + class: PhpTuf\ComposerStager\Domain\Core\Committer\Committer autowire: true package_manager.path_locator: class: Drupal\package_manager\PathLocator @@ -70,7 +137,7 @@ services: package_manager.validator.composer_executable: class: Drupal\package_manager\Validator\ComposerExecutableValidator arguments: - - '@PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface' + - '@PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface' - '@module_handler' - '@string_translation' tags: diff --git a/package_manager/src/ExecutableFinder.php b/package_manager/src/ExecutableFinder.php index d18f45be13..05c03183d5 100644 --- a/package_manager/src/ExecutableFinder.php +++ b/package_manager/src/ExecutableFinder.php @@ -3,8 +3,8 @@ namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface; -use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinder as StagerExecutableFinder; +use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinder as StagerExecutableFinder; +use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; /** @@ -15,7 +15,7 @@ class ExecutableFinder implements ExecutableFinderInterface { /** * The decorated executable finder. * - * @var \PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinder + * @var \PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinder */ private $decorated; diff --git a/package_manager/src/FileSyncerFactory.php b/package_manager/src/FileSyncerFactory.php index 65fdfbcb73..98a28f545c 100644 --- a/package_manager/src/FileSyncerFactory.php +++ b/package_manager/src/FileSyncerFactory.php @@ -3,36 +3,35 @@ namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; -use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface; -use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface; -use PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerFactory as StagerFileSyncerFactory; -use PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer; -use PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer; +use PhpTuf\ComposerStager\Domain\Service\FileSyncer\FileSyncerInterface; +use PhpTuf\ComposerStager\Infrastructure\Factory\FileSyncer\FileSyncerFactory as StagerFileSyncerFactory; +use PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer; +use PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer; use Symfony\Component\Process\ExecutableFinder; /** * A file syncer factory which creates a file syncer according to configuration. */ -class FileSyncerFactory implements FileSyncerFactoryInterface { +class FileSyncerFactory { /** * The decorated file syncer factory. * - * @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface + * @var \PhpTuf\ComposerStager\Infrastructure\Factory\FileSyncer\FileSyncerFactory */ protected $decorated; /** * The PHP file syncer service. * - * @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer + * @var \PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer */ protected $phpFileSyncer; /** * The rsync file syncer service. * - * @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer + * @var \PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer */ protected $rsyncFileSyncer; @@ -48,9 +47,9 @@ class FileSyncerFactory implements FileSyncerFactoryInterface { * * @param \Symfony\Component\Process\ExecutableFinder $executable_finder * The Symfony executable finder. - * @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer $php_file_syncer + * @param \PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer $php_file_syncer * The PHP file syncer service. - * @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer $rsync_file_syncer + * @param \PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer $rsync_file_syncer * The rsync file syncer service. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory service. diff --git a/package_manager/src/PackageManagerUninstallValidator.php b/package_manager/src/PackageManagerUninstallValidator.php index dd9ab87607..8348ed090d 100644 --- a/package_manager/src/PackageManagerUninstallValidator.php +++ b/package_manager/src/PackageManagerUninstallValidator.php @@ -4,6 +4,7 @@ namespace Drupal\package_manager; use Drupal\Core\Extension\ModuleUninstallValidatorInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; @@ -28,7 +29,8 @@ class PackageManagerUninstallValidator implements ModuleUninstallValidatorInterf $this->container->get('file_system'), $this->container->get('event_dispatcher'), $this->container->get('tempstore.shared'), - $this->container->get('datetime.time') + $this->container->get('datetime.time'), + $this->container->get(PathFactoryInterface::class) ); if ($stage->isAvailable() || !$stage->isApplying()) { return []; diff --git a/package_manager/src/ProcessFactory.php b/package_manager/src/ProcessFactory.php index fa1a8565d0..d7089d80dc 100644 --- a/package_manager/src/ProcessFactory.php +++ b/package_manager/src/ProcessFactory.php @@ -4,8 +4,8 @@ namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\File\FileSystemInterface; -use PhpTuf\ComposerStager\Infrastructure\Process\ProcessFactory as StagerProcessFactory; -use PhpTuf\ComposerStager\Infrastructure\Process\ProcessFactoryInterface; +use PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface; +use PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactory as StagerProcessFactory; use Symfony\Component\Process\Process; /** @@ -16,7 +16,7 @@ final class ProcessFactory implements ProcessFactoryInterface { /** * The decorated process factory. * - * @var \PhpTuf\ComposerStager\Infrastructure\Process\ProcessFactoryInterface + * @var \PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface */ private $decorated; diff --git a/package_manager/src/Stage.php b/package_manager/src/Stage.php index 49acc42a4f..c8194d7ae4 100644 --- a/package_manager/src/Stage.php +++ b/package_manager/src/Stage.php @@ -21,9 +21,11 @@ use Drupal\package_manager\Event\StageEvent; use Drupal\package_manager\Exception\StageException; use Drupal\package_manager\Exception\StageOwnershipException; use Drupal\package_manager\Exception\StageValidationException; -use PhpTuf\ComposerStager\Domain\BeginnerInterface; -use PhpTuf\ComposerStager\Domain\CommitterInterface; -use PhpTuf\ComposerStager\Domain\StagerInterface; +use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface; +use PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface; +use PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface; +use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; +use PhpTuf\ComposerStager\Infrastructure\Value\PathList\PathList; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -102,21 +104,21 @@ class Stage { /** * The beginner service. * - * @var \PhpTuf\ComposerStager\Domain\BeginnerInterface + * @var \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface */ protected $beginner; /** * The stager service. * - * @var \PhpTuf\ComposerStager\Domain\StagerInterface + * @var \PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface */ protected $stager; /** * The committer service. * - * @var \PhpTuf\ComposerStager\Domain\CommitterInterface + * @var \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface */ protected $committer; @@ -148,6 +150,13 @@ class Stage { */ protected $time; + /** + * The path factory service. + * + * @var \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface + */ + protected $pathFactory; + /** * The lock info for the stage. * @@ -164,11 +173,11 @@ class Stage { * The config factory service. * @param \Drupal\package_manager\PathLocator $path_locator * The path locator service. - * @param \PhpTuf\ComposerStager\Domain\BeginnerInterface $beginner + * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $beginner * The beginner service. - * @param \PhpTuf\ComposerStager\Domain\StagerInterface $stager + * @param \PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface $stager * The stager service. - * @param \PhpTuf\ComposerStager\Domain\CommitterInterface $committer + * @param \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface $committer * The committer service. * @param \Drupal\Core\File\FileSystemInterface $file_system * The file system service. @@ -178,8 +187,10 @@ class Stage { * The shared tempstore factory. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. + * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $path_factory + * The path factory service. */ - public function __construct(ConfigFactoryInterface $config_factory, PathLocator $path_locator, BeginnerInterface $beginner, StagerInterface $stager, CommitterInterface $committer, FileSystemInterface $file_system, EventDispatcherInterface $event_dispatcher, SharedTempStoreFactory $shared_tempstore, TimeInterface $time) { + public function __construct(ConfigFactoryInterface $config_factory, PathLocator $path_locator, BeginnerInterface $beginner, StagerInterface $stager, CommitterInterface $committer, FileSystemInterface $file_system, EventDispatcherInterface $event_dispatcher, SharedTempStoreFactory $shared_tempstore, TimeInterface $time, PathFactoryInterface $path_factory) { $this->configFactory = $config_factory; $this->pathLocator = $path_locator; $this->beginner = $beginner; @@ -189,6 +200,7 @@ class Stage { $this->eventDispatcher = $event_dispatcher; $this->time = $time; $this->tempStore = $shared_tempstore->get('package_manager_stage'); + $this->pathFactory = $path_factory; } /** @@ -275,15 +287,15 @@ class Stage { $this->tempStore->set(static::TEMPSTORE_LOCK_KEY, [$id, static::class]); $this->claim($id); - $active_dir = $this->pathLocator->getProjectRoot(); - $stage_dir = $this->getStageDirectory(); + $active_dir = $this->pathFactory->create($this->pathLocator->getProjectRoot()); + $stage_dir = $this->pathFactory->create($this->getStageDirectory()); $event = new PreCreateEvent($this); // If an error occurs and we won't be able to create the stage, mark it as // available. $this->dispatch($event, [$this, 'markAsAvailable']); - $this->beginner->begin($active_dir, $stage_dir, $event->getExcludedPaths(), NULL, $timeout); + $this->beginner->begin($active_dir, $stage_dir, new PathList($event->getExcludedPaths()), NULL, $timeout); $this->dispatch(new PostCreateEvent($this)); return $id; } @@ -302,23 +314,24 @@ class Stage { $this->checkOwnership(); $this->dispatch(new PreRequireEvent($this, $runtime, $dev)); - $dir = $this->getStageDirectory(); + $active_dir = $this->pathFactory->create($this->pathLocator->getProjectRoot()); + $stage_dir = $this->pathFactory->create($this->getStageDirectory()); // Change the runtime and dev requirements as needed, but don't update // the installed packages yet. if ($runtime) { $command = array_merge(['require', '--no-update'], $runtime); - $this->stager->stage($command, $dir); + $this->stager->stage($command, $active_dir, $stage_dir); } if ($dev) { $command = array_merge(['require', '--dev', '--no-update'], $dev); - $this->stager->stage($command, $dir); + $this->stager->stage($command, $active_dir, $stage_dir); } // If constraints were changed, update those packages. if ($runtime || $dev) { $command = array_merge(['update', '--with-all-dependencies'], $runtime, $dev); - $this->stager->stage($command, $dir); + $this->stager->stage($command, $active_dir, $stage_dir); } $this->dispatch(new PostRequireEvent($this, $runtime, $dev)); @@ -335,8 +348,8 @@ class Stage { public function apply(?int $timeout = 600): void { $this->checkOwnership(); - $active_dir = $this->pathLocator->getProjectRoot(); - $stage_dir = $this->getStageDirectory(); + $active_dir = $this->pathFactory->create($this->pathLocator->getProjectRoot()); + $stage_dir = $this->pathFactory->create($this->getStageDirectory()); // If an error occurs while dispatching the events, ensure that ::destroy() // doesn't think we're in the middle of applying the staged changes to the @@ -349,7 +362,7 @@ class Stage { $this->tempStore->set(self::TEMPSTORE_APPLY_TIME_KEY, $this->time->getRequestTime()); $this->dispatch($event, $release_apply); - $this->committer->commit($stage_dir, $active_dir, $event->getExcludedPaths(), NULL, $timeout); + $this->committer->commit($stage_dir, $active_dir, new PathList($event->getExcludedPaths()), NULL, $timeout); // Rebuild the container and clear all caches, to ensure that new services // are picked up. diff --git a/package_manager/src/Validator/ComposerExecutableValidator.php b/package_manager/src/Validator/ComposerExecutableValidator.php index d985321bd4..b6252e5bf8 100644 --- a/package_manager/src/Validator/ComposerExecutableValidator.php +++ b/package_manager/src/Validator/ComposerExecutableValidator.php @@ -9,14 +9,14 @@ use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreOperationStageEvent; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; -use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface; -use PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface; -use PhpTuf\ComposerStager\Exception\ExceptionInterface; +use PhpTuf\ComposerStager\Domain\Exception\ExceptionInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessOutputCallback\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface; /** * Validates the Composer executable is the correct version. */ -class ComposerExecutableValidator implements PreOperationStageValidatorInterface, OutputCallbackInterface { +class ComposerExecutableValidator implements PreOperationStageValidatorInterface, ProcessOutputCallbackInterface { use StringTranslationTrait; @@ -30,7 +30,7 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface /** * The Composer runner. * - * @var \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface + * @var \PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface */ protected $composer; @@ -51,7 +51,7 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface /** * Constructs a ComposerExecutableValidator object. * - * @param \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface $composer + * @param \PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface $composer * The Composer runner. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler service. diff --git a/package_manager/tests/modules/package_manager_bypass/src/Beginner.php b/package_manager/tests/modules/package_manager_bypass/src/Beginner.php index 5fc291a1ee..6509c0fcf1 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/Beginner.php +++ b/package_manager/tests/modules/package_manager_bypass/src/Beginner.php @@ -2,8 +2,11 @@ namespace Drupal\package_manager_bypass; -use PhpTuf\ComposerStager\Domain\BeginnerInterface; -use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface; +use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessOutputCallback\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ProcessRunnerInterface; +use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; +use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface; /** * Defines an update beginner which doesn't do anything. @@ -13,7 +16,7 @@ class Beginner extends InvocationRecorderBase implements BeginnerInterface { /** * {@inheritdoc} */ - public function begin(string $activeDir, string $stagingDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void { + public function begin(PathInterface $activeDir, PathInterface $stagingDir, ?PathListInterface $exclusions = NULL, ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = ProcessRunnerInterface::DEFAULT_TIMEOUT): void { $this->saveInvocationArguments($activeDir, $stagingDir, $exclusions, $timeout); } diff --git a/package_manager/tests/modules/package_manager_bypass/src/Committer.php b/package_manager/tests/modules/package_manager_bypass/src/Committer.php index f5f40847e4..ea528824a9 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/Committer.php +++ b/package_manager/tests/modules/package_manager_bypass/src/Committer.php @@ -2,43 +2,22 @@ namespace Drupal\package_manager_bypass; -use PhpTuf\ComposerStager\Domain\CommitterInterface; -use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface; +use PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessOutputCallback\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ProcessRunnerInterface; +use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; +use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface; /** * Defines an update committer which doesn't do any actual committing. */ class Committer extends InvocationRecorderBase implements CommitterInterface { - /** - * The decorated committer service. - * - * @var \PhpTuf\ComposerStager\Domain\CommitterInterface - */ - private $decorated; - - /** - * Constructs a Committer object. - * - * @param \PhpTuf\ComposerStager\Domain\CommitterInterface $decorated - * The decorated committer service. - */ - public function __construct(CommitterInterface $decorated) { - $this->decorated = $decorated; - } - /** * {@inheritdoc} */ - public function commit(string $stagingDir, string $activeDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void { + public function commit(PathInterface $stagingDir, PathInterface $activeDir, ?PathListInterface $exclusions = NULL, ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = ProcessRunnerInterface::DEFAULT_TIMEOUT): void { $this->saveInvocationArguments($stagingDir, $activeDir, $exclusions, $timeout); } - /** - * {@inheritdoc} - */ - public function directoryExists(string $stagingDir): bool { - return $this->decorated->directoryExists($stagingDir); - } - } diff --git a/package_manager/tests/modules/package_manager_bypass/src/Stager.php b/package_manager/tests/modules/package_manager_bypass/src/Stager.php index 237eccab38..38a67fb3e7 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/Stager.php +++ b/package_manager/tests/modules/package_manager_bypass/src/Stager.php @@ -2,8 +2,10 @@ namespace Drupal\package_manager_bypass; -use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface; -use PhpTuf\ComposerStager\Domain\StagerInterface; +use PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessOutputCallback\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ProcessRunnerInterface; +use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; /** * Defines an update stager which doesn't actually do anything. @@ -13,7 +15,7 @@ class Stager extends InvocationRecorderBase implements StagerInterface { /** * {@inheritdoc} */ - public function stage(array $composerCommand, string $stagingDir, ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void { + public function stage(array $composerCommand, PathInterface $activeDir, PathInterface $stagingDir, ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = ProcessRunnerInterface::DEFAULT_TIMEOUT): void { $this->saveInvocationArguments($composerCommand, $stagingDir); } diff --git a/package_manager/tests/modules/package_manager_test_api/src/ApiController.php b/package_manager/tests/modules/package_manager_test_api/src/ApiController.php index 45eb27f0f8..2d586cdf6f 100644 --- a/package_manager/tests/modules/package_manager_test_api/src/ApiController.php +++ b/package_manager/tests/modules/package_manager_test_api/src/ApiController.php @@ -5,6 +5,7 @@ namespace Drupal\package_manager_test_api; use Drupal\Core\Controller\ControllerBase; use Drupal\package_manager\PathLocator; use Drupal\package_manager\Stage; +use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -54,7 +55,8 @@ class ApiController extends ControllerBase { $container->get('file_system'), $container->get('event_dispatcher'), $container->get('tempstore.shared'), - $container->get('datetime.time') + $container->get('datetime.time'), + $container->get(PathFactoryInterface::class) ); return new static( $stage, diff --git a/package_manager/tests/src/Kernel/ComposerExecutableValidatorTest.php b/package_manager/tests/src/Kernel/ComposerExecutableValidatorTest.php index 7fd7b69989..a9d60ac959 100644 --- a/package_manager/tests/src/Kernel/ComposerExecutableValidatorTest.php +++ b/package_manager/tests/src/Kernel/ComposerExecutableValidatorTest.php @@ -7,8 +7,8 @@ use Drupal\Core\Url; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Validator\ComposerExecutableValidator; use Drupal\package_manager\ValidationResult; -use PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface; -use PhpTuf\ComposerStager\Exception\IOException; +use PhpTuf\ComposerStager\Domain\Exception\IOException; +use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface; use Prophecy\Argument; /** @@ -21,7 +21,7 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase { /** * The mocked Composer runner. * - * @var \Prophecy\Prophecy\ObjectProphecy|\PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface + * @var \Prophecy\Prophecy\ObjectProphecy|\PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface */ private $composerRunner; diff --git a/package_manager/tests/src/Kernel/ExecutableFinderTest.php b/package_manager/tests/src/Kernel/ExecutableFinderTest.php index 1dc88e6647..ff7ed9933a 100644 --- a/package_manager/tests/src/Kernel/ExecutableFinderTest.php +++ b/package_manager/tests/src/Kernel/ExecutableFinderTest.php @@ -4,7 +4,7 @@ namespace Drupal\Tests\package_manager\Kernel; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\package_manager\ExecutableFinder; -use PhpTuf\ComposerStager\Infrastructure\Process\ExecutableFinderInterface; +use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; /** diff --git a/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php b/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php index dacde715a1..6516815ce9 100644 --- a/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php +++ b/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php @@ -3,9 +3,9 @@ namespace Drupal\Tests\package_manager\Kernel; use Drupal\KernelTests\KernelTestBase; -use PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface; -use PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer; -use PhpTuf\ComposerStager\Infrastructure\FileSyncer\RsyncFileSyncer; +use PhpTuf\ComposerStager\Domain\Service\FileSyncer\FileSyncerInterface; +use PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer; +use PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer; /** * @covers \Drupal\package_manager\FileSyncerFactory diff --git a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php index 3a04735d0c..c42d0bf025 100644 --- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php +++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php @@ -16,6 +16,10 @@ use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamDirectory; use org\bovigo\vfs\vfsStreamFile; use org\bovigo\vfs\visitor\vfsStreamAbstractVisitor; +use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; +use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; +use PhpTuf\ComposerStager\Infrastructure\Value\Path\AbstractPath; +use Symfony\Component\DependencyInjection\Definition; /** * Base class for kernel tests of Package Manager's functionality. @@ -73,6 +77,13 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { public function register(ContainerBuilder $container) { parent::register($container); + // Ensure that Composer Stager uses the test path factory, which is aware + // of the virtual file system. + $definition = new Definition(TestPathFactory::class); + $class = $definition->getClass(); + $container->setDefinition($class, $definition->setPublic(FALSE)); + $container->setAlias(PathFactoryInterface::class, $class); + foreach ($this->disableValidators as $service_id) { if ($container->hasDefinition($service_id)) { $container->getDefinition($service_id)->clearTag('event_subscriber'); @@ -96,7 +107,8 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { $this->container->get('file_system'), $this->container->get('event_dispatcher'), $this->container->get('tempstore.shared'), - $this->container->get('datetime.time') + $this->container->get('datetime.time'), + new TestPathFactory() ); } @@ -284,6 +296,38 @@ trait TestStageTrait { } } + +/** + * Defines a path value object that is aware of the virtual file system. + */ +class TestPath extends AbstractPath { + + /** + * {@inheritdoc} + */ + protected function doResolve(string $basePath): string { + if (str_starts_with($this->path, vfsStream::SCHEME . '://')) { + return $this->path; + } + return implode(DIRECTORY_SEPARATOR, [$basePath, $this->path]); + } + +} + +/** + * Defines a path factory that is aware of the virtual file system. + */ +class TestPathFactory implements PathFactoryInterface { + + /** + * {@inheritdoc} + */ + public static function create(string $path): PathInterface { + return new TestPath($path); + } + +} + /** * Defines a stage specifically for testing purposes. */ -- GitLab