Composer: как его готовить и с чем кушать?

vasa_c

Новичок
Здравствуйте, уважаемые Знатоки! Тема сегодняшнего вопроса: "Composer и как его победить?".

Решил я компенсировать своё отставание от жизни и изучить все модные штучки, которые появились в последнее время.
Вот, дошёл до компосера. Все его используют и если ты выложил на гитхаб php-проект, а в корне нет composer.json, то с тобой даже здороваться перестанут.

Три раза я пытался в нём разобраться и все три раза останавливался при спонтанном возникновении чувства острой личной неприязни.
У меня есть несколько объяснений этому:

1. Эта вещь не для моего гуманитарного ума. Но, например, node+npm+grunt, недавно освоил с нуля за пару дней. Там всё чётко, логично и ясно. Здесь ничего не понять и документация не сильно помогает.

2. Я просто не могу ухватить сакральную философию компосера.

3. Либо вариант - это действительно ещё весьма сырое поделие.
Причём, даже не сырое, а складывается впечатление, что его изначально делали под какую-то определённую жёсткую инфраструктуру.
А потом решили выкатить для всеобщего использования и наспех допилили.

Ещё похоже, что в нём пытались использовать соответствующие подходы из других технологий, особенно не задумываясь, как это подходит к PHP.


Собственно, пример.

У меня на гитхабе библиотека. В ней есть каталог с, собственно, библиотекой. Есть вспомогательные библы, юнит-тесты, билды какие-то, документация и др.

Я так и не смог заставить компосер ставить то, что нужно. Он сливает вообще всё барахло. Более того, он клонирует всё это в конечной папке, то есть там остаётся репа .git. Теперь все эти либы в общий гит не положишь нормально.

В npm похоже, но там можно указать нужные файлы. Он всё во временный каталог склонирует и потому скопирует только то, что нужно.

Итого, вопрос: так и задумано или у меня руки кривые?

Структура каталогов

Всё валится в vendor в совершенно непонятной последовательности, плюс там создаются от самого компосера свои суррогатные автолоадеры и другой треш.

Только что внедряли стандарт PSR-0, благодаря которому можно написать один загрузчик в одну строчку, а потом просто класть все либы в соответствующие подкаталоги. И теперь те же люди внедряют совершенно противоположный подход. Я в замешательстве!

Версии

К чему вся эта морока со указанием версий, "master-dev" и всем остальным? Вы видите в этом реальный смысл?

Вот nodejs+npm, там с этим всё понятно, логично и органично. Модули не имеют глобальных имён и все свои зависимости ставят себе локально.
То есть, в системе одновременно может существовать модуль A, которых хочет B версии 1.2 и модуль C, который хочет B v1.1. И эти две версии B будут существовать параллельно.

У PHP никак две версии одной библиотеки параллельно не поставишь.

Именование

Именования пакетов, все эти "вендор/шмендор". Зачем?

В PHP есть чёткое имя, которое характеризует библиотеку - пространство имён.

То есть, вендор Вася написал класс MyClass и назвал его "vasa/MyClass", а Петя тоже MyClass наваял и назвал его "peta/MyClass".
С точки зрения компосера конфликтов пакетов не будет, но всё равно эти два пакета в одну систему никак не встанут.

Альтернативы

Можете указать какие-либо более-менее популярные альтернативы?

Пускай, даже, что-нибудь простое, которое не пытается ставить любую структуру из любых источников.
То есть, например, каждый пакет должен быть оформлен соответствующим образом, соответствовать PSR-0 и лежать в определённом месте.


Буду благодарен, если укажете, где ошибки в моих рассуждениях.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Можете указать какие-либо более-менее популярные альтернативы?

Пускай, даже, что-нибудь простое, которое не пытается ставить любую структуру из любых источников.
То есть, например, каждый пакет должен быть оформлен соответствующим образом, соответствовать PSR-0 и лежать в определённом месте.
PEAR называется.
 
  • Like
Реакции: WMix

vasa_c

Новичок
PEAR называется.
А чтобы локально ставить?

По мне менеджер зависимостей должен быть такой.
Написал - мне нужно добавить в свой проект библиотеку, он её скачал, все её зависимости тоже скачал и раскидал по нужным каталогам в соответствии с PSR. И я этой закоммитил спокойно с --message="Добавлена библиотека такая-то" и работаю дальше.
То есть это просто автоматизация ручного скачивания нужных либ.

