Версии и ограничения
Версии Composer и версии VCS
Поскольку Composer сильно ориентирован на использование систем управления версиями, таких как git, термин «версия» может быть немного неоднозначным. В смысле системы управления версиями «версия» — это определенный набор файлов, содержащий конкретные данные. В терминологии git это «ссылка» или конкретный коммит, который может быть представлен веткой HEAD или тэгом. Когда вы выгружаете эту версию в вашей системе управления версиями — например, тэг v1.1 или коммит e35fa0d — вы запрашиваете единый, известный набор файлов, и всегда получаете одни и те же файлы обратно.
В Composer то, что часто называют просто версией — то есть строка, следующая за именем пакета в строке require (например, ~1.1 или 1.2.*) — на самом деле является ограничением версии. Composer использует ограничения версии, чтобы определить, какие ссылки в системе управления версиями необходимо выгружать (или чтобы проверить, подходит ли данный библиотечный файл в случае статически поддерживаемой библиотеки со спецификацией version в composer.json).
Тэги и ветки VCS
Для следующего обсуждения предположим, что у нас есть следующий пример репозитория библиотеки:
~/my-library$ git branch
v1 v2 my-feature another-feature
~/my-library$ git tag
v1.0 v1.0.1 v1.0.2 v1.1-BETA v1.1-RC1 v1.1-RC2 v1.1 v1.1.1 v2.0-BETA v2.0-RC1 v2.0 v2.0.1 v2.0.2
Тэги
Обычно Composer работает с тэгами (в отличие от веток — если вы не знаете, что это значит, ознакомьтесь с системами управления версиями). Когда вы записываете ограничение версии, оно может ссылаться на конкретный тэг (например, 1.1) или на допустимый диапазон тэгов (например, >=1.1 <2.0, или ~4.0). Чтобы разрешить эти ограничения, Composer сначала запрашивает у системы управления версиями список всех доступных тэгов, затем создает внутренний список доступных версий на основе этих тэгов. В приведенном выше примере внутренний список Composer включает версии 1.0, 1.0.1, 1.0.2, бета-версию 1.1, первую и вторую кандидаты на выпуск 1.1, окончательную версию выпуска 1.1, и т.д.... (Обратите внимание, что Composer автоматически удаляет префикс «v» в имени тэга, чтобы получить действительное конечное число версии.)
Когда у Composer есть полный список доступных версий из вашей системы управления версиями, он находит самую высокую версию, которая соответствует всем ограничениям версии в вашем проекте (возможно, что другие пакеты требуют более конкретных версий библиотеки, чем у вас, поэтому выбранная версия может не всегда быть самой последней доступной версией), и загружает архив zip этого тэга для распаковки в нужном месте в вашей директории vendor.
Ветки
Если вы хотите, чтобы Composer выгружал ветку вместо тэга, вам нужно указать её с помощью специального префикса dev-* (или иногда суффикса; см. ниже). Если вы выгружаете ветку, предполагается, что вы хотите работать с ней, и Composer фактически клонирует репозиторий в нужное место в вашей директории vendor. Для тэгов он копирует нужные файлы без фактического клонирования репозитория. (Вы можете изменить это поведение с помощью --prefer-source и --prefer-dist, см. опции установки.)
В приведенном выше примере, если вы хотите выгрузить ветку my-feature, вы должны указать dev-my-feature как ограничение версии в вашей require части. Это приведет к тому, что Composer клонирует репозиторий my-library в мою директорию vendor и выгрузит ветку my-feature.
Когда имена веток похожи на версии, нам нужно уточнить для Composer, что мы пытаемся выгрузить ветку, а не тэг. В приведенном выше примере у нас есть две ветки с именами, похожими на версии: v1 и v2. Чтобы заставить Composer выгрузить одну из этих веток, вы должны указать ограничение версии, которое выглядит так: v1.x-dev. .x — это произвольная строка, необходимая Composer, чтобы понять, что мы говорим о ветке v1, а не о тэге v1 (или, альтернативно, вы можете назвать ветку v1.x вместо v1). В случае ветки с именем, похожим на версию (v1, в данном случае), вы добавляете -dev в качестве суффикса, а не используете dev- в качестве префикса.
Уровни стабильности
Composer распознает следующие уровни стабильности (в порядке убывания стабильности): dev, alpha, beta, RC и stable, где RC означает кандидат на выпуск. Уровень стабильности версии определяется её суффиксом, например, версия v1.1-BETA имеет уровень стабильности beta, а v1.1-RC1 — RC. Если такой суффикс отсутствует, например, версия v1.1, тогда Composer считает, что версия stable. Кроме того, Composer автоматически добавляет суффикс -dev ко всем числовым веткам и добавляет префикс dev- ко всем другим веткам, импортируемым из репозитория VCS. В обоих случаях назначается стабильность dev.
Учитывая это, вам будет легче понять следующий раздел.
Минимальный уровень стабильности
Есть еще одна вещь, которая повлияет на то, какие файлы из системы управления версиями библиотеки будут загружены и добавлены в ваш проект: Composer позволяет указывать ограничения по уровню стабильности, чтобы ограничить, какие тэги считаются допустимыми. В приведенном выше примере обратите внимание, что библиотека выпустила бета-версию и две кандидаты на выпуск для версии 1.1 до окончательного официального выпуска. Чтобы получить эти версии при запуске composer install или composer update, мы должны явно указать Composer, что мы согласны с кандидатами на выпуск и бета-версиями (и альфа-версиями, если нам они нужны). Это можно сделать, используя глобальное значение minimum-stability в composer.json или используя «флаги стабильности» в ограничениях версии. Подробнее об этом на странице схемы.
Запись ограничений версии
Теперь, когда вы имеете представление о том, как Composer видит версии, давайте обсудим, как указывать ограничения версий для зависимостей вашего проекта.
Точное ограничение версии
Вы можете указать точную версию пакета. Это сообщит Composer об установке только этой версии. Если другие зависимости требуют другую версию, решатель в конечном итоге потерпит неудачу и прервёт любые процессы установки или обновления.
Пример: 1.0.2
Диапазон версий
Используя операторы сравнения, вы можете указать диапазоны допустимых версий. Допустимые операторы — >, >=, <, <=, !=.
Вы можете определить несколько диапазонов. Диапазоны, разделенные пробелом ( ) или запятой (,), будут обрабатываться как логическое И. Двойная вертикальная черта (||) будет обрабатываться как логическое ИЛИ. ИЛИ имеет более низкий приоритет, чем И.
Примечание: Будьте осторожны при использовании неограниченных диапазонов, так как вы можете случайно установить версии, которые нарушают обратную совместимость. Вместо этого рассмотрите использование оператора caret для обеспечения безопасности.
Примечание: В более старых версиях Composer одиночная вертикальная черта (
|) была рекомендуемой альтернативой для логического ИЛИ. Таким образом, для обратной совместимости одиночная вертикальная черта (|) по-прежнему будет обрабатываться как логическое ИЛИ.
Примеры:
>=1.0>=1.0 <2.0>=1.0 <1.1 || >=1.2
Диапазон версий с дефисом (-)
Включенный набор версий. Частичные версии справа включаются, дописываются символами «*». Например, 1.0 - 2.0 эквивалентно >=1.0.0 <2.1, так как 2.0 превращается в 2.0.*. С другой стороны, 1.0.0 - 2.1.0 эквивалентно >=1.0.0 <=2.1.0.
Пример: 1.0 - 2.0
Диапазон версий с символом подстановки (.*)
Вы можете указать шаблон с символом подстановки *. 1.0.* эквивалентно >=1.0 <1.1.
Пример: 1.0.*
Операторы следующего значимого выпуска
Диапазон версий с тильдой (~)
Оператор ~ лучше всего объясняется на примерах: ~1.2 эквивалентно >=1.2 <2.0.0, а ~1.2.3 эквивалентно >=1.2.3 <1.3.0. Как вы можете видеть, он в основном полезен для проектов, соблюдающих семантическое версионирование. Общее использование — указать минимальную версию младшего разряда, на которой вы полагаетесь, как в ~1.2 (что позволяет всё до, но не включая 2.0). Поскольку теоретически никаких нарушений обратной совместимости не должно быть до версии 2.0, это работает хорошо. Другой способ взглянуть на это — использовать ~ для указания минимальной версии, но позволяет последней цифре, указанной в версии, увеличиваться.
Пример: ~1.2
Примечание: Хотя
2.0-beta.1строго предшествует2.0, ограничение версии, такое как~1.2, не установит её. Как сказано выше,~1.2означает, что.2может измениться, но часть1.остаётся неизменной.Примечание: Оператор
~имеет исключение в своём поведении для номера основной версии. Это означает, например, что~1эквивалентно~1.0, поскольку это не позволит увеличить номер основной версии, сохраняя при этом обратную совместимость.
Диапазон версий с символом «^» (^)
Оператор ^ ведет себя очень похоже, но он ещё более привязан к семантическому версионированию и всегда позволит обновления без нарушения обратной совместимости. Например, ^1.2.3 эквивалентно >=1.2.3 <2.0.0, так как ни один из выпусков до 2.0 не должен нарушать обратную совместимость. Для версий до 1.0 он также действует с осторожностью и рассматривает ^0.3 как >=0.3.0 <0.4.0, а ^0.0.3 как >=0.0.3 <0.0.4.
Это рекомендуемый оператор для максимальной совместимости при написании кода библиотек.
Пример: ^1.2.3
Ограничения стабильности
Если вы используете ограничение, которое не явно определяет стабильность, Composer по умолчанию использует -dev или -stable, в зависимости от используемого оператора(ов). Это происходит прозрачно.
Если вы хотите явно учитывать только стабильный выпуск при сравнении, добавьте суффикс -stable.
Примеры:
| Ограничение | Внутренне |
|---|---|
1.2.3 | =1.2.3.0-stable |
>1.2 | >1.2.0.0-stable |
>=1.2 | >=1.2.0.0-dev |
>=1.2-stable | >=1.2.0.0-stable |
<1.3 | <1.3.0.0-dev |
<=1.3 | <=1.3.0.0-stable |
1 - 2 | >=1.0.0.0-dev <3.0.0.0-dev |
~1.3 | >=1.3.0.0-dev <2.0.0.0-dev |
1.4.* | >=1.4.0.0-dev <1.5.0.0-dev |
Чтобы разрешить различные уровни стабильности без их принудительного применения на уровне ограничений, вы можете использовать флаги стабильности, такие как @<stability> (например, @dev), чтобы сообщить Composer, что данный пакет может быть установлен с другой стабильностью, отличной от вашего параметра минимальной стабильности по умолчанию. Все доступные флаги стабильности перечислены в разделе минимальной стабильности страницы схемы.
Обзор
"require": {
"vendor/package": "1.3.2", // exactly 1.3.2
// >, <, >=, <= | specify upper / lower bounds
"vendor/package": ">=1.3.2", // anything above or equal to 1.3.2
"vendor/package": "<1.3.2", // anything below 1.3.2
// * | wildcard
"vendor/package": "1.3.*", // >=1.3.0 <1.4.0
// ~ | allows last digit specified to go up
"vendor/package": "~1.3.2", // >=1.3.2 <1.4.0
"vendor/package": "~1.3", // >=1.3.0 <2.0.0
// ^ | doesn't allow breaking changes (major version fixed - following semver)
"vendor/package": "^1.3.2", // >=1.3.2 <2.0.0
"vendor/package": "^0.3.2", // >=0.3.2 <0.4.0 // except if major version is 0
} Тестирование ограничений версий
Вы можете протестировать ограничения версий, используя semver.madewithlove.com. Введите имя пакета, и он автоматически заполнит ограничение версии по умолчанию, которое Composer добавит в ваш composer.json файл. Вы можете настроить ограничение версии, и инструмент отобразит все версии, соответствующие этому ограничению.
© Nils Adermann, Jordi Boggiano
Licensed under the MIT License.
https://getcomposer.org/doc/articles/versions.md