среда, 28 апреля 2010 г.

[prog] Пишется инструмент под условным названием svn_tag_maker

Мой подчиненный, молодой C++ программист, в порядке обучения пишет программу под названием svn_tag_maker. Ее основное предназначение – наведение порядка в svn-репозиториях.

Суть вот в чем. У нас зависимости между проектами выставляются посредством svn-свойства svn:externals (более подробно идею можно прочитать в моей статье). Например, если проекту ig_inout_door-2.0 нужны подпроекты ace, so_4 и pcre, то ссылки на соответствующие ветки этих проектов помещаются в svn:externals для каталога dev в проекте ig_inout_door. Выглядит такое свойство, приблизительно следующим образом:

ace   http://***/ace/tags/universal_wrapper.1.2/dev/ace
ace_lib_distrib   http://***/ace/tags/distribs/5.6.5/ace_lib_distrib
pcre  http://***/regex/pcre/tags/mxx_ru/7.7/dev/pcre
so_4  http://***/so_4/tags/4.4.b6/dev/so_4

Благодаря этому, если я делаю себе checkout проекта ig_inout_door-2.0, то он автоматом получает и все необходимые зависимости.

В чем здесь есть сложность – в том, что со временем появляются новые версии подпроектов, которые фиксируются в новых тегах своих репозиториев. Причем я могу даже не подозревать об этом. В какой-то прекрасный момент я озадачиваюсь вопросом – а нет ли новых версий для ace или so_4? И что мне делать в этой ситуации?

Можно самому заглянуть в репозитории соответствующих подпроектов и найти там вручную новые теги. Но ведь лучше, чтобы это сделала программа. Как раз такой программой и должна стать svn_tag_maker.

У svn_tag_maker планируется три режима. Первый режим – find, поиск новых версий подпроектов. Натравливаю svn_tag_maker на каталог dev проекта ig_inout_door-2.0 и получаю на выходе текстовый файл вида:

ace # http://***/ace/tags/universal_wrapper.1.2/dev/ace
   http://***/ace/tags/universal_wrapper.1.3/

ace_lib_distrib # http://***/ace/tags/distribs/5.6.5/ace_lib_distrib
   http://***/ace/tags/distribs/5.6.6/
   http://***/ace/tags/distribs/5.6.7/
   http://***/ace/tags/distribs/5.6.8/
   http://***/ace/tags/distribs/5.7.8/

pcre # http://***/regex/pcre/tags/mxx_ru/7.7/dev/pcre
   http://***/regex/pcre/tags/mxx_ru/7.8/

so_4 # http://***/so_4/tags/4.4.b6/dev/so_4
   # New version not found! Last version is used.

Здесь каждый блок относится к одному подпроекту. Первая строка блока содержит имя каталога, завязанного на подпроект (например, ace и ace_lib_distrib), и текущую версию этого подпроекта. В последующих строках блока перечисляются более свежие версии подпроекта. Если для подпроекта новых версий нет (как в данном примере для so_4), то ничего не перечисляется.

Мне остается только выкинуть из этого файла строки с версиями, которые ему не интересны. Например, мне не интересны версии ace, отличные от 5.6.8, и не интересен so_4, т.к. для него нет новых версий. Я их удаляю и получаю файл вида:

ace # http://***/ace/tags/universal_wrapper.1.2/dev/ace
   http://***/ace/tags/universal_wrapper.1.3/

ace_lib_distrib # http://***/ace/tags/distribs/5.6.5/ace_lib_distrib
   http://***/ace/tags/distribs/5.6.8/

pcre # http://***/regex/pcre/tags/mxx_ru/7.7/dev/pcre
   http://***/regex/pcre/tags/mxx_ru/7.8/

(в принципе, строки для so_4 я мог бы и оставить, они были бы проигнорированы).

Результирующий файл скармливается svn_tag_maker в режиме update – это второй режим ее работы. Получив этот файл svn_tag_maker заменяет в svn:externals для ig_inout_door пути к подпроектам. И новый svn:externals приобретает вид:

ace   http://***/ace/tags/universal_wrapper.1.3/dev/ace
ace_lib_distrib   http://***/ace/tags/distribs/5.6.8/ace_lib_distrib
pcre  http://***/regex/pcre/tags/mxx_ru/7.8/dev/pcre
so_4  http://***/so_4/tags/4.4.b6/dev/so_4

Все, теперь я могу сделать svn up, получить новые версии подпроектов и проверить работоспособность проекта с ними.

Третий режим работы svn_tag_maker – это режим make. В этом режиме программе скармливается рабочая копия проекта и указывается, какую версию нужно создать в репозитории.

Например, пусть я разработал ig_inout_door версии 2.0.3 и мне нужно зафиксировать ее в виде тега. Я запускаю svn_tag_maker и говорю: вот рабочая копия ig_inout_door, версия у нее 2.0.3. После этого svn_tag_maker проверяет, все ли у меня закомичено (чтобы не потерять изменения). И если все нормально, то выполняет svn cp из рабочей копии в раздел tags репозитория – создается ветка tags/2.0.3. При этом для всех svn:externals в tags/2.0.3 будут прописаны точные ревизии подпроектов. Т.е. свойство svn:externals для tags/2.0.3 будет иметь вид:

ace -r346  http://***/ace/tags/universal_wrapper.1.3/dev/ace
ace_lib_distrib -r98  http://***/ace/tags/distribs/5.6.8/ace_lib_distrib
pcre -r13  http://***/regex/pcre/tags/mxx_ru/7.8/dev/pcre
so_4 -r729  http://***/so_4/tags/4.4.b6/dev/so_4

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

Собственно к чему я это. Если будет интерес к данному инструменту, то я попробую организовать его выпуск в виде открытого проекта. Ну а если нет, то он так и останется поделкой для внутреннего использования.

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