##// END OF EJS Templates
helptext: byteify extensions examples...
Matt Harbison -
r46543:f177fcd9 default
parent child Browse files
Show More
@@ -1,367 +1,368 b''
1 1 Extensions allow the creation of new features and using them directly from
2 2 the main hg command line as if they were built-in commands. The extensions
3 3 have full access to the *internal* API.
4 4
5 5 Use of Mercurial's internal API very likely makes your code subject to
6 6 Mercurial's license. Before going any further, read the License page.
7 7
8 8 There are NO guarantees that third-party code calling into Mercurial's
9 9 internals won't break from release to release. If you do use Mercurial's API
10 10 for published third-party code, we expect you to test your code before each
11 11 major Mercurial release. This will prevent various bug reports from your users
12 12 when they upgrade their copy of Mercurial.
13 13
14 14 File Layout
15 15 ===========
16 16
17 17 Extensions are usually written as simple python modules. Larger ones are
18 18 better split into multiple modules of a single package (see the convert
19 19 extension). The package root module gives its name to the extension and
20 20 implements the ``cmdtable`` and optional callbacks described below.
21 21
22 22 Command table
23 23 =============
24 24
25 25 To write your own extension, your python module can provide an optional dict
26 26 named ``cmdtable`` with entries describing each command. A command should be
27 registered to the ``cmdtable`` by ``@command`` decorator.
27 registered to the ``cmdtable`` by ``@command`` decorator. All string-like
28 values must be the ``bytes`` type, and are thus prefixed with ``b``.
28 29
29 30 Example using ``@command`` decorator (requires Mercurial 1.9)::
30 31
31 32 from mercurial.i18n import _
32 33
33 34 cmdtable = {}
34 35 try:
35 36 from mercurial import registrar
36 37 command = registrar.command(cmdtable)
37 38 except (AttributeError, ImportError):
38 39 # Fallback to hg < 4.3 support
39 40 from mercurial import cmdutil
40 41 command = cmdutil.command(cmdtable)
41 42
42 @command('print-parents',
43 [('s', 'short', None, _('print short form')),
44 ('l', 'long', None, _('print long form'))],
45 _('[options] node'))
43 @command(b'print-parents',
44 [(b's', b'short', None, _(b'print short form')),
45 (b'l', b'long', None, _(b'print long form'))],
46 _(b'[options] node'))
46 47 def printparents(ui, repo, node, **opts):
47 48 ...
48 49
49 50 The cmdtable dictionary
50 51 -----------------------
51 52
52 53 The ``cmdtable`` dictionary uses as key the new command names, and, as value,
53 54 a tuple containing:
54 55
55 56 1. the function to be called when the command is used.
56 57 2. a list of options the command can take.
57 58 3. a command line synopsis for the command (the function docstring is used for
58 59 the full help).
59 60
60 61 List of options
61 62 ---------------
62 63
63 64 All the command flag options are documented in the mercurial/fancyopts.py
64 65 sources.
65 66
66 67 The options list is a list of tuples containing:
67 68
68 69 1. the short option letter, or ``''`` if no short option is available
69 70 (for example, ``o`` for a ``-o`` option).
70 71 2. the long option name (for example, ``option`` for a ``--option`` option).
71 72 3. a default value for the option.
72 73 4. a help string for the option (it's possible to omit the "hg newcommand"
73 74 part and only the options and parameter substring is needed).
74 75
75 76 Command function signatures
76 77 ---------------------------
77 78
78 79 Functions that implement new commands always receive a ``ui`` and usually
79 80 a ``repo`` parameter. The rest of parameters are taken from the command line
80 81 items that don't start with a dash and are passed in the same order they were
81 82 written. If no default value is given in the parameter list they are required.
82 83
83 84 If there is no repo to be associated with the command and consequently no
84 85 ``repo`` passed, then ``norepo=True`` should be passed to the ``@command``
85 86 decorator::
86 87
87 @command('mycommand', [], norepo=True)
88 @command(b'mycommand', [], norepo=True)
88 89 def mycommand(ui, **opts):
89 90 ...
90 91
91 92 For examples of ``norepo``, see the convert extension.
92 93
93 94 Command function docstrings
94 95 ===========================
95 96
96 97 The docstring of your function is used as the main help text, shown by
97 98 ``hg help mycommand``. The docstring should be formatted using a simple
98 99 subset of reStructuredText markup. The supported constructs include:
99 100
100 101 Paragraphs::
101 102
102 103 This is a paragraph.
103 104
104 105 Paragraphs are separated
105 106 by blank lines.
106 107
107 108 A verbatim block is introduced with a double colon followed by an indented
108 109 block. The double colon is turned into a single colon on display::
109 110
110 111 Some text::
111 112
112 113 verbatim
113 114 text
114 115 !!
115 116
116 117 We have field lists::
117 118
118 119 :key1: value1
119 120 :key2: value2
120 121
121 122 Bullet lists::
122 123
123 124 - foo
124 125 - bar
125 126
126 127 Enumerated lists::
127 128
128 129 1. foo
129 130 2. bar
130 131
131 132 Inline markup::
132 133
133 134 ``*bold*``, ``monospace``, :hg:`command`
134 135
135 136 Mark Mercurial commands with ``:hg:`` to make a nice link to the corresponding
136 137 documentation. We'll expand the support if new constructs can be parsed
137 138 without too much trouble.
138 139
139 140 Communicating with the user
140 141 ===========================
141 142
142 143 Besides the ``ui`` methods, like ``ui.write(*msg)`` or
143 ``ui.prompt(msg, default="y")``, an extension can add help text for each
144 ``ui.prompt(msg, default=b"y")``, an extension can add help text for each
144 145 of its commands and the extension itself.
145 146
146 147 The module docstring will be used as help string when ``hg help extensionname``
147 148 is used and, similarly, the help string for a command and the docstring
148 149 belonging to the function that's wrapped by the command will be shown when
149 150 ``hg help command`` is invoked.
150 151
151 152 Setup Callbacks
152 153 ===============
153 154
154 155 Extensions are loaded in phases. All extensions are processed in a given phase
155 156 before the next phase begins. In the first phase, all extension modules are
156 157 loaded and registered with Mercurial. This means that you can find all enabled
157 158 extensions with ``extensions.find`` in the following phases.
158 159
159 160 Extension setup
160 161 ---------------
161 162
162 163 There are two callbacks to be called when extensions are loaded, named
163 164 ``uisetup`` and ``extsetup``. ``uisetup`` is called first for each extension,
164 165 then ``extsetup`` is called. This means ``extsetup`` can be useful in case
165 166 one extension optionally depends on another extension.
166 167
167 168 Both ``uisetup`` and ``extsetup`` receive a ui object with the local
168 169 repository configuration::
169 170
170 171 def uisetup(ui):
171 172 # ...
172 173
173 174 def extsetup(ui):
174 175 # ...
175 176
176 177 Be aware that ``uisetup`` in NOT the function to configure a ``ui`` instance.
177 178 It's called only once per process, not per ``ui`` instance. Also, any changes
178 179 to the ``ui`` may be discarded because the ``ui`` here is a temporarily loaded
179 180 local configuration. So, it's generally wrong to do `ui.setconfig()` in
180 181 these callbacks. Notable exception is setting ``pre/post-<command>`` hooks
181 182 and extending ``ui.__class__``.
182 183
183 184 In Mercurial 1.3.1 or earlier, ``extsetup`` takes no argument.
184 185
185 186 Command table setup
186 187 -------------------
187 188
188 189 After ``extsetup``, the ``cmdtable`` is copied into the global command table
189 190 in Mercurial.
190 191
191 192 Ui instance setup
192 193 -----------------
193 194
194 195 The optional ``uipopulate`` is called for each ``ui`` instance after
195 196 configuration is loaded, where extensions can set up additional ui members,
196 197 update configuration by ``ui.setconfig()``, and extend the class dynamically.
197 198
198 199 Typically there are three ``ui`` instances involved in command execution:
199 200
200 201 ``req.ui`` (or ``repo.baseui``)
201 202 Only system and user configurations are loaded into it.
202 203 ``lui``
203 204 Local repository configuration is loaded as well. This will be used at
204 205 early dispatching stage where a repository isn't available.
205 206 ``repo.ui``
206 207 The fully-loaded ``ui`` used after a repository is instantiated. This
207 208 will be created from the ``req.ui`` per repository.
208 209
209 210 In command server and hgweb, this may be called more than once for the same
210 211 ``ui`` instance.
211 212
212 213 (New in Mercurial 4.9)
213 214
214 215 Repository setup
215 216 ----------------
216 217
217 218 Extensions can implement an optional callback named ``reposetup``. It is
218 219 called after the main Mercurial repository initialization, and can be used
219 220 to setup any local state the extension might need.
220 221
221 222 As other command functions it receives an ``ui`` object and a ``repo`` object
222 223 (no additional parameters for this, though)::
223 224
224 225 def reposetup(ui, repo):
225 226 #do initialization here.
226 227
227 228 It is important to take into account that the ``ui`` object that is received
228 229 by the ``reposetup`` function is not the same as the one received by the
229 230 ``uisetup`` and ``extsetup`` functions. This is particularly important when
230 231 setting up hooks as described in the following section, since not all hooks
231 232 use the same ``ui`` object and hence different hooks must be configured in
232 233 different setup functions.
233 234
234 235 Wrapping methods on the ui and repo classes
235 236 -------------------------------------------
236 237
237 238 Because extensions can be loaded *per repository*, you should avoid using
238 239 ``extensions.wrapfunction()`` on methods of the ``ui`` and ``repo`` objects.
239 240 Instead, create a subclass of the specific class of the instance passed into
240 241 the ``*setup()`` hook; e.g. use ``ui.__class__`` as the base class, then
241 242 reassign your new class to ``ui.__class__`` again. Mercurial will then use
242 243 your updated ``ui`` or ``repo`` instance only for repositories where your
243 244 extension is enabled (or copies thereof, reusing your new class).
244 245
245 246 For example::
246 247
247 248 def uisetup(ui):
248 249 class echologui(ui.__class__):
249 250 def log(self, service, *msg, **opts):
250 251 if msg:
251 self.write('%s: %s\n' % (service, msg[0] % msg[1:]))
252 self.write(b'%s: %s\n' % (service, msg[0] % msg[1:]))
252 253 super(echologui, self).log(service, *msg, **opts)
253 254
254 255 ui.__class__ = echologui
255 256
256 257 Configuring Hooks
257 258 =================
258 259
259 260 Some extensions must use hooks to do their work. These required hooks can
260 261 be configured manually by the user by modifying the ``[hook]`` section of
261 262 their hgrc, but they can also be configured automatically by calling the
262 ``ui.setconfig('hooks', ...)`` function in one of the setup functions
263 ``ui.setconfig(b'hooks', ...)`` function in one of the setup functions
263 264 described above.
264 265
265 266 The main difference between manually modifying the hooks section in the hgrc
266 267 and using ``ui.setconfig()`` is that when using ``ui.setconfig()`` you have
267 268 access to the actual hook function object, which you can pass directly to
268 269 ``ui.setconfig()``, while when you use the hooks section of the hgrc file
269 270 you must refer to the hook function by using the
270 271 ``python:modulename.functioname`` idiom (e.g. ``python:hgext.notify.hook``).
271 272
272 273 For example::
273 274
274 275 # Define hooks -- note that the actual function name it irrelevant.
275 276 def preupdatehook(ui, repo, **kwargs):
276 ui.write("Pre-update hook triggered\n")
277 ui.write(b"Pre-update hook triggered\n")
277 278
278 279 def updatehook(ui, repo, **kwargs):
279 ui.write("Update hook triggered\n")
280 ui.write(b"Update hook triggered\n")
280 281
281 282 def uisetup(ui):
282 283 # When pre-<cmd> and post-<cmd> hooks are configured by means of
283 284 # the ui.setconfig() function, you must use the ui object passed
284 285 # to uisetup or extsetup.
285 ui.setconfig("hooks", "pre-update.myextension", preupdatehook)
286 ui.setconfig(b"hooks", b"pre-update.myextension", preupdatehook)
286 287
287 288 def reposetup(ui, repo):
288 289 # Repository-specific hooks can be configured here. These include
289 290 # the update hook.
290 ui.setconfig("hooks", "update.myextension", updatehook)
291 ui.setconfig(b"hooks", b"update.myextension", updatehook)
291 292
292 293 Note how different hooks may need to be configured in different setup
293 294 functions. In the example you can see that the ``update`` hook must be
294 295 configured in the ``reposetup`` function, while the ``pre-update`` hook
295 296 must be configured on the ``uisetup`` or the ``extsetup`` functions.
296 297
297 298 Marking compatible versions
298 299 ===========================
299 300
300 301 Every extension should use the ``testedwith`` variable to specify Mercurial
301 302 releases it's known to be compatible with. This helps us and users diagnose
302 303 where problems are coming from::
303 304
304 testedwith = '2.0 2.0.1 2.1 2.1.1 2.1.2'
305 testedwith = b'2.0 2.0.1 2.1 2.1.1 2.1.2'
305 306
306 307 Do not use the ``internal`` marker in third-party extensions; we will
307 308 immediately drop all bug reports mentioning your extension if we catch you
308 309 doing this.
309 310
310 311 Similarly, an extension can use the ``buglink`` variable to specify how users
311 312 should report issues with the extension. This link will be included in the
312 313 error message if the extension produces errors::
313 314
314 buglink = 'https://bitbucket.org/USER/REPO/issues'
315 buglink = b'https://bitbucket.org/USER/REPO/issues'
315 316
316 317 If an extension requires a minimum version of Mercurial, it can be declared
317 318 with the ``minimumhgversion`` variable::
318 319
319 minimumhgversion = '4.6'
320 minimumhgversion = b'4.6'
320 321
321 322 Older clients will print a warning that the extension requires a new version,
322 323 instead of attempting to load it.
323 324
324 325 Wrap up: what belongs where?
325 326 ============================
326 327
327 328 You will find here a list of most common tasks, based on setups from the
328 329 extensions included in Mercurial core.
329 330
330 331 uisetup
331 332 -------
332 333
333 334 * Changes to ``ui.__class__`` . The ``ui`` object that will be used to run
334 335 the command has not yet been created. Changes made here will affect ``ui``
335 336 objects created after this, and in particular the ``ui`` that will be passed
336 337 to ``runcommand``
337 338 * Command wraps (``extensions.wrapcommand``)
338 339 * Changes that need to be visible by other extensions: because initialization
339 340 occurs in phases (all extensions run ``uisetup``, then all run ``extsetup``),
340 341 a change made here will be visible by other extensions during ``extsetup``.
341 342 * Monkeypatches or function wraps (``extensions.wrapfunction``) of ``dispatch``
342 343 module members
343 344 * Set up ``pre-*`` and ``post-*`` hooks. (DEPRECATED. ``uipopulate`` is
344 345 preferred on Mercurial 4.9 and later.)
345 346 * ``pushkey`` setup
346 347
347 348 extsetup
348 349 --------
349 350
350 * Changes depending on the status of other extensions. (``if extensions.find('mq')``)
351 * Changes depending on the status of other extensions. (``if extensions.find(b'mq')``)
351 352 * Add a global option to all commands
352 353 * Extend revsets
353 354
354 355 uipopulate
355 356 ----------
356 357
357 358 * Modify ``ui`` instance attributes and configuration variables.
358 359 * Changes to ``ui.__class__`` per instance.
359 360 * Set up all hooks per scoped configuration.
360 361
361 362 reposetup
362 363 ---------
363 364
364 365 * Set up all hooks but ``pre-*`` and ``post-*``. (DEPRECATED. ``uipopulate`` is
365 366 preferred on Mercurial 4.9 and later.)
366 367 * Modify configuration variables
367 368 * Changes to ``repo.__class__``, ``repo.dirstate.__class__``
General Comments 0
You need to be logged in to leave comments. Login now