Mercurial > hg-stable
annotate mercurial/namespaces.py @ 23610:9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
For any namespace, we generate a template keyword. For example, given a
namespace 'babar', we automatically have the ability to use it in a template:
hg log -r . -T '{babars % "King: {babar}\n"}'
Furthermore, we only generate this keyword for a namespace if one doesn't
already exist. This is necessary for 'branches' and 'bookmarks' since both of
those have concepts of 'current' (something outside the namespace api) and also
allows extensions to override default behavior if desired.
author | Sean Farley <sean.michael.farley@gmail.com> |
---|---|
date | Thu, 16 Oct 2014 23:19:09 -0700 |
parents | 807ee1a02bb0 |
children | eee55c09010a |
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 |
23610
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
3 import templatekw |
23553
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
4 |
23555
f08f6a7d4d5f
namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents:
23554
diff
changeset
|
5 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
|
6 """ |
f08f6a7d4d5f
namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents:
23554
diff
changeset
|
7 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
|
8 """ |
f08f6a7d4d5f
namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents:
23554
diff
changeset
|
9 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
|
10 return [] |
f08f6a7d4d5f
namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents:
23554
diff
changeset
|
11 else: |
f08f6a7d4d5f
namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents:
23554
diff
changeset
|
12 return [val] |
f08f6a7d4d5f
namespaces: add a function to turn single results into lists
Sean Farley <sean.michael.farley@gmail.com>
parents:
23554
diff
changeset
|
13 |
23553
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
14 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
|
15 """ |
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
16 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
|
17 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
|
18 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
|
19 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
|
20 |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
21 More precisely, we define a list of names (the namespace), a mapping of |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
22 names to nodes, and a mapping from nodes to names. Each mapping |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
23 returns a list of nodes. |
23553
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
24 |
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
25 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
|
26 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
|
27 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
|
28 |
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
29 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
|
30 its value is a dictionary of functions: |
23605
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
31 'templatename': name to use for templating (usually the singular form |
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
32 of the plural namespace name) |
23553
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
33 'namemap': function that takes a name and returns a list of nodes |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
34 'nodemap': function that takes a node and returns a list of names |
23553
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
35 """ |
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
36 |
7cebb6a8c75f
namespaces: introduce a generic way to map between names and nodes
Sean Farley <sean.michael.farley@gmail.com>
parents:
diff
changeset
|
37 _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
|
38 |
23561
3c2419e07df5
namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents:
23559
diff
changeset
|
39 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
|
40 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
|
41 |
23562
59e703aecaf6
namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents:
23561
diff
changeset
|
42 addns = self.addnamespace |
59e703aecaf6
namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents:
23561
diff
changeset
|
43 |
23558
3198aac7a95d
namespaces: add bookmarks to the names data structure
Sean Farley <sean.michael.farley@gmail.com>
parents:
23557
diff
changeset
|
44 # 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
|
45 # branches) to be initialized somewhere, so that place is here |
23605
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
46 addns("bookmarks", "bookmark", |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
47 lambda repo, name: tolist(repo._bookmarks.get(name)), |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
48 lambda repo, name: repo.nodebookmarks(name)) |
23562
59e703aecaf6
namespaces: add tags
Sean Farley <sean.michael.farley@gmail.com>
parents:
23561
diff
changeset
|
49 |
23605
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
50 addns("tags", "tag", |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
51 lambda repo, name: tolist(repo._tagscache.tags.get(name)), |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
52 lambda repo, name: repo.nodetags(name)) |
23558
3198aac7a95d
namespaces: add bookmarks to the names data structure
Sean Farley <sean.michael.farley@gmail.com>
parents:
23557
diff
changeset
|
53 |
23605
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
54 addns("branches", "branch", |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
55 lambda repo, name: tolist(repo.branchtip(name)), |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
56 lambda repo, node: [repo[node].branch()]) |
23563
114992041625
namespaces: add branches
Sean Farley <sean.michael.farley@gmail.com>
parents:
23562
diff
changeset
|
57 |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
58 def addnamespace(self, namespace, templatename, namemap, nodemap, |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
59 order=None): |
23554
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
60 """ |
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
61 register a namespace |
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
62 |
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
63 namespace: the name to be registered (in plural form) |
23605
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
64 templatename: the name to use for templating |
23554
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
65 namemap: function that inputs a node, output name(s) |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
66 nodemap: function that inputs a name, output node(s) |
23554
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
67 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
|
68 (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
|
69 """ |
23605
4c4c967814ef
namespaces: add template name of a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23563
diff
changeset
|
70 val = {'templatename': templatename, |
23607
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
71 'namemap': namemap, |
0fd778ef0f61
namespaces: add nodemap property
Sean Farley <sean.michael.farley@gmail.com>
parents:
23606
diff
changeset
|
72 'nodemap': nodemap} |
23554
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
73 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
|
74 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
|
75 else: |
75f9643cab1b
namespaces: add a method to register new namespaces
Sean Farley <sean.michael.farley@gmail.com>
parents:
23553
diff
changeset
|
76 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
|
77 |
23610
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
78 # we only generate a template keyword if one does not already exist |
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
79 if namespace not in templatekw.keywords: |
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
80 def generatekw(**args): |
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
81 return templatekw.shownames(namespace, **args) |
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
82 |
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
83 templatekw.keywords[namespace] = generatekw |
9266d1dd6a6e
namespaces: generate template keyword when registering a namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23608
diff
changeset
|
84 |
23561
3c2419e07df5
namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents:
23559
diff
changeset
|
85 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
|
86 """ |
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
|
87 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
|
88 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
|
89 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
|
90 |
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
|
91 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
|
92 """ |
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
|
93 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
|
94 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
|
95 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
|
96 # 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
|
97 if len(n) > 1: |
23561
3c2419e07df5
namespaces: remove weakref; always pass in repo
Ryan McElroy <rmcelroy@fb.com>
parents:
23559
diff
changeset
|
98 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
|
99 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
|
100 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
|
101 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
|
102 raise KeyError(_('no such name: %s') % name) |
23606
80e3cbe227d1
namespaces: add method to get template name of namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23605
diff
changeset
|
103 |
80e3cbe227d1
namespaces: add method to get template name of namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23605
diff
changeset
|
104 def templatename(self, namespace): |
80e3cbe227d1
namespaces: add method to get template name of namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23605
diff
changeset
|
105 """method that returns the template name of a namespace""" |
80e3cbe227d1
namespaces: add method to get template name of namespace
Sean Farley <sean.michael.farley@gmail.com>
parents:
23605
diff
changeset
|
106 return self._names[namespace]['templatename'] |
23608
807ee1a02bb0
namespaces: add names method to return list of names for a given node
Sean Farley <sean.michael.farley@gmail.com>
parents:
23607
diff
changeset
|
107 |
807ee1a02bb0
namespaces: add names method to return list of names for a given node
Sean Farley <sean.michael.farley@gmail.com>
parents:
23607
diff
changeset
|
108 def names(self, repo, namespace, node): |
807ee1a02bb0
namespaces: add names method to return list of names for a given node
Sean Farley <sean.michael.farley@gmail.com>
parents:
23607
diff
changeset
|
109 """method that returns a (sorted) list of names in a namespace that |
807ee1a02bb0
namespaces: add names method to return list of names for a given node
Sean Farley <sean.michael.farley@gmail.com>
parents:
23607
diff
changeset
|
110 match a given node""" |
807ee1a02bb0
namespaces: add names method to return list of names for a given node
Sean Farley <sean.michael.farley@gmail.com>
parents:
23607
diff
changeset
|
111 return sorted(self._names[namespace]['nodemap'](repo, node)) |