# HG changeset patch # User Christian Ebert # Date 1202319316 -3600 # Node ID 290d023e83064d6939314419298631ffaa6460fc # Parent 63ebc698d06b7bee70583997a315d269af5a4cc6 (0.9.2compat) get changes from stable branch diff -r 63ebc698d06b -r 290d023e8306 hgkw/keyword.py --- a/hgkw/keyword.py Wed Jan 23 11:38:22 2008 +0100 +++ b/hgkw/keyword.py Wed Feb 06 18:35:16 2008 +0100 @@ -79,8 +79,9 @@ like CVS' $Log$, are not supported. A keyword template map "Log = {desc}" expands to the first line of the changeset description. -Caveat: "hg import" fails if the patch context contains an active - keyword. In that case run "hg kwshrink", and then reimport. +Caveat: With Mercurial versions prior to 4574925db5c0 "hg import" might + cause rejects if the patch context contains an active keyword. + In that case run "hg kwshrink", and then reimport. Or, better, use bundle/unbundle to share changes. ''' @@ -90,9 +91,51 @@ from mercurial.i18n import gettext as _ import getopt, os.path, re, shutil, sys, tempfile, time +commands.optionalrepo += ' kwdemo' + +# hg commands that do not act on keywords +nokwcommands = ('add addremove bundle copy export grep identify incoming init' + ' log outgoing push remove rename rollback tip convert') + +# hg commands that trigger expansion only when writing to working dir, +# not when reading filelog, and unexpand when reading from working dir +restricted = 'diff1 record qfold qimport qnew qpush qrefresh qrecord' + +def utcdate(date): + '''Returns hgdate in cvs-like UTC format.''' + return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) + + +_kwtemplater = None + # backwards compatibility hacks try: + # avoid spurious rejects if patchfile is available + from mercurial.patch import patchfile + _patchfile_init = patchfile.__init__ + + def _kwpatchfile_init(self, ui, fname, missing=False): + '''Monkeypatch/wrap patch.patchfile.__init__ to avoid + rejects or conflicts due to expanded keywords in working dir.''' + _patchfile_init(self, ui, fname, missing=missing) + if _kwtemplater.matcher(self.fname): + # shrink keywords read from working dir + kwshrunk = _kwtemplater.shrink(''.join(self.lines)) + self.lines = kwshrunk.splitlines(True) +except ImportError: + pass + +try: + # templatefilters module introduced in 9f1e6ab76069 + from mercurial import templatefilters + template_filters = templatefilters.filters + template_firstline = templatefilters.firstline +except ImportError: + template_filters = templater.common_filters + template_firstline = templater.firstline + +try: # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78 # also avoid name conflict with other dispatch package(s) from mercurial.dispatch import _parse @@ -187,20 +230,6 @@ fancyopts.fancyopts = _fancyopts -commands.optionalrepo += ' kwdemo' - -# hg commands that trigger expansion only when writing to working dir, -# not when reading filelog, and unexpand when reading from working dir -restricted = ('diff1', 'record', - 'qfold', 'qimport', 'qnew', 'qpush', 'qrefresh', 'qrecord') - -def utcdate(date): - '''Returns hgdate in cvs-like UTC format.''' - return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) - - -_kwtemplater = None - class kwtemplater(object): ''' Sets up keyword templates, corresponding keyword regex, and @@ -216,11 +245,11 @@ 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', } - def __init__(self, ui, repo, inc, exc, hgcmd): + def __init__(self, ui, repo, inc, exc, restricted): self.ui = ui self.repo = repo self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1] - self.hgcmd = hgcmd + self.restricted = restricted self.commitnode = None self.path = '' @@ -233,7 +262,7 @@ kwpat = r'\$(%s)(: [^$\n\r]*? )??\$' % '|'.join(escaped) self.re_kw = re.compile(kwpat) - templater.common_filters['utcdate'] = utcdate + template_filters['utcdate'] = utcdate self.ct = self._changeset_templater() def _changeset_templater(self): @@ -261,13 +290,13 @@ self.ct.use_template(self.templates[kw]) self.ui.pushbuffer() self.ct.show(changenode=fnode, root=self.repo.root, file=self.path) - return '$%s: %s $' % (kw, templater.firstline(self.ui.popbuffer())) + return '$%s: %s $' % (kw, template_firstline(self.ui.popbuffer())) return subfunc(kwsub, data) def expand(self, node, data): '''Returns data with keywords expanded.''' - if util.binary(data) or self.hgcmd in restricted: + if self.restricted or util.binary(data): return data return self.substitute(node, data, self.re_kw.sub) @@ -510,13 +539,8 @@ if not repo.local(): return - nokwcommands = ('add', 'addremove', 'bundle', 'clone', 'copy', - 'export', 'grep', 'identify', 'incoming', 'init', - 'log', 'outgoing', 'push', 'remove', 'rename', - 'rollback', 'tip', - 'convert') hgcmd, func, args, opts, cmdopts = _parse(ui, sys.argv[1:]) - if hgcmd in nokwcommands: + if hgcmd in nokwcommands.split(): return if hgcmd == 'diff': @@ -538,7 +562,8 @@ return global _kwtemplater - _kwtemplater = kwtemplater(ui, repo, inc, exc, hgcmd) + _restricted = hgcmd in restricted.split() + _kwtemplater = kwtemplater(ui, repo, inc, exc, _restricted) class kwrepo(repo.__class__): def file(self, f, kwmatch=False): @@ -550,12 +575,12 @@ def wread(self, filename): data = super(kwrepo, self).wread(filename) - if hgcmd in restricted and _kwtemplater.matcher(filename): + if _restricted and _kwtemplater.matcher(filename): return _kwtemplater.shrink(data) return data def _commit(self, files, text, user, date, match, force, lock, wlock, - force_editor, p1, p2, extra): + force_editor, p1, p2, extra, empty_ok): '''Private commit wrapper for backwards compatibility.''' try: return super(kwrepo, self).commit(files=files, text=text, @@ -565,15 +590,25 @@ force_editor=force_editor, p1=p1, p2=p2, extra=extra) except TypeError: - return super(kwrepo, self).commit(files=files, text=text, - user=user, date=date, - match=match, force=force, - force_editor=force_editor, - p1=p1, p2=p2, extra=extra) + try: + return super(kwrepo, self).commit(files=files, text=text, + user=user, date=date, + match=match, force=force, + force_editor=force_editor, + p1=p1, p2=p2, + extra=extra, + empty_ok=empty_ok) + except TypeError: + return super(kwrepo, self).commit(files=files, text=text, + user=user, date=date, + match=match, force=force, + force_editor=force_editor, + p1=p1, p2=p2, extra=extra) def commit(self, files=None, text='', user=None, date=None, match=util.always, force=False, lock=None, wlock=None, - force_editor=False, p1=None, p2=None, extra={}): + force_editor=False, p1=None, p2=None, extra={}, + empty_ok=False): # (w)lock arguments removed in 126f527b3ba3 # so they are None or what was passed to commit # use private _(w)lock for deletion @@ -605,7 +640,8 @@ _p2 = hex(_p2) node = self._commit(files, text, user, date, match, force, - _lock, _wlock, force_editor, p1, p2, extra) + _lock, _wlock, force_editor, p1, p2, extra, + empty_ok) # restore commit hooks for name, cmd in commithooks.iteritems(): @@ -618,6 +654,10 @@ del _wlock, _lock repo.__class__ = kwrepo + try: + patchfile.__init__ = _kwpatchfile_init + except NameError: + pass cmdtable = { diff -r 63ebc698d06b -r 290d023e8306 tests/test-keyword.out --- a/tests/test-keyword.out Wed Jan 23 11:38:22 2008 +0100 +++ b/tests/test-keyword.out Wed Feb 06 18:35:16 2008 +0100 @@ -30,8 +30,9 @@ Expansions spanning more than one line and incremental expansions, like CVS' $Log$, are not supported. A keyword template map "Log = {desc}" expands to the first line of the changeset description. -Caveat: "hg import" fails if the patch context contains an active - keyword. In that case run "hg kwshrink", and then reimport. +Caveat: With Mercurial versions prior to 4574925db5c0 "hg import" might + cause rejects if the patch context contains an active keyword. + In that case run "hg kwshrink", and then reimport. Or, better, use bundle/unbundle to share changes. kwdemo print [keywordmaps] configuration and an expansion example kwexpand expand keywords in working directory