Понадобилось сделать mercurial hook для проверки json файлов на валидность. К сожалению, документация mercurial оставляет желать лучшего, поэтому напишу, как я реализовал эту задачу.
Так, у нас есть сервер с репозиторием, мы хотим сделать так, чтобы при изменении, добавлении невалидного json в репозиторий, push отваливался с ошибкой.
Для начала, напишем сам hook. Было решено написать его на python.
# -*- coding: utf-8 -*-
import os
try:
import simplejson as json
except ImportError:
import json
check_extension = 'json'
# colors
BLUE = '\033[94m'
GREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
# mercurial passes ui, repo, hooktype and node as parameters
# node is a revision
def run(ui, repo, hooktype, node, **kwargs):
fileSet = set()
# we analyze each change
for change_id in xrange(repo[node].rev(), len(repo)):
for currentFile in repo[change_id].files():
# check each changed file, if it is json then validate it
if currentFile.endswith('.%s' % check_extension):
fileSet.add(currentFile)
for currentFile in fileSet:
ctx = repo['tip']
# do not check removed files
if currentFile not in ctx:
continue
fctx = ctx[currentFile]
try:
json_object = json.loads(fctx.data())
except Exception, e:
ui.write('JSON parsing of {0} {1} {2} FAILED: {3}\n'.format(
GREEN, currentFile, FAIL, ENDC))
ui.write(e.message + '\n')
return True
return False
Думаю, что код с комментариями достаточно понятный. Еще раз замечу, что внутренности mercurial очень плохо документированы, зачастую приходится смотреть в код mercurial, чтоб понять с какими параметрами вызывать объекты.
Вот статья про хуки из документации: https://www.mercurial-scm.org/wiki/Hook Как видите, информации совсем мало, правда внизу страницы есть ссылка на более подробное описание.
Теперь, когда хук готов, нужно добавить его в секцию [hooks] в hgrc репозитория. На сервере репы лежат в /var/hg/repos, репозиторий называется projects. Меняем файл /var/hg/repos/projects/.hg/hgrc
[hooks]
pretxnchangegroup.syntax_check = python:/usr/local/share/hg-hooks/validate_json.py:run
/usr/local/share/hg-hooks/validate_json.py — это наш хук, run — это имя функции. которую мы вызвали.
Если функция возвращает True, это как бы exit code 1, значит валидация не прошла и push откатит изменения, выдав предупреждение.
Cтатья, которую я взял за основу.