Workaround pre Composer globálne

PHPComposer

David Grudl nedávno písal o rôznych variantách inštalácie Composera. Priznám sa, sprvoti som nerozumel, kde môže pri globálnej inštalácii nastať konflikt, no nakoniec mi to doplo.

V podstate nejde o nič nové a na rovnaký problém môžete naraziť pri vašom projekte. Keď jedna knižnica, ktorú používate (alebo projekt samotný), povedzme A, je závislá na ďalšej, volajme ju B, a iná, napr. C, je tiež závislá na B.

Konflikt nastane keď:

  • A potrebuje na svoje fungovanie B, napr. verziu ~1.3
  • a C potrebuje taktiž B, no už novú major verziu, napr. ~2.2

To isté sa deje s globálnou inštaláciou, t.j. keď používate composer global require, pretože adresár .composer je akoby spomínaný projekt, akurát v inom adresári.

Ak chcete používať binárky knižníc globálne tak, aby sa vám to jedného dňa nerozsypalo, je nutné každú nainštalovať izolovane. To môžete spraviť pomocou composer global create-project.

Nevýhodou je, že nainštalované knižnice nebudú v jednom projekte, a tak nie je možné pridať do $PATH napríklad celý adresár vendor/bin.

Workaround

Napadlo mi potom úplne jednoduché riešenie. Vytvoríte si nový projekt, v ktorom budú adresáre s jednotlivými knižnicami

  • každá vlastne ako separátny projekt. Takto:
tester/
tester/composer.json
phpunit/
phpunit/composer.json
...
install.sh

V tester/composer.json bude napr.:

{
    "require": {
        "nette/tester": "~1.3"
    }
}

Následne pridáte jednoduchý skript install.sh, ktorý jednotlivé projekty nainštaluje pomocou Composera a vytvorí symlinky do /usr/local/bin:

find . -type d ! -name ".*" -depth 1 -exec composer install -d {} \;
find `pwd` -path "*/vendor/bin/*" -exec ln -s {} /usr/local/bin \;

A je to. Ba Dum Tss.

PS: Nie, nemohol som len spustiť skript install.sh v adresári .composer, pretože create-project je pre začatie nového projektu a nevytvára vendor/bin, kde by boli jeho vlastné binárky.

Sample kód nájdete na Githube.