Версии пакетов в composer.json

Вы наверняка видели всякие "^3.2", "~3.2" в файле composer.json. Давайте разберемся что значат эти знаки и поддержку каких версий пакетов они означают.

Начнем с общего примера, где показаны все возможные варианты. Пример файла composer.json:

{
  "require": {
	"author/package": ">=5.6",
	"author/package": "~2.0.14",
	"author/package": "~2.0.0",
	"author/package": "~2.0.0 || ~2.1.0",
	"author/package": "2.4.1"
	"author/package": "dev-master",
	"author/package": "*"
  },
  "require-dev": {
	"author/package": "~2.1.0",
	"author/package": "~2.1.0",
	"author/package": "~2.0.0",
	"author/package": "^4.0",
	"author/package": "^1.0",
	"author/package": "^1.0",
	"author/package": "^1.0",
	"author/package": "~0.5.0 || ~1.1.0",
	"author/package": ">=2.7 <=4.2.4"
  }
}

Точная версия

Разрешает только указанную версию пакета. Указывается явно без всяких знаков:

"erusev/parsedown": "1.7"

Последняя версия/код

*
Разрешены только стабильные релизы - последний релиз с тегом версии.
dev-* например "dev-master"

Разрешены любые изменения, включая последние коммиты в ветку *. Даже коммиты без стабильных тегов.

* нужно заменить на название ветки, изменения из который вы хотите забирать. Например:

"vendor/package": "dev-master",
"vendor/package": "dev-main",
"vendor/package": "dev-dev"

Диапазоны версий

Разрешает обновлять пакет в версиях указанного диапазона.

> например ">1.7"
Разрешено все что больше указанной версии.
>= например ">=1.7"
Разрешено все что больше или равно указанной версии.
< например "<1.7"
Разрешено все что меньше указанной версии.
<= например "<=1.7"
Разрешено все что меньше или равно указанной версии.
!= например "!=1.7"
Разрешено все кроме указанной версии.
* например "1.1.*"

Подстановочный знак. Означает любое число. С помощью него указывается шаблон версии.

  • 1.0.* включает в себя все версии 1.0 1.0.1 1.0.2 1.0.3 и т.д.
~ например "~1.2.3"

Оператор тильда. Позволяет повышаться последней указанной цифре.

Обычно используется для обозначения минимальной минорной версии, от которой зависит код.

  • ~1.2 тоже что >=1.2 <2.0.0 (допускает все до 2.0, но не включая 2.0).

  • ~1.2.3 тоже что >=1.2.3 <1.3.0 (допускает все до 1.3, но не включая 1.3).

Пример:

// Версия пакета больше или равна 2.0.14 но меньше 2.1
"erusev/parsedown": "~2.0.14"
^ например "^1.2.3"

Каретка фиксирует первую цифру и позволяет расти всем числам правее. Если первая цифра ноль, каретка "проваливается" глубже, ища первую ненулевую, которую затем фиксирует.

Обратите внимение, что вниз изменения недопустимы. Напрмер

  • ^7 - позволит 7.1, 7.5
  • ^7.4 - позволит минимум 7.4, 7.5 ...

Это рекомендованный оператор для совместимости при написании/использовании библиотеки.

Обычно используется для обозначения минимальной мажорной версии. Т.е. указывает основную допустимую версию, и разрешает все вложенные (минорные) версии.

  • ^1.2.3 тоже что >=1.2.3 <2.0.0 (допускает все до 2.0, но не включая 2.0).

  • Если мажорная версия начинается с 0, то разрешает все обновления до второго числа. Т.е. для версий до 1.0 он также учитывает безопасность обновлений и рассматривает ^0.3 как >=0.3.0 <0.4.0.

Пример:

"erusev/parsedown": "^4.0"

Объединение диапазонов

Можно указать одновременно несколько диапазонов:

  например ">2.7 <4.2.4"
, например ">2.7,<4.8"
Логическое AND. Пробел или запятая между версиями означает AND.
|| например "2.0.0 || 2.1.0"
| например "^1|^2"

Логическое OR. Двойная вертикальная черта означает OR.

NOTE: В старых версиях Composer одинарная труба | была рекомендуемой альтернативой логическому OR. Поэтому для обратной совместимости | по-прежнему рассматривается как логическое OR.

ВАЖНО: AND приоритетнее чем OR.

Примеры:

// Больше или равно версии 2.6
"erusev/parsedown": ">=2.6"

// Больше версии 2.7  И  меньше версии 4.2.4
"erusev/parsedown": ">2.7 <4.2.4"

// Версия 2.0.0   ИЛИ   версия 2.1.0
"erusev/parsedown": "2.0.0 || 2.1.0"

