From 99ea66c2a4670a47e7e9c32f6dfd2b6adce675df Mon Sep 17 00:00:00 2001 From: gwleuverink Date: Wed, 3 Jun 2026 00:38:09 +0200 Subject: [PATCH] prune only the php binary archives, not the whole bin dir php.js copies the one binary we need into the build resources, so the php-*.zip files left in the source tree are dead weight. We were removing the whole binary directory to clear them, which shipped every unused archive on a root path and could take the app down with it. Target just the archives we manage (bin/{os}/{arch}/php-*.zip) so the build stays small, a user's other files in bin/ survive, and a root path no longer wipes the app (#115). --- .../Concerns/PrunesVendorDirectory.php | 14 +++++--- tests/Build/PruneVendorDirectoryTest.php | 34 ++++++++++++++----- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Builder/Concerns/PrunesVendorDirectory.php b/src/Builder/Concerns/PrunesVendorDirectory.php index 343ffd77..4d60b380 100644 --- a/src/Builder/Concerns/PrunesVendorDirectory.php +++ b/src/Builder/Concerns/PrunesVendorDirectory.php @@ -24,10 +24,14 @@ public function pruneVendorDirectory() $this->buildPath('app/vendor/nativephp/php-bin'), ]); - // Remove custom php binary package directory - $binaryPackageDirectory = trim($this->binaryPackageDirectory(), "./\\ \t\n\r\0\x0B"); - if ($binaryPackageDirectory !== '' && $filesystem->exists($this->buildPath("app/{$binaryPackageDirectory}"))) { - $filesystem->remove($this->buildPath("app/{$binaryPackageDirectory}")); - } + // Remove the bundled PHP binaries for a custom binary path. + // They get duplicated into the app's build resources, so + // the copies left in the source tree are dead weight. + // + // We remove only the archives we manage, never the + // parent directory, so the user's files are kept, + // and a root path never wipes the app (#115). + $binaryDirectory = $this->buildPath('app/'.$this->binaryPackageDirectory().'bin'); + $filesystem->remove(glob("{$binaryDirectory}/*/*/php-*.zip")); } } diff --git a/tests/Build/PruneVendorDirectoryTest.php b/tests/Build/PruneVendorDirectoryTest.php index 6bed312c..c85d56de 100644 --- a/tests/Build/PruneVendorDirectoryTest.php +++ b/tests/Build/PruneVendorDirectoryTest.php @@ -20,6 +20,8 @@ }); afterEach(function () use ($buildPath) { + putenv('NATIVEPHP_PHP_BINARY_PATH'); + $filesystem = new Filesystem; $filesystem->remove($buildPath); }); @@ -54,30 +56,46 @@ public function buildPath(string $path = ''): string | Tests |-------------------------------------------------------------------------- */ -it('removes the custom php binary package directory', function () use ($buildPath, $command) { +it('prunes the bundled php binary archives from a custom binary directory', function () use ($buildPath, $command) { putenv('NATIVEPHP_PHP_BINARY_PATH=php-bin/'); createFiles([ "$buildPath/app/index.php", - "$buildPath/app/php-bin/bin/php", + "$buildPath/app/php-bin/bin/win/x64/php-8.4.zip", + "$buildPath/app/php-bin/bin/mac/arm64/php-8.4.zip", ]); $command->pruneVendorDirectory(); - expect("$buildPath/app/php-bin")->not->toBeDirectory(); + // The redundant archives are stripped... + expect("$buildPath/app/php-bin/bin/win/x64/php-8.4.zip")->not->toBeFile(); + expect("$buildPath/app/php-bin/bin/mac/arm64/php-8.4.zip")->not->toBeFile(); + + // ...while the rest of the app is left intact. expect("$buildPath/app/index.php")->toBeFile(); -})->after(fn () => putenv('NATIVEPHP_PHP_BINARY_PATH')); +}); -it('does not delete the app when the binary path normalizes to the app root', function () use ($buildPath, $command) { +it('does not delete the app when the binary path is the project root', function () use ($buildPath, $command) { + // Regression test for #115: a binary path that normalises to the app root + // (e.g. binaries kept directly in the project's bin/ directory) must not + // take the whole app down with the prune. putenv('NATIVEPHP_PHP_BINARY_PATH=./'); createFiles([ "$buildPath/app/index.php", - "$buildPath/app/bin/win/x64/php.exe", + "$buildPath/app/bin/win/x64/php-8.4.zip", + "$buildPath/app/bin/mac/arm64/php-8.4.zip", + // Unrelated tooling a user happens to keep in bin/ must survive. + "$buildPath/app/bin/deploy.sh", ]); $command->pruneVendorDirectory(); + // The app and any non-NativePHP files in bin/ are preserved... expect("$buildPath/app/index.php")->toBeFile(); - expect("$buildPath/app/bin/win/x64/php.exe")->toBeFile(); -})->after(fn () => putenv('NATIVEPHP_PHP_BINARY_PATH')); + expect("$buildPath/app/bin/deploy.sh")->toBeFile(); + + // ...but the bundled php archives are still pruned. + expect("$buildPath/app/bin/win/x64/php-8.4.zip")->not->toBeFile(); + expect("$buildPath/app/bin/mac/arm64/php-8.4.zip")->not->toBeFile(); +});