Jeden plik, a tyle możliwości! Czyli cała prawda o "composer.json". Cz. I
Published on
Apr 5, 2012
Apr 6, 2012 − Kolejna część naszej serii artykułów na temat narzędzia Composer i jego możliwości. W tej części poruszamy tematy takie jak podstawowe funkcje i sposoby skonfigurowania pliku composer.json.
Czym jest plik composer.json
?
W poprzedniej części poruszyliśmy ten temat, lecz wspomniane tam informacje to tylko wierzchołek góry lodowej. Wiecie już iż composer.json
to podstawowy plik wykorzystywany do zarządzania zależnościami w projekcie. Tenże plik jest również wykorzystywany w poszczególnych bibliotekach do zarządzania ich zależnościami, ale nie tylko. Lecz o tym za chwilę.
Podstawowy wygląd pliku composer.json
dla Twojego projektu wygląda mniej więcej tak:
{
"require": {
"autor/nazwa": "wersja"
}
}
Każda nowa zależność jest dodawana jak w wpis w zwykłej tablicy JSON
co czyni to niezmiernie łatwym w obsłudze, tak więc dodajmy jako zależność Symfony:
{
"require": {
"doctrine/orm": "2.1.*",
"symfony/symfony": "2.0.10"
}
}
Teraz wywołujemy komendę:
$ php composer.phar update
I gotowe! Symfony zostało dodane jako zależność w Twoim projekcie!
Czy Composer obsługuje tylko tyle możliwości definiowania wersji bibliotek ?
Wersje poszczególnych bibliotek mogą być dużo bardziej zróżnicowane.
W powyższym przykładzie wymagamy wersji 2.1.*
Doctrine ORM. A to oznacza że każda wersja z drzewa rozwoju 2.1
będzie pasowała jako zależność. Tak więc zarówno wersja: 2.1.0
, 2.1.2
lub 2.1.666
, będzie spełniała nasze wymagania.
Definiowanie wersji można wykonać na kilka sposobów:
- Konkretna wersja: Możesz podać konkretną wersję biblioteki której używasz, np.
2.0.10
. Nie jest to zbyt często wykorzystywane, ale może być przydatne. - Zakres: Poprzez wykorzystanie operatorów porównania, można zdefiniować zakres wersji które nas interesują. Obsługiwane operatory to:
>
,>=
,<
,<=
. Przykładem zakresu jest:>=1.0
. Możesz również zdefiniować kilka zakresów, poprzez oddzielenie ich przecinkiem:>=1.0,<2.0
. - Wildcard: Możesz użyć również wzorca z wildcard'em (
*
). Np.:1.0.*
jest równoznaczne:>=1.0,<1.1-dev
.
Ale co gdy mój projekt zawiera kod który nie ma pliku composer.json
?
Jak wiadomo projekt często składa się z wielu różnych bibliotek, nie zawsze są one jednak dostępne w ten sam sposób. Tutaj Composer również wyciąga do nas pomocną dłoń oferując wsparcie dla wielu systemów kontroli wersji takich jak:
Ale aby zainstalować biblioteki korzystając z nich musisz mieć zainstalowane programy klienckie, co niestety nie zawsze jest możliwe. I tu znowu Composer stara się pomóc udostępniając wsparcie dla GitHuba i BitBucketa, które poprzez swoje API pozwalają ściągać kod spakowany jako zipy.
Wróćmy jednak do tego jak dodać taką bibliotekę jako jedną z zależności w naszym projekcie. Jako przykład posłuży nam tutaj system szablonów Smarty:
{
"require": {
"doctrine/orm": "2.1.*",
"symfony/symfony": "2.0.10",
"smarty/smarty": "3.1.*"
},
"repositories": [
{
"type": "package",
"package": {
"name": "smarty/smarty",
"version": "3.1.8",
"dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.8.zip",
"type": "zip"
},
"source": {
"url": "http://smarty-php.googlecode.com/svn/",
"type": "svn",
"reference": "tags/Smarty_3_1_8/distribution/"
}
}
}
]
}
Teraz postaramy się opisać co takiego zrobiliśmy aby dodać tę zależność. Mamy zupełnie nowy tag: repositories
. Jest to tablica w której definiujemy biblioteki które są naszymi zależnościami jako paczki. W poszczególnej paczce definiujemy informacje dla Composera, takie jak: nazwa, wersja, informacje nt. zawartości (dist
) czy też źródła (source
).
dist
zawiera informacje nt. zawartości paczki, najczęściej stabilnej wersji.url
to adres gdzie Composer powinien szukać danych, atype
to informacja w jaki sposób dane te powinny być przetworzone, obecnie obsługiwane typy to:zip
,pear
,vcs
, jak również poszczególne typy które powinny być używane w zastępstwie dlavcs
, tj.:git
,svn
lubhg
.source
zawiera informację nt. źródeł biblioteki, najczęściej najnowszej wersji, ale również może być używany jako alternatywa dla danych z tagudist
.url
odnosi się do tego samego jak powyżej,type
to typ systemu kontroli wersji, czyli:git
,svn
lubhg
. Tagreference
odnosi się do tagu lub gałęzi z której kod powinien być pobrany.
Aby ukazać jak jest to proste wbrew pozorom zadanie, taki oto kod pozwoli nam na dodanie jako zależności komponentu Zend Frameworka, w tym wypadku komponentu Zend/Cache:
{
"require": {
"doctrine/orm": "2.1.*",
"symfony/symfony": "2.0.10",
"smarty/smarty": "3.1.*",
"zf/cache": "2.0.0beta3"
},
"repositories": [
{
"type": "package",
"package": {
"name": "smarty/smarty",
"version": "3.1.8",
"dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.8.zip",
"type": "zip"
},
"source": {
"url": "http://smarty-php.googlecode.com/svn/",
"type": "svn",
"reference": "tags/Smarty_3_1_8/distribution/"
}
}
},
{
"type": "package",
"package": {
"name": "zf/cache",
"version": "2.0.0beta3",
"dist": {
"url": "http://packages.zendframework.com/get/Zend_Cache-2.0.0beta3.tgz",
"type": "pear"
}
}
}
]
}
Niektóre klasy z mojego kodu nie są dostępne! Pomocy!!!111oneoneone
W poprzedniej części wspomnieliśmy o tym iż Composer automatycznie tworzy plik autoloadera
. Aby nie męczyć się i ręcznie konfigurować / edytować plik naszego autoloadera dodając poszczególne biblioteki, możemy to zautomatyzować za pomocą Composera:
"autoload": {
"psr-0": {
"Internal_" : "gdzie/w/twoim/projekcie",
"Namespaced\Code" : "gdzie/indziej/w/tymze/projekcie"
}
}
I to wszystko! Composer automatycznie dodane te regułki do generowanego autoloadera! Jedyny problem jaki tu możemy napotkać to taki iż klasy muszą być zgodne z PSR-0. Ale to tylko chwilowy problem który w prosty sposób rozwiązujemy z pomocą takie regułki:
"autoload": {
"classmap": [
"moj/brzydki/kod",
"moj/inny/brzydki/kod"
]
}
Oba powyższe przykłady można używać jednocześnie, np.
"autoload": {
"psr-0": {
"Internal_" : "gdzie/w/twoim/projekcie",
"Namespaced\Code" : [
"gdzie/indziej/w/tymze/projekcie",
"zupelnie/gdzie/indziej"
]
},
"classmap": [
"moj/brzydki/kod",
"moj/inny/brzydki/kod"
]
}
Jak zauważyliście, wpisy w psr-0
również mogą być tablicą folderów. Czyż nie jest to proste i przyjemne ? =)
Kolejnym praktycznym przykładem który naprawi nasz kod powyżej, odnosi się do dodanej paczki Zend/Cache, niestety nie zadziała ona domyślnie. Powodem jest miejsce gdzie została ona zapisana, a przestrzeń nazw w której ona operuje. Aby naprawić ten błąd, dodajemy tag autoloader
do zdefiniowanej paczki:
{
"type": "package",
"package": {
"name": "zf/cache",
"version": "2.0.0beta3",
"dist": {
"url": "http://packages.zendframework.com/get/Zend_Cache-2.0.0beta3.tgz",
"type": "pear"
},
"autoload": {
"psr-0": {
"Zend\Cache": "php/"
}
}
}
}
I to wszystko!
Composer pozwala również rozwiązać problem jeśli namespace
nie odpowiada strukturze w której biblioteka byłaby domyślnie zainstalowana. Jako przykład można tu użyć komponentu Symfony/Yaml, który domyślnie byłby w folderze nie odpowiadającym przestrzeni nazw, aby ten problem rozwiązać stosujemy tag target-dir
:
{
"autoload": {
"psr-0": { "Symfony\Component\Yaml": "" }
},
"target-dir": "Symfony/Component/Yaml"
}
Domyślna instalacja byłaby w folderze: vendor/symfony/yaml
, ale dzięki tej zmianie docelowy folder to: vendor/symfony/yaml/Symfony/Component/Yaml
, co pozwala autoloaderowi na poprawne działanie.
Co dalej ? Co jeszcze mogę uzyskać ?
Powoli, bez pośpiechu =)
To już koniec tej części, poruszyliśmy większość podstawowych zagadnień wykorzystywanych przez Composera i definiowanych w pliku composer.json
. W następnej części dowiecie się jeszcze więcej na ten temat, tak tak to jeszcze nie wszystkie możliwości które daje nam konfiguracja tego pliku!
Comments