[PATCH 2 of 2] templater: introduce latesttag() function to match a pattern (issue4184)

Matt Harbison mharbison72 at gmail.com
Sat Aug 22 23:50:34 CDT 2015


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1440300516 14400
#      Sat Aug 22 23:28:36 2015 -0400
# Node ID b65f8c20a934f9a6d7741dd09af9d895ad36a905
# Parent  d315fc51e187c70ee75964f7503b8780f1c95884
templater: introduce latesttag() function to match a pattern (issue4184)

This allows the latest class of tag to be found, such as a release candidate or
final build, instead of just the absolute latest.

It doesn't appear that the existing keyword can be given an optional argument.
There is a keyword, function and filter for 'date', so it doesn't seem harmful
to introduce a new function with the same name as an existing keyword.  Most
functions are pretty Mercurial agnostic, but there is {revset()} as precedent.

It's unfortunate that the original 'latesttags' cache can't be used to determine
the proper values, but it isn't fully populated for the entire repo.  For
example, the {latesttagdistance} keyword on the Mecurial repo builds the cache
up back to the revision for 1.4.  If the pattern was 're:^0\.\d$', that wouldn't
be in the cache.  Maybe this can be optimized some other way, but for now, this
is the simpliest implementation.

With this in place, it is trivial to also implement a method for
{latesttagdistance} and {changessincelatesttag}.

diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -122,14 +122,21 @@
         revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
     return revcache['files']
 
-def getlatesttags(repo, ctx, cache):
+def getlatesttags(repo, ctx, cache, pattern=None):
     '''return date, distance and name for the latest tag of rev'''
 
-    if 'latesttags' not in cache:
+    cachename = 'latesttags'
+    if pattern is not None:
+        cachename += '-' + pattern
+        match = util.stringmatcher(pattern)[2]
+    else:
+        match = util.always
+
+    if cachename 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']
+        cache[cachename] = {-1: (0, 0, ['null'])}
+    latesttags = cache[cachename]
 
     rev = ctx.rev()
     todo = [rev]
@@ -139,7 +146,8 @@
             continue
         ctx = repo[rev]
         tags = [t for t in ctx.tags()
-                if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
+                if (repo.tagtype(t) and repo.tagtype(t) != 'local'
+                    and match(t))]
         if tags:
             latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
             continue
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -551,6 +551,22 @@
 
     return minirst.format(text, style=style, keep=['verbose'])
 
+def latesttag(context, mapping, args):
+    """:latesttag(pattern): The global tags matching the given pattern on the
+    most recent globally tagged ancestor of this changeset."""
+    if len(args) != 1:
+        # i18n: "latesttag" is a keyword
+        raise error.ParseError(_("latesttag expects one argument"))
+
+    pattern = stringify(args[0][0](context, mapping, args[0][1]))
+
+    repo, ctx = mapping['repo'], mapping['ctx']
+    cache = mapping['cache']
+    latesttags = templatekw.getlatesttags(repo, ctx, cache, pattern)[2]
+
+    return templatekw.showlist('latesttag', latesttags, separator=':',
+                               **mapping)
+
 def shortest(context, mapping, args):
     """:shortest(node, minlength=4): Obtain the shortest representation of
     a node."""
@@ -693,6 +709,7 @@
     "indent": indent,
     "join": join,
     "label": label,
+    "latesttag": latesttag,
     "pad": pad,
     "revset": revset,
     "rstdoc": rstdoc,
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -2681,6 +2681,19 @@
   1: t1+0
   0: null+1
 
+  $ hg log --template "{rev}: {latesttag('re:^t[13]$')}\n"
+  10: t3
+  9: t3
+  8: t3
+  7: t3
+  6: t3
+  5: t3
+  4: t3
+  3: t3
+  2: t1
+  1: t1
+  0: null
+
   $ cd ..
 
 


More information about the Mercurial-devel mailing list