Диапазон версий через дефис -

Дефис -, указывает какой набор версий подходит: от версии - до версии. Самое правое неуказанное число в версии дополняется знаком *.

Например, 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.

Пример:

// больше или равно 2.0 но меньше 3.1
"erusev/parsedown": "2.0 - 3.0"

Ограничения стабильности

Добавьте суффикс -stable, если нужно загружать только стабильные версии.

Если никакой суффикс не указан, то Composer под капотом будет использовать -dev или -stable, в зависимости от указанного оператора:

Указанная версия Как её понимает composer
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

Алиасы

Когда для версии композер пакета мы указываем ветку (например, dev-main), а не версию, мы можем столкнуться с конфилктом, если зависимость требует например версию 1.0.*. Алиас решает эту проблему:

  • вы говорите Composer считать dev-main как 1.0.x-dev.

Тогда dev-main выглядит как версия 1.0.*, и зависимость не конфликтует.

Заметка: dev- префикс в композере:

Composer всегда помечает ветки (branches) как dev-{branch_name}. То есть:

  • Ветка main в Composer будет dev-main
  • bugfix = dev-bugfix.
  • feature/foo = dev-feature/foo.

Почему:

Composer различает "версии" (теги: 1.2.3, 1.0.x) и "ветки" (dev-main, dev-dev).
Чтобы их не путать, ветки получают префикс dev-.
Это стандарт и часть правил сравнения версий в Composer.

Inline alias (алиас в require)

Composer позволяет указывать алиасы прямо в require, когда вам нужно временно использовать свою ветку с фиксом бага в зависимости.

Например:

  • вы нашли баг в monolog/monolog
  • форкнули его
  • создали ветку bugfix
  • хотите использовать этот код в вашем проекте

Но ваш проект использует symfony/monolog-bundle, который требует monolog/monolog версии 1.*.

Нужно сделать так, чтобы ваша dev-bugfix ветка подходила под это ограничение.

В корневом composer.json файле:

{
	"repositories": [
		{
			"type": "vcs",
			"url": "https://github.com/you/monolog"
		}
	],
	"require": {
		"symfony/monolog-bundle": "2.0",
		"monolog/monolog": "dev-bugfix as 1.0.x-dev"
	}
}

Важные примечания:

  • Inline alias работает только в корневом проекте - только в composer.json вашего проекта (того, где вы запускаете "composer install"). Внутри зависимостей (в их собственных composer.json) алиасы не работают и игнорируются.

  • Inline alias лучше избегать, особенно в публичных пакетах. Если есть баг - отправьте PR в оригинальный репозиторий.

Branch alias (алиас ветки)

Алиас ветки позволяет дать ветке dev-main семантическую версию, например 1.0.x-dev.

{
	"extra": {
		"branch-alias": {
			"dev-main": "1.0.x-dev"
		}
	}
}

Ограничения:

  • Алиасить можно только версии которые можно сравнивать. Например:

    • Можно: "dev-main": "1.0.x-dev"
    • Нельзя: "dev-main": "dev-master"
  • Можно алиасить и сравнимые версии, но только, но только в более специфичные. Например:

    • Можно: 1.x-dev: 1.2.x-dev, 2.x-dev: 2.1.x-dev
    • Нельзя: 1.2.x-dev: 1.x-dev, 2.3.x-dev: 2.0.x-dev
  • Алиас для ветки должен хранится в этой же ветке.

  • Чтобы использовать branch alias, вы должны владеть репозиторием пакета. Если вы хотите алиасить чужой пакет, не создавая форк, используйте inline alias.

Итого

"require": {
  // только верся 1.3.2
  "author/package": "1.3.2",

  // >, <, >=, <= | укажите верхние / нижние границы
  "author/package": ">=1.3.2", // все, что выше или равно 1.3.2
  "author/package": "<1.3.2",  // ниже 1.3.2

  // * | подстановочный знак
  "author/package": "1.3.*", // >=1.3.0 <1.4.0

  // ~ | позволяет быть выше последней указанной цифре
  "author/package": "~1.3.2", // >=1.3.2 <1.4.0
  "author/package": "~1.3", // >=1.3.0 <2.0.0

  // ^ | не допускает критических изменений
  "author/package": "^1.3.2", // >=1.3.2 <2.0.0
  "author/package": "^0.3.2", // >=0.3.2 <0.4.0

  // OR
  "phpunit/phpunit": "^3||^4||^5||^6||^7||^8||^9",
  // old variant
  "phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9",

  // Alias
  "author/package": "dev-bugfix as 1.0.x-dev"
}

--

Офф. дока: https://getcomposer.org/doc/articles/versions.md