Видов программ великое множество, и все они сильно друг от друга отличаются. Со временем даже одна система может развиться так, что ее станет не узнать. Как же разобраться во всем этом хаосе? Одним из решений является “Версионирование ПО”, с которым мы познакомимся в этой статье.

Версионирование это способ группировки и маркировки изменений, вызванных эволюцией системы. Говоря проще, это использование имен, для описания некоторого состояния программы. Чаще всего, в качестве имени выступает цифра, но может так же использоваться некоторое слово или смесь обоих, на пример - 2.4-alpha.

Польза от версионирования ПО

Применение версионирования решает следующие основные задачи разработки и сопровождения ПО:

  1. Контроль изменений - с помощью версий, пользователи данной системы могут выбрать наиболее полезное для себя состояние (к примеру, с некоторой функциональностью или совместимую с данной ОС)
  2. Группировка - версии позволяют автору ПО сгруппировать изменения и предоставить их пользователям в виде патча или обновления
  3. Совместимость - при использовании “Семантического версионирования” (о котором мы поговорим немного позже), разработчики, использующие данный пакет, могут не бояться сломать свою систему после обновления или патча, так как правильный выбор версии гарантирует совместимость на уровне кода

Семантическое версионирование

Как уже было сказано ранее, версия может обозначаться любой последовательностью символов. Часто применяется простая модель версионирования: инкремент числа версии при каждом изменении - но это не всегда является удачным решением. Для понимания проблемы, с которой вы можете столкнуться при использовании такой модели версионирования, давайте рассмотрим простой пример:

Представьте, что вы используете пакет для обработки изображений в своей системе “Галерея фотографий”. Вся логика галереи всецело зависит от этого пакета, но пакет часто меняется, в нем появляются новые функции и закрываются старые баги, что постоянно изменяет его версию. Вы конечно же хотите “идти в ногу со временем” и часто обновляете этот пакет, но в один ужасный день вся система перестает работать. Быстрый анализ показывает, что проблема вызвана удалением из пакета одной старой, но используемой галереей функции (назовем ее crop).

Как же обезопасить свой код от такого рода проблем? Решение есть, оно называется “Семантическим версионированием”. Использование систем, применяющих эту модель версионирования, обеспечивает вас удобным инструментом для контроля за возможными изменениями и совместимостью. Работает это очень просто, нужно всего навсего следовать следующим правилам при выборе версии ПО:

  1. Версия представляется в виде трех целых цифр, разделенных точкой (на пример 2.4.1). Первая цифра называется минором версии, вторая мажором, а третья патчем
  2. Каждая из трех цифр не ограничена в своей размерности и служит для контроля изменений на данном уровне (об уровнях чуть позже). Это означает, что версия вида 3.15.91 вполне обычное явление и не следует стремиться к смене мажорной версии при достижении патч-версии десятки (частая ошибка новичков)
  3. Патч-версия изменяется при любых изменениях системы, не добавляющих новую функциональность и не изменяющих старую. Обычно изменение патч-версии ПО означает, что в нем были поправлены некоторые баги или выполнен рефакторинг
  4. Мажорная версия изменяется при добавлении новой функциональности с учетом обратной совместимости. Другими словами, вы можете смело обновлять ПО на новую мажорную версию, не опасаясь ошибок, описанных в примере выше, так как с этим обновлением вы получите только новую функциональность
  5. Минорная версия изменяется при появлении несовместимых изменений, таких как: удаление устаревших (но, может быть, используемых кем то) функций, расширения семантики компонентов системы (к примеру добавление новых, обязательных аргументов функции) и т.п. Для обновления минорной версии необходимо предварительно обеспечить совместимость ваших компонентом с ее правками

Чтобы было понятнее, рассмотрим несколько примеров:

Если вы увидите, что для используемого вами пакета обработки изображений ImageEditor 1.1.4 изменилась версия до 1.1.5 (патч-версия), смело обновляйте ее, ведь это не нарушит совместимости с вашей галереей.

В новой версии 1.2.0 (мажорная версия) этого же пакета появилась функция resize? Обновитесь. Галерея будет продолжать работать без ошибок, ведь новая функция никак ей не помешает.

Вышла новая версия ImageEditor 2.0.0 из которой была удалена функция crop? Для обновления придется заменить эту функцию на аналогичную в вашей галерее, иначе обновиться до новой минорной версии вы не сможете.

Альфа, бета и другие имена версий

Часто имеет смысл расширять версию некоторым именем, на пример alpha. Делается это для дополнительной семантической группировки изменений, либо для конфиденциальности. Рассмотрим два случая такой модели:

  1. “Альфа”, “бета” и “релиз” версионирование - такая модель используется для описания состояний системы, при которых она тестируется разными группами людей. Система, версия которой помечена как alpha (на пример 1.1.0-alpha) обычно еще слишком сырая для представления пользователю и тестируется внутри компании или только доверенными лицами. Пометка beta (на пример 1.1.4-beta) означает, что система, по мнению разработчика, завершена, но ее еще следует протестировать целевым пользователям. Релизная версия, маркеруемая как r (на пример 1.1.5-r) или вовсе не имеющая буквенных маркеров, полностью прошла тестирование внутри и вне компании и может безопасно использоваться клиентами
  2. Проектные имена - эта модель подразумевает параллельное версионирование, облегчающее пользователям восприятие новой версии продукта. Она выражается в использовании запоминающихся имен версий, таких как star, zero, red и т.д., которые будут известны пользователям. Внутри компании, часто используется обычное семантическое версионирование

Список изменений

Для отслеживания изменений в версиях применяются файлы “Логов изменений” (Changelog), в которых описываются правки, сгруппированные по версиям. При выпуске новой версии ПО этот файл дополняется соответствующими этой версии изменениями. Каждая группа в этом файле, как правило, состоит из четырех подгрупп:

  1. Добавлено (added) - новые функции
  2. Устарело (deprecated) - устаревшие функции, которые будут удалены в следующих (минорных) версиях
  3. Удалено (removed) - удаленные функции
  4. Исправлено (Fixed) - исправленные баги и рефакторинг

Взгляните на этот файл на примере пакета Zend-Diactoros.