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