Какие изъяны есть в моём подходе?
 

hell0w0rd

Продвинутый новичок
Не понял что не так с композером.
Можете скинуть ссылку на ваш проект на гитхабе?
Я бы не сказал что npm проще... Там зависимости ставятся рекурсивно.
vendor/package для того чтобы можно было поставить doctine/dbal и blabla/dbal вместе. Принято vendor/package называть github_owner/github_project.
 

Koc

Новичок
Я так и не смог заставить компосер ставить то, что нужно. Он сливает вообще всё барахло. Более того, он клонирует всё это в конечной папке, то есть там остаётся репа .git. Теперь все эти либы в общий гит не положишь нормально.
встречный вопрос: а с какой целью их класть в общий гит? vendor/ обычно под gitignore лежит. При этом copposer.json+composer.lock под системой контроля версий. При развертывании копии проекта просто делаешь composer install и все нужные версии (пробитые в лок-файле) ставятся автоматом в vendor/

upd: заставлять его ставить что-то конкретно а не весь package не нужно. Уже были попытки так делать https://github.com/symfony/symfony/issues/6605 и в итоге от этого отказались
 

vasa_c

Новичок
Не понял что не так с композером.
Может быть всё и так, просто я это понять до конца не могу. Возможно, я просто неверное представляю его область применения.

Можете скинуть ссылку на ваш проект на гитхабе?
Ну, вот это, например: https://github.com/vasa-c/go-Request
Как сделать, чтобы тянулась не вся репа, а только каталог src?

Я бы не сказал что npm проще... Там зависимости ставятся рекурсивно.
Там хоть понятно, что происходит. Хотя вот там, наоборот, нет вендоров, а могли бы пригодиться.

vendor/package для того чтобы можно было поставить doctine/dbal и blabla/dbal вместе. Принято vendor/package называть github_owner/github_project.
Да, но если я назову свои классы как у доктрины, то никакое именование пакета не поможет.
Нужно просто использовать другие пространства имён, то есть добавлять вендора именно в namespace, тогда приходим к тому, что я сказал: имя пакета = namespace
 

hell0w0rd

Продвинутый новичок
vasa_c, ну а какая разница? в npm пришлось бы называть doctrine-dbal и blabla-dbal
По поводу проекта - освойте .gitignore и добавьте туда *.phar
Уберите из composer.json version, я не знаю зачем эта опция поддерживаются - версии берутся из тегов в репозитории.
Composer имеет свой автолоадер, зачем писать свой велосипед/копипастить его?
PHP:
"autoload": {
  "psr-0": {
    "": "src/"
  }
}
И да, вы должны складывать свои папки в соответствии с psr-0, то есть
go/Request
Еще не обязательно, но принято называть неймспейсы с заглавной буквы, так проще читать.

Эту идиотскую вещь из psr-0 должны поправить в psr-4, но пока используем что есть (я про невозможность использовать Foo\Bar относительно src, надо обязательно создавать каталоги Foo/Bar)
 
Последнее редактирование:

vasa_c

Новичок
встречный вопрос: а с какой целью их класть в общий гит? vendor/ обычно под gitignore лежит. При этом copposer.json+composer.lock под системой контроля версий. При развертывании копии проекта просто делаешь composer install и все нужные версии (пробитые в лок-файле) ставятся автоматом в vendor/

upd: заставлять его ставить что-то конкретно а не весь package не нужно. Уже были попытки так делать https://github.com/symfony/symfony/issues/6605 и в итоге от этого отказались
Ну, возможно, в этом и содержится моё недопонимание. По мне, так все библиотеки должны в гите лежать.
Я сначала всё установил, запушил и кто другой pull сделал и у него сразу всё работает.
 

Koc

Новичок
То есть это просто автоматизация ручного скачивания нужных либ.
ну он так и работает.

плюс там создаются от самого компосера свои суррогатные автолоадеры и другой треш.

Только что внедряли стандарт PSR-0, благодаря которому можно написать один загрузчик в одну строчку, а потом просто класть все либы в соответствующие подкаталоги. И теперь те же люди внедряют совершенно противоположный подход. Я в замешательстве!
не вижу нигде противоположности. Все по PSR-0 так грузится + есть возможность для legacy-либ указать classmap или кастомные лоадеры. + искаропки возможность генерации classmap для повышения производительности.
 

