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

Issue #3255011 by phenaproxima: Don't stage git directories

parent 46cab4c8
No related branches found
No related tags found
No related merge requests found
Showing
with 47 additions and 266 deletions
......@@ -11,6 +11,7 @@ use Drupal\package_manager\Event\StageEvent;
use Drupal\package_manager\PathLocator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
/**
* Defines an event subscriber to exclude certain paths from staging areas.
......@@ -180,6 +181,20 @@ class ExcludedPathsSubscriber implements EventSubscriberInterface {
$project[] = $options['database'] . '-wal';
}
// Find all .git directories in the project and exclude them. We cannot do
// this with FileSystemInterface::scanDirectory() because it unconditionally
// excludes anything starting with a dot.
$finder = Finder::create()
->in($this->pathLocator->getProjectRoot())
->directories()
->name('.git')
->ignoreVCS(FALSE)
->ignoreDotFiles(FALSE);
foreach ($finder as $git_directory) {
$project[] = $git_directory->getPathname();
}
$this->excludeInWebRoot($event, $web);
$this->excludeInProjectRoot($event, $project);
}
......
{}
This file should never be staged.
# This file should never be staged.
must_not_be: 'empty'
<?php
/**
* @file
* This file should never be staged.
*/
<?php
/**
* @file
* This file should never be staged.
*/
This file should be staged.
This file should never be staged.
This file should never be staged.
This file should never be staged.
This file should never be staged.
# This file should never be staged.
key: "value"
<?php
/**
* @file
* This file should never be staged.
*/
<?php
/**
* @file
* This file should never be staged.
*/
This file should never be staged.
# This file should never be staged.
This file should never be staged.
......@@ -3,11 +3,8 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Component\Serialization\Json;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\package_manager\Exception\StageValidationException;
use Drupal\package_manager\PathLocator;
use Drupal\package_manager\ValidationResult;
use org\bovigo\vfs\vfsStream;
/**
* @covers \Drupal\package_manager\EventSubscriber\ComposerSettingsValidator
......@@ -16,22 +13,6 @@ use org\bovigo\vfs\vfsStream;
*/
class ComposerSettingsValidatorTest extends PackageManagerKernelTestBase {
/**
* {@inheritdoc}
*/
protected function disableValidators(ContainerBuilder $container): void {
parent::disableValidators($container);
// Disable the disk space validator, since it tries to inspect the file
// system in ways that vfsStream doesn't support, like calling stat() and
// disk_free_space().
$container->removeDefinition('package_manager.validator.disk_space');
// Disable the lock file validator, since the mock file system we create in
// this test doesn't have any lock files to validate.
$container->removeDefinition('package_manager.validator.lock_file');
}
/**
* Data provider for ::testSecureHttpValidation().
*
......@@ -78,16 +59,10 @@ class ComposerSettingsValidatorTest extends PackageManagerKernelTestBase {
* @dataProvider providerSecureHttpValidation
*/
public function testSecureHttpValidation(string $contents, array $expected_results): void {
$file = vfsStream::newFile('composer.json')->setContent($contents);
$this->vfsRoot->addChild($file);
$active_dir = $this->vfsRoot->url();
$locator = $this->prophesize(PathLocator::class);
$locator->getActiveDirectory()->willReturn($active_dir);
$locator->getProjectRoot()->willReturn($active_dir);
$locator->getWebRoot()->willReturn('');
$locator->getVendorDirectory()->willReturn($active_dir);
$this->container->set('package_manager.path_locator', $locator->reveal());
$this->createTestProject();
$active_dir = $this->container->get('package_manager.path_locator')
->getActiveDirectory();
file_put_contents("$active_dir/composer.json", $contents);
try {
$this->createStage()->create();
......
......@@ -2,9 +2,7 @@
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\EventSubscriber\DiskSpaceValidator;
use Drupal\package_manager\ValidationResult;
use Drupal\Component\Utility\Bytes;
......@@ -15,31 +13,6 @@ use Drupal\Component\Utility\Bytes;
*/
class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
// Replace the validator under test with a mocked version which can be
// rigged up to return specific values for various filesystem checks.
$container->getDefinition('package_manager.validator.disk_space')
->setClass(TestDiskSpaceValidator::class);
}
/**
* {@inheritdoc}
*/
protected function disableValidators(ContainerBuilder $container): void {
parent::disableValidators($container);
// Disable the lock file and Composer settings validators, since in this
// test we are validating an imaginary file system which doesn't have any
// Composer files.
$container->removeDefinition('package_manager.validator.lock_file');
$container->removeDefinition('package_manager.validator.composer_settings');
}
/**
* Data provider for ::testDiskSpaceValidation().
*
......@@ -47,17 +20,21 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
* Sets of arguments to pass to the test method.
*/
public function providerDiskSpaceValidation(): array {
$root_insufficient = t('Drupal root filesystem "root" has insufficient space. There must be at least 1024 megabytes free.');
$vendor_insufficient = t('Vendor filesystem "vendor" has insufficient space. There must be at least 1024 megabytes free.');
$temp_insufficient = t('Directory "temp" has insufficient space. There must be at least 1024 megabytes free.');
// These will be defined by ::createTestProject().
$root = 'vfs://root/active';
$vendor = "$root/vendor";
$root_insufficient = "Drupal root filesystem \"$root\" has insufficient space. There must be at least 1024 megabytes free.";
$vendor_insufficient = "Vendor filesystem \"$vendor\" has insufficient space. There must be at least 1024 megabytes free.";
$temp_insufficient = 'Directory "temp" has insufficient space. There must be at least 1024 megabytes free.';
$summary = t("There is not enough disk space to create a staging area.");
return [
'shared, vendor and temp sufficient, root insufficient' => [
TRUE,
[
'root' => '1M',
'vendor' => '2G',
$root => '1M',
$vendor => '2G',
'temp' => '4G',
],
[
......@@ -67,8 +44,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'shared, root and vendor insufficient, temp sufficient' => [
TRUE,
[
'root' => '1M',
'vendor' => '2M',
$root => '1M',
$vendor => '2M',
'temp' => '2G',
],
[
......@@ -78,8 +55,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'shared, vendor and root sufficient, temp insufficient' => [
TRUE,
[
'root' => '2G',
'vendor' => '4G',
$root => '2G',
$vendor => '4G',
'temp' => '1M',
],
[
......@@ -89,8 +66,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'shared, root and temp insufficient, vendor sufficient' => [
TRUE,
[
'root' => '1M',
'vendor' => '2G',
$root => '1M',
$vendor => '2G',
'temp' => '2M',
],
[
......@@ -103,8 +80,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'not shared, root insufficient, vendor and temp sufficient' => [
FALSE,
[
'root' => '5M',
'vendor' => '1G',
$root => '5M',
$vendor => '1G',
'temp' => '4G',
],
[
......@@ -114,8 +91,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'not shared, vendor insufficient, root and temp sufficient' => [
FALSE,
[
'root' => '2G',
'vendor' => '10M',
$root => '2G',
$vendor => '10M',
'temp' => '4G',
],
[
......@@ -125,8 +102,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'not shared, root and vendor sufficient, temp insufficient' => [
FALSE,
[
'root' => '1G',
'vendor' => '2G',
$root => '1G',
$vendor => '2G',
'temp' => '3M',
],
[
......@@ -136,8 +113,8 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
'not shared, root and vendor insufficient, temp sufficient' => [
FALSE,
[
'root' => '500M',
'vendor' => '75M',
$root => '500M',
$vendor => '75M',
'temp' => '2G',
],
[
......@@ -156,22 +133,17 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
* @param bool $shared_disk
* Whether the root and vendor directories are on the same logical disk.
* @param array $free_space
* The free space that should be reported for various locations. The keys
* are the locations (only 'root', 'vendor', and 'temp' are supported), and
* the values are the space that should be reported, in a format that can be
* parsed by \Drupal\Component\Utility\Bytes::toNumber().
* The free space that should be reported for various paths. The keys
* are the paths, and the values are the free space that should be reported,
* in a format that can be parsed by
* \Drupal\Component\Utility\Bytes::toNumber().
* @param \Drupal\package_manager\ValidationResult[] $expected_results
* The expected validation results.
*
* @dataProvider providerDiskSpaceValidation
*/
public function testDiskSpaceValidation(bool $shared_disk, array $free_space, array $expected_results): void {
$path_locator = $this->prophesize('\Drupal\package_manager\PathLocator');
$path_locator->getProjectRoot()->willReturn('root');
$path_locator->getWebRoot()->willReturn('');
$path_locator->getActiveDirectory()->willReturn('root');
$path_locator->getVendorDirectory()->willReturn('vendor');
$this->container->set('package_manager.path_locator', $path_locator->reveal());
$this->createTestProject();
/** @var \Drupal\Tests\package_manager\Kernel\TestDiskSpaceValidator $validator */
$validator = $this->container->get('package_manager.validator.disk_space');
......@@ -182,47 +154,3 @@ class DiskSpaceValidatorTest extends PackageManagerKernelTestBase {
}
}
/**
* A test version of the disk space validator.
*/
class TestDiskSpaceValidator extends DiskSpaceValidator {
/**
* Whether the root and vendor directories are on the same logical disk.
*
* @var bool
*/
public $sharedDisk;
/**
* The amount of free space, keyed by location.
*
* @var float[]
*/
public $freeSpace = [];
/**
* {@inheritdoc}
*/
protected function stat(string $path): array {
return [
'dev' => $this->sharedDisk ? 'disk' : uniqid(),
];
}
/**
* {@inheritdoc}
*/
protected function freeSpace(string $path): float {
return $this->freeSpace[$path];
}
/**
* {@inheritdoc}
*/
protected function temporaryDirectory(): string {
return 'temp';
}
}
<?php
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Core\Database\Connection;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber;
/**
* @covers \Drupal\package_manager\EventSubscriber\ExcludedPathsSubscriber
*
* @group package_manager
*/
class ExcludedPathsSubscriberTest extends PackageManagerKernelTestBase {
/**
* Data provider for ::testSqliteDatabaseExcluded().
*
* @return array[]
* Sets of arguments to pass to the test method.
*/
public function providerSqliteDatabaseExcluded(): array {
$drupal_root = $this->getDrupalRoot();
return [
'relative path, in site directory' => [
'sites/example.com/db.sqlite',
[
'sites/example.com/db.sqlite',
'sites/example.com/db.sqlite-shm',
'sites/example.com/db.sqlite-wal',
],
],
'relative path, at root' => [
'db.sqlite',
[
'db.sqlite',
'db.sqlite-shm',
'db.sqlite-wal',
],
],
'absolute path, in site directory' => [
$drupal_root . '/sites/example.com/db.sqlite',
[
'sites/example.com/db.sqlite',
'sites/example.com/db.sqlite-shm',
'sites/example.com/db.sqlite-wal',
],
],
'absolute path, at root' => [
$drupal_root . '/db.sqlite',
[
'db.sqlite',
'db.sqlite-shm',
'db.sqlite-wal',
],
],
];
}
/**
* Tests that SQLite database paths are excluded from the staging area.
*
* The exclusion of SQLite databases from the staging area is functionally
* tested by \Drupal\Tests\package_manager\Functional\ExcludedPathsTest. The
* purpose of this test is to ensure that SQLite database paths are processed
* properly (e.g., converting an absolute path to a relative path) before
* being flagged for exclusion.
*
* @param string $database
* The path of the SQLite database, as set in the database connection
* options.
* @param string[] $expected_exclusions
* The database paths which should be flagged for exclusion.
*
* @dataProvider providerSqliteDatabaseExcluded
*
* @see \Drupal\Tests\package_manager\Functional\ExcludedPathsTest
*/
public function testSqliteDatabaseExcluded(string $database, array $expected_exclusions): void {
$connection = $this->prophesize(Connection::class);
$connection->driver()->willReturn('sqlite');
$connection->getConnectionOptions()->willReturn(['database' => $database]);
$subscriber = new ExcludedPathsSubscriber(
'sites/default',
$this->container->get('package_manager.symfony_file_system'),
$this->container->get('stream_wrapper_manager'),
$connection->reveal(),
$this->container->get('package_manager.path_locator')
);
$event = new PreCreateEvent($this->createStage());
$subscriber->ignoreCommonPaths($event);
// All of the expected exclusions should be flagged.
$this->assertEmpty(array_diff($expected_exclusions, $event->getExcludedPaths()));
}
}
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