Repository navigation
fix(install): survive an autoloader rename during package upgrade (1.14.1-beta1, #779) - #780
Merged
Merged
Conversation
bootstrap.php require_once's vendor/autoload.php on every MODX request, so the installed version's composer/autoload_real.php is already in memory when the transport unpacks a new vendor over it. The migrations resolver then re-reads autoload.php, its require_once on the unchanged autoload_real.php path is a no-op, and the call to ComposerAutoloaderInit* hits a class nobody declared. Composer derives that name from the package set, which moved in 1.14.0-beta1 when modxkit/testbench joined require-dev — so upgrades from 1.13 died with `Class "ComposerAutoloaderInit541a2bb3..." not found`. The plain require that exposes the trap arrived in #726; before it the resolver used require_once and skipped the file wholesale. - ms3PhinxEnsureAutoloaderInit() reads the expected class out of the new autoload.php and requires composer/autoload_real.php directly when it is not declared. This is what rescues upgrades from versions built before the fix. - composer.json pins config.autoloader-suffix so the class name stops moving with the package set. - _build/vendor_guard.php refuses to package a vendor/ that still holds require-dev packages: 1.14.0-beta1 shipped PHPUnit, PHPStan and the testbench, 45 MB instead of roughly seven. chore(release): 1.14.1-beta1
The guard ran at the top of process(), but the constructor has already built the transport package and category by then, so a rejected build left a stub .transport.zip behind. Move it ahead of initialize().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Экстренный патч: 1.14.0-beta1 не устанавливается поверх предыдущих версий (#779).
Механизм
bootstrap.php:9подключаетvendor/autoload.phpна каждом запросе MODX. Поэтому при обновлении в одном запросе:composer/autoload_real.phpустановленной версии.vendor/поверх.resolver_02_migrations.php→phinx_vendor.php→require vendor/autoload.php: файл на диске уже новый, читается заново.require_once __DIR__ . '/composer/autoload_real.php'— no-op, путь не изменился и уже подключён.ComposerAutoloaderInit541a2bb3…::getLoader(). Класса нет. Fatal, установка обрывается целиком.Нужны два условия, и оба сошлись в 1.14.0-beta1:
require-devдобавилсяmodxkit/testbench. Раньше состав между релизами не менялся и имя совпадало случайно;requireвместоrequire_once— регрессия из Миграции: Phinx из vendor MiniShop3, не из чужого extra #726, есть только в 1.14.0-beta1. До неё резолвер делалrequire_onceи до строки 25 не доходил.Замечание из issue про dev-vendor в пакете оказалось не побочным: именно изменение состава
require-devи сдвинуло хеш.Что сделано
phinx_vendor.php—ms3PhinxEnsureAutoloaderInit()вычитывает имя класса из новогоautoload.phpи, если оно не объявлено, требуетcomposer/autoload_real.phpнапрямую, в обход кэшаrequire_once. Новое имя с прежним не столкнётся — это и есть условие, при котором мы сюда попали.Это единственная часть, которая спасает уже пострадавших: они обновляются со старого хеша, и один
autoloader-suffixим не поможет — новыйautoload.phpвсё равно позовёт класс, которого нет в памяти. Защита приезжает внутри пакета и исполняется уже из новых файлов.composer.json—config.autoloader-suffix: "MiniShop3". Имя класса больше не зависит от состава пакетов. Проверено: одинаково с--no-devи без.composer.lockне изменился._build/vendor_guard.php+ вызов вbuild.phpдо создания vehicle — сборка отказывается паковатьvendor/сrequire-dev(читаетdevиdev-package-namesизinstalled.json) и печатает, что запустить. В 1.14.0-beta1 в пакет уехали PHPUnit, PHPStan и testbench: 45 МБ вместо примерно семи.Проверка
Воспроизведено на живом сайте, где лежал старый хеш:
Тот же файл и та же строка, что в логе установки из issue. С исправленным
phinx_vendor.php—ClassLoader получен, установка продолжается.Тесты
tests/PhinxVendorAutoloadUpgradeTest.php— строит поддельныйvendor/, проигрывает последовательность обновления и падает, если ловушка перестала воспроизводиться; дальше проверяет защиту, первый запуск, отсутствующийvendor/и закреплённый суффикс.tests/BuildVendorGuardTest.php— dev-сборка отклоняется с инструкцией,--no-devпроходит,installed.jsonбез dev-маркеров проходит, отсутствующийinstalled.jsonотклоняется, порядок вызова вbuild.php.Локально: PHPStan 458 файлов без ошибок, smoke 119 тестов зелёные,
composer validateчистый.Closes #779
🤖 Generated with Claude Code