mercurial-i18n

Giorgos Keramidas keramida at ceid.upatras.gr
Mon Jun 22 06:52:10 CDT 2009


On Sun, 21 Jun 2009 23:34:00 +0200, Martin Geisler <mg at lazybytes.net> wrote:
> Giorgos Keramidas <keramida at ceid.upatras.gr> writes:
>
>> On Sun, 21 Jun 2009 20:14:11 +0200, Martin Geisler <mg at lazybytes.net> wrote:
>>>Giorgos Keramidas <keramida at ceid.upatras.gr> writes:
>>>> I have cloned this at http://bitbucket.org/keramida/mercurial-i18n/
>>>> and pushed what bits of the Greek translation I have.
>>>
>>> I've pushed your Greek translation along with a bunch of Danish updates.
>>> Could you prefix your commits with 'i18n-el' in the future -- that will
>>> make them easy to distinguish.
>>
>> Thanks!  I will try to remember the log prefix, or install a local hook
>> to remind me :)
>
> That is not a bad idea -- if you do, then I suggest you add it to the
> wiki under the Tips section I just made:
>
>   http://www.selenic.com/mercurial/wiki/TranslatingMercurial#Tips

That's an excellent idea, thanks!  I just 'hacked' a small hook script
together, and manually copied it to the load path of my Python
installation at `/usr/local/lib/python2.6/site-packages':

% root at kobe:/usr/local/lib/python2.6/site-packages# find hghook | fgrep .py
% hghook/__init__.py
% hghook/i18n/__init__.py
% hghook/i18n/logcheck.py

The main idea was to make the hook script configurable enough to be
useful for other translation teams too, so I tried matching filename
patterns with regular expressions for commit log validation.  So the
hook can be installed by copying it somewhere in Python's load path and
adding to `.hgrc':

    [hooks]
    pretxncommit = python:hghook.i18n.logcheck.hook

    [i18n.logcheck]
    i18n/el.po = ^i18n-el:\s.*$
    i18n/da.po = ^i18n-da:\s.*$

When a commit log fails to match with one of the patterns listed in the
[i18n.logcheck] config section, something like this happens:

keramida at kobe:/hg/mercurial/foo$ echo foo > i18n/el.po 
keramida at kobe:/hg/mercurial/foo$ hg ci -m 'foo' i18n/el.po 
i18n: changeset 2cfc2e96725d log fails '^i18n-el:\s.*$' check for i18n/el.po
i18n: changeset 2cfc2e96725d log fails '^i18n-([a-z][a-z]):\s.*$' check for i18n/**
error: pretxncommit hook failed: changeset 2cfc2e96725d fails i18n commit log checks
transaction abort!
rollback completed
abort: changeset 2cfc2e96725d fails i18n commit log checks

The hook script itself is attached below, but I am not sure how to
describe its installation to Python's load path on the Wiki.  Does
anyone want to help me with the documentation details?

--- 8< --- cut here --- 8< --- cut here --- 8< --- cut here --- 8< --- cut here ---
# hghook/i18n/logcheck.py -- a hook that checks mercurial-i18n commit logs
#
# Copyright 2009 Giorgos Keramidas <keramida at ceid.upatras.gr>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.

"""hook extension to check mercurial-i18n commit log messages

This short extension can be used as a pretxncommit hook, to ensure that
all commits in a mercurial-i18n clone match the preferred format for
changes related to the internationalizatio of mercurial.

The acceptable patterns of commit logs can be configured through hgrc.

To use this hook in a repository, add it to the .hg/hgrc file of the
specific repository:

    [hooks]
    pretxncommit = python:hghook.i18n.logcheck.hook

Then configure the commit summary patterns it will consider appropriate,
by adding them to the [check-i18n] section:

    [i18n.logcheck]
    pattern = regexp

for example:

    [i18n.logcheck]
    ** = ^i18n-([a-z][a-z]):\s.*$

 config items:

 REQUIRED:
   hooks.pretxncommit           # required to enable the hook

 OPTIONAL:
   i18n.logcheck                # a map of file -> regexp checks
"""

from mercurial.i18n import _
from mercurial import cmdutil, match, templater, util
import re

def buildmatchers(ui, repo, key):
    """Read a section of the config file that maps filename patterns to regular
    expressions, and build a list of tuples that contain four items: a filename
    pattern, a matcher object for that pattern, a regular expression, a compile
    re object for the same regexp: (pat, matcher, regexp, compiledregexp).

    If the 'key' section does not exist, we just return None.  If one of the
    regular expressions listed in the 'key' section is invalid, this particular
    filename pattern is entirely skipped."""

    if not ui.has_section(key):
        ui.debug(_('i18n: %s not enabled\n') % key)
        return None
    m = []
    for pat, regex in ui.configitems(key):
        try:
            m1 = match.match(repo.root, '', [pat])
            cre = re.compile(regex)
            m.append((pat, m1, regex, cre))
        except Exception, inst:
            ui.warn(_("i18n: invalid regexp '%s' for pattern %s\n") % \
                    (regex, pat))
    return len(m) and m or None

def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
    """Hook entry point for the i18n.logcheck module."""

    # This may be be strictly necessary, but it's probably ok for now.
    if hooktype != 'pretxncommit':
        raise util.Abort(_('i18n: unsupported hook type: %s') % hooktype)

    checks = buildmatchers(ui, repo, 'i18n.logcheck')
    if checks is None:
        ui.debug(_("i18n: no file patterns to check; all commits allowed"))
        return
    for rev in xrange(repo[node], len(repo)):
        ctx = repo[rev]
        desc = ctx.description()
        d = desc.split('\n')[0]
        err = None
        for f in ctx.files():
            for pat, m, regex, mre in checks:
                if m and m(f) and not mre.match(d):
                    err = (err or 0) + 1
                    ui.warn(_(
                        "i18n: changeset %s log fails '%s' check for %s\n") % \
                        (ctx, regex, pat))
        if err:
            raise util.Abort(_("changeset %s fails i18n commit log checks") % ctx)
        ui.debug(_("changeset %s looks ok\n") % ctx)
    return
--- 8< --- cut here --- 8< --- cut here --- 8< --- cut here --- 8< --- cut here ---


More information about the Mercurial-devel mailing list