cmdutil: extract latest tags closures in templatekw
authorPatrick Mezard <pmezard@gmail.com>
Sun, 13 Dec 2009 18:06:24 +0100
changeset 10057 babc00a82c5e
parent 10056 1a114aca93fa
child 10058 c829563b3118
cmdutil: extract latest tags closures in templatekw
mercurial/cmdutil.py
mercurial/templatekw.py
tests/test-template-engine
--- a/mercurial/cmdutil.py	Sun Dec 13 18:06:24 2009 +0100
+++ b/mercurial/cmdutil.py	Sun Dec 13 18:06:24 2009 +0100
@@ -763,9 +763,7 @@
                                          'manifest': '{rev}:{node|formatnode}',
                                          'filecopy': '{name} ({source})',
                                          'extra': '{key}={value|stringescape}'})
-        # Cache mapping from rev to a tuple with tag date, tag
-        # distance and tag name
-        self._latesttagcache = {-1: (0, 0, 'null')}
+        self.cache = {}
 
     def use_template(self, t):
         '''set template string to use'''
@@ -783,30 +781,6 @@
             return []
         return parents
 
-    def _latesttaginfo(self, rev):
-        '''return date, distance and name for the latest tag of rev'''
-        todo = [rev]
-        while todo:
-            rev = todo.pop()
-            if rev in self._latesttagcache:
-                continue
-            ctx = self.repo[rev]
-            tags = [t for t in ctx.tags() if self.repo.tagtype(t) == 'global']
-            if tags:
-                self._latesttagcache[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
-                continue
-            try:
-                # The tuples are laid out so the right one can be found by comparison.
-                pdate, pdist, ptag = max(
-                    self._latesttagcache[p.rev()] for p in ctx.parents())
-            except KeyError:
-                # Cache miss - recurse
-                todo.append(rev)
-                todo.extend(p.rev() for p in ctx.parents())
-                continue
-            self._latesttagcache[rev] = pdate, pdist + 1, ptag
-        return self._latesttagcache[rev]
-
     def _show(self, ctx, copies, props):
         '''show a single changeset or file revision'''
 
@@ -820,17 +794,10 @@
         def showcopies(repo, ctx, templ, **args):
             c = [{'name': x[0], 'source': x[1]} for x in copies]
             return showlist(templ, 'file_copy', c, plural='file_copies', **args)
-        
-        def showlatesttag(repo, ctx, templ, **args):
-            return self._latesttaginfo(ctx.rev())[2]
-        def showlatesttagdistance(repo, ctx, templ, **args):
-            return self._latesttaginfo(ctx.rev())[1]
 
         defprops = {
             'file_copies': showcopies,            
             'parents': showparents,            
-            'latesttag': showlatesttag,
-            'latesttagdistance': showlatesttagdistance,
             }
         props = props.copy()
         props.update(templatekw.keywords)
@@ -839,6 +806,7 @@
         props['ctx'] = ctx
         props['repo'] = self.repo
         props['revcache'] = {}
+        props['cache'] = self.cache
 
         # find correct templates for current mode
 
--- a/mercurial/templatekw.py	Sun Dec 13 18:06:24 2009 +0100
+++ b/mercurial/templatekw.py	Sun Dec 13 18:06:24 2009 +0100
@@ -75,6 +75,39 @@
                                         ctx.node())[:3]
     return revcache['files']
 
+def getlatesttags(repo, ctx, cache):
+    '''return date, distance and name for the latest tag of rev'''
+
+    if 'latesttags' not in cache:
+        # Cache mapping from rev to a tuple with tag date, tag
+        # distance and tag name
+        cache['latesttags'] = {-1: (0, 0, 'null')}
+    latesttags = cache['latesttags']
+
+    rev = ctx.rev()
+    todo = [rev]
+    while todo:
+        rev = todo.pop()
+        if rev in latesttags:
+            continue
+        ctx = repo[rev]
+        tags = [t for t in ctx.tags() if repo.tagtype(t) == 'global']
+        if tags:
+            latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
+            continue
+        try:
+            # The tuples are laid out so the right one can be found by
+            # comparison.
+            pdate, pdist, ptag = max(
+                latesttags[p.rev()] for p in ctx.parents())
+        except KeyError:
+            # Cache miss - recurse
+            todo.append(rev)
+            todo.extend(p.rev() for p in ctx.parents())
+            continue
+        latesttags[rev] = pdate, pdist + 1, ptag
+    return latesttags[rev]
+
 def showauthor(repo, ctx, templ, **args):
     return ctx.user()
 
@@ -117,6 +150,12 @@
 def showfiles(repo, ctx, templ, **args):
     return showlist(templ, 'file', ctx.files(), **args)
 
+def showlatesttag(repo, ctx, templ, cache, **args):
+    return getlatesttags(repo, ctx, cache)[2]
+
+def showlatesttagdistance(repo, ctx, templ, cache, **args):
+    return getlatesttags(repo, ctx, cache)[1]
+
 def showmanifest(repo, ctx, templ, **args):
     args = args.copy()
     args.update(dict(rev=repo.manifest.rev(ctx.changeset()[0]),
@@ -143,6 +182,8 @@
     'file_dels': showfiledels,
     'file_mods': showfilemods,
     'files': showfiles,
+    'latesttag': showlatesttag,
+    'latesttagdistance': showlatesttagdistance,
     'manifest': showmanifest,
     'node': shownode,
     'rev': showrev,
--- a/tests/test-template-engine	Sun Dec 13 18:06:24 2009 +0100
+++ b/tests/test-template-engine	Sun Dec 13 18:06:24 2009 +0100
@@ -11,7 +11,7 @@
     def process(self, t, map):
         tmpl = self.loader(t)
         for k, v in map.iteritems():
-            if k in ('templ', 'ctx', 'repo', 'revcache'):
+            if k in ('templ', 'ctx', 'repo', 'revcache', 'cache'):
                 continue
             if hasattr(v, '__call__'):
                 v = v(**map)