annotate mercurial/namespaces.py @ 23562:59e703aecaf6

namespaces: add tags
author Sean Farley <sean.michael.farley@gmail.com>
date Fri, 17 Oct 2014 15:27:33 -0700
parents 3c2419e07df5
children 114992041625
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
23559
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
1 from i18n import _
23553
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
2 from mercurial import util
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
3
23555
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
4 def tolist(val):
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
5 """
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
6 a convenience method to return an empty list instead of None
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
7 """
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
8 if val is None:
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
9 return []
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
10 else:
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
11 return [val]
f08f6a7d4d5f namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents: 23554
diff changeset
12
23553
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
13 class namespaces(object):
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
14 """
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
15 provides an interface to register a generic many-to-many mapping between
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
16 some (namespaced) names and nodes. The goal here is to control the
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
17 pollution of jamming things into tags or bookmarks (in extension-land) and
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
18 to simplify internal bits of mercurial: log output, tab completion, etc.
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
19
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
20 More precisely, we define a list of names (the namespace) and a mapping of
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
21 names to nodes. This name mapping returns a list of nodes.
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
22
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
23 Furthermore, each name mapping will be passed a name to lookup which might
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
24 not be in its domain. In this case, each method should return an empty list
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
25 and not raise an error.
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
26
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
27 We'll have a dictionary '_names' where each key is a namespace and
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
28 its value is a dictionary of functions:
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
29 'namemap': function that takes a name and returns a list of nodes
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
30 """
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
31
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
32 _names_version = 0
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
33
23561
3c2419e07df5 namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents: 23559
diff changeset
34 def __init__(self):
23553
7cebb6a8c75f namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff changeset
35 self._names = util.sortdict()
23554
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
36
23562
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
37 addns = self.addnamespace
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
38
23558
3198aac7a95d namespaces: add bookmarks to the names data structure
Sean Farley <sean.michael.farley@gmail.com>
parents: 23557
diff changeset
39 # we need current mercurial named objects (bookmarks, tags, and
3198aac7a95d namespaces: add bookmarks to the names data structure
Sean Farley <sean.michael.farley@gmail.com>
parents: 23557
diff changeset
40 # branches) to be initialized somewhere, so that place is here
23562
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
41 addns("bookmarks",
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
42 lambda repo, name: tolist(repo._bookmarks.get(name)))
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
43
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
44 addns("tags",
59e703aecaf6 namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents: 23561
diff changeset
45 lambda repo, name: tolist(repo._tagscache.tags.get(name)))
23558
3198aac7a95d namespaces: add bookmarks to the names data structure
Sean Farley <sean.michael.farley@gmail.com>
parents: 23557
diff changeset
46
23554
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
47 def addnamespace(self, namespace, namemap, order=None):
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
48 """
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
49 register a namespace
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
50
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
51 namespace: the name to be registered (in plural form)
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
52 namemap: function that inputs a node, output name(s)
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
53 order: optional argument to specify the order of namespaces
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
54 (e.g. 'branches' should be listed before 'bookmarks')
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
55 """
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
56 val = {'namemap': namemap}
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
57 if order is not None:
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
58 self._names.insert(order, namespace, val)
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
59 else:
75f9643cab1b namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents: 23553
diff changeset
60 self._names[namespace] = val
23559
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
61
23561
3c2419e07df5 namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents: 23559
diff changeset
62 def singlenode(self, repo, name):
23559
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
63 """
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
64 Return the 'best' node for the given name. Best means the first node
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
65 in the first nonempty list returned by a name-to-nodes mapping function
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
66 in the defined precedence order.
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
67
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
68 Raises a KeyError if there is no such node.
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
69 """
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
70 for ns, v in self._names.iteritems():
23561
3c2419e07df5 namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents: 23559
diff changeset
71 n = v['namemap'](repo, name)
23559
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
72 if n:
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
73 # return max revision number
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
74 if len(n) > 1:
23561
3c2419e07df5 namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents: 23559
diff changeset
75 cl = repo.changelog
23559
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
76 maxrev = max(cl.rev(node) for node in n)
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
77 return cl.node(maxrev)
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
78 return n[0]
3b3a962e3677 namespaces: add a method to the first matching node for a given name
Sean Farley <sean.michael.farley@gmail.com>
parents: 23558
diff changeset
79 raise KeyError(_('no such name: %s') % name)