Halb versioniertes vendor/: wie autoload_files.php eine Seite lahmlegt

Wer vendor/ mitversioniert, aber die Entwicklungspakete per .gitignore ausschließt, handelt sich einen Totalausfall ein: composer/autoload_files.php lädt bestimmte Dateien beim Start unbedingt. Fehlt eine davon auf dem Server, bricht jede PHP-Anfrage ab – noch bevor TYPO3 hochfährt und etwas ins Log schreiben könnte.

Die Idee klingt vernünftig: vendor/ wird mitversioniert und so ausgeliefert, aber PHPUnit und das Testing-Framework haben auf dem Server nichts verloren – also in die .gitignore damit. Die Rechnung geht nicht auf.

Die Fehlermeldung, die man nie zu sehen bekommt

Warning: require(/pfad/vendor/composer/../myclabs/deep-copy/src/DeepCopy/deep_copy.php):
Failed to open stream: No such file or directory
in /pfad/vendor/composer/autoload_real.php on line 41

Composer kennt neben dem Klassen-Autoloading auch das sogenannte files-Autoloading für Pakete, die Funktionen statt Klassen bereitstellen. Diese Dateien werden bei jedem Request eingebunden, unabhängig davon, ob jemand sie braucht. PHPUnit und myclabs/deep-copy gehören dazu.

vendor/composer/autoload_files.php

return array(
    '...' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
    '...' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert/Functions.php',
    // ...
);

Fehlt eine dieser Dateien, scheitert require im Autoloader – vor dem TYPO3-Bootstrap. Deshalb steht im TYPO3-Log auch nichts: Den Logger gibt es zu diesem Zeitpunkt noch gar nicht. Ob das eigene Repository stimmig ist, lässt sich in einer Zeile prüfen:

Prüfen, ob alle files-Einträge wirklich vorhanden sind

php -r '$f = require "vendor/composer/autoload_files.php";
foreach ($f as $p) { if (!file_exists($p)) echo "FEHLT: $p\n"; }'

Die Lehre: Entweder vendor/ ist vollständig versioniert oder gar nicht. Ein Mittelweg ist nicht stimmig, denn die generierten Autoloader-Dateien kennen den Unterschied zwischen Produktiv- und Entwicklungspaketen nicht mehr, sobald sie einmal geschrieben sind. Wer die Testpakete wirklich heraushalten will, muss den Autoloader mit composer dump-autoload --no-dev erzeugen – und daran denken, dass jeder lokale Testlauf ihn wieder umschreibt.


Erstellt am: