diff --git a/src/Infrastructure/File/ArchiveHandler.php b/src/Infrastructure/File/ArchiveHandler.php index b7388c0a9..85b1fe671 100644 --- a/src/Infrastructure/File/ArchiveHandler.php +++ b/src/Infrastructure/File/ArchiveHandler.php @@ -73,7 +73,16 @@ public function compressDirectory(string $directory, ?string $regex = null): str $umask = umask(self::OWNER_ONLY); try { - $this->archive->buildFromDirectory($directory, $regex); + // Only pass the pattern when there is one. `?string $regex = null` offers "archive + // the whole directory" as an option, and `PharData::buildFromDirectory()` declares its + // second parameter `string` — so taking that option emits a deprecation on PHP 8.5, + // becomes a fatal on PHP 9, and is already a hard error under the test suite's error + // handler. The one-argument form is what "no pattern" means to Phar. + if ($regex === null) { + $this->archive->buildFromDirectory($directory); + } else { + $this->archive->buildFromDirectory($directory, $regex); + } // Before compressing, not only after: the uncompressed archive holds the same thing // the compressed one does and exists for as long as compressing takes, which on a diff --git a/tests/Unit/Infrastructure/File/ArchiveHandlerTest.php b/tests/Unit/Infrastructure/File/ArchiveHandlerTest.php index 6b161749f..9e294e51e 100644 --- a/tests/Unit/Infrastructure/File/ArchiveHandlerTest.php +++ b/tests/Unit/Infrastructure/File/ArchiveHandlerTest.php @@ -50,10 +50,8 @@ class ArchiveHandlerTest extends TestCase { /** - * The one production caller always passes a regex (`BackupFile::BACKUP_INCLUDE_REGEX`), and so - * does this — `compressDirectory()`'s `?string $regex = null` default reaches - * `PharData::buildFromDirectory()`, which requires a string, so the null is a TypeError. It is - * unreachable today and is not this change's to fix. + * The one production caller passes a regex (`BackupFile::BACKUP_INCLUDE_REGEX`); most of these + * do too, and one below takes the other option deliberately. */ private const EVERYTHING = '/.*/'; @@ -132,6 +130,29 @@ public function theCompressedArchiveIsOwnerOnly(): void self::assertSame(0600, fileperms($this->archivePath()) & 0777); } + /** + * Archiving a whole directory, which is what `?string $regex = null` offers. + * + * Taking that option handed the null straight to `PharData::buildFromDirectory()`, whose second + * parameter is declared `string` — a deprecation on PHP 8.5, a fatal on PHP 9, and already a + * hard error under this suite's error handler, which is how it was found. The one production + * caller always passes a regex, so nothing had reached it. + * + * Asserted on the contents rather than on the absence of an error: the fix is the one-argument + * form, and the thing worth pinning is that it still archives everything. + */ + #[Test] + public function aDirectoryCanBeArchivedWithNoPatternAtAll(): void + { + file_put_contents($this->source . DIRECTORY_SEPARATOR . 'second.txt', 'more'); + + $this->handler()->compressDirectory($this->source); + + $entries = iterator_to_array(new PharData($this->archivePath())); + + self::assertCount(2, $entries); + } + /** * And nothing is left beside it — the uncompressed tar, which holds exactly the same thing, * is removed once the gz exists.