diff --git a/src/Service/VersionService.php b/src/Service/VersionService.php index b696709..34dad5d 100644 --- a/src/Service/VersionService.php +++ b/src/Service/VersionService.php @@ -81,7 +81,7 @@ public function createZipArchiveFromPath(string $path): string if ($current->isDir()) { // if $current is a directory, check for excluded directories foreach ($this->excludeConfiguration['directories'] as $excludeDirectory) { - if (preg_match('/^' . $excludeDirectory . '/i', $path)) { + if (preg_match('/^' . preg_quote((string)$excludeDirectory, '/') . '/i', $path)) { return false; } } @@ -90,7 +90,7 @@ public function createZipArchiveFromPath(string $path): string if ($current->isFile()) { // if $current is a file, check for excluded files foreach ($this->excludeConfiguration['files'] as $excludeFile) { - if (preg_match('/' . $excludeFile . '$/i', $filename)) { + if (preg_match('/' . preg_quote((string)$excludeFile, '/') . '$/i', $filename)) { return false; } } diff --git a/tests/Unit/Fixtures/ExcludeFromPackaging/config_nested_directory.php b/tests/Unit/Fixtures/ExcludeFromPackaging/config_nested_directory.php new file mode 100644 index 0000000..c178dc3 --- /dev/null +++ b/tests/Unit/Fixtures/ExcludeFromPackaging/config_nested_directory.php @@ -0,0 +1,8 @@ + [ + 'Resources/Private/Build', + ], + 'files' => [], +]; diff --git a/tests/Unit/Service/VersionServiceTest.php b/tests/Unit/Service/VersionServiceTest.php index abf4cf5..ff21ce5 100644 --- a/tests/Unit/Service/VersionServiceTest.php +++ b/tests/Unit/Service/VersionServiceTest.php @@ -19,6 +19,9 @@ class VersionServiceTest extends TestCase { + /** @var list */ + protected array $temporaryDirectories = []; + #[Test] public function defaultExcludeFromPackagingConfigurationIsUsedOnNonExistingEnvVar(): void { @@ -105,6 +108,81 @@ public function getVersionFilenameAsMd5Test(): void ); } + #[Test] + public function excludedDirectoryContainingASlashIsNotPackaged(): void + { + unset($_ENV); + putenv('TYPO3_EXCLUDE_FROM_PACKAGING=' . __DIR__ . '/../Fixtures/ExcludeFromPackaging/config_nested_directory.php'); + + $extensionPath = $this->createExtensionDirectory(); + $transactionPath = $this->createTemporaryDirectory(); + + $archivePath = (new VersionService('1.0.0', 'my_ext', $transactionPath)) + ->createZipArchiveFromPath($extensionPath); + + $archive = new \ZipArchive(); + $archive->open($archivePath); + $packagedFiles = []; + + for ($index = 0; $index < $archive->numFiles; $index++) { + $packagedFiles[] = $archive->getNameIndex($index); + } + + $archive->close(); + + self::assertContains('ext_emconf.php', $packagedFiles); + self::assertNotContains('Resources/Private/Build/gulpfile.js', $packagedFiles); + } + + /** + * Create an extension directory holding a valid ext_emconf.php and a file + * inside the nested directory the exclude configuration names. + */ + protected function createExtensionDirectory(): string + { + $path = $this->createTemporaryDirectory(); + + file_put_contents( + $path . '/ext_emconf.php', + ' \'1.0.0\', \'constraints\' => [\'depends\' => [\'typo3\' => \'13.4.0-13.4.99\']]];' . PHP_EOL + ); + + mkdir($path . '/Resources/Private/Build', 0777, true); + file_put_contents($path . '/Resources/Private/Build/gulpfile.js', '// build only'); + + return $path; + } + + protected function createTemporaryDirectory(): string + { + $path = sys_get_temp_dir() . '/tailor-test-' . bin2hex(random_bytes(8)); + mkdir($path, 0777, true); + $this->temporaryDirectories[] = $path; + + return $path; + } + + protected function tearDown(): void + { + foreach ($this->temporaryDirectories as $directory) { + $files = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($files as $file) { + $file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname()); + } + + rmdir($directory); + } + + $this->temporaryDirectories = []; + + parent::tearDown(); + } + /** * Invoke a protected / private method from VersionService *