vasa_c

Новичок
vasa_c, ну а какая разница? в npm пришлось бы называть doctrine-dbal и blabla-dbal
Ладно, другой пример - Twig. Там глобальный класс Twig, а пакет называется twig/Twig. Если я напишу свой класс Twig и назову его vasa-c/Twig, то это решит конфликты на уровне компосера, но проект с двумя этими классами будет не рабочий.

По поводу проекта - освойте .gitignore и добавьте туда *.phar
С какой целью.

Уберите из composer.json version, я не знаю зачем эта опция поддерживаются - версии берутся из тегов в репозитории.
Вот ещё веселуха.

Composer имеет свой автолоадер, зачем писать свой велосипед/копипастить его?
PHP:
"autoload": {
  "psr-0": {
    "": "src/"
  }
}
Где велосипед, какой велосипед?
 

Koc

Новичок
https://github.com/vasa-c/go-Request/blob/master/src/Autoloader.php вот этот велосипед

Я сначала всё установил, запушил и кто другой pull сделал и у него сразу всё работает.
теперь после pull нужно еще делать composer install. Ну или на крайняк это можно на post-pull hook повесить. Но там на самом деле можно много других полезных вещей прицепить, например резолвинг новых параметров

Если я напишу свой класс Twig и назову его vasa-c/Twig, то это решит конфликты на уровне компосера, но проект с двумя этими классами будет не рабочий.
композер решает конфликты на уровне композера. Естественно конфликты на уровне пхп он решить не в состоянии, да и не должен.
 

hell0w0rd

Продвинутый новичок
С той целью, что бинарники в системе контроля версий никто не хранит. у гитхаба есть возможность к релизу прицепить бинарник для лентяев.
Также бинарниками можно считать сжатые скрипты, стили. В общем все, что можно сгенерировать из того, что уже есть в системе контроля версий.
 

vasa_c

Новичок
Я не использую компосер и его автолоадер, поэтому там свой.
Если есть комментарии по той библиотеке, я с удовольствием их выслушаю, только тему другую создам. Здесь она для примера про компосер.

Все по PSR-0 так грузится
Но, как же? Мой класс go\Request\Request лежит в файле go\Request\src\Request.php.

композер решает конфликты на уровне композера. Естественно конфликты на уровне пхп он решить не в состоянии, да и не должен.
Тогда смысл придумывать имена для пакетов?
Именно, ощущение, что это взято из системы, где имеет смысл. Из той же ноды, например.
 

Koc

Новичок
у нас у всех вообще композер глобально установлен и *.phar в проекте нет).

Да, кстати, ты по идее можешь собирать phar для своей поделки в composer post-install/uprate hook.
 

vasa_c

Новичок
С той целью, что бинарники в системе контроля версий никто не хранит. у гитхаба есть возможность к релизу прицепить бинарник для лентяев.
github насколько помню, как раз отключил возможность файлы прикладывать.

я храню и к теме это имеет опосредованное отношение. Так же там хранятся юнит-тесты, которы никак из исходников не получишь и которые тоже в vendor никак не нужны.
 

hell0w0rd

Продвинутый новичок
vasa_c, нет, на этом форуме не помогают гавнокодерам, я считаю что подобное использование VCS - говнокодерство.
да, композер тянет все, ничего в этом такого нет, ничем это не мешает, вообще
 

Koc

Новичок
Но, как же? Мой класс go\Request\Request лежит в файле go\Request\src\Request.php.
Ну и лежит он как и лежал. Просто базовый путь в vendor/. PSR-0 нормально соблюдается и не нужно в каждой библиотеке создавать класс Autoloader.

бинарники нормально цепляются http://easycaptures.com/fs/uploaded/842/7079761938.png

Что значит тесты не нужны в вендорах? Чем они мешают? А если твои тесты используют тесты вендоров? А если ты что-то тестово в вендорах решил поправить и сразу тесты запустить?
 

vasa_c

Новичок
Кос, а как я их запущу, если они размазаны равномерным слоем по каким-то папкам внутри вендора?
 
Сверху