From 99a864a0d1983430d1a98db23aeacea430cd8ff9 Mon Sep 17 00:00:00 2001 From: Adam G-H <32250-phenaproxima@users.noreply.drupalcode.org> Date: Fri, 7 Jul 2023 17:13:58 +0000 Subject: [PATCH] Issue #3372673 by phenaproxima, tedbow: Update Composer Stager to 2.0.0-alpha4 to pave the way for translatability --- automatic_updates.services.yml | 18 +------- .../src/ExtensionUpdateStage.php | 16 +++---- composer.json | 2 +- package_manager/package_manager.install | 7 ++-- package_manager/package_manager.services.yml | 18 ++++---- package_manager/src/ComposerInspector.php | 18 ++++---- .../src/Event/CollectPathsToExcludeEvent.php | 20 ++++----- package_manager/src/ExecutableFinder.php | 22 +++------- package_manager/src/FileSyncerFactory.php | 14 +++---- .../src/NoSymlinksPointToADirectory.php | 22 ++++++---- .../src/PackageManagerServiceProvider.php | 11 ++--- .../src/PackageManagerUninstallValidator.php | 2 +- package_manager/src/ProcessFactory.php | 22 ++++------ package_manager/src/ProcessOutputCallback.php | 6 ++- package_manager/src/StageBase.php | 30 ++++++------- package_manager/src/StatusCheckTrait.php | 4 +- .../Validator/ComposerPluginsValidator.php | 2 +- .../src/Validator/RsyncValidator.php | 6 +-- .../src/Validator/SymlinkValidator.php | 14 +++---- .../src/FixtureManipulator.php | 16 ++++--- .../src/StageFixtureManipulator.php | 16 +++---- .../src/LoggingBeginner.php | 14 +++---- .../src/LoggingCommitter.php | 14 +++---- .../package_manager_bypass/src/NoOpStager.php | 10 ++--- .../src/ApiController.php | 3 +- .../Functional/ComposerRequirementTest.php | 18 ++++---- .../src/Kernel/ComposerInspectorTest.php | 22 +++++----- .../tests/src/Kernel/ExecutableFinderTest.php | 10 ++++- .../src/Kernel/FileSyncerFactoryTest.php | 6 +-- .../Kernel/PackageManagerKernelTestBase.php | 2 +- .../SqliteDatabaseExcluderTest.php | 2 +- .../tests/src/Kernel/RsyncValidatorTest.php | 10 +++-- .../tests/src/Kernel/ServicesTest.php | 4 +- .../tests/src/Kernel/StageBaseTest.php | 42 +++++++++++-------- .../tests/src/Kernel/StatusCheckTraitTest.php | 2 +- .../tests/src/Kernel/SymlinkValidatorTest.php | 27 +++++++----- .../tests/src/Unit/ProcessFactoryTest.php | 12 +++++- .../src/Unit/ProcessOutputCallbackTest.php | 2 +- src/CronUpdateStage.php | 16 +++---- src/UpdateStage.php | 16 +++---- .../ComposerStagerOperationFailureTest.php | 8 ++-- tests/src/Kernel/CronUpdateStageTest.php | 2 +- tests/src/Kernel/UpdateStageTest.php | 11 ++++- 43 files changed, 286 insertions(+), 253 deletions(-) diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index 9b29fe9166..8ec0841cb2 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -28,23 +28,7 @@ services: calls: - ['setLogger', ['@logger.channel.automatic_updates']] arguments: - - '@automatic_updates.release_chooser' - - '@plugin.manager.mail' - - '@automatic_updates.status_check_mailer' - - '@state' - - '@config.factory' - - '@package_manager.composer_inspector' - - '@package_manager.path_locator' - - '@PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface' - - '@PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface' - - '@PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface' - - '@file_system' - - '@event_dispatcher' - - '@tempstore.shared' - - '@datetime.time' - - '@PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface' - - '@package_manager.failure_marker' - - '@automatic_updates.cron_update_stage.inner' + $inner: '@automatic_updates.cron_update_stage.inner' decorates: 'cron' Drupal\automatic_updates\CronUpdateStage: '@automatic_updates.cron_update_stage' automatic_updates.requested_update_validator: diff --git a/automatic_updates_extensions/src/ExtensionUpdateStage.php b/automatic_updates_extensions/src/ExtensionUpdateStage.php index cc4b854740..9fb8df315f 100644 --- a/automatic_updates_extensions/src/ExtensionUpdateStage.php +++ b/automatic_updates_extensions/src/ExtensionUpdateStage.php @@ -13,10 +13,10 @@ use Drupal\package_manager\FailureMarker; use Drupal\package_manager\LegacyVersionUtility; use Drupal\package_manager\PathLocator; use Drupal\package_manager\StageBase; -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\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Core\CommitterInterface; +use PhpTuf\ComposerStager\API\Core\StagerInterface; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -35,11 +35,11 @@ class ExtensionUpdateStage extends StageBase { * The Composer inspector service. * @param \Drupal\package_manager\PathLocator $pathLocator * The path locator service. - * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $beginner + * @param \PhpTuf\ComposerStager\API\Core\BeginnerInterface $beginner * The beginner service. - * @param \PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface $stager + * @param \PhpTuf\ComposerStager\API\Core\StagerInterface $stager * The stager service. - * @param \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface $committer + * @param \PhpTuf\ComposerStager\API\Core\CommitterInterface $committer * The committer service. * @param \Drupal\Core\File\FileSystemInterface $fileSystem * The file system service. @@ -49,7 +49,7 @@ class ExtensionUpdateStage extends StageBase { * The shared tempstore factory. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service. * @param \Drupal\package_manager\FailureMarker $failureMarker * The failure marker service. diff --git a/composer.json b/composer.json index 3e19d7afce..24f1d56a65 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ }, "require": { "ext-json": "*", - "php-tuf/composer-stager": "2.0-alpha2", + "php-tuf/composer-stager": "2.0-alpha4", "composer-runtime-api": "^2.1" }, "require-dev": { diff --git a/package_manager/package_manager.install b/package_manager/package_manager.install index 5d59d0a8a3..303e3de373 100644 --- a/package_manager/package_manager.install +++ b/package_manager/package_manager.install @@ -9,7 +9,8 @@ declare(strict_types = 1); use Drupal\package_manager\ComposerInspector; use Drupal\package_manager\Exception\StageFailureMarkerException; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; /** * Implements hook_requirements(). @@ -17,7 +18,7 @@ use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterfac function package_manager_requirements(string $phase) { $requirements = []; // BEGIN: DELETE FROM CORE MERGE REQUEST - if (!class_exists('\PhpTuf\ComposerStager\Domain\Core\Beginner\Beginner')) { + if (!interface_exists(BeginnerInterface::class)) { $requirements['package_manager_composer_dependencies'] = [ 'title' => t('Missing dependency'), 'description' => t('External dependencies for Package Manager are not available. Composer must be used to download the module with dependencies.'), @@ -45,7 +46,7 @@ function package_manager_requirements(string $phase) { if ($phase !== 'runtime') { return $requirements; } - /** @var \PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface $executable_finder */ + /** @var \PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface $executable_finder */ $executable_finder = \Drupal::service(ExecutableFinderInterface::class); // Report the Composer version in use, as well as its path. diff --git a/package_manager/package_manager.services.yml b/package_manager/package_manager.services.yml index 3e6a7f50c5..43e0aa906b 100644 --- a/package_manager/package_manager.services.yml +++ b/package_manager/package_manager.services.yml @@ -16,11 +16,11 @@ services: public: false Drupal\package_manager\FileSyncerFactory: public: false - PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface: + PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface: alias: 'Drupal\package_manager\ExecutableFinder' - PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface: + PhpTuf\ComposerStager\API\Process\Factory\ProcessFactoryInterface: alias: 'Drupal\package_manager\ProcessFactory' - PhpTuf\ComposerStager\Domain\Service\FileSyncer\FileSyncerInterface: + PhpTuf\ComposerStager\API\FileSyncer\Service\FileSyncerInterface: factory: ['@Drupal\package_manager\FileSyncerFactory', 'create'] logger.channel.package_manager: parent: logger.channel_base @@ -33,14 +33,14 @@ services: # Services provided to Drupal by Package Manager. package_manager.beginner: - class: PhpTuf\ComposerStager\Domain\Core\Beginner\Beginner - PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface: '@package_manager.beginner' + class: PhpTuf\ComposerStager\Internal\Core\Beginner + PhpTuf\ComposerStager\API\Core\BeginnerInterface: '@package_manager.beginner' package_manager.stager: - class: PhpTuf\ComposerStager\Domain\Core\Stager\Stager - PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface: '@package_manager.stager' + class: PhpTuf\ComposerStager\Internal\Core\Stager + PhpTuf\ComposerStager\API\Core\StagerInterface: '@package_manager.stager' package_manager.committer: - class: PhpTuf\ComposerStager\Domain\Core\Committer\Committer - PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface: '@package_manager.committer' + class: PhpTuf\ComposerStager\Internal\Core\Committer + PhpTuf\ComposerStager\API\Core\CommitterInterface: '@package_manager.committer' package_manager.path_locator: class: Drupal\package_manager\PathLocator arguments: diff --git a/package_manager/src/ComposerInspector.php b/package_manager/src/ComposerInspector.php index 013d0ca7da..4c3044bd60 100644 --- a/package_manager/src/ComposerInspector.php +++ b/package_manager/src/ComposerInspector.php @@ -7,11 +7,11 @@ namespace Drupal\package_manager; use Composer\Semver\Semver; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\package_manager\Exception\ComposerNotReadyException; -use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; -use PhpTuf\ComposerStager\Domain\Exception\RuntimeException; -use PhpTuf\ComposerStager\Domain\Service\Precondition\ComposerIsAvailableInterface; -use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Exception\PreconditionException; +use PhpTuf\ComposerStager\API\Exception\RuntimeException; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Precondition\Service\ComposerIsAvailableInterface; +use PhpTuf\ComposerStager\API\Process\Service\ComposerProcessRunnerInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Psr\Log\LoggerInterface; @@ -63,15 +63,15 @@ class ComposerInspector implements LoggerAwareInterface { /** * Constructs a ComposerInspector object. * - * @param \PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface $runner + * @param \PhpTuf\ComposerStager\API\Process\Service\ComposerProcessRunnerInterface $runner * The Composer runner service from Composer Stager. - * @param \PhpTuf\ComposerStager\Domain\Service\Precondition\ComposerIsAvailableInterface $composerIsAvailable + * @param \PhpTuf\ComposerStager\API\Precondition\Service\ComposerIsAvailableInterface $composerIsAvailable * The Composer Stager precondition to ensure that Composer is available. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service from Composer Stager. */ public function __construct( - private readonly ComposerRunnerInterface $runner, + private readonly ComposerProcessRunnerInterface $runner, private readonly ComposerIsAvailableInterface $composerIsAvailable, private readonly PathFactoryInterface $pathFactory ) { diff --git a/package_manager/src/Event/CollectPathsToExcludeEvent.php b/package_manager/src/Event/CollectPathsToExcludeEvent.php index facece949a..ea63d612a1 100644 --- a/package_manager/src/Event/CollectPathsToExcludeEvent.php +++ b/package_manager/src/Event/CollectPathsToExcludeEvent.php @@ -6,9 +6,9 @@ namespace Drupal\package_manager\Event; use Drupal\package_manager\StageBase; use Drupal\package_manager\PathLocator; -use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Value\PathList\PathList; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathList; +use PhpTuf\ComposerStager\API\Path\Value\PathListInterface; /** * Defines an event that collects paths to exclude. @@ -21,7 +21,7 @@ final class CollectPathsToExcludeEvent extends StageEvent implements PathListInt /** * The list of paths to exclude. * - * @var \PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface + * @var \PhpTuf\ComposerStager\API\Path\Value\PathListInterface */ protected PathListInterface $pathList; @@ -32,7 +32,7 @@ final class CollectPathsToExcludeEvent extends StageEvent implements PathListInt * The stage which fired this event. * @param \Drupal\package_manager\PathLocator $pathLocator * The path locator service. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service. */ public function __construct( @@ -41,14 +41,14 @@ final class CollectPathsToExcludeEvent extends StageEvent implements PathListInt protected PathFactoryInterface $pathFactory ) { parent::__construct($stage); - $this->pathList = new PathList([]); + $this->pathList = new PathList(); } /** * {@inheritdoc} */ - public function add(array $paths): void { - $this->pathList->add($paths); + public function add(string ...$paths): void { + $this->pathList->add(...$paths); } /** @@ -76,7 +76,7 @@ final class CollectPathsToExcludeEvent extends StageEvent implements PathListInt foreach ($paths as $path) { // Make the path relative to the project root by prefixing the web root. - $this->add([$web_root . $path]); + $this->add($web_root . $path); } } @@ -101,7 +101,7 @@ final class CollectPathsToExcludeEvent extends StageEvent implements PathListInt // Make absolute paths relative to the project root. $path = str_replace($project_root, '', $path); $path = ltrim($path, '/'); - $this->add([$path]); + $this->add($path); } } diff --git a/package_manager/src/ExecutableFinder.php b/package_manager/src/ExecutableFinder.php index 93e8ddd05a..731a751c6d 100644 --- a/package_manager/src/ExecutableFinder.php +++ b/package_manager/src/ExecutableFinder.php @@ -5,9 +5,8 @@ declare(strict_types = 1); namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinder as StagerExecutableFinder; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; -use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; +use PhpTuf\ComposerStager\Internal\Finder\Service\ExecutableFinder as StagerExecutableFinder; /** * An executable finder which looks for executable paths in configuration. @@ -19,27 +18,18 @@ use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; */ final class ExecutableFinder implements ExecutableFinderInterface { - /** - * The decorated executable finder. - * - * @var \PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinder - */ - private $decorated; - /** * Constructs an ExecutableFinder object. * - * @param \Symfony\Component\Process\ExecutableFinder $symfony_executable_finder - * The Symfony executable finder. + * @param \PhpTuf\ComposerStager\Internal\Finder\Service\ExecutableFinder $decorated + * The decorated executable finder. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory service. */ public function __construct( - SymfonyExecutableFinder $symfony_executable_finder, + private readonly StagerExecutableFinder $decorated, private readonly ConfigFactoryInterface $configFactory - ) { - $this->decorated = new StagerExecutableFinder($symfony_executable_finder); - } + ) {} /** * {@inheritdoc} diff --git a/package_manager/src/FileSyncerFactory.php b/package_manager/src/FileSyncerFactory.php index 1210ae817f..cd7beee881 100644 --- a/package_manager/src/FileSyncerFactory.php +++ b/package_manager/src/FileSyncerFactory.php @@ -5,10 +5,10 @@ declare(strict_types = 1); namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; -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 PhpTuf\ComposerStager\API\FileSyncer\Service\FileSyncerInterface; +use PhpTuf\ComposerStager\Internal\FileSyncer\Factory\FileSyncerFactory as StagerFileSyncerFactory; +use PhpTuf\ComposerStager\Internal\FileSyncer\Service\PhpFileSyncer; +use PhpTuf\ComposerStager\Internal\FileSyncer\Service\RsyncFileSyncer; use Symfony\Component\Process\ExecutableFinder; /** @@ -24,7 +24,7 @@ final class FileSyncerFactory { /** * The decorated file syncer factory. * - * @var \PhpTuf\ComposerStager\Infrastructure\Factory\FileSyncer\FileSyncerFactory + * @var \PhpTuf\ComposerStager\Internal\FileSyncer\Factory\FileSyncerFactory */ private $decorated; @@ -33,9 +33,9 @@ final class FileSyncerFactory { * * @param \Symfony\Component\Process\ExecutableFinder $executable_finder * The Symfony executable finder. - * @param \PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer $phpFileSyncer + * @param \PhpTuf\ComposerStager\Internal\FileSyncer\Service\PhpFileSyncer $phpFileSyncer * The PHP file syncer service. - * @param \PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer $rsyncFileSyncer + * @param \PhpTuf\ComposerStager\Internal\FileSyncer\Service\RsyncFileSyncer $rsyncFileSyncer * The rsync file syncer service. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory service. diff --git a/package_manager/src/NoSymlinksPointToADirectory.php b/package_manager/src/NoSymlinksPointToADirectory.php index fb97daf558..98b44711cd 100644 --- a/package_manager/src/NoSymlinksPointToADirectory.php +++ b/package_manager/src/NoSymlinksPointToADirectory.php @@ -6,9 +6,10 @@ namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; -use PhpTuf\ComposerStager\Domain\Service\Precondition\NoSymlinksPointToADirectoryInterface; -use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; -use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathListInterface; +use PhpTuf\ComposerStager\API\Precondition\Service\NoSymlinksPointToADirectoryInterface; +use PhpTuf\ComposerStager\API\Translation\Value\TranslatableInterface; /** * Checks if the code base contains any symlinks that point to a directory. @@ -29,7 +30,7 @@ final class NoSymlinksPointToADirectory implements NoSymlinksPointToADirectoryIn /** * Constructs a NoSymlinksPointToADirectory object. * - * @param \PhpTuf\ComposerStager\Domain\Service\Precondition\NoSymlinksPointToADirectoryInterface $decorated + * @param \PhpTuf\ComposerStager\API\Precondition\Service\NoSymlinksPointToADirectoryInterface $decorated * The decorated precondition. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory. @@ -42,21 +43,21 @@ final class NoSymlinksPointToADirectory implements NoSymlinksPointToADirectoryIn /** * {@inheritdoc} */ - public function getName(): string { + public function getName(): TranslatableInterface { return $this->decorated->getName(); } /** * {@inheritdoc} */ - public function getDescription(): string { + public function getDescription(): TranslatableInterface { return $this->decorated->getDescription(); } /** * {@inheritdoc} */ - public function getStatusMessage(PathInterface $activeDir, PathInterface $stagingDir, ?PathListInterface $exclusions = NULL,): string { + public function getStatusMessage(PathInterface $activeDir, PathInterface $stagingDir, ?PathListInterface $exclusions = NULL,): TranslatableInterface { if ($this->isUsingRsync()) { return $this->t('Symlinks to directories are supported by the rsync file syncer.'); } @@ -94,4 +95,11 @@ final class NoSymlinksPointToADirectory implements NoSymlinksPointToADirectoryIn return $syncer === 'rsync'; } + /** + * {@inheritdoc} + */ + public function getLeaves(): array { + return [$this]; + } + } diff --git a/package_manager/src/PackageManagerServiceProvider.php b/package_manager/src/PackageManagerServiceProvider.php index b6f5ccb513..ba31f9985b 100644 --- a/package_manager/src/PackageManagerServiceProvider.php +++ b/package_manager/src/PackageManagerServiceProvider.php @@ -6,8 +6,8 @@ namespace Drupal\package_manager; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceProviderBase; -use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface; -use PhpTuf\ComposerStager\Domain\Service\Precondition\NoSymlinksPointToADirectoryInterface; +use PhpTuf\ComposerStager\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Precondition\Service\NoSymlinksPointToADirectoryInterface; /** * Defines dynamic container services for Package Manager. @@ -33,13 +33,14 @@ final class PackageManagerServiceProvider extends ServiceProviderBase { // Use an interface that we know exists to determine the absolute path where // Composer Stager is installed. $mirror = new \ReflectionClass(BeginnerInterface::class); - $path = dirname($mirror->getFileName(), 4); + $path = dirname($mirror->getFileName(), 3); // Certain subdirectories of Composer Stager shouldn't be scanned for // services. $ignore_directories = [ - $path . '/Domain/Exception', - $path . '/Infrastructure/Value', + $path . '/API/Exception', + $path . '/Internal/Path/Value', + $path . '/Internal/Translation/Value', ]; // As we scan for services, compile a list of which classes implement which // interfaces so that we can set up aliases for interfaces that are only diff --git a/package_manager/src/PackageManagerUninstallValidator.php b/package_manager/src/PackageManagerUninstallValidator.php index fa81fe4275..27f8203abe 100644 --- a/package_manager/src/PackageManagerUninstallValidator.php +++ b/package_manager/src/PackageManagerUninstallValidator.php @@ -6,7 +6,7 @@ namespace Drupal\package_manager; use Drupal\Core\Extension\ModuleUninstallValidatorInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; diff --git a/package_manager/src/ProcessFactory.php b/package_manager/src/ProcessFactory.php index be9b445ec2..a231e61e0c 100644 --- a/package_manager/src/ProcessFactory.php +++ b/package_manager/src/ProcessFactory.php @@ -6,8 +6,8 @@ namespace Drupal\package_manager; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\File\FileSystemInterface; -use PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactory as StagerProcessFactory; +use PhpTuf\ComposerStager\API\Process\Factory\ProcessFactoryInterface; +use PhpTuf\ComposerStager\Internal\Process\Factory\ProcessFactory as StagerProcessFactory; use Symfony\Component\Process\Process; // cspell:ignore BINDIR @@ -22,13 +22,6 @@ use Symfony\Component\Process\Process; */ final class ProcessFactory implements ProcessFactoryInterface { - /** - * The decorated process factory. - * - * @var \PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface - */ - private $decorated; - /** * Constructs a ProcessFactory object. * @@ -36,13 +29,14 @@ final class ProcessFactory implements ProcessFactoryInterface { * The file system service. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory service. + * @param \PhpTuf\ComposerStager\Internal\Process\Factory\ProcessFactory $decorated + * The decorated process factory service. */ public function __construct( private readonly FileSystemInterface $fileSystem, - private readonly ConfigFactoryInterface $configFactory - ) { - $this->decorated = new StagerProcessFactory(); - } + private readonly ConfigFactoryInterface $configFactory, + private readonly StagerProcessFactory $decorated, + ) {} /** * Returns the value of an environment variable. @@ -67,7 +61,7 @@ final class ProcessFactory implements ProcessFactoryInterface { $process = $this->decorated->create($command); $env = $process->getEnv(); - if ($this->isComposerCommand($command)) { + if ($command && $this->isComposerCommand($command)) { $env['COMPOSER_HOME'] = $this->getComposerHomePath(); } // Ensure that the current PHP installation is the first place that will be diff --git a/package_manager/src/ProcessOutputCallback.php b/package_manager/src/ProcessOutputCallback.php index 8ce6625087..fd0ac56d8a 100644 --- a/package_manager/src/ProcessOutputCallback.php +++ b/package_manager/src/ProcessOutputCallback.php @@ -4,7 +4,7 @@ declare(strict_types = 1); namespace Drupal\package_manager; -use PhpTuf\ComposerStager\Domain\Service\ProcessOutputCallback\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessOutputCallbackInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Psr\Log\NullLogger; @@ -48,6 +48,10 @@ final class ProcessOutputCallback implements ProcessOutputCallbackInterface, Log * {@inheritdoc} */ public function __invoke(string $type, string $buffer): void { + // \Symfony\Component\Process\Process defines the output types in lowercase, + // but Composer Stager uses uppercase. + $type = strtoupper($type); + if ($type === self::OUT) { $this->outBuffer .= $buffer; } diff --git a/package_manager/src/StageBase.php b/package_manager/src/StageBase.php index d4f7a8c866..293ee12b11 100644 --- a/package_manager/src/StageBase.php +++ b/package_manager/src/StageBase.php @@ -28,13 +28,13 @@ use Drupal\package_manager\Exception\ApplyFailedException; use Drupal\package_manager\Exception\StageEventException; use Drupal\package_manager\Exception\StageException; use Drupal\package_manager\Exception\StageOwnershipException; -use PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface; -use PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface; -use PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface; -use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException; -use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Value\PathList\PathList; +use PhpTuf\ComposerStager\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Core\CommitterInterface; +use PhpTuf\ComposerStager\API\Core\StagerInterface; +use PhpTuf\ComposerStager\API\Exception\InvalidArgumentException; +use PhpTuf\ComposerStager\API\Exception\PreconditionException; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathList; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Psr\Log\NullLogger; @@ -166,11 +166,11 @@ abstract class StageBase implements LoggerAwareInterface { * * @param \Drupal\package_manager\PathLocator $pathLocator * The path locator service. - * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $beginner + * @param \PhpTuf\ComposerStager\API\Core\BeginnerInterface $beginner * The beginner service. - * @param \PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface $stager + * @param \PhpTuf\ComposerStager\API\Core\StagerInterface $stager * The stager service. - * @param \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface $committer + * @param \PhpTuf\ComposerStager\API\Core\CommitterInterface $committer * The committer service. * @param \Drupal\Core\File\FileSystemInterface $fileSystem * The file system service. @@ -180,7 +180,7 @@ abstract class StageBase implements LoggerAwareInterface { * The shared tempstore factory. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service. * @param \Drupal\package_manager\FailureMarker $failureMarker * The failure marker service. @@ -330,7 +330,7 @@ abstract class StageBase implements LoggerAwareInterface { $this->dispatch($event, [$this, 'markAsAvailable']); try { - $this->beginner->begin($active_dir, $stage_dir, new PathList($event->getExcludedPaths()), NULL, $timeout); + $this->beginner->begin($active_dir, $stage_dir, new PathList(...$event->getExcludedPaths()), NULL, $timeout); } catch (\Throwable $error) { $this->destroy(); @@ -452,10 +452,10 @@ abstract class StageBase implements LoggerAwareInterface { // Create a marker file so that we can tell later on if the commit failed. $this->failureMarker->write($this, $this->getFailureMarkerMessage()); // Exclude the failure file from the commit operation. - $paths_to_exclude = new PathList($event->getExcludedPaths()); - $paths_to_exclude->add([ + $paths_to_exclude = new PathList(...$event->getExcludedPaths()); + $paths_to_exclude->add( str_replace($this->pathLocator->getProjectRoot() . DIRECTORY_SEPARATOR, '', $this->failureMarker->getPath()), - ]); + ); try { $this->committer->commit($stage_dir, $active_dir, $paths_to_exclude, NULL, $timeout); diff --git a/package_manager/src/StatusCheckTrait.php b/package_manager/src/StatusCheckTrait.php index 4bad25258d..23386235b8 100644 --- a/package_manager/src/StatusCheckTrait.php +++ b/package_manager/src/StatusCheckTrait.php @@ -6,7 +6,7 @@ namespace Drupal\package_manager; use Drupal\package_manager\Event\CollectPathsToExcludeEvent; use Drupal\package_manager\Event\StatusCheckEvent; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -28,7 +28,7 @@ trait StatusCheckTrait { * (optional) The event dispatcher service. * @param \Drupal\package_manager\PathLocator $path_locator * (optional) The path locator service. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $path_factory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $path_factory * (optional) The path factory service. * * @return \Drupal\package_manager\ValidationResult[] diff --git a/package_manager/src/Validator/ComposerPluginsValidator.php b/package_manager/src/Validator/ComposerPluginsValidator.php index 369f0fb5a6..4cd11ce467 100644 --- a/package_manager/src/Validator/ComposerPluginsValidator.php +++ b/package_manager/src/Validator/ComposerPluginsValidator.php @@ -13,7 +13,7 @@ use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreOperationStageEvent; use Drupal\package_manager\Event\StatusCheckEvent; use Drupal\package_manager\PathLocator; -use PhpTuf\ComposerStager\Domain\Exception\RuntimeException; +use PhpTuf\ComposerStager\API\Exception\RuntimeException; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** diff --git a/package_manager/src/Validator/RsyncValidator.php b/package_manager/src/Validator/RsyncValidator.php index b6551fe75b..315ea17731 100644 --- a/package_manager/src/Validator/RsyncValidator.php +++ b/package_manager/src/Validator/RsyncValidator.php @@ -11,8 +11,8 @@ use Drupal\Core\Url; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreOperationStageEvent; use Drupal\package_manager\Event\StatusCheckEvent; -use PhpTuf\ComposerStager\Domain\Exception\LogicException; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Exception\LogicException; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -32,7 +32,7 @@ final class RsyncValidator implements EventSubscriberInterface { * * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory. - * @param \PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface $executableFinder + * @param \PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface $executableFinder * The executable finder service. * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler * The module handler service. diff --git a/package_manager/src/Validator/SymlinkValidator.php b/package_manager/src/Validator/SymlinkValidator.php index 80b7d50794..7c4da395aa 100644 --- a/package_manager/src/Validator/SymlinkValidator.php +++ b/package_manager/src/Validator/SymlinkValidator.php @@ -7,10 +7,10 @@ namespace Drupal\package_manager\Validator; use Drupal\package_manager\Event\PreOperationStageEvent; use Drupal\package_manager\Event\PreRequireEvent; use Drupal\package_manager\PathLocator; -use PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\NoUnsupportedLinksExistInterface; -use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Value\PathList\PathList; +use PhpTuf\ComposerStager\API\Exception\PreconditionException; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathList; +use PhpTuf\ComposerStager\API\Precondition\Service\NoUnsupportedLinksExistInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -32,9 +32,9 @@ final class SymlinkValidator implements EventSubscriberInterface { * * @param \Drupal\package_manager\PathLocator $pathLocator * The path locator service. - * @param \PhpTuf\ComposerStager\Domain\Aggregate\PreconditionsTree\NoUnsupportedLinksExistInterface $precondition + * @param \PhpTuf\ComposerStager\API\Precondition\Service\NoUnsupportedLinksExistInterface $precondition * The Composer Stager precondition that this validator wraps. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service. */ public function __construct( @@ -75,7 +75,7 @@ final class SymlinkValidator implements EventSubscriberInterface { } try { - $this->precondition->assertIsFulfilled($active_dir, $stage_dir, new PathList($excluded_paths)); + $this->precondition->assertIsFulfilled($active_dir, $stage_dir, new PathList(...$excluded_paths)); } catch (PreconditionException $e) { $event->addErrorFromThrowable($e); diff --git a/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php b/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php index 71ecc8c9fb..92aff515da 100644 --- a/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php +++ b/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php @@ -4,8 +4,8 @@ namespace Drupal\fixture_manipulator; use Drupal\Component\FileSystem\FileSystem; use Drupal\Component\Utility\NestedArray; -use PhpTuf\ComposerStager\Domain\Service\ProcessOutputCallback\ProcessOutputCallbackInterface; -use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\API\Process\Service\ComposerProcessRunnerInterface; use Symfony\Component\Filesystem\Filesystem as SymfonyFileSystem; use Drupal\Component\Serialization\Yaml; @@ -55,8 +55,8 @@ class FixtureManipulator { * Validate the fixtures still passes `composer validate`. */ private function validateComposer(): void { - /** @var \PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface $runner */ - $runner = \Drupal::service(ComposerRunnerInterface::class); + /** @var \PhpTuf\ComposerStager\API\Process\Service\ComposerProcessRunnerInterface $runner */ + $runner = \Drupal::service(ComposerProcessRunnerInterface::class); $runner->run([ 'validate', '--check-lock', @@ -446,6 +446,10 @@ class FixtureManipulator { * {@inheritdoc} */ public function __invoke(string $type, string $buffer): void { + // \Symfony\Component\Process\Process defines the output types in + // lowercase, but Composer Stager uses uppercase. + $type = strtoupper($type); + if ($type === self::OUT) { $this->stdout .= $buffer; return; @@ -458,8 +462,8 @@ class FixtureManipulator { } }; - /** @var \PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface $runner */ - $runner = \Drupal::service(ComposerRunnerInterface::class); + /** @var \PhpTuf\ComposerStager\API\Process\Service\ComposerProcessRunnerInterface $runner */ + $runner = \Drupal::service(ComposerProcessRunnerInterface::class); $command_options[] = "--working-dir={$this->dir}"; $runner->run($command_options, $plain_output); return $plain_output; diff --git a/package_manager/tests/modules/fixture_manipulator/src/StageFixtureManipulator.php b/package_manager/tests/modules/fixture_manipulator/src/StageFixtureManipulator.php index 03667d4dac..29e0db0da3 100644 --- a/package_manager/tests/modules/fixture_manipulator/src/StageFixtureManipulator.php +++ b/package_manager/tests/modules/fixture_manipulator/src/StageFixtureManipulator.php @@ -5,11 +5,11 @@ declare(strict_types = 1); namespace Drupal\fixture_manipulator; use Drupal\Core\State\StateInterface; -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; +use PhpTuf\ComposerStager\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathListInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessRunnerInterface; /** * A fixture manipulator service that commits changes after begin. @@ -31,7 +31,7 @@ final class StageFixtureManipulator extends FixtureManipulator implements Beginn /** * The decorated service. * - * @var \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface + * @var \PhpTuf\ComposerStager\API\Core\BeginnerInterface */ private BeginnerInterface $inner; @@ -40,7 +40,7 @@ final class StageFixtureManipulator extends FixtureManipulator implements Beginn * * @param \Drupal\Core\State\StateInterface $state * The state service. - * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $inner + * @param \PhpTuf\ComposerStager\API\Core\BeginnerInterface $inner * The decorated beginner service. */ public function __construct(StateInterface $state, BeginnerInterface $inner) { @@ -54,7 +54,7 @@ final class StageFixtureManipulator extends FixtureManipulator implements Beginn public function begin(PathInterface $activeDir, PathInterface $stagingDir, ?PathListInterface $exclusions = NULL, ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = ProcessRunnerInterface::DEFAULT_TIMEOUT): void { $this->inner->begin($activeDir, $stagingDir, $exclusions, $callback, $timeout); if ($this->getQueuedManipulationItems()) { - $this->doCommitChanges($stagingDir->resolve()); + $this->doCommitChanges($stagingDir->resolved()); } } diff --git a/package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php b/package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php index ffe51348c7..e5c154c828 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php +++ b/package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php @@ -5,11 +5,11 @@ declare(strict_types = 1); namespace Drupal\package_manager_bypass; use Drupal\Core\State\StateInterface; -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; +use PhpTuf\ComposerStager\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathListInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessRunnerInterface; /** * A composer-stager Beginner decorator that adds logging. @@ -24,7 +24,7 @@ final class LoggingBeginner implements BeginnerInterface { /** * The decorated service. * - * @var \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface + * @var \PhpTuf\ComposerStager\API\Core\BeginnerInterface */ private $inner; @@ -33,7 +33,7 @@ final class LoggingBeginner implements BeginnerInterface { * * @param \Drupal\Core\State\StateInterface $state * The state service. - * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $inner + * @param \PhpTuf\ComposerStager\API\Core\BeginnerInterface $inner * The decorated beginner service. */ public function __construct(StateInterface $state, BeginnerInterface $inner) { diff --git a/package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php b/package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php index e6aea32a9d..cf813a12db 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php +++ b/package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php @@ -5,11 +5,11 @@ declare(strict_types = 1); namespace Drupal\package_manager_bypass; use Drupal\Core\State\StateInterface; -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; +use PhpTuf\ComposerStager\API\Core\CommitterInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathListInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessRunnerInterface; /** * A composer-stager Committer decorator that adds logging. @@ -24,7 +24,7 @@ final class LoggingCommitter implements CommitterInterface { /** * The decorated service. * - * @var \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface + * @var \PhpTuf\ComposerStager\API\Core\CommitterInterface */ private $inner; @@ -33,7 +33,7 @@ final class LoggingCommitter implements CommitterInterface { * * @param \Drupal\Core\State\StateInterface $state * The state service. - * @param \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface $inner + * @param \PhpTuf\ComposerStager\API\Core\CommitterInterface $inner * The decorated committer service. */ public function __construct(StateInterface $state, CommitterInterface $inner) { diff --git a/package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php b/package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php index a7819d302e..5adc41d3cb 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php +++ b/package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php @@ -6,10 +6,10 @@ namespace Drupal\package_manager_bypass; use Composer\Json\JsonFile; use Drupal\Core\State\StateInterface; -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; +use PhpTuf\ComposerStager\API\Core\StagerInterface; +use PhpTuf\ComposerStager\API\Path\Value\PathInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessOutputCallbackInterface; +use PhpTuf\ComposerStager\API\Process\Service\ProcessRunnerInterface; /** * A composer-stager Stager implementation that does nothing, except logging. @@ -49,7 +49,7 @@ final class NoOpStager implements StagerInterface { // If desired, simulate a change to the lock file (e.g., as a result of // running `composer update`). - $lockFile = new JsonFile($stagingDir->resolve() . '/composer.lock'); + $lockFile = new JsonFile($stagingDir->resolved() . '/composer.lock'); $changeLockFile = $this->state->get(static::class . ' lock', TRUE); if ($changeLockFile && $lockFile->exists()) { 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 9178d26780..bbc229018a 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 @@ -8,6 +8,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Url; use Drupal\package_manager\PathLocator; use Drupal\package_manager\StageBase; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -65,7 +66,7 @@ class ApiController extends ControllerBase { $container->get('event_dispatcher'), $container->get('tempstore.shared'), $container->get('datetime.time'), - $container->get('PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface'), + $container->get(PathFactoryInterface::class), $container->get('package_manager.failure_marker')); return new static( $stage, diff --git a/package_manager/tests/src/Functional/ComposerRequirementTest.php b/package_manager/tests/src/Functional/ComposerRequirementTest.php index 8eb7729b7e..161a0f18e6 100644 --- a/package_manager/tests/src/Functional/ComposerRequirementTest.php +++ b/package_manager/tests/src/Functional/ComposerRequirementTest.php @@ -6,7 +6,7 @@ namespace Drupal\Tests\package_manager\Functional; use Drupal\package_manager\ComposerInspector; use Drupal\Tests\BrowserTestBase; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; /** * Tests that Package Manager shows the Composer version on the status report. @@ -27,14 +27,20 @@ class ComposerRequirementTest extends BrowserTestBase { protected $defaultTheme = 'stark'; /** - * Tests that Composer and file syncer info is listed on the status report. + * Tests that Composer version and path are listed on the status report. */ public function testComposerInfoShown(): void { - /** @var \PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface $executable_finder */ + $config = $this->config('package_manager.settings'); + + // Ensure we can locate the Composer executable. + /** @var \PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface $executable_finder */ $executable_finder = $this->container->get(ExecutableFinderInterface::class); $composer_path = $executable_finder->find('composer'); $composer_version = $this->container->get(ComposerInspector::class)->getVersion(); + // With a valid path to Composer, ensure the status report shows its version + // number and path. + $config->set('executables.composer', $composer_path)->save(); $account = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($account); $this->drupalGet('/admin/reports/status'); @@ -44,12 +50,10 @@ class ComposerRequirementTest extends BrowserTestBase { // If the path to Composer is invalid, we should see the error message // that gets raised when we try to get its version. - $this->config('package_manager.settings') - ->set('executables.composer', '/path/to/composer') - ->save(); + $config->set('executables.composer', '/path/to/composer')->save(); $this->getSession()->reload(); $assert_session->statusCodeEquals(200); - $assert_session->pageTextContains('Composer was not found. The error message was: The command "\'/path/to/composer\' \'--format=json\'" failed.'); + $assert_session->pageTextContains('Composer was not found. The error message was: Failed to run process: The command "\'/path/to/composer\' \'--format=json\'" failed.'); } } diff --git a/package_manager/tests/src/Kernel/ComposerInspectorTest.php b/package_manager/tests/src/Kernel/ComposerInspectorTest.php index 02cc502af1..5d4c0de288 100644 --- a/package_manager/tests/src/Kernel/ComposerInspectorTest.php +++ b/package_manager/tests/src/Kernel/ComposerInspectorTest.php @@ -14,11 +14,12 @@ use Drupal\package_manager\ProcessOutputCallback; use Drupal\package_manager\InstalledPackagesList; use Drupal\Tests\package_manager\Traits\InstalledPackagesListTrait; use Drupal\package_manager\PathLocator; -use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; -use PhpTuf\ComposerStager\Domain\Exception\RuntimeException; -use PhpTuf\ComposerStager\Domain\Service\Precondition\ComposerIsAvailableInterface; -use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ComposerRunnerInterface; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactory; +use PhpTuf\ComposerStager\API\Exception\PreconditionException; +use PhpTuf\ComposerStager\API\Exception\RuntimeException; +use PhpTuf\ComposerStager\API\Precondition\Service\ComposerIsAvailableInterface; +use PhpTuf\ComposerStager\API\Process\Service\ComposerProcessRunnerInterface; +use PhpTuf\ComposerStager\Internal\Path\Factory\PathFactory; +use PhpTuf\ComposerStager\Internal\Translation\Value\TranslatableMessage; use Prophecy\Argument; use Prophecy\Prophecy\ObjectProphecy; @@ -154,8 +155,9 @@ class ComposerInspectorTest extends PackageManagerKernelTestBase { $mocked_precondition = $precondition->reveal(); $this->container->set(ComposerIsAvailableInterface::class, $mocked_precondition); + $message = new TranslatableMessage("Well, that didn't work."); $precondition->assertIsFulfilled(Argument::cetera()) - ->willThrow(new PreconditionException($mocked_precondition, "Well, that didn't work.")) + ->willThrow(new PreconditionException($mocked_precondition, $message)) // The result of the precondition is statically cached, so it should only // be called once even though we call validate() twice. ->shouldBeCalledOnce(); @@ -250,7 +252,7 @@ class ComposerInspectorTest extends PackageManagerKernelTestBase { // The runner should be called with `validate` as the first argument, but // it won't affect the outcome of this test. $runner->run(Argument::withEntry(0, 'validate')); - $this->container->set(ComposerRunnerInterface::class, $runner->reveal()); + $this->container->set(ComposerProcessRunnerInterface::class, $runner->reveal()); if ($expected_message === '<default>') { $expected_message = "The detected Composer version, $reported_version, does not satisfy <code>" . ComposerInspector::SUPPORTED_VERSION . '</code>.'; @@ -285,7 +287,7 @@ class ComposerInspectorTest extends PackageManagerKernelTestBase { * [null] */ public function testGetVersion(?string $reported_version): void { - $this->container->set(ComposerRunnerInterface::class, $this->mockComposerRunner($reported_version)->reveal()); + $this->container->set(ComposerProcessRunnerInterface::class, $this->mockComposerRunner($reported_version)->reveal()); if (empty($reported_version)) { $this->expectException(\UnexpectedValueException::class); @@ -355,7 +357,7 @@ class ComposerInspectorTest extends PackageManagerKernelTestBase { */ public function testMetapackagePath(bool $is_metapackage, ?string $install_path, ?string $exception_message): void { $inspector = new class ( - $this->container->get(ComposerRunnerInterface::class), + $this->container->get(ComposerProcessRunnerInterface::class), $this->container->get(ComposerIsAvailableInterface::class), new PathFactory(), ) extends ComposerInspector { @@ -484,7 +486,7 @@ class ComposerInspectorTest extends PackageManagerKernelTestBase { * The configurator for the mocked Composer runner. */ private function mockComposerRunner(?string $reported_version): ObjectProphecy { - $runner = $this->prophesize(ComposerRunnerInterface::class); + $runner = $this->prophesize(ComposerProcessRunnerInterface::class); $pass_version_to_output_callback = function (array $arguments_passed_to_runner) use ($reported_version): void { $command_output = Json::encode([ diff --git a/package_manager/tests/src/Kernel/ExecutableFinderTest.php b/package_manager/tests/src/Kernel/ExecutableFinderTest.php index 5a4c4818a5..82402899b4 100644 --- a/package_manager/tests/src/Kernel/ExecutableFinderTest.php +++ b/package_manager/tests/src/Kernel/ExecutableFinderTest.php @@ -6,7 +6,9 @@ namespace Drupal\Tests\package_manager\Kernel; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\package_manager\ExecutableFinder; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; +use PhpTuf\ComposerStager\Internal\Finder\Service\ExecutableFinder as StagerExecutableFinder; +use PhpTuf\ComposerStager\API\Translation\Factory\TranslatableFactoryInterface; use Symfony\Component\Process\ExecutableFinder as SymfonyExecutableFinder; /** @@ -32,7 +34,10 @@ class ExecutableFinderTest extends PackageManagerKernelTestBase { }; $container->getDefinition(ExecutableFinder::class) - ->setArgument('$symfony_executable_finder', $symfony_executable_finder); + ->setArgument('$decorated', new StagerExecutableFinder( + $symfony_executable_finder, + $this->createMock(TranslatableFactoryInterface::class), + )); } /** @@ -44,6 +49,7 @@ class ExecutableFinderTest extends PackageManagerKernelTestBase { ->save(); $executable_finder = $this->container->get(ExecutableFinderInterface::class); + $this->assertInstanceOf(ExecutableFinder::class, $executable_finder); $this->assertSame('/path/to/composer', $executable_finder->find('composer')); $this->assertSame('/dev/null', $executable_finder->find('rsync')); } diff --git a/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php b/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php index c0b2f335d6..2ff5bb65ae 100644 --- a/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php +++ b/package_manager/tests/src/Kernel/FileSyncerFactoryTest.php @@ -6,9 +6,9 @@ namespace Drupal\Tests\package_manager\Kernel; use Drupal\KernelTests\KernelTestBase; use Drupal\Tests\package_manager\Traits\AssertPreconditionsTrait; -use PhpTuf\ComposerStager\Domain\Service\FileSyncer\FileSyncerInterface; -use PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\PhpFileSyncer; -use PhpTuf\ComposerStager\Infrastructure\Service\FileSyncer\RsyncFileSyncer; +use PhpTuf\ComposerStager\API\FileSyncer\Service\FileSyncerInterface; +use PhpTuf\ComposerStager\Internal\FileSyncer\Service\PhpFileSyncer; +use PhpTuf\ComposerStager\Internal\FileSyncer\Service\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 0dae050e06..b094bf13b1 100644 --- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php +++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php @@ -29,7 +29,7 @@ use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Utils; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactory; +use PhpTuf\ComposerStager\Internal\Path\Factory\PathFactory; use Psr\Http\Message\RequestInterface; use Symfony\Component\Filesystem\Filesystem; diff --git a/package_manager/tests/src/Kernel/PathExcluder/SqliteDatabaseExcluderTest.php b/package_manager/tests/src/Kernel/PathExcluder/SqliteDatabaseExcluderTest.php index 05fa39946e..b556127962 100644 --- a/package_manager/tests/src/Kernel/PathExcluder/SqliteDatabaseExcluderTest.php +++ b/package_manager/tests/src/Kernel/PathExcluder/SqliteDatabaseExcluderTest.php @@ -10,7 +10,7 @@ use Drupal\package_manager\Event\CollectPathsToExcludeEvent; use Drupal\package_manager\PathExcluder\SqliteDatabaseExcluder; use Drupal\package_manager\PathLocator; use Drupal\Tests\package_manager\Kernel\PackageManagerKernelTestBase; -use PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; /** * @covers \Drupal\package_manager\PathExcluder\SqliteDatabaseExcluder diff --git a/package_manager/tests/src/Kernel/RsyncValidatorTest.php b/package_manager/tests/src/Kernel/RsyncValidatorTest.php index 807636be9a..54b4aae401 100644 --- a/package_manager/tests/src/Kernel/RsyncValidatorTest.php +++ b/package_manager/tests/src/Kernel/RsyncValidatorTest.php @@ -8,8 +8,9 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\ValidationResult; use Drupal\package_manager\Validator\RsyncValidator; -use PhpTuf\ComposerStager\Domain\Exception\LogicException; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Exception\LogicException; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; +use PhpTuf\ComposerStager\Internal\Translation\Value\TranslatableMessage; /** * @covers \Drupal\package_manager\Validator\RsyncValidator @@ -21,7 +22,7 @@ class RsyncValidatorTest extends PackageManagerKernelTestBase { /** * The mocked executable finder. * - * @var \PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface + * @var \PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface */ private $executableFinder; @@ -120,7 +121,8 @@ class RsyncValidatorTest extends PackageManagerKernelTestBase { * Tests that the stage cannot be created if rsync is selected, but not found. */ public function testPreCreateFailsIfRsyncNotFound(): void { - $this->executableFinder->find('rsync')->willThrow(new LogicException('Nope!')); + $message = new TranslatableMessage('Nope!'); + $this->executableFinder->find('rsync')->willThrow(new LogicException($message)); $result = ValidationResult::createError([ t('<code>rsync</code> is not available.'), diff --git a/package_manager/tests/src/Kernel/ServicesTest.php b/package_manager/tests/src/Kernel/ServicesTest.php index e9d81754f0..26862671b2 100644 --- a/package_manager/tests/src/Kernel/ServicesTest.php +++ b/package_manager/tests/src/Kernel/ServicesTest.php @@ -8,8 +8,8 @@ use Drupal\KernelTests\KernelTestBase; use Drupal\package_manager\ExecutableFinder; use Drupal\package_manager\ProcessFactory; use Drupal\Tests\package_manager\Traits\AssertPreconditionsTrait; -use PhpTuf\ComposerStager\Infrastructure\Factory\Process\ProcessFactoryInterface; -use PhpTuf\ComposerStager\Infrastructure\Service\Finder\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Finder\Service\ExecutableFinderInterface; +use PhpTuf\ComposerStager\API\Process\Factory\ProcessFactoryInterface; /** * Tests that Package Manager services are wired correctly. diff --git a/package_manager/tests/src/Kernel/StageBaseTest.php b/package_manager/tests/src/Kernel/StageBaseTest.php index a1547f03d9..61e4939a58 100644 --- a/package_manager/tests/src/Kernel/StageBaseTest.php +++ b/package_manager/tests/src/Kernel/StageBaseTest.php @@ -22,9 +22,11 @@ use Drupal\package_manager\Validator\WritableFileSystemValidator; use Drupal\package_manager_bypass\LoggingBeginner; use Drupal\package_manager_bypass\LoggingCommitter; use Drupal\package_manager_bypass\NoOpStager; -use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException; -use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; -use PhpTuf\ComposerStager\Domain\Service\Precondition\PreconditionInterface; +use PhpTuf\ComposerStager\API\Exception\ExceptionInterface; +use PhpTuf\ComposerStager\API\Exception\InvalidArgumentException; +use PhpTuf\ComposerStager\API\Exception\PreconditionException; +use PhpTuf\ComposerStager\API\Precondition\Service\PreconditionInterface; +use PhpTuf\ComposerStager\Internal\Translation\Value\TranslatableMessage; use Psr\Log\LogLevel; use ColinODell\PsrTestLogger\TestLogger; @@ -227,11 +229,11 @@ class StageBaseTest extends PackageManagerKernelTestBase { // simulate an attempt to destroy the stage while it's being applied, for // testing purposes. $event->stage->destroy($force); - // @see \PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirDoesNotExist + // @see \PhpTuf\ComposerStager\Internal\Precondition\Service\StagingDirDoesNotExist LoggingCommitter::setException( new PreconditionException( $this->prophesize(PreconditionInterface::class)->reveal(), - 'Stage directory does not exist', + new TranslatableMessage('Stage directory does not exist'), ) ); }; @@ -359,14 +361,20 @@ class StageBaseTest extends PackageManagerKernelTestBase { $stage->create(); $stage->require(['drupal/core:9.8.1']); - $thrown_message = 'A very bad thing happened'; + $throwable_arguments = [ + 'A very bad thing happened', + 123, + ]; + // Composer Stager's exception messages are usually translatable, so they + // need to be wrapped by a TranslatableMessage object. + if (is_subclass_of($thrown_class, ExceptionInterface::class)) { + $throwable_arguments[0] = new TranslatableMessage($throwable_arguments[0]); + } // PreconditionException requires a preconditions object. if ($thrown_class === PreconditionException::class) { - $throwable = new PreconditionException($this->prophesize(PreconditionInterface::class)->reveal(), $thrown_message, 123); - } - else { - $throwable = new $thrown_class($thrown_message, 123); + array_unshift($throwable_arguments, $this->createMock(PreconditionInterface::class)); } + $throwable = new $thrown_class(...$throwable_arguments); LoggingCommitter::setException($throwable); try { @@ -374,19 +382,19 @@ class StageBaseTest extends PackageManagerKernelTestBase { $this->fail('Expected an exception.'); } catch (\Throwable $exception) { + $this->assertInstanceOf($expected_class, $exception); + $this->assertSame(123, $exception->getCode()); + // This needs to be done because we always use the message from // \Drupal\package_manager\Stage::getFailureMarkerMessage() when throwing // ApplyFailedException. if ($expected_class == ApplyFailedException::class) { $class_in_message = get_class($throwable); - $thrown_message = "/^Staged changes failed to apply, and the site is in an indeterminate state. It is strongly recommended to restore the code and database from a backup. Caused by $class_in_message, with this message: A very bad thing happened\nBacktrace:\n#0 .*/"; + $this->assertMatchesRegularExpression("/^Staged changes failed to apply, and the site is in an indeterminate state. It is strongly recommended to restore the code and database from a backup. Caused by $class_in_message, with this message: A very bad thing happened\nBacktrace:\n#0 .*/", $exception->getMessage()); } else { - $thrown_message = "/^$thrown_message$/"; + $this->assertSame('A very bad thing happened', $exception->getMessage()); } - $this->assertInstanceOf($expected_class, $exception); - $this->assertMatchesRegularExpression($thrown_message, $exception->getMessage()); - $this->assertSame(123, $exception->getCode()); $failure_marker = $this->container->get(FailureMarker::class); if ($exception instanceof ApplyFailedException) { @@ -644,7 +652,7 @@ class StageBaseTest extends PackageManagerKernelTestBase { */ public function testCollectPathsToExclude(): void { $this->addEventTestListener(function (CollectPathsToExcludeEvent $event): void { - $event->add(['exclude/me']); + $event->add('exclude/me'); }, CollectPathsToExcludeEvent::class); // On pre-create and pre-apply, ensure that the excluded path is known to @@ -676,7 +684,7 @@ class StageBaseTest extends PackageManagerKernelTestBase { $committer = $this->container->get('package_manager.committer'); $committer_args = $committer->getInvocationArguments(); $this->assertCount(1, $committer_args); - /** @var \PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface $path_list */ + /** @var \PhpTuf\ComposerStager\API\Path\Value\PathListInterface $path_list */ $path_list = $committer_args[0][2]; $this->assertContains('PACKAGE_MANAGER_FAILURE.yml', $path_list->getAll()); } diff --git a/package_manager/tests/src/Kernel/StatusCheckTraitTest.php b/package_manager/tests/src/Kernel/StatusCheckTraitTest.php index fb9ceaa5ab..ba6e71e4a9 100644 --- a/package_manager/tests/src/Kernel/StatusCheckTraitTest.php +++ b/package_manager/tests/src/Kernel/StatusCheckTraitTest.php @@ -23,7 +23,7 @@ class StatusCheckTraitTest extends PackageManagerKernelTestBase { */ public function testPathsToExcludeCollected(): void { $this->addEventTestListener(function (CollectPathsToExcludeEvent $event): void { - $event->add(['/junk/drawer']); + $event->add('/junk/drawer'); }, CollectPathsToExcludeEvent::class); $status_check_called = FALSE; diff --git a/package_manager/tests/src/Kernel/SymlinkValidatorTest.php b/package_manager/tests/src/Kernel/SymlinkValidatorTest.php index fa284bb462..1f59dc4c8a 100644 --- a/package_manager/tests/src/Kernel/SymlinkValidatorTest.php +++ b/package_manager/tests/src/Kernel/SymlinkValidatorTest.php @@ -8,7 +8,7 @@ use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Exception\StageEventException; use Drupal\package_manager\PathLocator; use Drupal\package_manager\ValidationResult; -use PhpTuf\ComposerStager\Domain\Service\Host\HostInterface; +use PhpTuf\ComposerStager\Internal\Host\Service\HostInterface; /** * @covers \Drupal\package_manager\Validator\SymlinkValidator @@ -47,7 +47,7 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { link($project_root . '/composer.json', $project_root . '/composer.link'); $result = ValidationResult::createError([ - t('The active directory at "@dir" contains hard links, which is not supported. The first one is "@dir/composer.json".', [ + t('The active directory at @dir contains hard links, which is not supported. The first one is @dir/composer.json.', [ '@dir' => $project_root, ]), ]); @@ -63,7 +63,7 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { symlink($project_root . '/composer.json', $project_root . '/composer.link'); $result = ValidationResult::createError([ - t('The active directory at "@dir" contains absolute links, which is not supported. The first one is "@dir/composer.link".', [ + t('The active directory at @dir contains absolute links, which is not supported. The first one is @dir/composer.link.', [ '@dir' => $project_root, ]), ]); @@ -84,7 +84,7 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { chdir($project_root); symlink('../hello.txt', 'fail.txt'); $result = ValidationResult::createError([ - t('The active directory at "@dir" contains links that point outside the codebase, which is not supported. The first one is "@dir/fail.txt".', [ + t('The active directory at @dir contains links that point outside the codebase, which is not supported. The first one is @dir/fail.txt.', [ '@dir' => $project_root, ]), ]); @@ -111,7 +111,7 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { symlink('../hello.txt', 'fail.txt'); $result = ValidationResult::createError([ - t('The staging directory at "@dir" contains links that point outside the codebase, which is not supported. The first one is "@dir/fail.txt".', [ + t('The staging directory at @dir contains links that point outside the codebase, which is not supported. The first one is @dir/fail.txt.', [ '@dir' => $stage_dir, ]), ]); @@ -136,7 +136,7 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { 'php', [ ValidationResult::createError([ - t('The active directory at "<PROJECT_ROOT>" contains symlinks that point to a directory, which is not supported. The first one is "<PROJECT_ROOT>/modules/custom/example_module".'), + t('The active directory at <PROJECT_ROOT> contains symlinks that point to a directory, which is not supported. The first one is <PROJECT_ROOT>/modules/custom/example_module.'), ]), ], ], @@ -178,9 +178,16 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { * Tests that symlinks are not supported on Windows, even if they're safe. */ public function testSymlinksNotAllowedOnWindows(): void { - $host = $this->prophesize(HostInterface::class); - $host->isWindows()->willReturn(TRUE); - $this->container->set(HostInterface::class, $host->reveal()); + $this->container->set(HostInterface::class, new class () implements HostInterface { + + /** + * {@inheritdoc} + */ + public static function isWindows(): bool { + return TRUE; + } + + }); $project_root = $this->container->get(PathLocator::class) ->getProjectRoot(); @@ -190,7 +197,7 @@ class SymlinkValidatorTest extends PackageManagerKernelTestBase { symlink('composer.json', 'composer.link'); $result = ValidationResult::createError([ - t('The active directory at "@dir" contains links, which is not supported on Windows. The first one is "@dir/composer.link".', [ + t('The active directory at @dir contains links, which is not supported on Windows. The first one is @dir/composer.link.', [ '@dir' => $project_root, ]), ]); diff --git a/package_manager/tests/src/Unit/ProcessFactoryTest.php b/package_manager/tests/src/Unit/ProcessFactoryTest.php index a6d1c4fd07..c83e6d1e79 100644 --- a/package_manager/tests/src/Unit/ProcessFactoryTest.php +++ b/package_manager/tests/src/Unit/ProcessFactoryTest.php @@ -4,8 +4,11 @@ declare(strict_types = 1); namespace Drupal\Tests\package_manager\Unit; +use Drupal\Core\File\FileSystemInterface; use Drupal\package_manager\ProcessFactory; use Drupal\Tests\UnitTestCase; +use PhpTuf\ComposerStager\API\Translation\Factory\TranslatableFactoryInterface; +use PhpTuf\ComposerStager\Internal\Process\Factory\ProcessFactory as StagerProcessFactory; /** * @coversDefaultClass \Drupal\package_manager\ProcessFactory @@ -18,9 +21,14 @@ class ProcessFactoryTest extends UnitTestCase { * Tests that the process factory prepends the PHP directory to PATH. */ public function testPhpDirectoryPrependedToPath(): void { + $decorated = new StagerProcessFactory( + $this->createMock(TranslatableFactoryInterface::class), + ); + $factory = new ProcessFactory( - $this->prophesize('\Drupal\Core\File\FileSystemInterface')->reveal(), - $this->getConfigFactoryStub() + $this->createMock(FileSystemInterface::class), + $this->getConfigFactoryStub(), + $decorated, ); // Ensure that the directory of the PHP interpreter can be found. diff --git a/package_manager/tests/src/Unit/ProcessOutputCallbackTest.php b/package_manager/tests/src/Unit/ProcessOutputCallbackTest.php index a1443385f8..6d99082334 100644 --- a/package_manager/tests/src/Unit/ProcessOutputCallbackTest.php +++ b/package_manager/tests/src/Unit/ProcessOutputCallbackTest.php @@ -33,7 +33,7 @@ class ProcessOutputCallbackTest extends UnitTestCase { $callback = new ProcessOutputCallback(); $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage("Unsupported output type: 'telegram'"); + $this->expectExceptionMessage("Unsupported output type: 'TELEGRAM'"); $callback('telegram', 'Into the void...'); } diff --git a/src/CronUpdateStage.php b/src/CronUpdateStage.php index 15f39ee97d..646ab893fd 100644 --- a/src/CronUpdateStage.php +++ b/src/CronUpdateStage.php @@ -22,10 +22,10 @@ use Drupal\package_manager\PathLocator; use Drupal\package_manager\ProjectInfo; use Drupal\update\ProjectRelease; use GuzzleHttp\Psr7\Uri as GuzzleUri; -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\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Core\CommitterInterface; +use PhpTuf\ComposerStager\API\Core\StagerInterface; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -85,11 +85,11 @@ class CronUpdateStage extends UpdateStage implements CronInterface { * The Composer inspector service. * @param \Drupal\package_manager\PathLocator $pathLocator * The path locator service. - * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $beginner + * @param \PhpTuf\ComposerStager\API\Core\BeginnerInterface $beginner * The beginner service. - * @param \PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface $stager + * @param \PhpTuf\ComposerStager\API\Core\StagerInterface $stager * The stager service. - * @param \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface $committer + * @param \PhpTuf\ComposerStager\API\Core\CommitterInterface $committer * The committer service. * @param \Drupal\Core\File\FileSystemInterface $fileSystem * The file system service. @@ -99,7 +99,7 @@ class CronUpdateStage extends UpdateStage implements CronInterface { * The shared tempstore factory. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service. * @param \Drupal\package_manager\FailureMarker $failureMarker * The failure marker service. diff --git a/src/UpdateStage.php b/src/UpdateStage.php index f5bf4e0f66..e26f706086 100644 --- a/src/UpdateStage.php +++ b/src/UpdateStage.php @@ -12,10 +12,10 @@ use Drupal\package_manager\ComposerInspector; use Drupal\package_manager\FailureMarker; use Drupal\package_manager\PathLocator; use Drupal\package_manager\StageBase; -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\API\Core\BeginnerInterface; +use PhpTuf\ComposerStager\API\Core\CommitterInterface; +use PhpTuf\ComposerStager\API\Core\StagerInterface; +use PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -40,11 +40,11 @@ class UpdateStage extends StageBase { * The Composer inspector service. * @param \Drupal\package_manager\PathLocator $pathLocator * The path locator service. - * @param \PhpTuf\ComposerStager\Domain\Core\Beginner\BeginnerInterface $beginner + * @param \PhpTuf\ComposerStager\API\Core\BeginnerInterface $beginner * The beginner service. - * @param \PhpTuf\ComposerStager\Domain\Core\Stager\StagerInterface $stager + * @param \PhpTuf\ComposerStager\API\Core\StagerInterface $stager * The stager service. - * @param \PhpTuf\ComposerStager\Domain\Core\Committer\CommitterInterface $committer + * @param \PhpTuf\ComposerStager\API\Core\CommitterInterface $committer * The committer service. * @param \Drupal\Core\File\FileSystemInterface $fileSystem * The file system service. @@ -54,7 +54,7 @@ class UpdateStage extends StageBase { * The shared tempstore factory. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. - * @param \PhpTuf\ComposerStager\Infrastructure\Factory\Path\PathFactoryInterface $pathFactory + * @param \PhpTuf\ComposerStager\API\Path\Factory\PathFactoryInterface $pathFactory * The path factory service. * @param \Drupal\package_manager\FailureMarker $failureMarker * The failure marker service. diff --git a/tests/src/Functional/ComposerStagerOperationFailureTest.php b/tests/src/Functional/ComposerStagerOperationFailureTest.php index f75342b51b..4263a4d6a1 100644 --- a/tests/src/Functional/ComposerStagerOperationFailureTest.php +++ b/tests/src/Functional/ComposerStagerOperationFailureTest.php @@ -7,8 +7,9 @@ namespace Drupal\Tests\automatic_updates\Functional; use Drupal\package_manager_bypass\LoggingBeginner; use Drupal\package_manager_bypass\LoggingCommitter; use Drupal\package_manager_bypass\NoOpStager; -use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException; -use PhpTuf\ComposerStager\Domain\Exception\LogicException; +use PhpTuf\ComposerStager\API\Exception\InvalidArgumentException; +use PhpTuf\ComposerStager\API\Exception\LogicException; +use PhpTuf\ComposerStager\Internal\Translation\Value\TranslatableMessage; /** * @covers \Drupal\automatic_updates\Form\UpdaterForm @@ -38,7 +39,8 @@ class ComposerStagerOperationFailureTest extends UpdaterFormTestBase { $page->hasButton('Update to 9.8.1'); // Make the specified Composer Stager operation class throw an exception. - $exception = new $exception_class('Failure from inside ' . $service_class); + $message = new TranslatableMessage("Failure from inside $service_class"); + $exception = new $exception_class($message); call_user_func([$service_class, 'setException'], $exception); // Start the update. diff --git a/tests/src/Kernel/CronUpdateStageTest.php b/tests/src/Kernel/CronUpdateStageTest.php index b94b20086f..77a52f7f8f 100644 --- a/tests/src/Kernel/CronUpdateStageTest.php +++ b/tests/src/Kernel/CronUpdateStageTest.php @@ -349,7 +349,7 @@ class CronUpdateStageTest extends AutomaticUpdatesKernelTestBase { $listener = function (PostRequireEvent $event) use (&$cron_stage_dir, $original_stage_directory): void { $this->assertDirectoryDoesNotExist($original_stage_directory); - $cron_stage_dir = $this->container->get('package_manager.stager')->getInvocationArguments()[0][1]->resolve(); + $cron_stage_dir = $this->container->get('package_manager.stager')->getInvocationArguments()[0][1]->resolved(); $this->assertSame($event->stage->getStageDirectory(), $cron_stage_dir); $this->assertDirectoryExists($cron_stage_dir); }; diff --git a/tests/src/Kernel/UpdateStageTest.php b/tests/src/Kernel/UpdateStageTest.php index e5a4476453..ab47c3ce61 100644 --- a/tests/src/Kernel/UpdateStageTest.php +++ b/tests/src/Kernel/UpdateStageTest.php @@ -9,7 +9,9 @@ use Drupal\package_manager\Exception\ApplyFailedException; use Drupal\package_manager\Exception\StageException; use Drupal\package_manager_bypass\LoggingCommitter; use Drupal\Tests\user\Traits\UserCreationTrait; -use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException; +use PhpTuf\ComposerStager\API\Exception\ExceptionInterface; +use PhpTuf\ComposerStager\API\Exception\InvalidArgumentException; +use PhpTuf\ComposerStager\Internal\Translation\Value\TranslatableMessage; /** * @coversDefaultClass \Drupal\automatic_updates\UpdateStage @@ -182,12 +184,17 @@ class UpdateStageTest extends AutomaticUpdatesKernelTestBase { ]); $stage->stage(); $thrown_message = 'A very bad thing happened'; + // Composer Stager's exception messages are usually translatable, so they + // need to be wrapped by a TranslatableMessage object. + if (is_subclass_of($thrown_class, ExceptionInterface::class)) { + $thrown_message = new TranslatableMessage($thrown_message); + } LoggingCommitter::setException(new $thrown_class($thrown_message, 123)); $this->expectException($expected_class); $expected_message = $expected_class === ApplyFailedException::class ? "Automatic updates failed to apply, and the site is in an indeterminate state. Consider restoring the code and database from a backup." : $thrown_message; - $this->expectExceptionMessage($expected_message); + $this->expectExceptionMessage((string) $expected_message); $this->expectExceptionCode(123); $stage->apply(); } -- GitLab