mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
ebb835d541 raised phpunit/phpunit from ^11.0 to ^13.3. PHPUnit 13 requires
PHP >=8.4.1 and ubuntu-latest ships 8.3.6, so composer install could not
resolve and test-unit-php failed on every CI run:
- phpunit/phpunit[13.3.0, ..., 13.3.2] require php >=8.4.1
-> your php version (8.3.6) does not satisfy that requirement.
Nothing in this repository installs a particular PHP. ensure_php_toolchain
takes whatever the distro php package is, so the vendor tree was resolved
against an ambient interpreter that no file named. A dependency floor above
that interpreter is then only discovered by the resolver, on the machine that
happens to have the oldest PHP.
Declare the floor and resolve against it. config.platform.php binds composer
everywhere, including Dependabot; require states the same for readers; the
phpunit constraint follows it. Packagist floors: 11 -> >=8.2, 12 -> >=8.3,
13 -> >=8.4.1.
Verified in the dev container: the pinned resolution downgrades phpunit
13.3.2 -> 12.5.34 and the suite passes unchanged, 26 tests, 56 assertions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
"""PHP toolchain provisioning for the PHP unit suite."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
|
|
from utils import PROJECT_ROOT
|
|
from utils.install.primitives import log
|
|
from utils.install.system_pkg import (
|
|
ensure_command_present,
|
|
ensure_php_extension_present,
|
|
)
|
|
|
|
_PHPUNIT = PROJECT_ROOT / "vendor" / "bin" / "phpunit"
|
|
|
|
_PHPUNIT_EXTENSIONS = ("dom", "mbstring", "xmlwriter")
|
|
|
|
|
|
def ensure_php_toolchain() -> None:
|
|
"""Install the PHP interpreter, Composer and the extensions PHPUnit needs.
|
|
|
|
``phpunit/phpunit`` declares ``_PHPUNIT_EXTENSIONS`` as platform
|
|
requirements and Composer refuses to resolve the vendor tree without them,
|
|
so they are part of the toolchain rather than of the suite consuming it.
|
|
A distro ships them as packages separate from the interpreter, which is why
|
|
a present ``php`` binary does not imply they are there.
|
|
|
|
Composer needs an archive extractor for its dist downloads. Without one it
|
|
silently falls back to ``--prefer-source`` and mirror-clones every
|
|
dependency, which blows its 300 s process timeout on ``phpunit.git``. Arch
|
|
ships no zip extension and no ``php-zip`` package, so the extractor has to
|
|
be the ``unzip`` binary rather than the extension.
|
|
|
|
Raises:
|
|
RuntimeError: php, composer, unzip or one of the extensions is still
|
|
absent.
|
|
"""
|
|
ensure_command_present("php")
|
|
ensure_command_present("composer")
|
|
ensure_command_present("unzip")
|
|
for extension in _PHPUNIT_EXTENSIONS:
|
|
ensure_php_extension_present(extension)
|
|
|
|
|
|
def ensure_php_present() -> None:
|
|
"""Install the PHP toolchain and the Composer vendor tree.
|
|
|
|
Raises:
|
|
RuntimeError: php, composer or phpunit is still absent afterwards.
|
|
subprocess.CalledProcessError: ``composer install`` failed.
|
|
"""
|
|
ensure_php_toolchain()
|
|
|
|
if not _PHPUNIT.is_file():
|
|
log("phpunit missing; running composer install.")
|
|
subprocess.run(
|
|
["composer", "install", "--no-interaction", "--no-progress"],
|
|
cwd=PROJECT_ROOT,
|
|
check=True,
|
|
)
|
|
|
|
if not _PHPUNIT.is_file():
|
|
raise RuntimeError(f"{_PHPUNIT} missing after composer install")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
ensure_php_present()
|