HG HOOKs

Mercural - хорошая штука.

Мне потребовалось написать hook (ловушка). Об этом очень хорошо, внятно и подробно написано в статье "Глава 10. Обработка событий в репозитории с помощью ловушек". Всё понятно, но тут я хочу записать те моменты, которые хочу запомнить, некоторые нюансики.

Примеров для чайников маловато.

Mercurial может выполнять ловушки, определённые в системном глобальном ~/.hgrc файле.

Чтобы написать ловуку в centos найти этот файл мне не удалось, зато есть /etc/mercurial/hgrc.d/mergetools.rc

Так как я php-программист, я упорно старалась написать hook на php. Добавляем в .../mergetools.rc строки


pre-clone = php /path/to/hooks/fork.php pre-clone

теперь, если на моём сервере запустят

# hg clonе /Path/from/repo 

до клонирования будет вызываться скрипт  /path/to/hooks/fork.php 
pre-clone же будет  в аргументе
<?php
/* fork.php */
print_r($_SERVER)
print_r($argv)
?>

Каждый параметр ловушки передается в качестве переменной окружения, имя в верхнем регистре с префиксом «HG_».

Так вот эти параметры можно получить/прочитать распечатав переменную $_SERVER
На каждое событие свои параметры, описаны тут http://www.selenic.com/mercurial/hgrc.5.html#hooks

Для того, чтобы команда hg seve/clone/commit (не важно) меняла свои параметры в ловушке, средствами php мне удалось реализовать. Пришлось вникать в питон

http://mercurial.selenic.com/wiki/MercurialApi - это описание API для работы с меркуриалом. Настаиваю на прочтении первого же параграфа "Why you shouldn't use Mercurial's internal API" Но здесь хоть как-то описаны методы, которые я и использовала для себя в своём хуке.

Кратко выглядит так. В /etc/mercurial/hgrc.d/mergetools.rc добавляем строку
pre-serve = python:/var/www/html/pm/services/support/hg/hooks/serve:ctrlport

Дать права на выполнение файлу serve
Для простоты понимая в лоб надо писать такой код

#!/usr/bin/python

def ctrlport(ui, repo, hooktype, node=None, source=None, **kwargs):

    print ui
    print repo
    print hooktype
    print node
    print source
    print kwargs

    return 1

Функция питона должна возвращать 0 - нет ошибок, или 1 - если есть

Для отладки кода я возвращаю 1

У питона один, лично для меня, недостаток: придирается к отступам. Поэтому, первое за чем надо следить - это отсутствие смешанных отступов. Т.е. используете 4 пробела - хорошо, не мешайте с табами. И наоборот. Это я где-то вычитала, к сожалению не сразу :(

Для меня самым интересным параметром оказался kwargs, я не совсем поняла, что значит ** (звёздочки) но по аналогии с другими языками, решила что указатели на переменную. Поэтому смело использовала её для подмены значений, таких как port

kwargs в моей распечатки был таким
#hg serve -p  8088
{'pats': [], 'args': 'serve', 'opts': {'webdir_conf': '', 'prefix': '', 'port': '8088', 'accesslog': '', 'style': '', 'certificate': '', 'ipv6': None, 'cmdserver': '', 'daemon_pipefds': '', 'templates': '', 'web_conf': '', 'pid_file': '', 'address': '', 'daemon': None, 'name': '', 'stdio': None, 'errorlog': ''}}

в питоне же я в лоб использовала присвоение
kwargs['opts']['port'] = 8888
И если не будет ошибок в коде, и хук вернет 0, то web интерфейс запустится на порту 8888

К сожалению есть одна неприятность. Если делать присвоение, то выводы, все принты, продублируются (лично у меня ни с того ни с сего было, когда я вызываю так "hg serve -d" без "-d" - всё нормально ) или не выведется должная информация. Например.

Без хука, или с хуком пустым, будет выведено

def ctrlport(ui, repo, hooktype, node=None, source=None, **kwargs):

    print 'test'
    return 0


# hg serve
test
listening at http://localhost.localdomain:8088/ (bound to *:8088)

И вот :(
def ctrlport(ui, repo, hooktype, node=None, source=None, **kwargs):

    print 'test2'
    kwargs['opts']['port'] = 8888
    return 0

# hg serve
test2

Почему - не знаю, уже и нет времени разбираться, но при этом всё работает! 
Если кто знает, объясните, пожалуйста.

Комментарии

Популярные сообщения