Composer: Управление версиями


Оригинал: Composer Versioning

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

Всемогущая звездочка

Поскольку Composer — это менеджер зависимостей, он должен автоматически определять, что мне нужно для проекта, так? Нет, не так.
Объявление номера версии с помощью *— одно из худших решений, которое может прийти вам в голову. В такой ситуации у вас нет совершенно никакого контроля над тем, что вы получите. Это может быть абсолютно любая версия, которая соответствует вашей минимальной стабильности и другим требованиям.
По сути, вы играете с Composer в рулетку зависимостей. В конечном итоге вы потерпите поражение и начнете обвинять Composer в том, что он работает из рук вон плохо.
Если вы планируете и дальше сохранять звездную независимость, стоит хотя бы установить последнюю версию от разработчиков, которые обычно помечены как dev-master.

Жестко закодированные бранчи

Итак, теперь переходим к использованию версии dev-master. Проблема в том, что dev-master — величина непостоянная. С одной стороны, вы всегда будете получать нестабильные пакеты (нестабильные с точки зрения Composer). Но большая проблема скрывается в том, что смысл версии dev-master может измениться в любой момент.
Давайте предположим, что dev-master представляет собой последнюю версию от разработчиков под номером 1.0. В какой-то момент разработчики дали указание библиотеке переходить на работу с версией 1.1, что является логичным продолжением ветки 1.0, и dev-master становится последней версией авторов под номером 1.1.
Если вы не следите за развитием этой библиотеки, то вы не заметите ничего необычного, пока не запустите обновление Composer. Приложение даст сбой, и вся ваша работа пойдет насмарку. Поэтому непосредственно указывать на имя бранча не стоит, так как это не слишком надежно. К счастью, Composer готов помочь нам с псевдонимами.

Бранч-псевдонимы

Бранч-псевдоним — это свойство, которое разработчики могут интегрировать в файл composer.json, что позволит сопоставлять имя бранча с версией. Для бранчей под номерами 1.0, 2.1, и т.д. в этом нет необходимости — Composer сам их обрабатывает.
Но для бранча с именем master, который является производным от dev-master, нужно в обязательном порядке указывать псевдоним. В руководствах к Composer есть большая статья по псевдонимам которая объясняет, как бранч-псевдонимы могут быть определены:

{
    "extra": {
        "branch-alias": {
            "dev-master": "1.0.x-dev"
        }
    }
}
Здесь dev-master получает псевдоним 1.0.x-dev, который по существу означает, что вы можете запрашивать пакет с ограничением 1.0.*@dev. Главная особенность такого подхода заключается в том, что значение 1.0 уже определено и меняться не будет. Таким образом, переход на стабильные версии осуществляется гораздо проще.
Но при использовании бранч-псевдонимов есть одно условие: разработчики пакета должны интегрировать их внутрь. Если вы используете библиотеку, которая не имеет бранч-псевдонима, отправьте разработчикам запрос, чтобы они добавили extra секцию в composer.json.

Стабильные релизы

Версия с ограничениями 1.0.*@dev работает довольно неплохо. Проблема в том, что стабильной версии пока не существует. Использование нестабильной версии не сильно сказывается на вашем коде.
Но что если среди вас есть другие пользователи, находящиеся в зависимости от вашего пакета? Им потребуется ваша зависимость с флагом разработчика @dev, чтобы Composer установил нестабильную версию или, что еще хуже, ниже минимальной стабильности. Это означает, что пользователи получают нестабильные версии всех пакетов.
Чтобы избежать проблем, связанных с версией для разработчика, достаточно обратить внимание на версии, отмеченные тэгами. Если вы используете библиотеку, которая не имеет отмеченных релизов, найдите и доставайте разработчика, пока он не проставит тэги. Сделай это прямо сейчас!
Мы, как Composer-сообщество, должны взять на себя определенную ответственность. Нам нужно не только как следует проставлять тэги на релизах, но и поддерживать в порядке логи изменений. Это трудная задача, имеющая огромное значение для всей системы в целом. Помните, что надо следить за тэгами ответственно и семантически.
Если у вас есть стабильный релиз, вы можете удалить флаг разработчика @dev и изменить ограничение до 1.0.*.

Следующий значительный релиз

Если зависимость, которую вы используете, придерживается правил семантики и сохраняет строгую нумерацию релизов, то вы можете сделать больше ограничений.
Сейчас в версии 1.0.* допускаются некоторые проблемы при совместимости с версией 1.1. Если вы зависите от 1.0, а кто-то нуждается в функции из версии 1.1 (которая является обратно совместимой), то он не может установить ее. Тогда мы получим что-то вроде 1.*.
И когда вы указываете номер версии >=1.1,<2.0 — это раздражает. Вместо такой громоздкой конструкции используйте знак тильды, который означает то же самое, но без лишних символов: ~1.1. Это означает, что версия — «любая 1.* из 1.1 или выше». Таким образом, мы задействовали всего лишь один символ и получили полную пакетную совместимость и семантическую поддержку.

Резюмируем:

8 комментариев

avatar
Кто-то ещё не использует композер?
avatar
Я например не особо вижу смысла в нем, если только ты не делаешь инструмент, а сайт. Во многих случаях обновление частей функционала необходимо заморозить, что бы они не отвалились автоматически.
avatar
А как закачать только определенную ветку? Например:
«require»: {
«smarty/smarty»: "~3.1"
}

закачает в vendor и deployment и distribution и прочее сопутствующее, а нужен только distribution?
avatar
«smarty/smarty»: «3.1.*» — закачает последнюю доступную версию из ветки 3.1.
avatar
Вы не поняли, мне нужно только distribution без development и пр.
avatar
Это особенность данного пакета.
code.google.com/p/smarty-php/source/browse/trunk/composer.json
Разработчики не используют зависимости. Вместо этого хранят все пакеты в сразу репозитории.
avatar
На будущее, четче формулируйте вопрос. Ветки — это по сути версии. А то, о чем говорите Вы, это дополнительные инструменты для разработчиков. Они указываются в композере в зависимостях require-dev.
avatar
Ок. Тем более, что в autoload включается именно distrubibution.

Оставить комментарий