Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
hgbook.pdf
Скачиваний:
50
Добавлен:
17.03.2015
Размер:
3.15 Mб
Скачать

Обработка событий в репозитории с помощью ловушек

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

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

Если ловушка pretxncommit завершает свою работу с кодом возврата 0, транзакция завершается; фиксация заканчивается, и выполняется ловушка commit. Если ловушка pretxncommit выходит с ненулевым кодом возврата, транзакция откатывается; метаданные, представляющие изменения стираются, а ловушка commit не выполняется.

$ cat check_bug_id

#!/bin/sh

# check that a commit comment mentions a numeric bug id hg log -r $1 --template {desc} | grep -q "\<bug *[0-9]"

$ echo 'pretxncommit.bug_id_required = ./check_bug_id $HG_NODE' >> .hg/hgrc $ echo a >> a

$ hg commit -m 'i am not mentioning a bug id' transaction abort!

rollback completed

abort: pretxncommit.bug_id_required hook exited with status 1 $ hg commit -m 'i refer you to bug 666'

committed 13b236affeff106b31ae144e61b115cc36f3a63e date of commit: Thu Feb 2 14:09:54 GMT 2012

Ловушка в приведенном выше примере проверяет, что комментарий при фиксации содержит id бага. Если он есть, фиксация завершается. Если нет, то происходит откат.

10.4. Написание собственных ловушек

Когда вы пишете ловушку, то может оказаться полезным для запускать Mercurial или с опцией -v, или параметром конфигурации verbose со значением «true». Когда вы это делаете, Mercurial выведет сообщение перед вызовом каждой ловушки.

10.4.1. Выбор того, как должна работать ваша ловушка

Вы можете написать ловушку как обычную программу, обычно скрипт на языке shell, или, как функции Python, которая выполняется в рамках процесса Mercurial.

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

Ловушка в процессе выполнения Python имеет полный доступ к Mercurial API, и не «создаёт» другой процесс, так что по своей сути быстрее, чем внешняя ловушка. Кроме того, легче получить больше информации, которая требуется ловушке с помощью API, чем выполнив команды Mercurial.

Если вы знакомы с Python, или требуются ловушки с высокой производительностью, использование ловушек в Python может быть хорошим выбором. Однако, если у вас есть простая ловушка и не нужно заботиться о производительности (вероятно, большинство ловушек), скрипт, это прекрасно.

10.4.2. Параметры ловушек

Mercurial вызывает каждую ловушку с набором четких параметров. В python, параметр передается в качестве аргументов функции ловушки. Для внешней программы, параметры передаются как переменные среды.

Написана ли ваша ловушка в python или скриптом, конкретные имена и значения параметров будут одинаковы. Логический параметр будет представлен как логическое значение в python, и как число 1 (для «true») или 0 (для «false»), в случае переменных среды для внешних ловушек. Если параметр ловушки называется foo, имя аргумента

113

Обработка событий в репозитории с помощью ловушек

ловушки в python будет также называться foo, в то время как переменная среды для внешних ловушек будет называться HG_FOO.

10.4.3. Возвращаемое значение ловушки и контроль за действием

Успешно выполнившаяся ловушка, должна выйти с кодом возврата 0, если она внешняя, или вернуть логическое «false», если внутрипроцессная. Отказ обозначается ненулевым кодом возврата из внешних ловушки, или внутри процесса ловушка возвращает логическое «true». Если в процессе выполнения ловушка генерирует исключение, ловушка считается выполнившейся неудачно.

Для контролирующей действие ловушки 0/false означает «разрешить», не-ноль/true/исключение означает «запретить».

10.4.4. Написание внешних ловушек

При определении внешней ловушки в вашем ~/.hgrc и ловушка запускаются, её переменные передаются вашей оболочке, которая интерпретирует её. Это означает, что вы можете использовать обычные конструкции shell в теле ловушки.

Исполняемая ловушка всегда выполняется с текущей директорией установленой в корневую директорию репозитория.

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

«HG_».

За исключением параметров ловушек, Mercurial не устанавливает и не изменяет переменные окружения при запуске ловушки. Это полезно помнить, если вы пишете ловушку на веб-сервере, который может быть запущен под целым рядом различных пользователей с различными наборами переменных окружения. В многопользовательской среде, вы не должны полагаться на переменные окружения, которые установлены в значения вашей среды, при тестировании ловушки.

10.4.5. Приказ Mercurial использовать внутренние ловушки

Cинтаксис ~/.hgrc для определения в внутренних ловушек несколько иной, чем для внешних ловушек. Значение ловушки должно начинаться с текста «python:», и продолжаться полностью определённым именем вызываемого объекта для использования в качестве значения ловушки.

Модуль, в котором находится ловушка автоматически импортируются при выполнении ловушки. До тех пор пока у вас есть имя модуля и правильный PYTHONPATH, это должно «просто работать».

Следующий ~/.hgrc фрагмент иллюстрирует синтаксис и смысл понятий, которые мы только что описали.

[hooks]

commit.example = python:mymodule.submodule.myhook

Когда Mercurial запускает ловушку commit.example, он импортирует mymodule.submodule, ищет объект с именем myhook, и вызывает его.

10.4.6. Написание внутрипроцессных ловушек

Простейших внутрипроцессный хук ничего не делает, но иллюстрирует основную формат api хуков:

def myhook(ui, repo, **kwargs): pass

Первый аргумент ловушки в python всегда ui объекта. Второй представляет собой репозиторий объектов, используемый в данный момент, это всегда localrepository. После этих двух аргументов идут другие аргументы. Какие аргументы будут переданы зависит от ловушки, но ловушка может игнорировать аргументы она не заботится о помещении их в аргументы словари такие как **kwargs выше.

114

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]