Logo

31 мая 2020 г.

Переход на Git

Для хранения исходного кода в «Канторовых системах» до недавнего времени использовалась система контроля версий Subversion (SVN). Среди современных разработчиков она считается устаревшей, но в некоторых популярных проектах продолжает использоваться по историческим причинам. Та же причина была и в «Канторовых системах». Когда в 2007 году начиналась разработка, Git не был так популярен, еще не было GitHub. SVN же был хорошо освоен и оказался весьма пригоден для отслеживания версий кода. Подкупала его легкость.

Возможный переход осознавался давно. Пару лет назад изучался вопрос использования Mercurial и Fossil, некоторое внимание привлекала малопопулярная система Pijul. Для облегчения перехода была перестроена историческая часть дерева исходников на соответствующую классической для SVN branches/tags/trunk.

Препятствиями использования Git были:
  • Раздутый дистрибутив со встроенным Perl и MinGW, пытающийся превратить Windows в Linux. 
  • Необходимость использования собственного терминала Git.
  • Отсутствие адекватной графической оболочки, удобной настолько же, как RapidSVN для SVN.
Со временем все препятствия были преодолены разработчиками Git и инструментов под него. Теперь Git не содержит встроенного Perl, давая возможность установить собственный, используемый вне Git. Perl иногда нужен для сборки некоторых открытых библиотек, так что лучше устанавливать его отдельно. Мной используется StrawberryPerl. Есть теперь и возможность вызывать Git из командной строки Windows или любого консольного приложения.

Адекватным графическим интерфейсом для Git оказался GitKraken. Он выводит всё на вкладках, а не в одном большом окне. Лицензия позволяет бесплатно использовать GitKraken в частных проектах с некоторыми ограничениями, некритичными для «Канторовых систем».

Тем самым ситуация 2020 года оказалась похожа на 2007-й, но для Git. Он хорошо освоен, есть графический интерфейс, также освоенный. Что еще надо?

Преимущества Git для «Канторовых систем» следующие:
  • Возможность дополнять коммиты.
  • Возможность переставлять коммиты, менять их порядок.
  • Быстрая работа в сравнении с Mercurial.
  • Популярность среди разработчиков.
В настоящий момент в проекте один разработчик, так что распределенные возможности Git фактически не востребованы. Останутся заделом на будущее.

Для публичного хранилища после некоторых колебаний был выбран GitHub, с расчетом придать больше социальности «Канторовым системам». Посмотрим, как оно окажется на самом деле. Присылайте свои запросы на слияние (pull request) для CoreLite и PE Tool.

Сложности перехода

Git имеет встроенные средства импорта хранилищ SVN. Ожидалось, что ветки SVN будут преобразованы в ветки Git, а теги — в теги Git. Об этом говорили и те, кому уже приходилось переходить на Git с импортом исходников. На практике же вышло не так просто.

В период работы с SVN его возможности были широко задействованы, что с точки зрения SVN могло считаться продвинутым использованием. Последовательность коммитов иногда была нелинейной, случались слияния из tags в основную ветку.

Неизвестно, что из перечисленного помешало Git корректно преобразовать хранилище. Было проделано множество попыток. В зависимости от параметров выходило два варианта:
  • Все коммиты собраны в master.
  • Импортированное хранилище представляет собой не дерево, а лес с несколькими корнями, без возможности слить их или переходить с ветки на ветку.
Это никуда не годилось. Оставался один путь — импортировать хранилище с каталогами branches, tags и trunk в master, а потом вручную собирать ветки как нужно. В процессе перехода хотелось разнести по разным веткам основные исходники, код на Канторе и файлы для веба.

Ручная сборка дерева заняла не один день. Несколько раз приходилось начинать сначала. В конце концов алгоритм ручной сборки был найден, и хранилище удалось преобразовать. Вышло не так быстро и безболезненно, как ожидалось, но результат достигнут. Теперь разработка пойдет на Git.

После преобразования пришлось восстановить файлы в кодировке Windows-1252, запорченные Git. По всей видимости, он не умеет корректно работать с кодировками, отличными от UTF-8, или не умеет работать с ними под Windows. Как и с импортом, в зависимости от настроек .gitattributes получались два варианта:
  • Команда git checkout выводила предупреждения, что не может преобразовать исходники в Windows-1252. Это поведение было по умолчанию, сразу после импорта.
  • Та же команда выводила сообщение, что текущие исходники будут затерты, и завершалась с ошибкой.
Решено было ничего не менять. Лучше предупреждения, чем ошибка и невозможность переходить с ветки на ветку. Несмотря на предупреждения, сами файлы выгружаются корректно.

Система сборки

В проекте ранее использовалась самописная система сборки, зависящая от SVN. Нужно было переписать ее для Git.

