comparison mercurial/namespaces.py @ 23717:d8663e6153c1

namespaces: use namespace object instead of dictionary This isn't as bad as the diff seems, it only looks like scary. In this patch, we use the 'namespace' object instead of accessing keys in a dictionary. This required the 'templatename' and 'names' method to change their implementation. Later, we will remove these functions entirely due to a better api.
author Sean Farley <sean.michael.farley@gmail.com>
date Fri, 19 Dec 2014 17:27:20 -0800
parents f4828a8f6ae9
children 42908c3275c6
comparison
equal deleted inserted replaced
23716:f4828a8f6ae9 23717:d8663e6153c1
37 _names_version = 0 37 _names_version = 0
38 38
39 def __init__(self): 39 def __init__(self):
40 self._names = util.sortdict() 40 self._names = util.sortdict()
41 41
42 addns = self.addnamespace 42 # shorten the class name for less indentation
43 ns = namespace
43 44
44 # we need current mercurial named objects (bookmarks, tags, and 45 # we need current mercurial named objects (bookmarks, tags, and
45 # branches) to be initialized somewhere, so that place is here 46 # branches) to be initialized somewhere, so that place is here
46 addns("bookmarks", "bookmark", 47 n = ns("bookmarks", "bookmark",
47 lambda repo, name: tolist(repo._bookmarks.get(name)), 48 lambda repo, name: tolist(repo._bookmarks.get(name)),
48 lambda repo, name: repo.nodebookmarks(name)) 49 lambda repo, name: repo.nodebookmarks(name))
50 self.addnamespace(n)
49 51
50 addns("tags", "tag", 52 n = ns("tags", "tag",
51 lambda repo, name: tolist(repo._tagscache.tags.get(name)), 53 lambda repo, name: tolist(repo._tagscache.tags.get(name)),
52 lambda repo, name: repo.nodetags(name)) 54 lambda repo, name: repo.nodetags(name))
55 self.addnamespace(n)
53 56
54 addns("branches", "branch", 57 n = ns("branches", "branch",
55 lambda repo, name: tolist(repo.branchtip(name)), 58 lambda repo, name: tolist(repo.branchtip(name)),
56 lambda repo, node: [repo[node].branch()]) 59 lambda repo, node: [repo[node].branch()])
60 self.addnamespace(n)
57 61
58 def addnamespace(self, namespace, templatename, namemap, nodemap, 62 def addnamespace(self, namespace, order=None):
59 order=None):
60 """ 63 """
61 register a namespace 64 register a namespace
62 65
63 namespace: the name to be registered (in plural form) 66 namespace: the name to be registered (in plural form)
64 templatename: the name to use for templating 67 templatename: the name to use for templating
65 namemap: function that inputs a node, output name(s) 68 namemap: function that inputs a node, output name(s)
66 nodemap: function that inputs a name, output node(s) 69 nodemap: function that inputs a name, output node(s)
67 order: optional argument to specify the order of namespaces 70 order: optional argument to specify the order of namespaces
68 (e.g. 'branches' should be listed before 'bookmarks') 71 (e.g. 'branches' should be listed before 'bookmarks')
69 """ 72 """
70 val = {'templatename': templatename,
71 'namemap': namemap,
72 'nodemap': nodemap}
73 if order is not None: 73 if order is not None:
74 self._names.insert(order, namespace, val) 74 self._names.insert(order, namespace.name, namespace)
75 else: 75 else:
76 self._names[namespace] = val 76 self._names[namespace.name] = namespace
77 77
78 # we only generate a template keyword if one does not already exist 78 # we only generate a template keyword if one does not already exist
79 if namespace not in templatekw.keywords: 79 if namespace.name not in templatekw.keywords:
80 def generatekw(**args): 80 def generatekw(**args):
81 return templatekw.shownames(namespace, **args) 81 return templatekw.shownames(namespace.name, **args)
82 82
83 templatekw.keywords[namespace] = generatekw 83 templatekw.keywords[namespace.name] = generatekw
84 84
85 def singlenode(self, repo, name): 85 def singlenode(self, repo, name):
86 """ 86 """
87 Return the 'best' node for the given name. Best means the first node 87 Return the 'best' node for the given name. Best means the first node
88 in the first nonempty list returned by a name-to-nodes mapping function 88 in the first nonempty list returned by a name-to-nodes mapping function
89 in the defined precedence order. 89 in the defined precedence order.
90 90
91 Raises a KeyError if there is no such node. 91 Raises a KeyError if there is no such node.
92 """ 92 """
93 for ns, v in self._names.iteritems(): 93 for ns, v in self._names.iteritems():
94 n = v['namemap'](repo, name) 94 n = v.namemap(repo, name)
95 if n: 95 if n:
96 # return max revision number 96 # return max revision number
97 if len(n) > 1: 97 if len(n) > 1:
98 cl = repo.changelog 98 cl = repo.changelog
99 maxrev = max(cl.rev(node) for node in n) 99 maxrev = max(cl.rev(node) for node in n)
101 return n[0] 101 return n[0]
102 raise KeyError(_('no such name: %s') % name) 102 raise KeyError(_('no such name: %s') % name)
103 103
104 def templatename(self, namespace): 104 def templatename(self, namespace):
105 """method that returns the template name of a namespace""" 105 """method that returns the template name of a namespace"""
106 return self._names[namespace]['templatename'] 106 return self._names[namespace].templatename
107 107
108 def names(self, repo, namespace, node): 108 def names(self, repo, namespace, node):
109 """method that returns a (sorted) list of names in a namespace that 109 """method that returns a (sorted) list of names in a namespace that
110 match a given node""" 110 match a given node"""
111 return sorted(self._names[namespace]['nodemap'](repo, node)) 111 return sorted(self._names[namespace].nodemap(repo, node))
112 112
113 class namespace(object): 113 class namespace(object):
114 """provides an interface to a namespace 114 """provides an interface to a namespace
115 115
116 Namespaces are basically generic many-to-many mapping between some 116 Namespaces are basically generic many-to-many mapping between some