Init context.filectx only once per file with class kwfilectx self_initializing_hook
authorChristian Ebert <blacktrash@gmx.net>
Fri, 12 Jan 2007 13:58:59 +0100
branchself_initializing_hook
changeset 92 3c7c187e4001
parent 91 04c899130750
child 93 9f70f953dd3b
Init context.filectx only once per file with class kwfilectx This way context.filectx is not initialized for every keyword match.
hgkw/keyword.py
--- a/hgkw/keyword.py	Fri Jan 12 01:45:22 2007 +0100
+++ b/hgkw/keyword.py	Fri Jan 12 13:58:59 2007 +0100
@@ -36,32 +36,13 @@
 from mercurial import context, util
 import os.path, re, sys, time
 
-
 re_kw = re.compile(
         r'\$(Id|Header|Author|Date|Revision|RCSFile|Source)[^$]*?\$')
 
-
-def kwexpand(matchobj, repo, path, changeid=None, fileid=None, filelog=None):
+def kwexpand(mobj, kwfctx):
     '''Called by kwfilelog.read and pretxnkw.
-    Sets supported keywords as local variables and evaluates them to
-    their expansion if matchobj is equal to string representation.'''
-    c = context.filectx(repo, path,
-            changeid=changeid, fileid=fileid, filelog=filelog)
-    def Revision():
-        return str(c.changectx())
-    def Author():
-        return util.shortuser(c.user())
-    def Date():
-        return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(c.date()[0]))
-    def RCSFile():
-        return os.path.basename(path)+',v'
-    def Source():
-        return repo.wjoin(path)+',v'
-    def Header():
-        return ' '.join([Source(), Revision(), Date(), Author()])
-    def Id():
-        return ' '.join([RCSFile(), Revision(), Date(), Author()])
-    return '$%s: %s $' % (matchobj.group(1), eval('%s()' % matchobj.group(1)))
+    Expands keywords according to file context.'''
+    return '$%s: %s $' % (mobj.group(1), kwfctx.expand(mobj.group(1)))
 
 def kwfmatches(ui, repo, files):
     '''Selects candidates for keyword substitution
@@ -79,6 +60,37 @@
                 break
     return candidates
 
+def utc(hgdate):
+    '''Returns hgdate in cvs-like UTC format.'''
+    return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(hgdate[0]))
+
+
+class kwfilectx(context.filectx):
+    '''
+    Provides keyword expansion functions based on file context.
+    '''
+    def __init__(self, repo, path, changeid=None, fileid=None, filelog=None):
+        context.filectx.__init__(self, repo, path, changeid, fileid, filelog)
+    def Revision(self):
+        return str(self.changectx())
+    def Author(self):
+        return util.shortuser(self.user())
+    def Date(self):
+        return utc(self.date())
+    def RCSFile(self):
+        return os.path.basename(self._path)+',v'
+    def Source(self):
+        return self._repo.wjoin(self._path)+',v'
+    def Header(self):
+        return ' '.join(
+                [self.Source(), self.Revision(), self.Date(), self.Author()])
+    def Id(self):
+        return ' '.join(
+                [self.RCSFile(), self.Revision(), self.Date(), self.Author()])
+    def expand(self, kw):
+        '''Called from kwexpand, evaluates keyword.'''
+        return eval('self.%s()' % kw)
+
 
 def reposetup(ui, repo):
     from mercurial import filelog, revlog
@@ -112,9 +124,9 @@
             '''Substitutes keywords when reading filelog.'''
             data = super(kwfilelog, self).read(node)
             if self.iskwcandidate(data):
-                return re_kw.sub(lambda m:
-                        kwexpand(m, self._repo, self._path,
-                            fileid=node, filelog=self), data)
+                kwfctx = kwfilectx(self._repo, self._path,
+                            fileid=node, filelog=self)
+                return re_kw.sub(lambda m: kwexpand(m, kwfctx), data)
             return data
 
         def add(self, text, meta, tr, link, p1=None, p2=None):
@@ -170,8 +182,8 @@
     for f in kwfmatches(ui, repo, modified+added):
         data = repo.wfile(f).read()
         if not util.binary(data):
-            data, kwct = re_kw.subn(lambda m:
-                    kwexpand(m, repo, f, changeid=args['node']), data)
+            kwfctx = kwfilectx(repo, f, changeid=args['node'])
+            data, kwct = re_kw.subn(lambda m: kwexpand(m, kwfctx), data)
             if kwct:
                 ui.debug(_('overwriting %s expanding keywords\n' % f))
                 repo.wfile(f, 'w').write(data)