Composer/Replace: Unterschied zwischen den Versionen
Aus Contao Community Documentation
Tril (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „{{stub}} # Wie composer mit <code>replace</code> umgeht Mit der <code>replace</code> Eigenschaft kann man festlegen, dass das eigene Paket ein fremdes Paket …“) |
(kein Unterschied)
|
Version vom 22. Mai 2014, 16:38 Uhr
Unvollständiger Artikel: dieser Artikel ist noch nicht sauber bearbeitet.
Bitte erweitere ihn und entferne erst anschliessend diesen Hinweis. |
- Wie composer mit
replace
umgeht
Mit der replace
Eigenschaft kann man festlegen, dass das eigene Paket ein fremdes Paket "ersetzt". Dafür kann es mehrere Gründe geben, der häufigste ist wohl, dass das Paket unter einem anderen Namen weiter entwickelt wird, weil bspw. der Entwickler gewechselt hat. Im Contao Kontext sieht man auch sehr viel { "replace": { "contao-legacy/my-extension": "..." } }
. Das sind replaces für Pakete, die über den Legacy ER2 Server in Composer bereitgestellt werden, vom Entwickler dann aber später als "echtes" Composer Paket weiter geführt werden.
Sehr weit verbreitet ist vor allem die Notation mit *
:
{ "replace": { "contao-legacy/my-extension": "*" } }
Im folgenden soll erläutert werden, warum ein replace auf alle Versionen wie in dem vorhergehenden Beispiel die denkbar schlechteste Variante ist, die man sich vorstellen kann. Dazu muss man erst ein mal verstehen, wie replace funktioniert.
Wir gehen einfach mal davon aus, wir haben die folgenden 3 Pakete:
{ "name": "test/old", "version": "1.0", "dist": { "url": "...", "type": "zip" }, "source": { "url": "...", "type": "svn", "reference": "master" } }
{ "name": "test/old", "version": "1.1", "dist": { "url": "...", "type": "zip" }, "source": { "url": "...", "type": "svn", "reference": "master" } }
{ "name": "test/new", "version": "2.0", "dist": { "url": "...", "type": "zip" }, "source": { "url": "...", "type": "svn", "reference": "master" }, "replace": { "test/old": "*" } }
Um die gültigen Pakete zu finden, arbeitet Composer intern mit einem Pool. In diesen Pool generiert Composer für jeden Paketnamen eine sortierte Liste der Pakete erzeugt, die für den Paketnamen gültig sind.
Für das Paket test/old
sieht diese Liste folgend aus:
- test/old 1.0
- test/old 1.1
- test/new 2.0
Wie Composer darauf kommt, dass test/new
in diese Liste kommt ist ganz einfach. Jedes Paket verfügt nicht nur über seinen eindeutigen Namen, sondern auch über Alias-Namen. Schaut man sich die BasePackage::getNames() Methode an, wird schnell klar welche Namen für ein Paket akzeptiert werden. Abgesehen vom Package::$name
werden auch noch alle Package::$provides
und Package::$replaces
als gültige Namen für das Paket betrachtet.
Unter Strich heißt dass, dass die Namensliste von test/new
aus [test/new, test/old]
besteht und test/new
deshalb in der Paketliste zu test/old
(2 Absätze zuvor) auftaucht.
- TLDR
Ein { "name": "me/my-extension", "replace": { "contao-legacy/my-extension": "*" } }
sorgt dafür, dass jede Version des alten Paketes, durch das neue ersetzt wird. Das bedeutet aber auch, dass eine potentiell inkompatible Version 3 von me/my-extension
installiert wird, auch wenn mit { "require": { "contao-legacy/my-extension": "1.0" } }
die Version 1 von contao-legacy/my-extension
angefordert wird.
Deshalb sollte immer { "name": "me/my-extension", "replace": { "contao-legacy/my-extension": "self.version" } }
verwendet werden!