Нередко мы хотим использовать composer для включения репозиториев Git в наш php-проект. Во многих случаях репозитории были созданы на packagist.org и требовать их с композитором очень просто. Но что делать, если репозиторий не был создан как пакет на packagist? Ответ заключается в том, что мы используем composer, чтобы потребовать пакет непосредственно из репозитория.
Заметка: Некоторая терминология в посте сбивает с толку, потому что несколько слов используются для описания разных вещей. Вот краткий словарный список, который поможет:
- Проект – пользовательское программное обеспечение, которое мы создаем. Это может быть веб-сайт, утилита командной строки, приложение или что-то еще, о чем мы мечтаем.
- Пакет - Любое программное обеспечение 3-й стороны, которое мы хотим загрузить и использовать в нашем проекте. Это может быть библиотека, тема Drupal, плагин WordPress или любое другое количество вещей.
- Репозиторий Git – AKA, репозиторий Git. Узел системы управления версиями для пакета. Распространенными хостами являются: GitHub, GitLab или Bitbucket; но любой доступный по URL-адресу репозиторий Git будет работать для этого учебника.
- Репозитории Composer — в файле composer.json есть необязательное свойство с именем «репозитории». В этом свойстве мы можем определить новые места для Composer при загрузке пакетов.
При добавлении репозитория Git в наш проект с composer мы можем оказаться в двух ситуациях: репозиторий содержит файл composer.json и определяет, как репозиторий должен обрабатываться, когда это необходимо, или нет. Несмотря на это, в обоих случаях мы можем добавить репозиторий Git в наш проект.
Начнем с репозитория Git, определившего файл composer.json .
Репозиторий Git с composer.json
Когда репозиторий включает файл composer.json , он определяет аспекты самого себя, которые важны для того, как composer управляет пакетом. Ниже приведен пример простого файла composer.json , который может содержаться в пакете.
{
"name": "daggerhart/my-custom-library",
"type": "library"
}
composer.json
Показаны два важных свойства, которые может определить файл composer.json :
- name: имя пакета с пространством имен. В данном случае daggerhart — это пространство имен для пакета my-custom-library.
- type: тип пакета, который представляет репозиторий. Типы пакетов используются для логики установки. Из коробки composer позволяет использовать следующие типы пакетов: библиотека, проект, метапакет, композитор-плагин.
Вы можете убедиться в этом, посмотрев на файл composer.json любого популярного проекта. Каждый из них определяет имя своего пакета и тип пакета в верхней части файла.
Когда репозиторий имеет эту информацию, определенную в файле composer.json, требование репозитория в нашем проекте является относительно простым.
Требуется репозиторий Git с файлом
composer.json Теперь, когда мы определили репозиторий GIt с файлом composer.json, давайте спросим этот репозиторий как пакет в нашем проекте.
В файле composer.json нашего проекта нам нужно определить новое свойство (при условии, что оно еще не существует) с именем "repositories". Значение свойства репозиториев представляет собой массив объектов. Каждый объект, содержащий информацию о репозитории, мы хотим включить в наш проект. Рассмотрите этот файл composer.json для нашего пользовательского проекта.
{
"name": "daggerhart/my-project-that-uses-composer",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/daggerhart/my-custom-library.git"
}
],
"require": {
"daggerhart/my-custom-library": "dev-master"
}
}
composer.json
Здесь мы делаем две важные вещи. Во-первых, мы определяем новый репозиторий, на который composer может ссылаться при запросе пакетов. А во-вторых, нам требуется пакет из вновь определенного репозитория.
Заметка: Версия пакета является частью оператора require, а не частью свойства репозитория. Мы можем запросить определенную ветвь репозитория, выбрав версию с именем "dev-<branch name>".
Если бы мы работали composer install
в контексте этого файла, composer искал бы проект по определенному URL-адресу, и если этот URL-адрес представляет репозиторий Git, содержащий файл composer.json, который определяет его имя и тип, composer загрузит этот пакет в наш проект и разместит его в соответствующем месте.
Пользовательские типы пакетов
Пример пакета, показанный выше, относится к типу «библиотека», но часто в нашей работе с WordPress и Drupal мы имеем дело с плагинами, модулями и темами. Когда в нашем проекте требуются специальные типы пакетов, важно, чтобы они были установлены в определенных местах в файловой структуре проекта. Разве не было бы хорошо, если бы мы смогли убедить композитора рассматривать эти типы пакетов как особые случаи? Что ж, нам повезло. Есть официальный композитор-плагин, который сделает это за нас.
composer/installers — плагин installers composer содержит пользовательскую логику, необходимую для обработки множества различных типов пакетов для большого разнообразия проектов. Это чрезвычайно полезно при работе с проектами, которые имеют хорошо известные и поддерживаемые этапы установки пакетов.
Этот проект позволяет нам определять типы пакетов, такие как: drupal-theme, drupal-module, wordpress-plugin, wordpress-theme и многие другие, для различных проектов. В случае пакета drupal-theme плагин composer/installers разместит необходимый репозиторий в папке /themes/contrib нашей установки Drupal.
Вот пример файла composer.json, который может жить в проекте темы Drupal в качестве собственного репозитория Git:
{
"name": "daggerhart/whatever-i-call-my-theme",
"type": "drupal-theme",
"description": "Drupal 8 theme",
"license": "GPL-2.0+"
}
composer.json
Обратите внимание, что единственное важное различие здесь заключается в том, что «тип» теперь «drupal-theme». С определенным типом темы drupal любой проект, который использует плагин composer / installers, может легко потребовать наше репозиторие в своем проекте Drupal, и он будет рассматриваться как добавленная тема.
Требовать любой репозиторий Git с Composer
Теперь, когда мы знаем, как требовать репозиторий Git, содержащий файл composer.json, давайте рассмотрим случай, когда репозиторий, который мы хотим включить в наш проект, ничего не определяет о себе с файлом composer.json.
Короче говоря, когда репозиторий не определяет свое имя или тип, мы должны определить эту информацию для репозитория в файле composer.json нашего проекта. Взгляните на этот пример:
{
"name": "daggerhart/my-project-that-uses-composer",
"repositories": [
{
"type": "package",
"package": {
"name": "daggerhart/my-custom-theme",
"version": "1.2.3",
"type": "drupal-theme",
"source": {
"url": "https://github.com/daggerhart/my-custom-theme.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"daggerhart/my-custom-theme": "^1",
"composer/installers": "^1"
}
}
composer.json
Обратите внимание, что наш тип репозитория теперь "package". Именно здесь мы собираемся определить все о пакете, который мы хотим потребовать. Затем мы создаем новый объект с именем "package", где мы определяем всю важную информацию, которую композитор должен знать, чтобы иметь возможность включить этот произвольный репозиторий git в наш проект. Включая:
- name — имя пакета с пространством имен. Вероятно, он должен соответствовать репозиторию, который нам нужен, но не обязательно.
- type – Тип упаковки. Как мы хотим, чтобы композитор относился к этому репозиторию.
- version – составленный номер версии для репозитория.
-
source — объект, содержащий следующие сведения репозитория:
- url — URL-адрес Git (или другого VCS), в котором можно найти репозиторий пакета.
- type — тип VCS для пакета. git, svn, cvs (?) ... и так далее.
- ссылка – ветвь или тег, который мы хотим загрузить.
Рекомендую ознакомиться с официальной документацией по репозиториям пакетов композиторов. Обратите внимание, что можно также включить zip-файлы в качестве пакетов композитора.
По сути, теперь мы несем ответственность за все части того, как композитор относится к этому репозиторию. Поскольку сам репозиторий не предоставляет композитору никакой информации, мы несем ответственность за определение практически всего, включая номер текущей версии пакета.
Такой подход позволяет нам включать в наш проект практически все в качестве композиторского пакета, но у него есть некоторые недостатки. Примечательные недостатки:
- Composer не будет обновлять пакет, пока вы не измените
version
поле. - Composer не будет обновлять ссылки на фиксацию, поэтому, если вы используете
master
в качестве ссылки, вам придется удалить пакет, чтобы принудительно обновить, и вам придется иметь дело с нестабильным файлом блокировки.
Пользовательские версии пакетов
Поддержание версии пакета в нашем файле composer.json не всегда необходимо. Composer достаточно умен, чтобы искать релизы GitHub и использовать их в качестве версий пакета. Но в конце концов мы обнаружим, что хотим включить простой проект, который имеет только несколько филиалов и не имеет официальных релизов.
Если репозиторий не имеет выпусков, мы несем ответственность за принятие решения о том, какую версию ветвь репозитория представляет для нашего проекта. Другими словами, если мы хотим, чтобы composer обновил пакет, нам нужно будет увеличить «версию», определенную в файле composer.json нашего проекта перед запуском composer update
.
Переопределение composer.json
репозитория Git Интересная вещь, которую мы можем сделать при определении нового репозитория composer пакета типов, — это переопределить собственные определения composer.json пакета. Рассмотрим репозиторий Git, который определяет себя как библиотеку в своем composer.json, но мы знаем, что код на самом деле является drupal-темой. Мы можем использовать этот приведенный выше подход для включения репозитория Git в наш проект в качестве drupal-темы, что позволяет композитору обращаться с кодом соответствующим образом, когда это необходимо.
Пример: требуйте Guzzle в качестве drupal-темы только для того, чтобы доказать, что мы можем.
{
"name": "daggerhart/my-project-that-uses-composer",
"repositories": [
{
"type": "package",
"package": {
"name": "daggerhart/guzzle-theme",
"version": "1.2.3",
"type": "drupal-theme",
"source": {
"url": "https://github.com/guzzle/guzzle.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"daggerhart/guzzle-theme": "^1",
"composer/installers": "^1"
}
}
composer.json
Это работает! Это загрузит библиотеку Guzzle и поместит ее в папку /themes моего проекта Drupal. Очевидно, что это не очень практичный пример, но, надеюсь, он подчеркивает, насколько контроль обеспечивает подход к типу упаковки.
Summary
Composer предлагает нам множество вариантов включения произвольных пакетов в наш проект. Вопрос о том, как эти пакеты включаются в проект, в первую очередь сводится к тому, «кто определяет информацию о пакете?». Если репозиторий Git содержит файл composer.json, который определяет его имя и тип, то мы можем попросить composer полагаться на сам репозиторий для определения. Но если мы хотим включить репозиторий, который не определяет свое имя и тип, то наш проект должен определить и поддерживать эту информацию для нашего собственного внутреннего использования.
Кроме того, если репозиторий не определяет файл composer.json, рассмотрите возможность отправки запроса на извлечение, который его добавляет. ?
Ссылки: