diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index a5e5545c3a647ed120e68dbee0c58b52d3b29439..5d0fc38d790a6515e2c9aa70e8fe1134c2bdde64 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 dea4d1ff45b378a6ee3238d76c8373357b9a5dfd..2e4867dab545e638a08fae4c91963d7f01fafeb7 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 1d6b9da4c2bcf10dc4c8f85da0f8d582294f2174..5027023d5054bb23b10e16b01b34c15526d4ffa1 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 c4fb7265e2bef0967057a98dbd6b9fe73f025c3f..a533010e3cd6b86ecbc22a298d0f60455c77e834 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 31701a6b04220fdaa5cbc456c28fd209cab2999f..60f7142c4af76d0d04bfeed502fa371e43375fe7 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 d18f45be1327de05370db1c6cfefd8e3d2254c4a..05c03183d5fe0d991ffe36242d0a1d942ec2b7a7 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 65fdfbcb73a90d95f6405ba340de4d5a501d397c..98a28f545c1a14219d23e502adff595f84b7203c 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 dd9ab876071ed9f8669e22c0daf1a7c3a437fb44..8348ed090d822f848b1165c6328122e64cf9b42c 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 fa1a8565d086bea0c7d03d269a25ac1609b7ee85..d7089d80dc2f24fe2c83a69eb5f8fca9307b5637 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 49acc42a4f4d71c4dc6f6bdeb42b333c68ad46ba..c8194d7ae468fef257da5062cca56b22b87c8593 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 d985321bd47c919f371d809b5e39ec3f860fd501..b6252e5bf887acf5da194df5d92f4ed982abed35 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 5fc291a1ee7be94c32d81b9a62981b59f7964034..6509c0fcf1873ab5857ceb92eea2c1ad7c77f308 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 f5f40847e4d8929037cec72bfacc7bfc50e81897..ea528824a9c4537e4966e664d072c53175572eb3 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 237eccab38c119a5c764dc1337674b41458daa59..38a67fb3e7e6e21591691040393831efdbe75084 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 45eb27f0f8d1091476fcfa98a894a2929391430f..2d586cdf6f5ed9f7aee2d34799b245c970d2e792 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 7fd7b6998918fb071afe8932dd962a5c7dc796fc..a9d60ac959bb16883715b95b9ac8b725013003cf 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 1dc88e66472329749d42c65204288d99c17abb06..ff7ed9933a83b3a466090a116f4d54a75956c298 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 dacde715a1515132450d884f0811e53f7d70a35b..6516815ce9daf6cd8c9355adbf8fca77c3601245 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 3a04735d0c2c999457e5727c51d987e3bd5e34ad..c42d0bf025688df3b935d0cf85ca7272f3ead6af 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. */