##// END OF EJS Templates
registrar: fixing typo in comment...
Saurabh Singh -
r34437:c1fe66e8 default
parent child Browse files
Show More
@@ -1,381 +1,381 b''
1 # registrar.py - utilities to register function for specific purpose
1 # registrar.py - utilities to register function for specific purpose
2 #
2 #
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from . import (
10 from . import (
11 configitems,
11 configitems,
12 error,
12 error,
13 pycompat,
13 pycompat,
14 util,
14 util,
15 )
15 )
16
16
17 # unlike the other registered items, config options are neither functions or
17 # unlike the other registered items, config options are neither functions or
18 # classes. Registering the option is just small function call.
18 # classes. Registering the option is just small function call.
19 #
19 #
20 # We still add the official API to the registrar module for consistency with
20 # We still add the official API to the registrar module for consistency with
21 # the other items extensions want might to register.
21 # the other items extensions want might to register.
22 configitem = configitems.getitemregister
22 configitem = configitems.getitemregister
23
23
24 class _funcregistrarbase(object):
24 class _funcregistrarbase(object):
25 """Base of decorator to register a function for specific purpose
25 """Base of decorator to register a function for specific purpose
26
26
27 This decorator stores decorated functions into own dict 'table'.
27 This decorator stores decorated functions into own dict 'table'.
28
28
29 The least derived class can be defined by overriding 'formatdoc',
29 The least derived class can be defined by overriding 'formatdoc',
30 for example::
30 for example::
31
31
32 class keyword(_funcregistrarbase):
32 class keyword(_funcregistrarbase):
33 _docformat = ":%s: %s"
33 _docformat = ":%s: %s"
34
34
35 This should be used as below:
35 This should be used as below:
36
36
37 keyword = registrar.keyword()
37 keyword = registrar.keyword()
38
38
39 @keyword('bar')
39 @keyword('bar')
40 def barfunc(*args, **kwargs):
40 def barfunc(*args, **kwargs):
41 '''Explanation of bar keyword ....
41 '''Explanation of bar keyword ....
42 '''
42 '''
43 pass
43 pass
44
44
45 In this case:
45 In this case:
46
46
47 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
47 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
48 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
48 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
49 """
49 """
50 def __init__(self, table=None):
50 def __init__(self, table=None):
51 if table is None:
51 if table is None:
52 self._table = {}
52 self._table = {}
53 else:
53 else:
54 self._table = table
54 self._table = table
55
55
56 def __call__(self, decl, *args, **kwargs):
56 def __call__(self, decl, *args, **kwargs):
57 return lambda func: self._doregister(func, decl, *args, **kwargs)
57 return lambda func: self._doregister(func, decl, *args, **kwargs)
58
58
59 def _doregister(self, func, decl, *args, **kwargs):
59 def _doregister(self, func, decl, *args, **kwargs):
60 name = self._getname(decl)
60 name = self._getname(decl)
61
61
62 if name in self._table:
62 if name in self._table:
63 msg = 'duplicate registration for name: "%s"' % name
63 msg = 'duplicate registration for name: "%s"' % name
64 raise error.ProgrammingError(msg)
64 raise error.ProgrammingError(msg)
65
65
66 if func.__doc__ and not util.safehasattr(func, '_origdoc'):
66 if func.__doc__ and not util.safehasattr(func, '_origdoc'):
67 doc = pycompat.sysbytes(func.__doc__).strip()
67 doc = pycompat.sysbytes(func.__doc__).strip()
68 func._origdoc = doc
68 func._origdoc = doc
69 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
69 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
70
70
71 self._table[name] = func
71 self._table[name] = func
72 self._extrasetup(name, func, *args, **kwargs)
72 self._extrasetup(name, func, *args, **kwargs)
73
73
74 return func
74 return func
75
75
76 def _parsefuncdecl(self, decl):
76 def _parsefuncdecl(self, decl):
77 """Parse function declaration and return the name of function in it
77 """Parse function declaration and return the name of function in it
78 """
78 """
79 i = decl.find('(')
79 i = decl.find('(')
80 if i >= 0:
80 if i >= 0:
81 return decl[:i]
81 return decl[:i]
82 else:
82 else:
83 return decl
83 return decl
84
84
85 def _getname(self, decl):
85 def _getname(self, decl):
86 """Return the name of the registered function from decl
86 """Return the name of the registered function from decl
87
87
88 Derived class should override this, if it allows more
88 Derived class should override this, if it allows more
89 descriptive 'decl' string than just a name.
89 descriptive 'decl' string than just a name.
90 """
90 """
91 return decl
91 return decl
92
92
93 _docformat = None
93 _docformat = None
94
94
95 def _formatdoc(self, decl, doc):
95 def _formatdoc(self, decl, doc):
96 """Return formatted document of the registered function for help
96 """Return formatted document of the registered function for help
97
97
98 'doc' is '__doc__.strip()' of the registered function.
98 'doc' is '__doc__.strip()' of the registered function.
99 """
99 """
100 return self._docformat % (decl, doc)
100 return self._docformat % (decl, doc)
101
101
102 def _extrasetup(self, name, func):
102 def _extrasetup(self, name, func):
103 """Execute exra setup for registered function, if needed
103 """Execute exra setup for registered function, if needed
104 """
104 """
105
105
106 class command(_funcregistrarbase):
106 class command(_funcregistrarbase):
107 """Decorator to register a command function to table
107 """Decorator to register a command function to table
108
108
109 This class receives a command table as its argument. The table should
109 This class receives a command table as its argument. The table should
110 be a dict.
110 be a dict.
111
111
112 The created object can be used as a decorator for adding commands to
112 The created object can be used as a decorator for adding commands to
113 that command table. This accepts multiple arguments to define a command.
113 that command table. This accepts multiple arguments to define a command.
114
114
115 The first argument is the command name.
115 The first argument is the command name.
116
116
117 The options argument is an iterable of tuples defining command arguments.
117 The options argument is an iterable of tuples defining command arguments.
118 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
118 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
119
119
120 The synopsis argument defines a short, one line summary of how to use the
120 The synopsis argument defines a short, one line summary of how to use the
121 command. This shows up in the help output.
121 command. This shows up in the help output.
122
122
123 The norepo argument defines whether the command does not require a
123 The norepo argument defines whether the command does not require a
124 local repository. Most commands operate against a repository, thus the
124 local repository. Most commands operate against a repository, thus the
125 default is False.
125 default is False.
126
126
127 The optionalrepo argument defines whether the command optionally requires
127 The optionalrepo argument defines whether the command optionally requires
128 a local repository.
128 a local repository.
129
129
130 The inferrepo argument defines whether to try to find a repository from the
130 The inferrepo argument defines whether to try to find a repository from the
131 command line arguments. If True, arguments will be examined for potential
131 command line arguments. If True, arguments will be examined for potential
132 repository locations. See ``findrepo()``. If a repository is found, it
132 repository locations. See ``findrepo()``. If a repository is found, it
133 will be used.
133 will be used.
134 """
134 """
135
135
136 def _doregister(self, func, name, options=(), synopsis=None,
136 def _doregister(self, func, name, options=(), synopsis=None,
137 norepo=False, optionalrepo=False, inferrepo=False):
137 norepo=False, optionalrepo=False, inferrepo=False):
138 func.norepo = norepo
138 func.norepo = norepo
139 func.optionalrepo = optionalrepo
139 func.optionalrepo = optionalrepo
140 func.inferrepo = inferrepo
140 func.inferrepo = inferrepo
141 if synopsis:
141 if synopsis:
142 self._table[name] = func, list(options), synopsis
142 self._table[name] = func, list(options), synopsis
143 else:
143 else:
144 self._table[name] = func, list(options)
144 self._table[name] = func, list(options)
145 return func
145 return func
146
146
147 class revsetpredicate(_funcregistrarbase):
147 class revsetpredicate(_funcregistrarbase):
148 """Decorator to register revset predicate
148 """Decorator to register revset predicate
149
149
150 Usage::
150 Usage::
151
151
152 revsetpredicate = registrar.revsetpredicate()
152 revsetpredicate = registrar.revsetpredicate()
153
153
154 @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
154 @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
155 def mypredicatefunc(repo, subset, x):
155 def mypredicatefunc(repo, subset, x):
156 '''Explanation of this revset predicate ....
156 '''Explanation of this revset predicate ....
157 '''
157 '''
158 pass
158 pass
159
159
160 The first string argument is used also in online help.
160 The first string argument is used also in online help.
161
161
162 Optional argument 'safe' indicates whether a predicate is safe for
162 Optional argument 'safe' indicates whether a predicate is safe for
163 DoS attack (False by default).
163 DoS attack (False by default).
164
164
165 Optional argument 'takeorder' indicates whether a predicate function
165 Optional argument 'takeorder' indicates whether a predicate function
166 takes ordering policy as the last argument.
166 takes ordering policy as the last argument.
167
167
168 Optional argument 'weight' indicates the estimated run-time cost, useful
168 Optional argument 'weight' indicates the estimated run-time cost, useful
169 for static optimization, default is 1. Higher weight means more expensive.
169 for static optimization, default is 1. Higher weight means more expensive.
170 Usually, revsets that are fast and return only one revision has a weight of
170 Usually, revsets that are fast and return only one revision has a weight of
171 0.5 (ex. a symbol); revsets with O(changelog) complexity and read only the
171 0.5 (ex. a symbol); revsets with O(changelog) complexity and read only the
172 changelog have weight 10 (ex. author); revsets reading manifest deltas have
172 changelog have weight 10 (ex. author); revsets reading manifest deltas have
173 weight 30 (ex. adds); revset reading manifest contents have weight 100
173 weight 30 (ex. adds); revset reading manifest contents have weight 100
174 (ex. contains). Note: those values are flexible. If the revset has a
174 (ex. contains). Note: those values are flexible. If the revset has a
175 same big-O time complexity as 'contains', but with a smaller constant, it
175 same big-O time complexity as 'contains', but with a smaller constant, it
176 might have a weight of 90.
176 might have a weight of 90.
177
177
178 'revsetpredicate' instance in example above can be used to
178 'revsetpredicate' instance in example above can be used to
179 decorate multiple functions.
179 decorate multiple functions.
180
180
181 Decorated functions are registered automatically at loading
181 Decorated functions are registered automatically at loading
182 extension, if an instance named as 'revsetpredicate' is used for
182 extension, if an instance named as 'revsetpredicate' is used for
183 decorating in extension.
183 decorating in extension.
184
184
185 Otherwise, explicit 'revset.loadpredicate()' is needed.
185 Otherwise, explicit 'revset.loadpredicate()' is needed.
186 """
186 """
187 _getname = _funcregistrarbase._parsefuncdecl
187 _getname = _funcregistrarbase._parsefuncdecl
188 _docformat = "``%s``\n %s"
188 _docformat = "``%s``\n %s"
189
189
190 def _extrasetup(self, name, func, safe=False, takeorder=False, weight=1):
190 def _extrasetup(self, name, func, safe=False, takeorder=False, weight=1):
191 func._safe = safe
191 func._safe = safe
192 func._takeorder = takeorder
192 func._takeorder = takeorder
193 func._weight = weight
193 func._weight = weight
194
194
195 class filesetpredicate(_funcregistrarbase):
195 class filesetpredicate(_funcregistrarbase):
196 """Decorator to register fileset predicate
196 """Decorator to register fileset predicate
197
197
198 Usage::
198 Usage::
199
199
200 filesetpredicate = registrar.filesetpredicate()
200 filesetpredicate = registrar.filesetpredicate()
201
201
202 @filesetpredicate('mypredicate()')
202 @filesetpredicate('mypredicate()')
203 def mypredicatefunc(mctx, x):
203 def mypredicatefunc(mctx, x):
204 '''Explanation of this fileset predicate ....
204 '''Explanation of this fileset predicate ....
205 '''
205 '''
206 pass
206 pass
207
207
208 The first string argument is used also in online help.
208 The first string argument is used also in online help.
209
209
210 Optional argument 'callstatus' indicates whether a predicate
210 Optional argument 'callstatus' indicates whether a predicate
211 implies 'matchctx.status()' at runtime or not (False, by
211 implies 'matchctx.status()' at runtime or not (False, by
212 default).
212 default).
213
213
214 Optional argument 'callexisting' indicates whether a predicate
214 Optional argument 'callexisting' indicates whether a predicate
215 implies 'matchctx.existing()' at runtime or not (False, by
215 implies 'matchctx.existing()' at runtime or not (False, by
216 default).
216 default).
217
217
218 'filesetpredicate' instance in example above can be used to
218 'filesetpredicate' instance in example above can be used to
219 decorate multiple functions.
219 decorate multiple functions.
220
220
221 Decorated functions are registered automatically at loading
221 Decorated functions are registered automatically at loading
222 extension, if an instance named as 'filesetpredicate' is used for
222 extension, if an instance named as 'filesetpredicate' is used for
223 decorating in extension.
223 decorating in extension.
224
224
225 Otherwise, explicit 'fileset.loadpredicate()' is needed.
225 Otherwise, explicit 'fileset.loadpredicate()' is needed.
226 """
226 """
227 _getname = _funcregistrarbase._parsefuncdecl
227 _getname = _funcregistrarbase._parsefuncdecl
228 _docformat = "``%s``\n %s"
228 _docformat = "``%s``\n %s"
229
229
230 def _extrasetup(self, name, func, callstatus=False, callexisting=False):
230 def _extrasetup(self, name, func, callstatus=False, callexisting=False):
231 func._callstatus = callstatus
231 func._callstatus = callstatus
232 func._callexisting = callexisting
232 func._callexisting = callexisting
233
233
234 class _templateregistrarbase(_funcregistrarbase):
234 class _templateregistrarbase(_funcregistrarbase):
235 """Base of decorator to register functions as template specific one
235 """Base of decorator to register functions as template specific one
236 """
236 """
237 _docformat = ":%s: %s"
237 _docformat = ":%s: %s"
238
238
239 class templatekeyword(_templateregistrarbase):
239 class templatekeyword(_templateregistrarbase):
240 """Decorator to register template keyword
240 """Decorator to register template keyword
241
241
242 Usage::
242 Usage::
243
243
244 templatekeyword = registrar.templatekeyword()
244 templatekeyword = registrar.templatekeyword()
245
245
246 @templatekeyword('mykeyword')
246 @templatekeyword('mykeyword')
247 def mykeywordfunc(repo, ctx, templ, cache, revcache, **args):
247 def mykeywordfunc(repo, ctx, templ, cache, revcache, **args):
248 '''Explanation of this template keyword ....
248 '''Explanation of this template keyword ....
249 '''
249 '''
250 pass
250 pass
251
251
252 The first string argument is used also in online help.
252 The first string argument is used also in online help.
253
253
254 'templatekeyword' instance in example above can be used to
254 'templatekeyword' instance in example above can be used to
255 decorate multiple functions.
255 decorate multiple functions.
256
256
257 Decorated functions are registered automatically at loading
257 Decorated functions are registered automatically at loading
258 extension, if an instance named as 'templatekeyword' is used for
258 extension, if an instance named as 'templatekeyword' is used for
259 decorating in extension.
259 decorating in extension.
260
260
261 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
261 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
262 """
262 """
263
263
264 class templatefilter(_templateregistrarbase):
264 class templatefilter(_templateregistrarbase):
265 """Decorator to register template filer
265 """Decorator to register template filer
266
266
267 Usage::
267 Usage::
268
268
269 templatefilter = registrar.templatefilter()
269 templatefilter = registrar.templatefilter()
270
270
271 @templatefilter('myfilter')
271 @templatefilter('myfilter')
272 def myfilterfunc(text):
272 def myfilterfunc(text):
273 '''Explanation of this template filter ....
273 '''Explanation of this template filter ....
274 '''
274 '''
275 pass
275 pass
276
276
277 The first string argument is used also in online help.
277 The first string argument is used also in online help.
278
278
279 'templatefilter' instance in example above can be used to
279 'templatefilter' instance in example above can be used to
280 decorate multiple functions.
280 decorate multiple functions.
281
281
282 Decorated functions are registered automatically at loading
282 Decorated functions are registered automatically at loading
283 extension, if an instance named as 'templatefilter' is used for
283 extension, if an instance named as 'templatefilter' is used for
284 decorating in extension.
284 decorating in extension.
285
285
286 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
286 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
287 """
287 """
288
288
289 class templatefunc(_templateregistrarbase):
289 class templatefunc(_templateregistrarbase):
290 """Decorator to register template function
290 """Decorator to register template function
291
291
292 Usage::
292 Usage::
293
293
294 templatefunc = registrar.templatefunc()
294 templatefunc = registrar.templatefunc()
295
295
296 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3')
296 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3')
297 def myfuncfunc(context, mapping, args):
297 def myfuncfunc(context, mapping, args):
298 '''Explanation of this template function ....
298 '''Explanation of this template function ....
299 '''
299 '''
300 pass
300 pass
301
301
302 The first string argument is used also in online help.
302 The first string argument is used also in online help.
303
303
304 If optional 'argspec' is defined, the function will receive 'args' as
304 If optional 'argspec' is defined, the function will receive 'args' as
305 a dict of named arguments. Otherwise 'args' is a list of positional
305 a dict of named arguments. Otherwise 'args' is a list of positional
306 arguments.
306 arguments.
307
307
308 'templatefunc' instance in example above can be used to
308 'templatefunc' instance in example above can be used to
309 decorate multiple functions.
309 decorate multiple functions.
310
310
311 Decorated functions are registered automatically at loading
311 Decorated functions are registered automatically at loading
312 extension, if an instance named as 'templatefunc' is used for
312 extension, if an instance named as 'templatefunc' is used for
313 decorating in extension.
313 decorating in extension.
314
314
315 Otherwise, explicit 'templater.loadfunction()' is needed.
315 Otherwise, explicit 'templater.loadfunction()' is needed.
316 """
316 """
317 _getname = _funcregistrarbase._parsefuncdecl
317 _getname = _funcregistrarbase._parsefuncdecl
318
318
319 def _extrasetup(self, name, func, argspec=None):
319 def _extrasetup(self, name, func, argspec=None):
320 func._argspec = argspec
320 func._argspec = argspec
321
321
322 class internalmerge(_funcregistrarbase):
322 class internalmerge(_funcregistrarbase):
323 """Decorator to register in-process merge tool
323 """Decorator to register in-process merge tool
324
324
325 Usage::
325 Usage::
326
326
327 internalmerge = registrar.internalmerge()
327 internalmerge = registrar.internalmerge()
328
328
329 @internalmerge('mymerge', internalmerge.mergeonly,
329 @internalmerge('mymerge', internalmerge.mergeonly,
330 onfailure=None, precheck=None):
330 onfailure=None, precheck=None):
331 def mymergefunc(repo, mynode, orig, fcd, fco, fca,
331 def mymergefunc(repo, mynode, orig, fcd, fco, fca,
332 toolconf, files, labels=None):
332 toolconf, files, labels=None):
333 '''Explanation of this internal merge tool ....
333 '''Explanation of this internal merge tool ....
334 '''
334 '''
335 return 1, False # means "conflicted", "no deletion needed"
335 return 1, False # means "conflicted", "no deletion needed"
336
336
337 The first string argument is used to compose actual merge tool name,
337 The first string argument is used to compose actual merge tool name,
338 ":name" and "internal:name" (the latter is historical one).
338 ":name" and "internal:name" (the latter is historical one).
339
339
340 The second argument is one of merge types below:
340 The second argument is one of merge types below:
341
341
342 ========== ======== ======== =========
342 ========== ======== ======== =========
343 merge type precheck premerge fullmerge
343 merge type precheck premerge fullmerge
344 ========== ======== ======== =========
344 ========== ======== ======== =========
345 nomerge x x x
345 nomerge x x x
346 mergeonly o x o
346 mergeonly o x o
347 fullmerge o o o
347 fullmerge o o o
348 ========== ======== ======== =========
348 ========== ======== ======== =========
349
349
350 Optional argument 'onfalure' is the format of warning message
350 Optional argument 'onfailure' is the format of warning message
351 to be used at failure of merging (target filename is specified
351 to be used at failure of merging (target filename is specified
352 at formatting). Or, None or so, if warning message should be
352 at formatting). Or, None or so, if warning message should be
353 suppressed.
353 suppressed.
354
354
355 Optional argument 'precheck' is the function to be used
355 Optional argument 'precheck' is the function to be used
356 before actual invocation of internal merge tool itself.
356 before actual invocation of internal merge tool itself.
357 It takes as same arguments as internal merge tool does, other than
357 It takes as same arguments as internal merge tool does, other than
358 'files' and 'labels'. If it returns false value, merging is aborted
358 'files' and 'labels'. If it returns false value, merging is aborted
359 immediately (and file is marked as "unresolved").
359 immediately (and file is marked as "unresolved").
360
360
361 'internalmerge' instance in example above can be used to
361 'internalmerge' instance in example above can be used to
362 decorate multiple functions.
362 decorate multiple functions.
363
363
364 Decorated functions are registered automatically at loading
364 Decorated functions are registered automatically at loading
365 extension, if an instance named as 'internalmerge' is used for
365 extension, if an instance named as 'internalmerge' is used for
366 decorating in extension.
366 decorating in extension.
367
367
368 Otherwise, explicit 'filemerge.loadinternalmerge()' is needed.
368 Otherwise, explicit 'filemerge.loadinternalmerge()' is needed.
369 """
369 """
370 _docformat = "``:%s``\n %s"
370 _docformat = "``:%s``\n %s"
371
371
372 # merge type definitions:
372 # merge type definitions:
373 nomerge = None
373 nomerge = None
374 mergeonly = 'mergeonly' # just the full merge, no premerge
374 mergeonly = 'mergeonly' # just the full merge, no premerge
375 fullmerge = 'fullmerge' # both premerge and merge
375 fullmerge = 'fullmerge' # both premerge and merge
376
376
377 def _extrasetup(self, name, func, mergetype,
377 def _extrasetup(self, name, func, mergetype,
378 onfailure=None, precheck=None):
378 onfailure=None, precheck=None):
379 func.mergetype = mergetype
379 func.mergetype = mergetype
380 func.onfailure = onfailure
380 func.onfailure = onfailure
381 func.precheck = precheck
381 func.precheck = precheck
General Comments 0
You need to be logged in to leave comments. Login now