2012-10-06

Composer - czyli jak zapanować nad zależnościami.

Ile razy zdarzyło Ci się "pałować" z dependencjami bibliotek projektu? Często aplikacja wymaga bibliotek w konkretnej wersji, do tego te biblioteki zależą od innych bibliotek, również w określonej wersji. Instalacja biblioteki globalnie w systemie, wiąże się z częstym problemem, gry upgrade biblioteki do wyższej wersji, wymaganej w w jednym projekcie wpływa na pozostałe projekty/biblioteki. 

Po bardzo ciekawej prezentacji "Composer - zarządzanie zależnościami w PHP" wygłoszonej przez Michała Pipa w miniony piątek na phpCon - postanowiłem utrawalić i usystematyzować wiedzę w temacie na blogu. 

Composer to fenomenalne narzędzie pozwalające zadeklarować biblioteki, od których zależy projekt. Composer sam ściągnie odpowiednie wersje bibliotek i zainstaluje. W momencie gdy dołączymy autoloadera composera do projektu 'vendor/autoload.php'; wszystkie biblioteki zostaną dołączone do projektu.

Instalacja jest banalna:
$ curl -s http://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer

Aktualizacja jest jeszcze prostsza - composer sam się zaktualizuje.
$ composer.phar self-update



Composer zarządza zależnościami, a nie pakietami. W pliku konfiguracyjnym możemy określić konkretną wersję biblioteki np. 1.0.1 lub operować wildcaredm * , np. gdy chcemy zawsze najnowszą wersję stabliną, która nie zmieniła się funkcjonalnie, wystarczy napisać: 1.0.* Warto zaznaczyć, że zgodnie ze standardem semver ostatnia cyfra oznacza jedynie bugfixing i nie wpływa funkcjonalność.

W praktyce wystarczy stworzyć plik composer.json :
{
    "require": {
        "monolog/monolog": "1.0.*"
    }
}

I uruchomić komendę:
$ composer.phar install

W efekcie zostaną utworzone:
  • Katalog vendor/
  • Plik composer.lock
  • Konfiguracja loadera (vendor/autoload.php)
Kilka słów o composer.lockTen plik bezwzględnie powinien być wersjonowany (razem z composer.json)! Wersjonowanie obu tych plików zapewnia, że każdy kto będzie instalował biblioteki dla projektu, zainstaluje tę samą ich wersję. Dzieje się tak dlatego, że polecenie install w pierwszej kolejności sprawdza wersję biblioteki w composer.lock; composer.json jest sprawdzany wyłącznie gdy composer.lock nie istnieje, a po sprawdzeniu jest on tworzony.

Polecenie update aktualizuje biblioteki do najnowszej wersji pasującej do definicje z composer.json i zapisuje te wersje w composer.lock;



Głównym repozytorium pakietów dla Composera jest Packegist



Choć Composer został pierwotnie zaprojektowany dla frameworka Symfony, to doskonale sprawdza się również w innych projektach. Np. dla CakePHP 2.x powstał bardzo łatwy w użyciu Plugin