Red Hot Chili Python

Работаем с меркуриалом из питона

«  Psql и таблички с большим количеством полей   ::   Contents   ::   Клавиатурное  »

Работаем с меркуриалом из питона

Занимаюсь потихоньку своим толстым редактором po-файлов, и захотелось сделать интеграцию с меркуриалом. Поэтому начал копать вот эту документацию http://mercurial.selenic.com/wiki/MercurialApi и исходники (/usr/local/lib/python2.6/dist-packages/mercurial/).

Итак, для начала:

from mercurial import ui as mercurial_ui, hg, commands

ui = mercurial_ui.ui()
repo = hg.repository(ui, '/home/kost/workspace/3.1.1-i18n/')

В меркуриале есть модуль commands, в котором функции – по сути команды в командной строе. То есть, чтоб сделать

hg log --limit 2

вы можете вызвать

commands.log(ui, repo, limit=2, date=None, rev=None, user=None)

Note

Заметьте кучу ненужных date=None, rev=None, user=None. По идее их быть не должно, но так уж исторически сложилось что в меркуриале много “обязательных” параметров. Если он ругается, что какого-то не хватает, просто передайте его как None.

Но нас не интересует эта штука, потому что она тупо печатает вывод команды (а мы ведь не собираемся её парсить, а хотим нормальной работы). Потому попытаемся получить hg log в виде списка ченджсетов.

В официальной вики (по той же ссылке) документация о Change contexts имеется, но она довольно скудная.

Вообще задача состоит в том, чтоб пройтись по ревизиям конкретных файлов (мы предварительно найдём все .po-файлы в репозитории) и сделать что-то с содержанием этих файлов в той ревизии. Для начала хотя бы научимся ходить по ревизиям.

Мне удалось этого добиться как-то вот так:

opts = {'rev': None,}
limit = 10
pats = [os.path.join(REPO_PATH, 'uaprom/i18n/tr/LC_MESSAGES/uaprom.po')]
matchfn = cmdutil.match(repo, pats, opts)
def prep(ctx, fns):
    pass
for i, ctx in enumerate(cmdutil.walkchangerevs(repo, matchfn, opts, prep)):
    i += 1
    print ctx
    if i >= limit:
        break

Честно скажу, что как API (даже тот, который более-менее внутренний), так и сам стиль кодирования (везде геттеры через функции с именем аргумента, частое использование во внутренних функциях внешних переменных) мне показались крайне странными и не-питонячьими.

Если вам нужно просто получить содержимое какого-то файла в какой-то ревизии – тут дела обстоят лучше, есть способ “попроще”.

filectx = repo[ctx.rev()][pofiles[0]]
file_data = mercurial.encoding.fromlocal(filectx.data())

Затем я продолжил копаться в исходниках меркуриала и того, как он устроен (в конце концов, должен быть какой-то путь попроще для этого всего и покрасивее), пока меня не остановили.

Внезапно появляется vcs

И тут, внезапно на канале #mercurial (freenode) мне советуют посмотреть в сторону пакета vcs.

И теперь всё стало намного проще:

repo = vcs.get_repo(path=REPO_PATH)

pofiles = ['uaprom/i18n/tr/LC_MESSAGES/uaprom.po']
for pofile in pofiles:
    print repo.get_changeset().get_node(pofile).content[:1000]

API намного лучше и чище нативного (хотя все равно мне кажется немного странным), плюс получим поддержку из коробки и гита заодно. Но (насколько я понял), искать все po-файлы нам все равно придется руками. Ну что ж, это уже не такой большой минус.

«  Psql и таблички с большим количеством полей   ::   Contents   ::   Клавиатурное  »

blog comments powered by Disqus