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

Issue #3254616 by phenaproxima, tedbow: Update Composer Stager to 0.3.0

parent 77a91645
No related branches found
No related tags found
No related merge requests found
Showing
with 197 additions and 120 deletions
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"drupal/core": "^9.2", "drupal/core": "^9.2",
"php-tuf/composer-stager": "0.2.3", "php-tuf/composer-stager": "0.3.0",
"composer/composer": "^2" "composer/composer": "^2"
}, },
"config": { "config": {
......
...@@ -4,8 +4,6 @@ services: ...@@ -4,8 +4,6 @@ services:
class: Symfony\Component\Filesystem\Filesystem class: Symfony\Component\Filesystem\Filesystem
package_manager.symfony_executable_finder: package_manager.symfony_executable_finder:
class: Symfony\Component\Process\ExecutableFinder class: Symfony\Component\Process\ExecutableFinder
package_manager.symfony_finder:
class: Symfony\Component\Finder\Finder
# Basic infrastructure services. # Basic infrastructure services.
package_manager.process_factory: package_manager.process_factory:
...@@ -45,8 +43,6 @@ services: ...@@ -45,8 +43,6 @@ services:
class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\PhpFileSyncer
arguments: arguments:
- '@package_manager.file_system' - '@package_manager.file_system'
- '@package_manager.symfony_finder'
- '@package_manager.symfony_finder'
package_manager.file_syncer.factory: package_manager.file_syncer.factory:
class: Drupal\package_manager\FileSyncerFactory class: Drupal\package_manager\FileSyncerFactory
arguments: arguments:
...@@ -55,7 +51,7 @@ services: ...@@ -55,7 +51,7 @@ services:
- '@package_manager.file_syncer.rsync' - '@package_manager.file_syncer.rsync'
- '@config.factory' - '@config.factory'
package_manager.file_syncer: package_manager.file_syncer:
class: PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerInterface class: PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
factory: ['@package_manager.file_syncer.factory', 'create'] factory: ['@package_manager.file_syncer.factory', 'create']
# Domain services. # Domain services.
...@@ -127,10 +123,10 @@ services: ...@@ -127,10 +123,10 @@ services:
package_manager.excluded_paths_subscriber: package_manager.excluded_paths_subscriber:
class: Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber class: Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber
arguments: arguments:
- '%app.root%'
- '%site.path%' - '%site.path%'
- '@file_system' - '@package_manager.symfony_file_system'
- '@stream_wrapper_manager' - '@stream_wrapper_manager'
- '@database' - '@database'
- '@package_manager.path_locator'
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
...@@ -15,12 +15,23 @@ trait ExcludedPathsTrait { ...@@ -15,12 +15,23 @@ trait ExcludedPathsTrait {
protected $excludedPaths = []; protected $excludedPaths = [];
/** /**
* Adds an absolute path to exclude from the current operation. * Adds a path to exclude from the current operation.
* *
* @todo This should only accept paths relative to the active directory. * If called on an instance of \Drupal\package_manager\Event\PreCreateEvent,
* excluded paths will not be copied into the staging area when the stage is
* created. If called on an instance of
* \Drupal\package_manager\Event\PreApplyEvent, excluded paths will not be
* deleted from the active directory when staged changes are applied. So,
* to ensure that a given path is never staged, but also preserved in the
* active directory, it should be passed to this method on both PreCreateEvent
* and PreApplyEvent. See
* \Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber for an
* example.
* *
* @param string $path * @param string $path
* The path to exclude. * The path to exclude, relative to the project root.
*
* @see \Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber
*/ */
public function excludePath(string $path): void { public function excludePath(string $path): void {
$this->excludedPaths[] = $path; $this->excludedPaths[] = $path;
......
...@@ -7,21 +7,21 @@ use Drupal\package_manager\Event\PreOperationStageEvent; ...@@ -7,21 +7,21 @@ use Drupal\package_manager\Event\PreOperationStageEvent;
use Drupal\Core\Extension\ExtensionVersion; use Drupal\Core\Extension\ExtensionVersion;
use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\StringTranslation\TranslationInterface;
use PhpTuf\ComposerStager\Domain\Output\ProcessOutputCallbackInterface; use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface;
use PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface;
use PhpTuf\ComposerStager\Exception\ExceptionInterface; use PhpTuf\ComposerStager\Exception\ExceptionInterface;
use PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunnerInterface;
/** /**
* Validates that the Composer executable can be found in the correct version. * Validates that the Composer executable can be found in the correct version.
*/ */
class ComposerExecutableValidator implements PreOperationStageValidatorInterface, ProcessOutputCallbackInterface { class ComposerExecutableValidator implements PreOperationStageValidatorInterface, OutputCallbackInterface {
use StringTranslationTrait; use StringTranslationTrait;
/** /**
* The Composer runner. * The Composer runner.
* *
* @var \PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunnerInterface * @var \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface
*/ */
protected $composer; protected $composer;
...@@ -35,7 +35,7 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface ...@@ -35,7 +35,7 @@ class ComposerExecutableValidator implements PreOperationStageValidatorInterface
/** /**
* Constructs a ComposerExecutableValidator object. * Constructs a ComposerExecutableValidator object.
* *
* @param \PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunnerInterface $composer * @param \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface $composer
* The Composer runner. * The Composer runner.
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation * @param \Drupal\Core\StringTranslation\TranslationInterface $translation
* The translation service. * The translation service.
......
...@@ -3,25 +3,20 @@ ...@@ -3,25 +3,20 @@
namespace Drupal\package_manager\EventSubscriber; namespace Drupal\package_manager\EventSubscriber;
use Drupal\Core\Database\Connection; use Drupal\Core\Database\Connection;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\LocalStream; use Drupal\Core\StreamWrapper\LocalStream;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface; use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\package_manager\Event\PreApplyEvent; use Drupal\package_manager\Event\PreApplyEvent;
use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Event\StageEvent;
use Drupal\package_manager\PathLocator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
/** /**
* Defines an event subscriber to exclude certain paths from staging areas. * Defines an event subscriber to exclude certain paths from staging areas.
*/ */
class ExcludedPathsSubscriber implements EventSubscriberInterface { class ExcludedPathsSubscriber implements EventSubscriberInterface {
/**
* The Drupal root.
*
* @var string
*/
protected $appRoot;
/** /**
* The current site path, relative to the Drupal root. * The current site path, relative to the Drupal root.
* *
...@@ -30,9 +25,9 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface { ...@@ -30,9 +25,9 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
protected $sitePath; protected $sitePath;
/** /**
* The file system service. * The Symfony file system service.
* *
* @var \Drupal\Core\File\FileSystemInterface * @var \Symfony\Component\Filesystem\Filesystem
*/ */
protected $fileSystem; protected $fileSystem;
...@@ -50,91 +45,157 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface { ...@@ -50,91 +45,157 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
*/ */
protected $database; protected $database;
/**
* The path locator service.
*
* @var \Drupal\package_manager\PathLocator
*/
protected $pathLocator;
/** /**
* Constructs an ExcludedPathsSubscriber. * Constructs an ExcludedPathsSubscriber.
* *
* @param string $app_root
* The Drupal root.
* @param string $site_path * @param string $site_path
* The current site path, relative to the Drupal root. * The current site path, relative to the Drupal root.
* @param \Drupal\Core\File\FileSystemInterface $file_system * @param \Symfony\Component\Filesystem\Filesystem $file_system
* The file system service. * The Symfony file system service.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager * @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
* The stream wrapper manager service. * The stream wrapper manager service.
* @param \Drupal\Core\Database\Connection $database * @param \Drupal\Core\Database\Connection $database
* The database connection. * The database connection.
* @param \Drupal\package_manager\PathLocator $path_locator
* The path locator service.
*/ */
public function __construct(string $app_root, string $site_path, FileSystemInterface $file_system, StreamWrapperManagerInterface $stream_wrapper_manager, Connection $database) { public function __construct(string $site_path, Filesystem $file_system, StreamWrapperManagerInterface $stream_wrapper_manager, Connection $database, PathLocator $path_locator) {
$this->appRoot = $app_root;
$this->sitePath = $site_path; $this->sitePath = $site_path;
$this->fileSystem = $file_system; $this->fileSystem = $file_system;
$this->streamWrapperManager = $stream_wrapper_manager; $this->streamWrapperManager = $stream_wrapper_manager;
$this->database = $database; $this->database = $database;
$this->pathLocator = $path_locator;
} }
/** /**
* Reacts before staged changes are committed the active directory. * Flags paths to be excluded, relative to the web root.
* *
* @param \Drupal\package_manager\Event\PreApplyEvent $event * This should only be used for paths that, if they exist at all, are
* *guaranteed* to exist within the web root.
*
* @param \Drupal\package_manager\Event\PreCreateEvent|\Drupal\package_manager\Event\PreApplyEvent $event
* The event object. * The event object.
* @param string[] $paths
* The paths to exclude. These should be relative to the web root, and will
* be made relative to the project root.
*/ */
public function preApply(PreApplyEvent $event): void { protected function excludeInWebRoot(StageEvent $event, array $paths): void {
// Don't copy anything from the staging area's sites/default. $web_root = $this->pathLocator->getWebRoot();
// @todo Make this a lot smarter in https://www.drupal.org/i/3228955. if ($web_root) {
$event->excludePath('sites/default'); $web_root .= '/';
}
// If the core-vendor-hardening plugin (used in the legacy-project template) foreach ($paths as $path) {
// is present, it may have written a web.config file into the vendor // Make the path relative to the project root by prefixing the web root.
// directory. We don't want to copy that. $event->excludePath($web_root . $path);
$event->excludePath('web.config'); }
} }
/** /**
* Excludes paths from a staging area before it is created. * Flags paths to be excluded, relative to the project root.
* *
* @param \Drupal\package_manager\Event\PreCreateEvent $event * @param \Drupal\package_manager\Event\PreCreateEvent|\Drupal\package_manager\Event\PreApplyEvent $event
* The event object. * The event object.
* @param string[] $paths
* The paths to exclude. Absolute paths will be made relative to the project
* root; relative paths will be assumed to already be relative to the
* project root, and excluded as given.
*/ */
public function preCreate(PreCreateEvent $event): void { protected function excludeInProjectRoot(StageEvent $event, array $paths): void {
// Automated test site directories should never be staged. $project_root = $this->pathLocator->getProjectRoot();
$event->excludePath('sites/simpletest');
foreach ($paths as $path) {
// Windows server configuration files, like web.config, should never be // Make absolute paths relative to the project root.
// staged either. (These can be written in the vendor directory by the $path = str_replace($project_root, NULL, $path);
// core-vendor-hardening plugin, which is used in the drupal/legacy-project $path = ltrim($path, '/');
// template.) $event->excludePath($path);
$event->excludePath('web.config');
if ($public = $this->getFilesPath('public')) {
$event->excludePath($public);
} }
if ($private = $this->getFilesPath('private')) { }
$event->excludePath($private);
/**
* Excludes common paths from staging operations.
*
* @param \Drupal\package_manager\Event\PreApplyEvent|\Drupal\package_manager\Event\PreCreateEvent $event
* The event object.
*
* @see \Drupal\package_manager\Event\ExcludedPathsTrait::excludePath()
*/
public function ignoreCommonPaths(StageEvent $event): void {
// Compile two lists of paths to exclude: paths that are relative to the
// project root, and paths that are relative to the web root.
$web = $project = [];
// Always ignore automated test directories. If they exist, they will be in
// the web root.
$web[] = 'sites/simpletest';
// If the core-vendor-hardening plugin (used in the legacy-project template)
// is present, it may have written security hardening files in the vendor
// directory. They should always be ignored.
$vendor_dir = $this->pathLocator->getVendorDirectory();
$project[] = $vendor_dir . '/web.config';
$project[] = $vendor_dir . '/.htaccess';
// Ignore public and private files. These paths could be either absolute or
// relative, depending on site settings. If they are absolute, treat them
// as relative to the project root. Otherwise, treat them as relative to
// the web root.
$files = array_filter([
$this->getFilesPath('public'),
$this->getFilesPath('private'),
]);
foreach ($files as $path) {
if ($this->fileSystem->isAbsolutePath($path)) {
$project[] = $path;
}
else {
$web[] = $path;
}
} }
// Exclude site-specific settings files. // Ignore site-specific settings files, which are always in the web root.
$settings_files = [ $settings_files = [
'settings.php', 'settings.php',
'settings.local.php', 'settings.local.php',
'services.yml', 'services.yml',
]; ];
$default_site = 'sites' . DIRECTORY_SEPARATOR . 'default';
foreach ($settings_files as $settings_file) { foreach ($settings_files as $settings_file) {
$event->excludePath($this->sitePath . DIRECTORY_SEPARATOR . $settings_file); $web[] = $this->sitePath . '/' . $settings_file;
$event->excludePath($default_site . DIRECTORY_SEPARATOR . $settings_file); $web[] = 'sites/default/' . $settings_file;
} }
// If the database is SQLite, it might be located in the active directory // If the database is SQLite, it might be located in the active directory
// and we should not stage it. // and we should ignore it. Always treat it as relative to the project root.
if ($this->database->driver() === 'sqlite') { if ($this->database->driver() === 'sqlite') {
$options = $this->database->getConnectionOptions(); $options = $this->database->getConnectionOptions();
$database = str_replace($this->appRoot, NULL, $options['database']); $project[] = $options['database'];
$database = ltrim($database, '/'); $project[] = $options['database'] . '-shm';
$event->excludePath($database); $project[] = $options['database'] . '-wal';
$event->excludePath("$database-shm");
$event->excludePath("$database-wal");
} }
$this->excludeInWebRoot($event, $web);
$this->excludeInProjectRoot($event, $project);
}
/**
* Reacts before staged changes are committed the active directory.
*
* @param \Drupal\package_manager\Event\PreApplyEvent $event
* The event object.
*/
public function preApply(PreApplyEvent $event): void {
// Don't copy anything from the staging area's sites/default.
// @todo Make this a lot smarter in https://www.drupal.org/i/3228955.
$this->excludeInWebRoot($event, ['sites/default']);
$this->ignoreCommonPaths($event);
} }
/** /**
...@@ -165,7 +226,7 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface { ...@@ -165,7 +226,7 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
*/ */
public static function getSubscribedEvents() { public static function getSubscribedEvents() {
return [ return [
PreCreateEvent::class => 'preCreate', PreCreateEvent::class => 'ignoreCommonPaths',
PreApplyEvent::class => 'preApply', PreApplyEvent::class => 'preApply',
]; ];
} }
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
namespace Drupal\package_manager; namespace Drupal\package_manager;
use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Config\ConfigFactoryInterface;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerFactoryInterface; 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\FileSyncerFactory as StagerFileSyncerFactory;
use PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerInterface;
use Symfony\Component\Process\ExecutableFinder; use Symfony\Component\Process\ExecutableFinder;
/** /**
...@@ -16,21 +16,21 @@ class FileSyncerFactory implements FileSyncerFactoryInterface { ...@@ -16,21 +16,21 @@ class FileSyncerFactory implements FileSyncerFactoryInterface {
/** /**
* The decorated file syncer factory. * The decorated file syncer factory.
* *
* @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerFactoryInterface * @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerFactoryInterface
*/ */
protected $decorated; protected $decorated;
/** /**
* The PHP file syncer service. * The PHP file syncer service.
* *
* @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerInterface * @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
*/ */
protected $phpFileSyncer; protected $phpFileSyncer;
/** /**
* The rsync file syncer service. * The rsync file syncer service.
* *
* @var \PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerInterface * @var \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface
*/ */
protected $rsyncFileSyncer; protected $rsyncFileSyncer;
...@@ -46,9 +46,9 @@ class FileSyncerFactory implements FileSyncerFactoryInterface { ...@@ -46,9 +46,9 @@ class FileSyncerFactory implements FileSyncerFactoryInterface {
* *
* @param \Symfony\Component\Process\ExecutableFinder $executable_finder * @param \Symfony\Component\Process\ExecutableFinder $executable_finder
* The Symfony executable finder. * The Symfony executable finder.
* @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerInterface $php_file_syncer * @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $php_file_syncer
* The PHP file syncer service. * The PHP file syncer service.
* @param \PhpTuf\ComposerStager\Infrastructure\FileSyncer\FileSyncerInterface $rsync_file_syncer * @param \PhpTuf\ComposerStager\Domain\FileSyncer\FileSyncerInterface $rsync_file_syncer
* The rsync file syncer service. * The rsync file syncer service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service. * The config factory service.
......
# This file should never be staged.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Drupal\package_manager_bypass; namespace Drupal\package_manager_bypass;
use PhpTuf\ComposerStager\Domain\BeginnerInterface; use PhpTuf\ComposerStager\Domain\BeginnerInterface;
use PhpTuf\ComposerStager\Domain\Output\ProcessOutputCallbackInterface; use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface;
/** /**
* Defines an update beginner which doesn't do anything. * Defines an update beginner which doesn't do anything.
...@@ -13,7 +13,7 @@ class Beginner extends InvocationRecorderBase implements BeginnerInterface { ...@@ -13,7 +13,7 @@ class Beginner extends InvocationRecorderBase implements BeginnerInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function begin(string $activeDir, string $stagingDir, ?array $exclusions = [], ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = 120): void { public function begin(string $activeDir, string $stagingDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
$this->saveInvocationArguments($activeDir, $stagingDir, $exclusions); $this->saveInvocationArguments($activeDir, $stagingDir, $exclusions);
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace Drupal\package_manager_bypass; namespace Drupal\package_manager_bypass;
use PhpTuf\ComposerStager\Domain\CommitterInterface; use PhpTuf\ComposerStager\Domain\CommitterInterface;
use PhpTuf\ComposerStager\Domain\Output\ProcessOutputCallbackInterface; use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface;
/** /**
* Defines an update committer which doesn't do any actual committing. * Defines an update committer which doesn't do any actual committing.
...@@ -30,7 +30,7 @@ class Committer extends InvocationRecorderBase implements CommitterInterface { ...@@ -30,7 +30,7 @@ class Committer extends InvocationRecorderBase implements CommitterInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function commit(string $stagingDir, string $activeDir, ?array $exclusions = [], ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = 120): void { public function commit(string $stagingDir, string $activeDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
$this->saveInvocationArguments($activeDir, $stagingDir, $exclusions); $this->saveInvocationArguments($activeDir, $stagingDir, $exclusions);
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace Drupal\package_manager_bypass; namespace Drupal\package_manager_bypass;
use PhpTuf\ComposerStager\Domain\Output\ProcessOutputCallbackInterface; use PhpTuf\ComposerStager\Domain\Process\OutputCallbackInterface;
use PhpTuf\ComposerStager\Domain\StagerInterface; use PhpTuf\ComposerStager\Domain\StagerInterface;
/** /**
...@@ -13,7 +13,7 @@ class Stager extends InvocationRecorderBase implements StagerInterface { ...@@ -13,7 +13,7 @@ class Stager extends InvocationRecorderBase implements StagerInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function stage(array $composerCommand, string $stagingDir, ?ProcessOutputCallbackInterface $callback = NULL, ?int $timeout = 120): void { public function stage(array $composerCommand, string $stagingDir, ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
$this->saveInvocationArguments($composerCommand, $stagingDir); $this->saveInvocationArguments($composerCommand, $stagingDir);
} }
......
...@@ -117,38 +117,44 @@ class ExcludedPathsTest extends BrowserTestBase { ...@@ -117,38 +117,44 @@ class ExcludedPathsTest extends BrowserTestBase {
}; };
$stage::$stagingRoot = $this->siteDirectory . '/stage'; $stage::$stagingRoot = $this->siteDirectory . '/stage';
$stage_dir = $stage::$stagingRoot . DIRECTORY_SEPARATOR . $stage->create(); $stage_dir = $stage::$stagingRoot . DIRECTORY_SEPARATOR . $stage->create();
$this->assertDirectoryExists($stage_dir); $this->assertDirectoryExists($stage_dir);
$this->assertDirectoryDoesNotExist("$stage_dir/sites/simpletest");
$this->assertFileDoesNotExist("$stage_dir/vendor/web.config");
$this->assertDirectoryDoesNotExist("$stage_dir/$site_path/files");
$this->assertDirectoryDoesNotExist("$stage_dir/private");
$this->assertFileDoesNotExist("$stage_dir/$site_path/settings.php");
$this->assertFileDoesNotExist("$stage_dir/$site_path/settings.local.php");
$this->assertFileDoesNotExist("$stage_dir/$site_path/services.yml");
// SQLite databases and their support files should never be staged.
$this->assertFileDoesNotExist("$stage_dir/$site_path/db.sqlite");
$this->assertFileDoesNotExist("$stage_dir/$site_path/db.sqlite-shm");
$this->assertFileDoesNotExist("$stage_dir/$site_path/db.sqlite-wal");
// Default site-specific settings files should never be staged.
$this->assertFileDoesNotExist("$stage_dir/sites/default/settings.php");
$this->assertFileDoesNotExist("$stage_dir/sites/default/settings.local.php");
$this->assertFileDoesNotExist("$stage_dir/sites/default/services.yml");
// A non-excluded file in the default site directory should be staged.
$this->assertFileExists("$stage_dir/sites/default/stage.txt");
$files = [ $ignore = [
'sites/default/no-copy.txt', 'sites/simpletest',
'web.config', 'vendor/.htaccess',
'vendor/web.config',
"$site_path/files/ignore.txt",
'private/ignore.txt',
"$site_path/settings.php",
"$site_path/settings.local.php",
"$site_path/services.yml",
// SQLite databases and their support files should always be ignored.
"$site_path/db.sqlite",
"$site_path/db.sqlite-shm",
"$site_path/db.sqlite-wal",
// Default site-specific settings files should be ignored.
'sites/default/settings.php',
'sites/default/settings.local.php',
'sites/default/services.yml',
]; ];
foreach ($files as $file) { foreach ($ignore as $path) {
$file = "$stage_dir/$file"; $this->assertFileExists("$active_dir/$path");
touch($file); $this->assertFileDoesNotExist("$stage_dir/$path");
$this->assertFileExists($file);
} }
// A non-excluded file in the default site directory should be staged.
$this->assertFileExists("$stage_dir/sites/default/stage.txt");
// A new file added to the staging area in an excluded directory, should not
// be copied to the active directory.
$file = "$stage_dir/sites/default/no-copy.txt";
touch($file);
$this->assertFileExists($file);
$stage->apply(); $stage->apply();
foreach ($files as $file) { $this->assertFileDoesNotExist("$active_dir/sites/default/no-copy.txt");
$this->assertFileDoesNotExist("$active_dir/$file");
// The ignored files should still be in the active directory.
foreach ($ignore as $path) {
$this->assertFileExists("$active_dir/$path");
} }
} }
......
...@@ -112,8 +112,8 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase { ...@@ -112,8 +112,8 @@ class ComposerExecutableValidatorTest extends PackageManagerKernelTestBase {
// Mock the output of `composer --version`, will be passed to the validator, // Mock the output of `composer --version`, will be passed to the validator,
// which is itself a callback function that gets called repeatedly as // which is itself a callback function that gets called repeatedly as
// Composer produces output. // Composer produces output.
/** @var \PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunnerInterface|\Prophecy\Prophecy\ObjectProphecy $runner */ /** @var \PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface|\Prophecy\Prophecy\ObjectProphecy $runner */
$runner = $this->prophesize('\PhpTuf\ComposerStager\Infrastructure\Process\Runner\ComposerRunnerInterface'); $runner = $this->prophesize('\PhpTuf\ComposerStager\Domain\Process\Runner\ComposerRunnerInterface');
$runner->run(['--version'], Argument::type(ComposerExecutableValidator::class)) $runner->run(['--version'], Argument::type(ComposerExecutableValidator::class))
// Whatever is passed to ::run() will be passed to this mock callback in // Whatever is passed to ::run() will be passed to this mock callback in
......
...@@ -85,6 +85,7 @@ class ComposerSettingsValidatorTest extends PackageManagerKernelTestBase { ...@@ -85,6 +85,7 @@ class ComposerSettingsValidatorTest extends PackageManagerKernelTestBase {
$locator = $this->prophesize(PathLocator::class); $locator = $this->prophesize(PathLocator::class);
$locator->getActiveDirectory()->willReturn($active_dir); $locator->getActiveDirectory()->willReturn($active_dir);
$locator->getProjectRoot()->willReturn($active_dir); $locator->getProjectRoot()->willReturn($active_dir);
$locator->getWebRoot()->willReturn('');
$locator->getVendorDirectory()->willReturn($active_dir); $locator->getVendorDirectory()->willReturn($active_dir);
$this->container->set('package_manager.path_locator', $locator->reveal()); $this->container->set('package_manager.path_locator', $locator->reveal());
......
...@@ -168,6 +168,7 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase { ...@@ -168,6 +168,7 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
public function testDiskSpaceValidation(bool $shared_disk, array $free_space, array $expected_results): void { public function testDiskSpaceValidation(bool $shared_disk, array $free_space, array $expected_results): void {
$path_locator = $this->prophesize('\Drupal\package_manager\PathLocator'); $path_locator = $this->prophesize('\Drupal\package_manager\PathLocator');
$path_locator->getProjectRoot()->willReturn('root'); $path_locator->getProjectRoot()->willReturn('root');
$path_locator->getWebRoot()->willReturn('');
$path_locator->getActiveDirectory()->willReturn('root'); $path_locator->getActiveDirectory()->willReturn('root');
$path_locator->getVendorDirectory()->willReturn('vendor'); $path_locator->getVendorDirectory()->willReturn('vendor');
$this->container->set('package_manager.path_locator', $path_locator->reveal()); $this->container->set('package_manager.path_locator', $path_locator->reveal());
......
...@@ -83,15 +83,15 @@ class ExcludedPathsSubscriberTest extends PackageManagerKernelTestBase { ...@@ -83,15 +83,15 @@ class ExcludedPathsSubscriberTest extends PackageManagerKernelTestBase {
$connection->getConnectionOptions()->willReturn(['database' => $database]); $connection->getConnectionOptions()->willReturn(['database' => $database]);
$subscriber = new ExcludedPathsSubscriber( $subscriber = new ExcludedPathsSubscriber(
$this->getDrupalRoot(),
'sites/default', 'sites/default',
$this->container->get('file_system'), $this->container->get('package_manager.symfony_file_system'),
$this->container->get('stream_wrapper_manager'), $this->container->get('stream_wrapper_manager'),
$connection->reveal() $connection->reveal(),
$this->container->get('package_manager.path_locator')
); );
$event = new PreCreateEvent($this->createStage()); $event = new PreCreateEvent($this->createStage());
$subscriber->preCreate($event); $subscriber->ignoreCommonPaths($event);
// All of the expected exclusions should be flagged. // All of the expected exclusions should be flagged.
$this->assertEmpty(array_diff($expected_exclusions, $event->getExcludedPaths())); $this->assertEmpty(array_diff($expected_exclusions, $event->getExcludedPaths()));
} }
......
...@@ -113,6 +113,7 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { ...@@ -113,6 +113,7 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
$path_locator = $this->prophesize(PathLocator::class); $path_locator = $this->prophesize(PathLocator::class);
$path_locator->getActiveDirectory()->willReturn($root->url()); $path_locator->getActiveDirectory()->willReturn($root->url());
$path_locator->getProjectRoot()->willReturn($root->url());
$path_locator->getWebRoot()->willReturn(''); $path_locator->getWebRoot()->willReturn('');
$path_locator->getVendorDirectory()->willReturn($vendor->url()); $path_locator->getVendorDirectory()->willReturn($vendor->url());
$this->container->set('package_manager.path_locator', $path_locator->reveal()); $this->container->set('package_manager.path_locator', $path_locator->reveal());
......
...@@ -220,10 +220,7 @@ END; ...@@ -220,10 +220,7 @@ END;
// Packagist. // Packagist.
$repositories['packagist.org'] = FALSE; $repositories['packagist.org'] = FALSE;
$repositories['drupal/automatic_updates'] = [ $repositories['drupal/automatic_updates'] = $this->createPathRepository(__DIR__ . '/../../..');
'type' => 'path',
'url' => __DIR__ . '/../../..',
];
// Use whatever the current branch of automatic_updates is. // Use whatever the current branch of automatic_updates is.
$data['require']['drupal/automatic_updates'] = '*'; $data['require']['drupal/automatic_updates'] = '*';
......
...@@ -64,6 +64,7 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase { ...@@ -64,6 +64,7 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
$locator->getActiveDirectory()->willReturn($active_dir); $locator->getActiveDirectory()->willReturn($active_dir);
$locator->getProjectRoot()->willReturn($active_dir); $locator->getProjectRoot()->willReturn($active_dir);
$locator->getWebRoot()->willReturn('');
$locator->getVendorDirectory()->willReturn($active_dir); $locator->getVendorDirectory()->willReturn($active_dir);
$stage_dir_exists = is_dir($stage_dir); $stage_dir_exists = is_dir($stage_dir);
......
...@@ -51,6 +51,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase { ...@@ -51,6 +51,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase {
$locator = $this->prophesize(PathLocator::class); $locator = $this->prophesize(PathLocator::class);
$locator->getActiveDirectory()->willReturn($fixture_dir); $locator->getActiveDirectory()->willReturn($fixture_dir);
$locator->getProjectRoot()->willReturn($fixture_dir); $locator->getProjectRoot()->willReturn($fixture_dir);
$locator->getWebRoot()->willReturn('');
$locator->getVendorDirectory()->willReturn($fixture_dir); $locator->getVendorDirectory()->willReturn($fixture_dir);
$this->container->set('package_manager.path_locator', $locator->reveal()); $this->container->set('package_manager.path_locator', $locator->reveal());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment