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

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

10.5. Несколько примеров ловушек

10.5.1. Проверка сообщений при фиксации

Трудно представить себе полезное сообщение при фиксации слишком коротким. Простая ловушка pretxncommit в приведенном ниже примере поможет предотвратить фиксацию ревизии с сообщением, которое составляет менее 10 байт.

$ cat .hg/hgrc

[hooks]

pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10 $ echo a > a

$ hg add a

$ hg commit -A -m 'too short' transaction abort!

rollback completed

abort: pretxncommit.msglen hook exited with status 1 $ hg commit -A -m 'long enough'

10.5.2. Проверка на конечные пробелы

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

Вы можете использовать precommit или pretxncommit ловушку для проверки конечных пробелов. Если вы используете ловушку precommit, ловушка не будет знать, какие файлы вы фиксируете, так что придется проверять каждый измененный файл в репозитории на завершающие пробелы. Если вы хотите зафиксировать изменения в файле foo, но файл bar содержит конечные пробелы, проверка в ловушке precommit может предотвратить фиксацию foo из-за проблемы с bar. Это кажется не правильным.

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

$ cat .hg/hgrc

[hooks]

pretxncommit.whitespace = hg export tip | (! egrep -q '^\+.*[ \t]$') $ echo 'a ' > a

$ hg commit -A -m 'test with trailing whitespace' adding a

transaction abort! rollback completed

abort: pretxncommit.whitespace hook exited with status 1 $ echo 'a' > a

$ hg commit -A -m 'drop trailing whitespace and try again'

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

#!/usr/bin/env python

#

# save as .hg/check_whitespace.py and make executable

import re

def trailing_whitespace(difflines):

#

115

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

linenum, header = 0, False

for line in difflines: if header:

# remember the name of the file that this diff affects m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)

if m and m.group(1) != '/dev/null': filename = m.group(1).split('/', 1)[-1]

if line.startswith('+++ '): header = False

continue

if line.startswith('diff '): header = True

continue

# hunk header - save the line number

m = re.match(r'@@ -\d+,\d+ \+(\d+),', line) if m:

linenum = int(m.group(1)) continue

# hunk body - check for an added line with trailing whitespace m = re.match(r'\+.*\s$', line)

if m:

yield filename, linenum if line and line[0] in ' +':

linenum += 1

if __name__ == '__main__': import os, sys

added = 0

for filename, linenum in trailing_whitespace(os.popen('hg export tip')): print >> sys.stderr, ('%s, line %d: trailing whitespace added' % (filename, linenum))

added += 1 if added:

# save the commit message so we don't need to retype it os.system('hg tip --template "{desc}" > .hg/commit.save') print >> sys.stderr, 'commit message saved to .hg/commit.save' sys.exit(1)

Выше версия гораздо более сложная, но и более полезная. Она анализирует унифицированный формат, чтобы увидеть, если добавились строки с конечными пробелами она печатает имя файла и номер строки, для каждого такого происшествия. Еще лучше, если изменение добавляет конечные пробелы, это ловушка сохраняет комментарии и печатает имя сохраненного файла перед выходом и говорит mercurial, откатить транзакцию, так что вы можете использовать опцию -l filename команды hg commit для повторного использования сохраненного сообщения фиксации, как только вы исправите проблемы.

$ cat .hg/hgrc

[hooks]

pretxncommit.whitespace = .hg/check_whitespace.py $ echo 'a ' >> a

$ hg commit -A -m 'add new line with trailing whitespace' a, line 2: trailing whitespace added

commit message saved to .hg/commit.save transaction abort!

rollback completed

abort: pretxncommit.whitespace hook exited with status 1 $ sed -i 's, *$,,' a

$ hg commit -A -m 'trimmed trailing whitespace' a, line 2: trailing whitespace added

commit message saved to .hg/commit.save transaction abort!

rollback completed

abort: pretxncommit.whitespace hook exited with status 1

В качестве последнего отступления, к сведению в приведенном выше примере используется особенность редактора sed — редактирование на месте, чтобы избавиться от конечных пробелов в файле. Это краткое и достаточно полезное действие, и я буду ещё повторять его здесь (Использование perl тоже неплохая мера).

perl -pi -e 's,\s+$,,' filename

116

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