##// END OF EJS Templates
test: make version based test-extensions failure more explanatory...
Pierre-Yves David -
r24257:31e9f668 default
parent child Browse files
Show More
@@ -1,1166 +1,1169
1 1 Test basic extension support
2 2
3 3 $ cat > foobar.py <<EOF
4 4 > import os
5 5 > from mercurial import cmdutil, commands
6 6 > cmdtable = {}
7 7 > command = cmdutil.command(cmdtable)
8 8 > def uisetup(ui):
9 9 > ui.write("uisetup called\\n")
10 10 > def reposetup(ui, repo):
11 11 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
12 12 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
13 13 > @command('foo', [], 'hg foo')
14 14 > def foo(ui, *args, **kwargs):
15 15 > ui.write("Foo\\n")
16 16 > @command('bar', [], 'hg bar', norepo=True)
17 17 > def bar(ui, *args, **kwargs):
18 18 > ui.write("Bar\\n")
19 19 > EOF
20 20 $ abspath=`pwd`/foobar.py
21 21
22 22 $ mkdir barfoo
23 23 $ cp foobar.py barfoo/__init__.py
24 24 $ barfoopath=`pwd`/barfoo
25 25
26 26 $ hg init a
27 27 $ cd a
28 28 $ echo foo > file
29 29 $ hg add file
30 30 $ hg commit -m 'add file'
31 31
32 32 $ echo '[extensions]' >> $HGRCPATH
33 33 $ echo "foobar = $abspath" >> $HGRCPATH
34 34 $ hg foo
35 35 uisetup called
36 36 reposetup called for a
37 37 ui == repo.ui
38 38 Foo
39 39
40 40 $ cd ..
41 41 $ hg clone a b
42 42 uisetup called
43 43 reposetup called for a
44 44 ui == repo.ui
45 45 reposetup called for b
46 46 ui == repo.ui
47 47 updating to branch default
48 48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 49
50 50 $ hg bar
51 51 uisetup called
52 52 Bar
53 53 $ echo 'foobar = !' >> $HGRCPATH
54 54
55 55 module/__init__.py-style
56 56
57 57 $ echo "barfoo = $barfoopath" >> $HGRCPATH
58 58 $ cd a
59 59 $ hg foo
60 60 uisetup called
61 61 reposetup called for a
62 62 ui == repo.ui
63 63 Foo
64 64 $ echo 'barfoo = !' >> $HGRCPATH
65 65
66 66 Check that extensions are loaded in phases:
67 67
68 68 $ cat > foo.py <<EOF
69 69 > import os
70 70 > name = os.path.basename(__file__).rsplit('.', 1)[0]
71 71 > print "1) %s imported" % name
72 72 > def uisetup(ui):
73 73 > print "2) %s uisetup" % name
74 74 > def extsetup():
75 75 > print "3) %s extsetup" % name
76 76 > def reposetup(ui, repo):
77 77 > print "4) %s reposetup" % name
78 78 > EOF
79 79
80 80 $ cp foo.py bar.py
81 81 $ echo 'foo = foo.py' >> $HGRCPATH
82 82 $ echo 'bar = bar.py' >> $HGRCPATH
83 83
84 84 Command with no output, we just want to see the extensions loaded:
85 85
86 86 $ hg paths
87 87 1) foo imported
88 88 1) bar imported
89 89 2) foo uisetup
90 90 2) bar uisetup
91 91 3) foo extsetup
92 92 3) bar extsetup
93 93 4) foo reposetup
94 94 4) bar reposetup
95 95
96 96 Check hgweb's load order:
97 97
98 98 $ cat > hgweb.cgi <<EOF
99 99 > #!/usr/bin/env python
100 100 > from mercurial import demandimport; demandimport.enable()
101 101 > from mercurial.hgweb import hgweb
102 102 > from mercurial.hgweb import wsgicgi
103 103 > application = hgweb('.', 'test repo')
104 104 > wsgicgi.launch(application)
105 105 > EOF
106 106
107 107 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
108 108 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
109 109 > | grep '^[0-9]) ' # ignores HTML output
110 110 1) foo imported
111 111 1) bar imported
112 112 2) foo uisetup
113 113 2) bar uisetup
114 114 3) foo extsetup
115 115 3) bar extsetup
116 116 4) foo reposetup
117 117 4) bar reposetup
118 118 4) foo reposetup
119 119 4) bar reposetup
120 120
121 121 $ echo 'foo = !' >> $HGRCPATH
122 122 $ echo 'bar = !' >> $HGRCPATH
123 123
124 124 Check "from __future__ import absolute_import" support for external libraries
125 125
126 126 #if windows
127 127 $ PATHSEP=";"
128 128 #else
129 129 $ PATHSEP=":"
130 130 #endif
131 131 $ export PATHSEP
132 132
133 133 $ mkdir $TESTTMP/libroot
134 134 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
135 135 $ mkdir $TESTTMP/libroot/mod
136 136 $ touch $TESTTMP/libroot/mod/__init__.py
137 137 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
138 138
139 139 #if absimport
140 140 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
141 141 > from __future__ import absolute_import
142 142 > import ambig # should load "libroot/ambig.py"
143 143 > s = ambig.s
144 144 > EOF
145 145 $ cat > loadabs.py <<EOF
146 146 > import mod.ambigabs as ambigabs
147 147 > def extsetup():
148 148 > print 'ambigabs.s=%s' % ambigabs.s
149 149 > EOF
150 150 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
151 151 ambigabs.s=libroot/ambig.py
152 152 $TESTTMP/a (glob)
153 153 #endif
154 154
155 155 #if no-py3k
156 156 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
157 157 > import ambig # should load "libroot/mod/ambig.py"
158 158 > s = ambig.s
159 159 > EOF
160 160 $ cat > loadrel.py <<EOF
161 161 > import mod.ambigrel as ambigrel
162 162 > def extsetup():
163 163 > print 'ambigrel.s=%s' % ambigrel.s
164 164 > EOF
165 165 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
166 166 ambigrel.s=libroot/mod/ambig.py
167 167 $TESTTMP/a (glob)
168 168 #endif
169 169
170 170 Check absolute/relative import of extension specific modules
171 171
172 172 $ mkdir $TESTTMP/extroot
173 173 $ cat > $TESTTMP/extroot/bar.py <<EOF
174 174 > s = 'this is extroot.bar'
175 175 > EOF
176 176 $ mkdir $TESTTMP/extroot/sub1
177 177 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
178 178 > s = 'this is extroot.sub1.__init__'
179 179 > EOF
180 180 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
181 181 > s = 'this is extroot.sub1.baz'
182 182 > EOF
183 183 $ cat > $TESTTMP/extroot/__init__.py <<EOF
184 184 > s = 'this is extroot.__init__'
185 185 > import foo
186 186 > def extsetup(ui):
187 187 > ui.write('(extroot) ', foo.func(), '\n')
188 188 > EOF
189 189
190 190 $ cat > $TESTTMP/extroot/foo.py <<EOF
191 191 > # test absolute import
192 192 > buf = []
193 193 > def func():
194 194 > # "not locals" case
195 195 > import extroot.bar
196 196 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
197 197 > return '\n(extroot) '.join(buf)
198 198 > # "fromlist == ('*',)" case
199 199 > from extroot.bar import *
200 200 > buf.append('from extroot.bar import *: %s' % s)
201 201 > # "not fromlist" and "if '.' in name" case
202 202 > import extroot.sub1.baz
203 203 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
204 204 > # "not fromlist" and NOT "if '.' in name" case
205 205 > import extroot
206 206 > buf.append('import extroot: %s' % extroot.s)
207 207 > # NOT "not fromlist" and NOT "level != -1" case
208 208 > from extroot.bar import s
209 209 > buf.append('from extroot.bar import s: %s' % s)
210 210 > EOF
211 211 $ hg --config extensions.extroot=$TESTTMP/extroot root
212 212 (extroot) from extroot.bar import *: this is extroot.bar
213 213 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
214 214 (extroot) import extroot: this is extroot.__init__
215 215 (extroot) from extroot.bar import s: this is extroot.bar
216 216 (extroot) import extroot.bar in func(): this is extroot.bar
217 217 $TESTTMP/a (glob)
218 218
219 219 #if no-py3k
220 220 $ rm "$TESTTMP"/extroot/foo.*
221 221 $ cat > $TESTTMP/extroot/foo.py <<EOF
222 222 > # test relative import
223 223 > buf = []
224 224 > def func():
225 225 > # "not locals" case
226 226 > import bar
227 227 > buf.append('import bar in func(): %s' % bar.s)
228 228 > return '\n(extroot) '.join(buf)
229 229 > # "fromlist == ('*',)" case
230 230 > from bar import *
231 231 > buf.append('from bar import *: %s' % s)
232 232 > # "not fromlist" and "if '.' in name" case
233 233 > import sub1.baz
234 234 > buf.append('import sub1.baz: %s' % sub1.baz.s)
235 235 > # "not fromlist" and NOT "if '.' in name" case
236 236 > import sub1
237 237 > buf.append('import sub1: %s' % sub1.s)
238 238 > # NOT "not fromlist" and NOT "level != -1" case
239 239 > from bar import s
240 240 > buf.append('from bar import s: %s' % s)
241 241 > EOF
242 242 $ hg --config extensions.extroot=$TESTTMP/extroot root
243 243 (extroot) from bar import *: this is extroot.bar
244 244 (extroot) import sub1.baz: this is extroot.sub1.baz
245 245 (extroot) import sub1: this is extroot.sub1.__init__
246 246 (extroot) from bar import s: this is extroot.bar
247 247 (extroot) import bar in func(): this is extroot.bar
248 248 $TESTTMP/a (glob)
249 249 #endif
250 250
251 251 $ cd ..
252 252
253 253 hide outer repo
254 254 $ hg init
255 255
256 256 $ cat > empty.py <<EOF
257 257 > '''empty cmdtable
258 258 > '''
259 259 > cmdtable = {}
260 260 > EOF
261 261 $ emptypath=`pwd`/empty.py
262 262 $ echo "empty = $emptypath" >> $HGRCPATH
263 263 $ hg help empty
264 264 empty extension - empty cmdtable
265 265
266 266 no commands defined
267 267
268 268
269 269 $ echo 'empty = !' >> $HGRCPATH
270 270
271 271 $ cat > debugextension.py <<EOF
272 272 > '''only debugcommands
273 273 > '''
274 274 > from mercurial import cmdutil
275 275 > cmdtable = {}
276 276 > command = cmdutil.command(cmdtable)
277 277 > @command('debugfoobar', [], 'hg debugfoobar')
278 278 > def debugfoobar(ui, repo, *args, **opts):
279 279 > "yet another debug command"
280 280 > pass
281 281 > @command('foo', [], 'hg foo')
282 282 > def foo(ui, repo, *args, **opts):
283 283 > """yet another foo command
284 284 > This command has been DEPRECATED since forever.
285 285 > """
286 286 > pass
287 287 > EOF
288 288 $ debugpath=`pwd`/debugextension.py
289 289 $ echo "debugextension = $debugpath" >> $HGRCPATH
290 290
291 291 $ hg help debugextension
292 292 debugextension extension - only debugcommands
293 293
294 294 no commands defined
295 295
296 296
297 297 $ hg --verbose help debugextension
298 298 debugextension extension - only debugcommands
299 299
300 300 list of commands:
301 301
302 302 foo yet another foo command
303 303
304 304 global options ([+] can be repeated):
305 305
306 306 -R --repository REPO repository root directory or name of overlay bundle
307 307 file
308 308 --cwd DIR change working directory
309 309 -y --noninteractive do not prompt, automatically pick the first choice for
310 310 all prompts
311 311 -q --quiet suppress output
312 312 -v --verbose enable additional output
313 313 --config CONFIG [+] set/override config option (use 'section.name=value')
314 314 --debug enable debugging output
315 315 --debugger start debugger
316 316 --encoding ENCODE set the charset encoding (default: ascii)
317 317 --encodingmode MODE set the charset encoding mode (default: strict)
318 318 --traceback always print a traceback on exception
319 319 --time time how long the command takes
320 320 --profile print command execution profile
321 321 --version output version information and exit
322 322 -h --help display help and exit
323 323 --hidden consider hidden changesets
324 324
325 325
326 326
327 327
328 328
329 329
330 330 $ hg --debug help debugextension
331 331 debugextension extension - only debugcommands
332 332
333 333 list of commands:
334 334
335 335 debugfoobar yet another debug command
336 336 foo yet another foo command
337 337
338 338 global options ([+] can be repeated):
339 339
340 340 -R --repository REPO repository root directory or name of overlay bundle
341 341 file
342 342 --cwd DIR change working directory
343 343 -y --noninteractive do not prompt, automatically pick the first choice for
344 344 all prompts
345 345 -q --quiet suppress output
346 346 -v --verbose enable additional output
347 347 --config CONFIG [+] set/override config option (use 'section.name=value')
348 348 --debug enable debugging output
349 349 --debugger start debugger
350 350 --encoding ENCODE set the charset encoding (default: ascii)
351 351 --encodingmode MODE set the charset encoding mode (default: strict)
352 352 --traceback always print a traceback on exception
353 353 --time time how long the command takes
354 354 --profile print command execution profile
355 355 --version output version information and exit
356 356 -h --help display help and exit
357 357 --hidden consider hidden changesets
358 358
359 359
360 360
361 361
362 362
363 363 $ echo 'debugextension = !' >> $HGRCPATH
364 364
365 365 Extension module help vs command help:
366 366
367 367 $ echo 'extdiff =' >> $HGRCPATH
368 368 $ hg help extdiff
369 369 hg extdiff [OPT]... [FILE]...
370 370
371 371 use external program to diff repository (or selected files)
372 372
373 373 Show differences between revisions for the specified files, using an
374 374 external program. The default program used is diff, with default options
375 375 "-Npru".
376 376
377 377 To select a different program, use the -p/--program option. The program
378 378 will be passed the names of two directories to compare. To pass additional
379 379 options to the program, use -o/--option. These will be passed before the
380 380 names of the directories to compare.
381 381
382 382 When two revision arguments are given, then changes are shown between
383 383 those revisions. If only one revision is specified then that revision is
384 384 compared to the working directory, and, when no revisions are specified,
385 385 the working directory files are compared to its parent.
386 386
387 387 (use "hg help -e extdiff" to show help for the extdiff extension)
388 388
389 389 options ([+] can be repeated):
390 390
391 391 -p --program CMD comparison program to run
392 392 -o --option OPT [+] pass option to comparison program
393 393 -r --rev REV [+] revision
394 394 -c --change REV change made by revision
395 395 -I --include PATTERN [+] include names matching the given patterns
396 396 -X --exclude PATTERN [+] exclude names matching the given patterns
397 397
398 398 (some details hidden, use --verbose to show complete help)
399 399
400 400
401 401
402 402
403 403
404 404
405 405
406 406
407 407
408 408
409 409 $ hg help --extension extdiff
410 410 extdiff extension - command to allow external programs to compare revisions
411 411
412 412 The extdiff Mercurial extension allows you to use external programs to compare
413 413 revisions, or revision with working directory. The external diff programs are
414 414 called with a configurable set of options and two non-option arguments: paths
415 415 to directories containing snapshots of files to compare.
416 416
417 417 The extdiff extension also allows you to configure new diff commands, so you
418 418 do not need to type "hg extdiff -p kdiff3" always.
419 419
420 420 [extdiff]
421 421 # add new command that runs GNU diff(1) in 'context diff' mode
422 422 cdiff = gdiff -Nprc5
423 423 ## or the old way:
424 424 #cmd.cdiff = gdiff
425 425 #opts.cdiff = -Nprc5
426 426
427 427 # add new command called meld, runs meld (no need to name twice). If
428 428 # the meld executable is not available, the meld tool in [merge-tools]
429 429 # will be used, if available
430 430 meld =
431 431
432 432 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
433 433 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
434 434 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
435 435 # your .vimrc
436 436 vimdiff = gvim -f "+next" \
437 437 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
438 438
439 439 Tool arguments can include variables that are expanded at runtime:
440 440
441 441 $parent1, $plabel1 - filename, descriptive label of first parent
442 442 $child, $clabel - filename, descriptive label of child revision
443 443 $parent2, $plabel2 - filename, descriptive label of second parent
444 444 $root - repository root
445 445 $parent is an alias for $parent1.
446 446
447 447 The extdiff extension will look in your [diff-tools] and [merge-tools]
448 448 sections for diff tool arguments, when none are specified in [extdiff].
449 449
450 450 [extdiff]
451 451 kdiff3 =
452 452
453 453 [diff-tools]
454 454 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
455 455
456 456 You can use -I/-X and list of file or directory names like normal "hg diff"
457 457 command. The extdiff extension makes snapshots of only needed files, so
458 458 running the external diff program will actually be pretty fast (at least
459 459 faster than having to compare the entire tree).
460 460
461 461 list of commands:
462 462
463 463 extdiff use external program to diff repository (or selected files)
464 464
465 465 (use "hg help -v -e extdiff" to show built-in aliases and global options)
466 466
467 467
468 468
469 469
470 470
471 471
472 472
473 473
474 474
475 475
476 476
477 477
478 478
479 479
480 480
481 481
482 482 $ echo 'extdiff = !' >> $HGRCPATH
483 483
484 484 Test help topic with same name as extension
485 485
486 486 $ cat > multirevs.py <<EOF
487 487 > from mercurial import cmdutil, commands
488 488 > cmdtable = {}
489 489 > command = cmdutil.command(cmdtable)
490 490 > """multirevs extension
491 491 > Big multi-line module docstring."""
492 492 > @command('multirevs', [], 'ARG', norepo=True)
493 493 > def multirevs(ui, repo, arg, *args, **opts):
494 494 > """multirevs command"""
495 495 > pass
496 496 > EOF
497 497 $ echo "multirevs = multirevs.py" >> $HGRCPATH
498 498
499 499 $ hg help multirevs
500 500 Specifying Multiple Revisions
501 501 """""""""""""""""""""""""""""
502 502
503 503 When Mercurial accepts more than one revision, they may be specified
504 504 individually, or provided as a topologically continuous range, separated
505 505 by the ":" character.
506 506
507 507 The syntax of range notation is [BEGIN]:[END], where BEGIN and END are
508 508 revision identifiers. Both BEGIN and END are optional. If BEGIN is not
509 509 specified, it defaults to revision number 0. If END is not specified, it
510 510 defaults to the tip. The range ":" thus means "all revisions".
511 511
512 512 If BEGIN is greater than END, revisions are treated in reverse order.
513 513
514 514 A range acts as a closed interval. This means that a range of 3:5 gives 3,
515 515 4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
516 516
517 517 use "hg help -c multirevs" to see help for the multirevs command
518 518
519 519
520 520
521 521
522 522
523 523
524 524 $ hg help -c multirevs
525 525 hg multirevs ARG
526 526
527 527 multirevs command
528 528
529 529 (some details hidden, use --verbose to show complete help)
530 530
531 531
532 532
533 533 $ hg multirevs
534 534 hg multirevs: invalid arguments
535 535 hg multirevs ARG
536 536
537 537 multirevs command
538 538
539 539 (use "hg multirevs -h" to show more help)
540 540 [255]
541 541
542 542
543 543
544 544 $ echo "multirevs = !" >> $HGRCPATH
545 545
546 546 Issue811: Problem loading extensions twice (by site and by user)
547 547
548 548 $ debugpath=`pwd`/debugissue811.py
549 549 $ cat > debugissue811.py <<EOF
550 550 > '''show all loaded extensions
551 551 > '''
552 552 > from mercurial import cmdutil, commands, extensions
553 553 > cmdtable = {}
554 554 > command = cmdutil.command(cmdtable)
555 555 > @command('debugextensions', [], 'hg debugextensions', norepo=True)
556 556 > def debugextensions(ui):
557 557 > "yet another debug command"
558 558 > ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
559 559 > EOF
560 560 $ cat <<EOF >> $HGRCPATH
561 561 > debugissue811 = $debugpath
562 562 > mq =
563 563 > strip =
564 564 > hgext.mq =
565 565 > hgext/mq =
566 566 > EOF
567 567
568 568 Show extensions:
569 569 (note that mq force load strip, also checking it's not loaded twice)
570 570
571 571 $ hg debugextensions
572 572 debugissue811
573 573 strip
574 574 mq
575 575
576 576 For extensions, which name matches one of its commands, help
577 577 message should ask '-v -e' to get list of built-in aliases
578 578 along with extension help itself
579 579
580 580 $ mkdir $TESTTMP/d
581 581 $ cat > $TESTTMP/d/dodo.py <<EOF
582 582 > """
583 583 > This is an awesome 'dodo' extension. It does nothing and
584 584 > writes 'Foo foo'
585 585 > """
586 586 > from mercurial import cmdutil, commands
587 587 > cmdtable = {}
588 588 > command = cmdutil.command(cmdtable)
589 589 > @command('dodo', [], 'hg dodo')
590 590 > def dodo(ui, *args, **kwargs):
591 591 > """Does nothing"""
592 592 > ui.write("I do nothing. Yay\\n")
593 593 > @command('foofoo', [], 'hg foofoo')
594 594 > def foofoo(ui, *args, **kwargs):
595 595 > """Writes 'Foo foo'"""
596 596 > ui.write("Foo foo\\n")
597 597 > EOF
598 598 $ dodopath=$TESTTMP/d/dodo.py
599 599
600 600 $ echo "dodo = $dodopath" >> $HGRCPATH
601 601
602 602 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
603 603 $ hg help -e dodo
604 604 dodo extension -
605 605
606 606 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
607 607
608 608 list of commands:
609 609
610 610 dodo Does nothing
611 611 foofoo Writes 'Foo foo'
612 612
613 613 (use "hg help -v -e dodo" to show built-in aliases and global options)
614 614
615 615 Make sure that '-v -e' prints list of built-in aliases along with
616 616 extension help itself
617 617 $ hg help -v -e dodo
618 618 dodo extension -
619 619
620 620 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
621 621
622 622 list of commands:
623 623
624 624 dodo Does nothing
625 625 foofoo Writes 'Foo foo'
626 626
627 627 global options ([+] can be repeated):
628 628
629 629 -R --repository REPO repository root directory or name of overlay bundle
630 630 file
631 631 --cwd DIR change working directory
632 632 -y --noninteractive do not prompt, automatically pick the first choice for
633 633 all prompts
634 634 -q --quiet suppress output
635 635 -v --verbose enable additional output
636 636 --config CONFIG [+] set/override config option (use 'section.name=value')
637 637 --debug enable debugging output
638 638 --debugger start debugger
639 639 --encoding ENCODE set the charset encoding (default: ascii)
640 640 --encodingmode MODE set the charset encoding mode (default: strict)
641 641 --traceback always print a traceback on exception
642 642 --time time how long the command takes
643 643 --profile print command execution profile
644 644 --version output version information and exit
645 645 -h --help display help and exit
646 646 --hidden consider hidden changesets
647 647
648 648 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
649 649 $ hg help -v dodo
650 650 hg dodo
651 651
652 652 Does nothing
653 653
654 654 (use "hg help -e dodo" to show help for the dodo extension)
655 655
656 656 options:
657 657
658 658 --mq operate on patch repository
659 659
660 660 global options ([+] can be repeated):
661 661
662 662 -R --repository REPO repository root directory or name of overlay bundle
663 663 file
664 664 --cwd DIR change working directory
665 665 -y --noninteractive do not prompt, automatically pick the first choice for
666 666 all prompts
667 667 -q --quiet suppress output
668 668 -v --verbose enable additional output
669 669 --config CONFIG [+] set/override config option (use 'section.name=value')
670 670 --debug enable debugging output
671 671 --debugger start debugger
672 672 --encoding ENCODE set the charset encoding (default: ascii)
673 673 --encodingmode MODE set the charset encoding mode (default: strict)
674 674 --traceback always print a traceback on exception
675 675 --time time how long the command takes
676 676 --profile print command execution profile
677 677 --version output version information and exit
678 678 -h --help display help and exit
679 679 --hidden consider hidden changesets
680 680
681 681 In case when extension name doesn't match any of its commands,
682 682 help message should ask for '-v' to get list of built-in aliases
683 683 along with extension help
684 684 $ cat > $TESTTMP/d/dudu.py <<EOF
685 685 > """
686 686 > This is an awesome 'dudu' extension. It does something and
687 687 > also writes 'Beep beep'
688 688 > """
689 689 > from mercurial import cmdutil, commands
690 690 > cmdtable = {}
691 691 > command = cmdutil.command(cmdtable)
692 692 > @command('something', [], 'hg something')
693 693 > def something(ui, *args, **kwargs):
694 694 > """Does something"""
695 695 > ui.write("I do something. Yaaay\\n")
696 696 > @command('beep', [], 'hg beep')
697 697 > def beep(ui, *args, **kwargs):
698 698 > """Writes 'Beep beep'"""
699 699 > ui.write("Beep beep\\n")
700 700 > EOF
701 701 $ dudupath=$TESTTMP/d/dudu.py
702 702
703 703 $ echo "dudu = $dudupath" >> $HGRCPATH
704 704
705 705 $ hg help -e dudu
706 706 dudu extension -
707 707
708 708 This is an awesome 'dudu' extension. It does something and also writes 'Beep
709 709 beep'
710 710
711 711 list of commands:
712 712
713 713 beep Writes 'Beep beep'
714 714 something Does something
715 715
716 716 (use "hg help -v dudu" to show built-in aliases and global options)
717 717
718 718 In case when extension name doesn't match any of its commands,
719 719 help options '-v' and '-v -e' should be equivalent
720 720 $ hg help -v dudu
721 721 dudu extension -
722 722
723 723 This is an awesome 'dudu' extension. It does something and also writes 'Beep
724 724 beep'
725 725
726 726 list of commands:
727 727
728 728 beep Writes 'Beep beep'
729 729 something Does something
730 730
731 731 global options ([+] can be repeated):
732 732
733 733 -R --repository REPO repository root directory or name of overlay bundle
734 734 file
735 735 --cwd DIR change working directory
736 736 -y --noninteractive do not prompt, automatically pick the first choice for
737 737 all prompts
738 738 -q --quiet suppress output
739 739 -v --verbose enable additional output
740 740 --config CONFIG [+] set/override config option (use 'section.name=value')
741 741 --debug enable debugging output
742 742 --debugger start debugger
743 743 --encoding ENCODE set the charset encoding (default: ascii)
744 744 --encodingmode MODE set the charset encoding mode (default: strict)
745 745 --traceback always print a traceback on exception
746 746 --time time how long the command takes
747 747 --profile print command execution profile
748 748 --version output version information and exit
749 749 -h --help display help and exit
750 750 --hidden consider hidden changesets
751 751
752 752 $ hg help -v -e dudu
753 753 dudu extension -
754 754
755 755 This is an awesome 'dudu' extension. It does something and also writes 'Beep
756 756 beep'
757 757
758 758 list of commands:
759 759
760 760 beep Writes 'Beep beep'
761 761 something Does something
762 762
763 763 global options ([+] can be repeated):
764 764
765 765 -R --repository REPO repository root directory or name of overlay bundle
766 766 file
767 767 --cwd DIR change working directory
768 768 -y --noninteractive do not prompt, automatically pick the first choice for
769 769 all prompts
770 770 -q --quiet suppress output
771 771 -v --verbose enable additional output
772 772 --config CONFIG [+] set/override config option (use 'section.name=value')
773 773 --debug enable debugging output
774 774 --debugger start debugger
775 775 --encoding ENCODE set the charset encoding (default: ascii)
776 776 --encodingmode MODE set the charset encoding mode (default: strict)
777 777 --traceback always print a traceback on exception
778 778 --time time how long the command takes
779 779 --profile print command execution profile
780 780 --version output version information and exit
781 781 -h --help display help and exit
782 782 --hidden consider hidden changesets
783 783
784 784 Disabled extension commands:
785 785
786 786 $ ORGHGRCPATH=$HGRCPATH
787 787 $ HGRCPATH=
788 788 $ export HGRCPATH
789 789 $ hg help email
790 790 'email' is provided by the following extension:
791 791
792 792 patchbomb command to send changesets as (a series of) patch emails
793 793
794 794 (use "hg help extensions" for information on enabling extensions)
795 795
796 796
797 797 $ hg qdel
798 798 hg: unknown command 'qdel'
799 799 'qdelete' is provided by the following extension:
800 800
801 801 mq manage a stack of patches
802 802
803 803 (use "hg help extensions" for information on enabling extensions)
804 804 [255]
805 805
806 806
807 807 $ hg churn
808 808 hg: unknown command 'churn'
809 809 'churn' is provided by the following extension:
810 810
811 811 churn command to display statistics about repository history
812 812
813 813 (use "hg help extensions" for information on enabling extensions)
814 814 [255]
815 815
816 816
817 817
818 818 Disabled extensions:
819 819
820 820 $ hg help churn
821 821 churn extension - command to display statistics about repository history
822 822
823 823 (use "hg help extensions" for information on enabling extensions)
824 824
825 825 $ hg help patchbomb
826 826 patchbomb extension - command to send changesets as (a series of) patch emails
827 827
828 828 (use "hg help extensions" for information on enabling extensions)
829 829
830 830
831 831 Broken disabled extension and command:
832 832
833 833 $ mkdir hgext
834 834 $ echo > hgext/__init__.py
835 835 $ cat > hgext/broken.py <<EOF
836 836 > "broken extension'
837 837 > EOF
838 838 $ cat > path.py <<EOF
839 839 > import os, sys
840 840 > sys.path.insert(0, os.environ['HGEXTPATH'])
841 841 > EOF
842 842 $ HGEXTPATH=`pwd`
843 843 $ export HGEXTPATH
844 844
845 845 $ hg --config extensions.path=./path.py help broken
846 846 broken extension - (no help text available)
847 847
848 848 (use "hg help extensions" for information on enabling extensions)
849 849
850 850
851 851 $ cat > hgext/forest.py <<EOF
852 852 > cmdtable = None
853 853 > EOF
854 854 $ hg --config extensions.path=./path.py help foo > /dev/null
855 855 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
856 856 abort: no such help topic: foo
857 857 (try "hg help --keyword foo")
858 858 [255]
859 859
860 860 $ cat > throw.py <<EOF
861 861 > from mercurial import cmdutil, commands, util
862 862 > cmdtable = {}
863 863 > command = cmdutil.command(cmdtable)
864 864 > class Bogon(Exception): pass
865 865 > @command('throw', [], 'hg throw', norepo=True)
866 866 > def throw(ui, **opts):
867 867 > """throws an exception"""
868 868 > raise Bogon()
869 869 > EOF
870 870
871 871 No declared supported version, extension complains:
872 872 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
873 873 ** Unknown exception encountered with possibly-broken third-party extension throw
874 874 ** which supports versions unknown of Mercurial.
875 875 ** Please disable throw and try your action again.
876 876 ** If that fixes the bug please report it to the extension author.
877 877 ** Python * (glob)
878 878 ** Mercurial Distributed SCM * (glob)
879 879 ** Extensions loaded: throw
880 880
881 881 empty declaration of supported version, extension complains:
882 882 $ echo "testedwith = ''" >> throw.py
883 883 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
884 884 ** Unknown exception encountered with possibly-broken third-party extension throw
885 885 ** which supports versions unknown of Mercurial.
886 886 ** Please disable throw and try your action again.
887 887 ** If that fixes the bug please report it to the extension author.
888 888 ** Python * (glob)
889 889 ** Mercurial Distributed SCM (*) (glob)
890 890 ** Extensions loaded: throw
891 891
892 892 If the extension specifies a buglink, show that:
893 893 $ echo 'buglink = "http://example.com/bts"' >> throw.py
894 894 $ rm -f throw.pyc throw.pyo
895 895 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
896 896 ** Unknown exception encountered with possibly-broken third-party extension throw
897 897 ** which supports versions unknown of Mercurial.
898 898 ** Please disable throw and try your action again.
899 899 ** If that fixes the bug please report it to http://example.com/bts
900 900 ** Python * (glob)
901 901 ** Mercurial Distributed SCM (*) (glob)
902 902 ** Extensions loaded: throw
903 903
904 904 If the extensions declare outdated versions, accuse the older extension first:
905 905 $ echo "from mercurial import util" >> older.py
906 906 $ echo "util.version = lambda:'2.2'" >> older.py
907 907 $ echo "testedwith = '1.9.3'" >> older.py
908 908 $ echo "testedwith = '2.1.1'" >> throw.py
909 909 $ rm -f throw.pyc throw.pyo
910 910 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
911 911 > throw 2>&1 | egrep '^\*\*'
912 912 ** Unknown exception encountered with possibly-broken third-party extension older
913 913 ** which supports versions 1.9 of Mercurial.
914 914 ** Please disable older and try your action again.
915 915 ** If that fixes the bug please report it to the extension author.
916 916 ** Python * (glob)
917 917 ** Mercurial Distributed SCM (version 2.2)
918 918 ** Extensions loaded: throw, older
919 919
920 920 One extension only tested with older, one only with newer versions:
921 921 $ echo "util.version = lambda:'2.1'" >> older.py
922 922 $ rm -f older.pyc older.pyo
923 923 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
924 924 > throw 2>&1 | egrep '^\*\*'
925 925 ** Unknown exception encountered with possibly-broken third-party extension older
926 926 ** which supports versions 1.9 of Mercurial.
927 927 ** Please disable older and try your action again.
928 928 ** If that fixes the bug please report it to the extension author.
929 929 ** Python * (glob)
930 930 ** Mercurial Distributed SCM (version 2.1)
931 931 ** Extensions loaded: throw, older
932 932
933 933 Older extension is tested with current version, the other only with newer:
934 934 $ echo "util.version = lambda:'1.9.3'" >> older.py
935 935 $ rm -f older.pyc older.pyo
936 936 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
937 937 > throw 2>&1 | egrep '^\*\*'
938 938 ** Unknown exception encountered with possibly-broken third-party extension throw
939 939 ** which supports versions 2.1 of Mercurial.
940 940 ** Please disable throw and try your action again.
941 941 ** If that fixes the bug please report it to http://example.com/bts
942 942 ** Python * (glob)
943 943 ** Mercurial Distributed SCM (version 1.9.3)
944 944 ** Extensions loaded: throw, older
945 945
946 946 Declare the version as supporting this hg version, show regular bts link:
947 947 $ hgver=`$PYTHON -c 'from mercurial import util; print util.version().split("+")[0]'`
948 948 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
949 $ if [ -z "$hgver" ]; then
950 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
951 > fi
949 952 $ rm -f throw.pyc throw.pyo
950 953 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
951 954 ** unknown exception encountered, please report by visiting
952 955 ** http://mercurial.selenic.com/wiki/BugTracker
953 956 ** Python * (glob)
954 957 ** Mercurial Distributed SCM (*) (glob)
955 958 ** Extensions loaded: throw
956 959
957 960 Patch version is ignored during compatibility check
958 961 $ echo "testedwith = '3.2'" >> throw.py
959 962 $ echo "util.version = lambda:'3.2.2'" >> throw.py
960 963 $ rm -f throw.pyc throw.pyo
961 964 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
962 965 ** unknown exception encountered, please report by visiting
963 966 ** http://mercurial.selenic.com/wiki/BugTracker
964 967 ** Python * (glob)
965 968 ** Mercurial Distributed SCM (*) (glob)
966 969 ** Extensions loaded: throw
967 970
968 971 Test version number support in 'hg version':
969 972 $ echo '__version__ = (1, 2, 3)' >> throw.py
970 973 $ rm -f throw.pyc throw.pyo
971 974 $ hg version -v
972 975 Mercurial Distributed SCM (version *) (glob)
973 976 (see http://mercurial.selenic.com for more information)
974 977
975 978 Copyright (C) 2005-* Matt Mackall and others (glob)
976 979 This is free software; see the source for copying conditions. There is NO
977 980 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
978 981
979 982 Enabled extensions:
980 983
981 984
982 985 $ hg version -v --config extensions.throw=throw.py
983 986 Mercurial Distributed SCM (version *) (glob)
984 987 (see http://mercurial.selenic.com for more information)
985 988
986 989 Copyright (C) 2005-* Matt Mackall and others (glob)
987 990 This is free software; see the source for copying conditions. There is NO
988 991 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
989 992
990 993 Enabled extensions:
991 994
992 995 throw 1.2.3
993 996 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
994 997 $ rm -f throw.pyc throw.pyo
995 998 $ hg version -v --config extensions.throw=throw.py
996 999 Mercurial Distributed SCM (version *) (glob)
997 1000 (see http://mercurial.selenic.com for more information)
998 1001
999 1002 Copyright (C) 2005-* Matt Mackall and others (glob)
1000 1003 This is free software; see the source for copying conditions. There is NO
1001 1004 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1002 1005
1003 1006 Enabled extensions:
1004 1007
1005 1008 throw 1.twentythree
1006 1009
1007 1010 Restore HGRCPATH
1008 1011
1009 1012 $ HGRCPATH=$ORGHGRCPATH
1010 1013 $ export HGRCPATH
1011 1014
1012 1015 Commands handling multiple repositories at a time should invoke only
1013 1016 "reposetup()" of extensions enabling in the target repository.
1014 1017
1015 1018 $ mkdir reposetup-test
1016 1019 $ cd reposetup-test
1017 1020
1018 1021 $ cat > $TESTTMP/reposetuptest.py <<EOF
1019 1022 > from mercurial import extensions
1020 1023 > def reposetup(ui, repo):
1021 1024 > ui.write('reposetup() for %s\n' % (repo.root))
1022 1025 > EOF
1023 1026 $ hg init src
1024 1027 $ echo a > src/a
1025 1028 $ hg -R src commit -Am '#0 at src/a'
1026 1029 adding a
1027 1030 $ echo '[extensions]' >> src/.hg/hgrc
1028 1031 $ echo '# enable extension locally' >> src/.hg/hgrc
1029 1032 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1030 1033 $ hg -R src status
1031 1034 reposetup() for $TESTTMP/reposetup-test/src (glob)
1032 1035
1033 1036 $ hg clone -U src clone-dst1
1034 1037 reposetup() for $TESTTMP/reposetup-test/src (glob)
1035 1038 $ hg init push-dst1
1036 1039 $ hg -q -R src push push-dst1
1037 1040 reposetup() for $TESTTMP/reposetup-test/src (glob)
1038 1041 $ hg init pull-src1
1039 1042 $ hg -q -R pull-src1 pull src
1040 1043 reposetup() for $TESTTMP/reposetup-test/src (glob)
1041 1044
1042 1045 $ cat <<EOF >> $HGRCPATH
1043 1046 > [extensions]
1044 1047 > # disable extension globally and explicitly
1045 1048 > reposetuptest = !
1046 1049 > EOF
1047 1050 $ hg clone -U src clone-dst2
1048 1051 reposetup() for $TESTTMP/reposetup-test/src (glob)
1049 1052 $ hg init push-dst2
1050 1053 $ hg -q -R src push push-dst2
1051 1054 reposetup() for $TESTTMP/reposetup-test/src (glob)
1052 1055 $ hg init pull-src2
1053 1056 $ hg -q -R pull-src2 pull src
1054 1057 reposetup() for $TESTTMP/reposetup-test/src (glob)
1055 1058
1056 1059 $ cat <<EOF >> $HGRCPATH
1057 1060 > [extensions]
1058 1061 > # enable extension globally
1059 1062 > reposetuptest = $TESTTMP/reposetuptest.py
1060 1063 > EOF
1061 1064 $ hg clone -U src clone-dst3
1062 1065 reposetup() for $TESTTMP/reposetup-test/src (glob)
1063 1066 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1064 1067 $ hg init push-dst3
1065 1068 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1066 1069 $ hg -q -R src push push-dst3
1067 1070 reposetup() for $TESTTMP/reposetup-test/src (glob)
1068 1071 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1069 1072 $ hg init pull-src3
1070 1073 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1071 1074 $ hg -q -R pull-src3 pull src
1072 1075 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1073 1076 reposetup() for $TESTTMP/reposetup-test/src (glob)
1074 1077
1075 1078 $ echo '[extensions]' >> src/.hg/hgrc
1076 1079 $ echo '# disable extension locally' >> src/.hg/hgrc
1077 1080 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1078 1081 $ hg clone -U src clone-dst4
1079 1082 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1080 1083 $ hg init push-dst4
1081 1084 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1082 1085 $ hg -q -R src push push-dst4
1083 1086 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1084 1087 $ hg init pull-src4
1085 1088 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1086 1089 $ hg -q -R pull-src4 pull src
1087 1090 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1088 1091
1089 1092 disabling in command line overlays with all configuration
1090 1093 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1091 1094 $ hg --config extensions.reposetuptest=! init push-dst5
1092 1095 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1093 1096 $ hg --config extensions.reposetuptest=! init pull-src5
1094 1097 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1095 1098
1096 1099 $ cat <<EOF >> $HGRCPATH
1097 1100 > [extensions]
1098 1101 > # disable extension globally and explicitly
1099 1102 > reposetuptest = !
1100 1103 > EOF
1101 1104 $ hg init parent
1102 1105 $ hg init parent/sub1
1103 1106 $ echo 1 > parent/sub1/1
1104 1107 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1105 1108 adding 1
1106 1109 $ hg init parent/sub2
1107 1110 $ hg init parent/sub2/sub21
1108 1111 $ echo 21 > parent/sub2/sub21/21
1109 1112 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1110 1113 adding 21
1111 1114 $ cat > parent/sub2/.hgsub <<EOF
1112 1115 > sub21 = sub21
1113 1116 > EOF
1114 1117 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1115 1118 adding .hgsub
1116 1119 $ hg init parent/sub3
1117 1120 $ echo 3 > parent/sub3/3
1118 1121 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1119 1122 adding 3
1120 1123 $ cat > parent/.hgsub <<EOF
1121 1124 > sub1 = sub1
1122 1125 > sub2 = sub2
1123 1126 > sub3 = sub3
1124 1127 > EOF
1125 1128 $ hg -R parent commit -Am '#0 at parent'
1126 1129 adding .hgsub
1127 1130 $ echo '[extensions]' >> parent/.hg/hgrc
1128 1131 $ echo '# enable extension locally' >> parent/.hg/hgrc
1129 1132 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1130 1133 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1131 1134 $ hg -R parent status -S -A
1132 1135 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1133 1136 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1134 1137 C .hgsub
1135 1138 C .hgsubstate
1136 1139 C sub1/1
1137 1140 C sub2/.hgsub
1138 1141 C sub2/.hgsubstate
1139 1142 C sub2/sub21/21
1140 1143 C sub3/3
1141 1144
1142 1145 $ cd ..
1143 1146
1144 1147 Test synopsis and docstring extending
1145 1148
1146 1149 $ hg init exthelp
1147 1150 $ cat > exthelp.py <<EOF
1148 1151 > from mercurial import commands, extensions
1149 1152 > def exbookmarks(orig, *args, **opts):
1150 1153 > return orig(*args, **opts)
1151 1154 > def uisetup(ui):
1152 1155 > synopsis = ' GREPME [--foo] [-x]'
1153 1156 > docstring = '''
1154 1157 > GREPME make sure that this is in the help!
1155 1158 > '''
1156 1159 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1157 1160 > synopsis, docstring)
1158 1161 > EOF
1159 1162 $ abspath=`pwd`/exthelp.py
1160 1163 $ echo '[extensions]' >> $HGRCPATH
1161 1164 $ echo "exthelp = $abspath" >> $HGRCPATH
1162 1165 $ cd exthelp
1163 1166 $ hg help bookmarks | grep GREPME
1164 1167 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1165 1168 GREPME make sure that this is in the help!
1166 1169
General Comments 0
You need to be logged in to leave comments. Login now