From cfc74bd10d5dc3dc6d854d29239685e8cba39e2a Mon Sep 17 00:00:00 2001 From: Wolfgang Ziegler // fago Date: Mon, 31 Aug 2026 22:17:43 +0200 Subject: [PATCH] fix: Repair the phar build on PHP 8.4, refs #43. "composer build" failed with 'Command "compile" is not defined' on checkouts that predate the box 2.7.5 -> 4.6.1 bump, and box 4.6.1 does not run on PHP 8.4 at all. - ScriptHandler::installPharTools only created the tool symlink when it was missing, so vendor/bin/box kept pointing at the box 2.7.5 phar of the previously pinned URL. Update the symlink unconditionally and keep it relative, so it survives the project being mounted at another path. - The phar was only downloaded when its file name was absent, so a new version published under the same name was never picked up. Record the installed URL and re-download whenever the pinned URL changes, removing the phar of the previously pinned version. - dumpFile() ignored the mode argument, leaving the downloaded phar non-executable. Set the mode via chmod(). - Pin box 4.7.0: 4.6.1 aborts on PHP 8.4 after emitting 260 implicit-nullable deprecations. - README: drop the deprecated "composer install --dev". Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_018ouHkvipwQik1mwsrrBmUd --- README.md | 2 +- composer.json | 2 +- composer.lock | 2 +- src/ScriptHandler.php | 35 +++++++++++++++++++++++++++-------- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9fc94d4..b08eb49 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Variable | Description | Example value | The phar is built using box, for details see https://github.com/box-project/box. To built the phar just run: - composer install --dev + composer install composer build ### Create a new release diff --git a/composer.json b/composer.json index 89f3c5f..7db5085 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ }, "tools": { "box": { - "url": "https://github.com/box-project/box/releases/download/4.6.1/box.phar" + "url": "https://github.com/box-project/box/releases/download/4.7.0/box.phar" } }, "enable-patching": true, diff --git a/composer.lock b/composer.lock index 6588674..04daa96 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a7b984493d3bc6fa2a75473319144140", + "content-hash": "bf599dbe4effdd6e25f0e735c8aa3e66", "packages": [ { "name": "composer/semver", diff --git a/src/ScriptHandler.php b/src/ScriptHandler.php index e3cf28c..ae3fa33 100644 --- a/src/ScriptHandler.php +++ b/src/ScriptHandler.php @@ -27,23 +27,42 @@ public static function installPharTools(Event $event) { $extras = $composer->getPackage()->getExtra(); if (array_key_exists('tools', $extras)) { + if (!$fs->exists($bin_dir)) { + $fs->mkdir($bin_dir); + } foreach ($extras['tools'] as $tool => $data) { if (empty($data['url'])) { throw new \LogicException("Missing tool url."); } $filename = basename($data['url']); - if (!$fs->exists("$bin_dir/$filename")) { - if (!$fs->exists($bin_dir)) { - $fs->mkdir($bin_dir); - } + // The URL of the currently installed phar is recorded, such that the + // tool is re-installed whenever the pinned URL changes. Checking for + // the file only is not sufficient, since a new version may well be + // published under the same file name. + $stamp_file = "$bin_dir/.$tool.url"; + $installed_url = $fs->exists($stamp_file) ? trim(file_get_contents($stamp_file)) : NULL; + + if ($installed_url !== $data['url'] || !$fs->exists("$bin_dir/$filename")) { $event->getIO()->write("Downloading $filename..."); $content = static::download($data['url']); - $fs->dumpFile("$bin_dir/$filename", $content, 0755); - - if (!$fs->exists("$bin_dir/$tool")) { - $fs->symlink("$bin_dir/$filename", "$bin_dir/$tool"); + $fs->dumpFile("$bin_dir/$filename", $content); + $fs->chmod("$bin_dir/$filename", 0755); + // Clean up the phar of the previously pinned version. + if ($installed_url && basename($installed_url) !== $filename) { + $fs->remove("$bin_dir/" . basename($installed_url)); } + $fs->dumpFile($stamp_file, $data['url']); + } + + // The symlink must be updated unconditionally: when the pinned URL + // changes it still points to the previously installed version. It is + // kept relative, so it keeps working when the project directory is + // mounted at another path; e.g. inside a container. + $link = "$bin_dir/$tool"; + if ($fs->exists($link) && !is_link($link)) { + $fs->remove($link); } + $fs->symlink($filename, $link); } } }