[PATCH 3 of 3 V3] templater: introduce {latesttag()} function to match a pattern (issue4184)
Yuya Nishihara
yuya at tcha.org
Mon Aug 24 08:18:12 CDT 2015
On Mon, 24 Aug 2015 00:54:20 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison at yahoo.com>
> # Date 1440387898 14400
> # Sun Aug 23 23:44:58 2015 -0400
> # Node ID 34d52e2098ee7f9a4e4402ebdd343525f0ed3e18
> # Parent 1a83ed3de651a4b5959f367d647ca5f693dbb234
> 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.
>
> Even though templatekw.getlatesttags() returns a single tuple, one entry of
> which is a list, it is simplest to present this as a list of tags instead of a
> single item, with each tag having a distance and change count attribute. It is
> also closer to how {latesttag} returns a list of tags, and how this function
> works when not given a '%' operator.
>
> diff --git a/mercurial/help/templates.txt b/mercurial/help/templates.txt
> --- a/mercurial/help/templates.txt
> +++ b/mercurial/help/templates.txt
> @@ -98,6 +98,10 @@
>
> $ hg log --template "{bookmarks % '{bookmark}{ifeq(bookmark, active, '*')} '}\n"
>
> +- Find the previous release candidate tag, the distance and changes since the tag::
> +
> + $ hg log -r . --template "{latesttag('re:^.*-rc$') % '{tag}, {changes}, {distance}'}\n"
I think "{latesttag % '{tag}, {changes}...'}" should be possible as well.
Perhaps it will need a helper function like templatekw.shownames().
> $ hg log --template "{ifcontains(rev, revset('.'), '@')}\n"
> diff --git a/mercurial/templater.py b/mercurial/templater.py
> --- a/mercurial/templater.py
> +++ b/mercurial/templater.py
> @@ -510,6 +510,44 @@
> # ignore args[0] (the label string) since this is supposed to be a a no-op
> yield args[1][0](context, mapping, args[1][1])
>
> +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 at most one argument"))
> +
> + pattern = None
> + if len(args) == 1:
> + 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)
> +
> + def changes(tag):
> + offset = 0
> + revs = [ctx.rev()]
> +
> + # The only() revset doesn't currently support wdir()
> + if ctx.rev() is None:
> + offset = 1
> + revs = [p.rev() for p in ctx.parents()]
> +
> + return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
> +
> + makemap = lambda v: {
> + 'changes': changes(v),
Because changes() is slow, it should be delayed. makemap() can have a
callable that implements the same interface as templatekw.showxxx() functions.
See templater.runmap() and runsymbol().
> + # Not the date the tag was applied, but not much we can do about that
> + #'commitdate': util.makedate(latesttags[0]),
> + 'distance': latesttags[1],
> + 'tag': v
> + }
> +
> + tags = latesttags[2]
> + f = templatekw._showlist('latesttag', tags, separator=':', **mapping)
> + return templatekw._hybrid(f, tags, makemap, lambda x: x['latesttag'])
Typo of x['tag'] ?
% hg log -T '{join(latesttag(), " ")}\n'
abort: template: no key named 'latesttag'
More information about the Mercurial-devel
mailing list