namespaces: record and expose whether namespace is built-in

Currently, the templating layer tends to treat each namespace
as a one-off, with explicit usage of {bookmarks}, {tags}, {branch},
etc instead of using {namespaces}. It would be really useful if
we could iterate over namespaces and operate on them generically.
However, some consumers may wish to differentiate namespaces by
whether they are built-in to core Mercurial or provided by extensions.
Expected use cases include ignoring non-built-in namespaces or
emitting a generic label for non-built-in namespaces.

This commit introduces an attribute on namespace instances
that says whether the namespace is "built-in" and then exposes
this to the templating layer.

As part of this, we implement a reusable extension for defining
custom names on each changeset for testing. A second consumer
will be introduced in a subsequent commit.
This commit is contained in:
Gregory Szorc 2017-06-24 14:52:15 -07:00
parent da11a0810d
commit 6c60659b4c
4 changed files with 49 additions and 16 deletions

View File

@ -35,7 +35,8 @@ class namespaces(object):
# i18n: column positioning for "hg log"
logfmt=_("bookmark: %s\n"),
listnames=bmknames,
namemap=bmknamemap, nodemap=bmknodemap)
namemap=bmknamemap, nodemap=bmknodemap,
builtin=True)
self.addnamespace(n)
tagnames = lambda repo: [t for t, n in repo.tagslist()]
@ -46,7 +47,8 @@ class namespaces(object):
logfmt=_("tag: %s\n"),
listnames=tagnames,
namemap=tagnamemap, nodemap=tagnodemap,
deprecated={'tip'})
deprecated={'tip'},
builtin=True)
self.addnamespace(n)
bnames = lambda repo: repo.branchmap().keys()
@ -56,7 +58,8 @@ class namespaces(object):
# i18n: column positioning for "hg log"
logfmt=_("branch: %s\n"),
listnames=bnames,
namemap=bnamemap, nodemap=bnodemap)
namemap=bnamemap, nodemap=bnodemap,
builtin=True)
self.addnamespace(n)
def __getitem__(self, namespace):
@ -134,12 +137,13 @@ class namespace(object):
'namemap': function that takes a name and returns a list of nodes
'nodemap': function that takes a node and returns a list of names
'deprecated': set of names to be masked for ordinary use
'builtin': bool indicating if this namespace is supported by core
Mercurial.
"""
def __init__(self, name, templatename=None, logname=None, colorname=None,
logfmt=None, listnames=None, namemap=None, nodemap=None,
deprecated=None):
deprecated=None, builtin=False):
"""create a namespace
name: the namespace to be registered (in plural form)
@ -154,7 +158,7 @@ class namespace(object):
namemap: function that inputs a name, output node(s)
nodemap: function that inputs a node, output name(s)
deprecated: set of names to be masked for ordinary use
builtin: whether namespace is implemented by core Mercurial
"""
self.name = name
self.templatename = templatename
@ -183,6 +187,8 @@ class namespace(object):
else:
self.deprecated = deprecated
self.builtin = builtin
def names(self, repo, node):
"""method that returns a (sorted) list of names in a namespace that
match a given node"""

View File

@ -557,10 +557,12 @@ def shownamespaces(**args):
namespaces = util.sortdict()
colornames = {}
builtins = {}
for k, ns in repo.names.iteritems():
namespaces[k] = showlist('name', ns.names(repo, ctx.node()), args)
colornames[k] = ns.colorname
builtins[k] = ns.builtin
f = _showlist('namespace', list(namespaces), args)
@ -568,6 +570,7 @@ def shownamespaces(**args):
return {
'namespace': ns,
'names': namespaces[ns],
'builtin': builtins[ns],
'colorname': colornames[ns],
}

18
tests/revnamesext.py Normal file
View File

@ -0,0 +1,18 @@
# Dummy extension to define a namespace containing revision names
from __future__ import absolute_import
from mercurial import (
namespaces,
)
def reposetup(ui, repo):
names = {'r%d' % rev: repo[rev].node() for rev in repo}
namemap = lambda r, name: names.get(name)
nodemap = lambda r, node: ['r%d' % repo[node].rev()]
ns = namespaces.namespace('revnames', templatename='revname',
logname='revname',
listnames=lambda r: names.keys(),
namemap=namemap, nodemap=nodemap)
repo.names.addnamespace(ns)

View File

@ -3894,30 +3894,36 @@ Test active bookmark templating
Test namespaces dict
$ hg log -T '{rev}\n{namespaces % " {namespace} color={colorname}\n {join(names, ",")}\n"}\n'
$ hg --config extensions.revnamesext=$TESTDIR/revnamesext.py log -T '{rev}\n{namespaces % " {namespace} color={colorname} builtin={builtin}\n {join(names, ",")}\n"}\n'
2
bookmarks color=bookmark
bookmarks color=bookmark builtin=True
bar,foo
tags color=tag
tags color=tag builtin=True
tip
branches color=branch
branches color=branch builtin=True
text.{rev}
revnames color=revname builtin=False
r2
1
bookmarks color=bookmark
bookmarks color=bookmark builtin=True
baz
tags color=tag
tags color=tag builtin=True
branches color=branch
branches color=branch builtin=True
text.{rev}
revnames color=revname builtin=False
r1
0
bookmarks color=bookmark
bookmarks color=bookmark builtin=True
tags color=tag
tags color=tag builtin=True
branches color=branch
branches color=branch builtin=True
default
revnames color=revname builtin=False
r0
$ hg log -r2 -T '{namespaces % "{namespace}: {names}\n"}'
bookmarks: bar foo