Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/Infrastructure/File/ArchiveHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 25 additions & 4 deletions tests/Unit/Infrastructure/File/ArchiveHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '/.*/';

Expand Down Expand Up @@ -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.
Expand Down