SVN нумерует коммиты возрастающими номерами, называемыми ревизиями. Достаточно было взять их и использовать для нумерации ревизий при сборке версий программ — PE Tool и примеров. Git же различает коммиты по хешу. Нужно было придумать, как теперь нумеровать выпуски, не прибегая к хешам.

Был выбран следующий подход:
  • Для разрабатывамых программ (альф и бет) создается отдельная ветка, содержащая номер версии, например PETool-0.7. Команда Git git describe --tags возвращает число коммитов с начала ветвления. Это возрастающие номера, подходящие для нумерации промежуточных сборок. Логика та же, что и в SVN: чем больше изменений в коде, тем выше номер. Git никак не называет эти числа. В SVN они именовались ревизиями, в Git решено было использовать термин «сборки» (builds).
  • Для выпуска релиза изменения сливаются в master, имя ветки уже использовать нельзя. В Git есть теги, но в master будет множество тегов разных программ. Номера сборок выпусков должны быть заведомо больше промежуточных, и желательно не задавать их вручную. Решено использовать дату последнего коммита — таковым, скорее всего, будет коммит слияния. Команда git log -1 --pretty=%cd-%h --date=format:%y%j берет две цифры года и номер дня с начала года. Получается что-то вроде 20148. Это число заведомо больше любого количества коммитов и хорошо подходит для нумерации окончательной сборки. Версия продукта берется из тега, выставляемого на коммит слияния, например, PETool-0.6.
Система сборки была переписана, чтобы иметь единый скрипт для сборки примеров и инструментов. В SVN PE Tool и примеры имели собственные скрипты, которые приходилось поддерживать. Собственные скрипты сохранились и сейчас, но теперь они вызывают общий скрипт сборки и выполняют специфичные для каждой программы действия. Был добавлен скрипт сборки всех программ, который можно использовать в качестве теста компилируемости исходников.

Новая система теперь собирает дистрибутив, а не просто программу. Дистрибутивы складываются в каталог Bin, как принято в других проектах. Если каталога не существует, он создается в процессе сборки. Для чистой сборки его можно смело удалять.

Процедура сборки использует PE Tool для обработки файлов программ и включения нужных флагов в образе. Если раньше подразумевалось, что PE Tool уже стоит в системе разработчика, то теперь она рекурсивно собирается при сборке других программ, если отсутствует в каталоге Bin\Pet.

Преимущества GitHub

Выше говорилось, что каждому выпуску программы будет сопоставлен соответствующий тег. GitHub распознает теги как релизы и предлагает скачать исходники в форматах .zip или .tar.gz. Логично использовать эту возможность. Достаточно лишь добавить все необходимые файлы в завершающий коммит выпуска. К таковым на данный момент относятся файлы .dof, нужные для корректной компиляции программ из Delphi IDE с возможностью отладки.

Таким образом, больше не придется вручную собирать архивы с исходниками, как это делалось на SourceForge. При выпуске версии выкладывается только двоичный дистрибутив.

Tricks

Как и прежде, скрипт сборки учитывает наличие “tricky” RTL Delphi, подразумевая, что она находится в каталоге Tricks на одном уровне с каталогом Кантора. Это облегченная версия модулей SysInit и System, позволяющая уменьшить размер выходного EXE на несколько десятков или сотен килобайт в зависимости от версии Delphi. В коде использование этого RTL окружено условными директивами {$IFDEF Tricks}. Если каталог Tricks не найден, программы компилируются со стандартным RTL, необходимые дополнительные функции берутся из CoreUtils.

К сожалению, правовой статус этих модулей неясен, на GitHub их выложить нельзя. Облегченные модули взяты из проекта KOL и доработаны, в том числе подменой некоторых системных функций реализациями из проекта FastCode, потеряв совместимость с оригиналом. Вы можете попробовать использовать модули KOL, не включая директиву {$DEFINE ForceMMX}. Работоспособность не проверялась, в связи с чем не гарантируется.

Исходники Кантора

Загруженные исходники содержат уже знакомые вам CoreLite и PE Tool. Исходники Кантора и Халва-Паскаля, как и прежде, закрыты. Они будут открыты в будущем, при соблюдении некоторых условий, но не раньше, чем появится рабочий прототип. Сейчас они представляют собой набор заготовок, которые нет смысла показывать даже под подписку о неразглашении (NDA). Из-за изменения позиционированая проекта и желаемых целей несколько раз приходилось начинать с нуля, но ничего работоспособного написано не было. До готовности прототипа не стоит привлекать и сторонних разработчиков из-за специфики проекта.

Исходники на самом Канторе открыты.

Комментариев нет :

Отправка комментария

Выбрав в выпадающем списке пункт «Имя/URL», можно оставить комментарий от своего имени без предварительной регистрации.