tests/test-extension.t
changeset 21849 a3306b8cdc0f
parent 21773 26d2fb899637
child 21937 54ff2789d75e
equal deleted inserted replaced
21848:ecdbbb6e5d06 21849:a3306b8cdc0f
     1 Test basic extension support
     1 Test basic extension support
     2 
     2 
     3   $ cat > foobar.py <<EOF
     3   $ cat > foobar.py <<EOF
     4   > import os
     4   > import os
     5   > from mercurial import cmdutil, commands
     5   > from mercurial import cmdutil, commands
     6   > 
       
     7   > cmdtable = {}
     6   > cmdtable = {}
     8   > command = cmdutil.command(cmdtable)
     7   > command = cmdutil.command(cmdtable)
     9   > 
       
    10   > def uisetup(ui):
     8   > def uisetup(ui):
    11   >     ui.write("uisetup called\\n")
     9   >     ui.write("uisetup called\\n")
    12   > 
       
    13   > def reposetup(ui, repo):
    10   > def reposetup(ui, repo):
    14   >     ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
    11   >     ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
    15   >     ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
    12   >     ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
    16   > 
       
    17   > @command('foo', [], 'hg foo')
    13   > @command('foo', [], 'hg foo')
    18   > def foo(ui, *args, **kwargs):
    14   > def foo(ui, *args, **kwargs):
    19   >     ui.write("Foo\\n")
    15   >     ui.write("Foo\\n")
    20   > 
       
    21   > @command('bar', [], 'hg bar', norepo=True)
    16   > @command('bar', [], 'hg bar', norepo=True)
    22   > def bar(ui, *args, **kwargs):
    17   > def bar(ui, *args, **kwargs):
    23   >     ui.write("Bar\\n")
    18   >     ui.write("Bar\\n")
    24   > 
       
    25   > EOF
    19   > EOF
    26   $ abspath=`pwd`/foobar.py
    20   $ abspath=`pwd`/foobar.py
    27 
    21 
    28   $ mkdir barfoo
    22   $ mkdir barfoo
    29   $ cp foobar.py barfoo/__init__.py
    23   $ cp foobar.py barfoo/__init__.py
   104   $ cat > hgweb.cgi <<EOF
    98   $ cat > hgweb.cgi <<EOF
   105   > #!/usr/bin/env python
    99   > #!/usr/bin/env python
   106   > from mercurial import demandimport; demandimport.enable()
   100   > from mercurial import demandimport; demandimport.enable()
   107   > from mercurial.hgweb import hgweb
   101   > from mercurial.hgweb import hgweb
   108   > from mercurial.hgweb import wsgicgi
   102   > from mercurial.hgweb import wsgicgi
   109   > 
       
   110   > application = hgweb('.', 'test repo')
   103   > application = hgweb('.', 'test repo')
   111   > wsgicgi.launch(application)
   104   > wsgicgi.launch(application)
   112   > EOF
   105   > EOF
   113 
   106 
   114   $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
   107   $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
   199   > buf = []
   192   > buf = []
   200   > def func():
   193   > def func():
   201   >     # "not locals" case
   194   >     # "not locals" case
   202   >     import extroot.bar
   195   >     import extroot.bar
   203   >     buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
   196   >     buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
   204   > 
       
   205   >     return '\n(extroot) '.join(buf)
   197   >     return '\n(extroot) '.join(buf)
   206   > 
       
   207   > # "fromlist == ('*',)" case
   198   > # "fromlist == ('*',)" case
   208   > from extroot.bar import *
   199   > from extroot.bar import *
   209   > buf.append('from extroot.bar import *: %s' % s)
   200   > buf.append('from extroot.bar import *: %s' % s)
   210   > 
       
   211   > # "not fromlist" and "if '.' in name" case
   201   > # "not fromlist" and "if '.' in name" case
   212   > import extroot.sub1.baz
   202   > import extroot.sub1.baz
   213   > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
   203   > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
   214   > 
       
   215   > # "not fromlist" and NOT "if '.' in name" case
   204   > # "not fromlist" and NOT "if '.' in name" case
   216   > import extroot
   205   > import extroot
   217   > buf.append('import extroot: %s' % extroot.s)
   206   > buf.append('import extroot: %s' % extroot.s)
   218   > 
       
   219   > # NOT "not fromlist" and NOT "level != -1" case
   207   > # NOT "not fromlist" and NOT "level != -1" case
   220   > from extroot.bar import s
   208   > from extroot.bar import s
   221   > buf.append('from extroot.bar import s: %s' % s)
   209   > buf.append('from extroot.bar import s: %s' % s)
   222   > EOF
   210   > EOF
   223   $ hg --config extensions.extroot=$TESTTMP/extroot root
   211   $ hg --config extensions.extroot=$TESTTMP/extroot root
   235   > buf = []
   223   > buf = []
   236   > def func():
   224   > def func():
   237   >     # "not locals" case
   225   >     # "not locals" case
   238   >     import bar
   226   >     import bar
   239   >     buf.append('import bar in func(): %s' % bar.s)
   227   >     buf.append('import bar in func(): %s' % bar.s)
   240   > 
       
   241   >     return '\n(extroot) '.join(buf)
   228   >     return '\n(extroot) '.join(buf)
   242   > 
       
   243   > # "fromlist == ('*',)" case
   229   > # "fromlist == ('*',)" case
   244   > from bar import *
   230   > from bar import *
   245   > buf.append('from bar import *: %s' % s)
   231   > buf.append('from bar import *: %s' % s)
   246   > 
       
   247   > # "not fromlist" and "if '.' in name" case
   232   > # "not fromlist" and "if '.' in name" case
   248   > import sub1.baz
   233   > import sub1.baz
   249   > buf.append('import sub1.baz: %s' % sub1.baz.s)
   234   > buf.append('import sub1.baz: %s' % sub1.baz.s)
   250   > 
       
   251   > # "not fromlist" and NOT "if '.' in name" case
   235   > # "not fromlist" and NOT "if '.' in name" case
   252   > import sub1
   236   > import sub1
   253   > buf.append('import sub1: %s' % sub1.s)
   237   > buf.append('import sub1: %s' % sub1.s)
   254   > 
       
   255   > # NOT "not fromlist" and NOT "level != -1" case
   238   > # NOT "not fromlist" and NOT "level != -1" case
   256   > from bar import s
   239   > from bar import s
   257   > buf.append('from bar import s: %s' % s)
   240   > buf.append('from bar import s: %s' % s)
   258   > EOF
   241   > EOF
   259   $ hg --config extensions.extroot=$TESTTMP/extroot root
   242   $ hg --config extensions.extroot=$TESTTMP/extroot root
   280   $ hg help empty
   263   $ hg help empty
   281   empty extension - empty cmdtable
   264   empty extension - empty cmdtable
   282   
   265   
   283   no commands defined
   266   no commands defined
   284 
   267 
       
   268 
   285   $ echo 'empty = !' >> $HGRCPATH
   269   $ echo 'empty = !' >> $HGRCPATH
   286 
   270 
   287   $ cat > debugextension.py <<EOF
   271   $ cat > debugextension.py <<EOF
   288   > '''only debugcommands
   272   > '''only debugcommands
   289   > '''
   273   > '''
   290   > from mercurial import cmdutil
   274   > from mercurial import cmdutil
   291   > cmdtable = {}
   275   > cmdtable = {}
   292   > command = cmdutil.command(cmdtable)
   276   > command = cmdutil.command(cmdtable)
   293   > 
       
   294   > @command('debugfoobar', [], 'hg debugfoobar')
   277   > @command('debugfoobar', [], 'hg debugfoobar')
   295   > def debugfoobar(ui, repo, *args, **opts):
   278   > def debugfoobar(ui, repo, *args, **opts):
   296   >     "yet another debug command"
   279   >     "yet another debug command"
   297   >     pass
   280   >     pass
   298   > 
       
   299   > @command('foo', [], 'hg foo')
   281   > @command('foo', [], 'hg foo')
   300   > def foo(ui, repo, *args, **opts):
   282   > def foo(ui, repo, *args, **opts):
   301   >     """yet another foo command
   283   >     """yet another foo command
   302   > 
       
   303   >     This command has been DEPRECATED since forever.
   284   >     This command has been DEPRECATED since forever.
   304   >     """
   285   >     """
   305   >     pass
   286   >     pass
   306   > EOF
   287   > EOF
   307   $ debugpath=`pwd`/debugextension.py
   288   $ debugpath=`pwd`/debugextension.py
   309 
   290 
   310   $ hg help debugextension
   291   $ hg help debugextension
   311   debugextension extension - only debugcommands
   292   debugextension extension - only debugcommands
   312   
   293   
   313   no commands defined
   294   no commands defined
       
   295 
   314 
   296 
   315   $ hg --verbose help debugextension
   297   $ hg --verbose help debugextension
   316   debugextension extension - only debugcommands
   298   debugextension extension - only debugcommands
   317   
   299   
   318   list of commands:
   300   list of commands:
   340    -h --help              display help and exit
   322    -h --help              display help and exit
   341       --hidden            consider hidden changesets
   323       --hidden            consider hidden changesets
   342   
   324   
   343   [+] marked option can be specified multiple times
   325   [+] marked option can be specified multiple times
   344 
   326 
       
   327 
       
   328 
       
   329 
       
   330 
       
   331 
   345   $ hg --debug help debugextension
   332   $ hg --debug help debugextension
   346   debugextension extension - only debugcommands
   333   debugextension extension - only debugcommands
   347   
   334   
   348   list of commands:
   335   list of commands:
   349   
   336   
   370       --version           output version information and exit
   357       --version           output version information and exit
   371    -h --help              display help and exit
   358    -h --help              display help and exit
   372       --hidden            consider hidden changesets
   359       --hidden            consider hidden changesets
   373   
   360   
   374   [+] marked option can be specified multiple times
   361   [+] marked option can be specified multiple times
       
   362 
       
   363 
       
   364 
       
   365 
       
   366 
   375   $ echo 'debugextension = !' >> $HGRCPATH
   367   $ echo 'debugextension = !' >> $HGRCPATH
   376 
   368 
   377 Extension module help vs command help:
   369 Extension module help vs command help:
   378 
   370 
   379   $ echo 'extdiff =' >> $HGRCPATH
   371   $ echo 'extdiff =' >> $HGRCPATH
   409   
   401   
   410   [+] marked option can be specified multiple times
   402   [+] marked option can be specified multiple times
   411   
   403   
   412   use "hg -v help extdiff" to show the global options
   404   use "hg -v help extdiff" to show the global options
   413 
   405 
       
   406 
       
   407 
       
   408 
       
   409 
       
   410 
       
   411 
       
   412 
       
   413 
       
   414 
   414   $ hg help --extension extdiff
   415   $ hg help --extension extdiff
   415   extdiff extension - command to allow external programs to compare revisions
   416   extdiff extension - command to allow external programs to compare revisions
   416   
   417   
   417   The extdiff Mercurial extension allows you to use external programs to compare
   418   The extdiff Mercurial extension allows you to use external programs to compare
   418   revisions, or revision with working directory. The external diff programs are
   419   revisions, or revision with working directory. The external diff programs are
   467   list of commands:
   468   list of commands:
   468   
   469   
   469    extdiff       use external program to diff repository (or selected files)
   470    extdiff       use external program to diff repository (or selected files)
   470   
   471   
   471   use "hg -v help extdiff" to show builtin aliases and global options
   472   use "hg -v help extdiff" to show builtin aliases and global options
       
   473 
       
   474 
       
   475 
       
   476 
       
   477 
       
   478 
       
   479 
       
   480 
       
   481 
       
   482 
       
   483 
       
   484 
       
   485 
       
   486 
       
   487 
   472 
   488 
   473   $ echo 'extdiff = !' >> $HGRCPATH
   489   $ echo 'extdiff = !' >> $HGRCPATH
   474 
   490 
   475 Test help topic with same name as extension
   491 Test help topic with same name as extension
   476 
   492 
   505       A range acts as a closed interval. This means that a range of 3:5 gives 3,
   521       A range acts as a closed interval. This means that a range of 3:5 gives 3,
   506       4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
   522       4 and 5. Similarly, a range of 9:6 gives 9, 8, 7, and 6.
   507   
   523   
   508   use "hg help -c multirevs" to see help for the multirevs command
   524   use "hg help -c multirevs" to see help for the multirevs command
   509 
   525 
       
   526 
       
   527 
       
   528 
       
   529 
       
   530 
   510   $ hg help -c multirevs
   531   $ hg help -c multirevs
   511   hg multirevs ARG
   532   hg multirevs ARG
   512   
   533   
   513   multirevs command
   534   multirevs command
   514   
   535   
   515   use "hg -v help multirevs" to show the global options
   536   use "hg -v help multirevs" to show the global options
       
   537 
       
   538 
   516 
   539 
   517   $ hg multirevs
   540   $ hg multirevs
   518   hg multirevs: invalid arguments
   541   hg multirevs: invalid arguments
   519   hg multirevs ARG
   542   hg multirevs ARG
   520   
   543   
   521   multirevs command
   544   multirevs command
   522   
   545   
   523   use "hg help multirevs" to show the full help text
   546   use "hg help multirevs" to show the full help text
   524   [255]
   547   [255]
       
   548 
       
   549 
   525 
   550 
   526   $ echo "multirevs = !" >> $HGRCPATH
   551   $ echo "multirevs = !" >> $HGRCPATH
   527 
   552 
   528 Issue811: Problem loading extensions twice (by site and by user)
   553 Issue811: Problem loading extensions twice (by site and by user)
   529 
   554 
   532   > '''show all loaded extensions
   557   > '''show all loaded extensions
   533   > '''
   558   > '''
   534   > from mercurial import cmdutil, commands, extensions
   559   > from mercurial import cmdutil, commands, extensions
   535   > cmdtable = {}
   560   > cmdtable = {}
   536   > command = cmdutil.command(cmdtable)
   561   > command = cmdutil.command(cmdtable)
   537   > 
       
   538   > @command('debugextensions', [], 'hg debugextensions', norepo=True)
   562   > @command('debugextensions', [], 'hg debugextensions', norepo=True)
   539   > def debugextensions(ui):
   563   > def debugextensions(ui):
   540   >     "yet another debug command"
   564   >     "yet another debug command"
   541   >     ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
   565   >     ui.write("%s\n" % '\n'.join([x for x, y in extensions.extensions()]))
   542   > 
       
   543   > EOF
   566   > EOF
   544   $ echo "debugissue811 = $debugpath" >> $HGRCPATH
   567   $ echo "debugissue811 = $debugpath" >> $HGRCPATH
   545   $ echo "mq=" >> $HGRCPATH
   568   $ echo "mq=" >> $HGRCPATH
   546   $ echo "strip=" >> $HGRCPATH
   569   $ echo "strip=" >> $HGRCPATH
   547   $ echo "hgext.mq=" >> $HGRCPATH
   570   $ echo "hgext.mq=" >> $HGRCPATH
   564   'email' is provided by the following extension:
   587   'email' is provided by the following extension:
   565   
   588   
   566       patchbomb     command to send changesets as (a series of) patch emails
   589       patchbomb     command to send changesets as (a series of) patch emails
   567   
   590   
   568   use "hg help extensions" for information on enabling extensions
   591   use "hg help extensions" for information on enabling extensions
       
   592 
       
   593 
   569   $ hg qdel
   594   $ hg qdel
   570   hg: unknown command 'qdel'
   595   hg: unknown command 'qdel'
   571   'qdelete' is provided by the following extension:
   596   'qdelete' is provided by the following extension:
   572   
   597   
   573       mq            manage a stack of patches
   598       mq            manage a stack of patches
   574   
   599   
   575   use "hg help extensions" for information on enabling extensions
   600   use "hg help extensions" for information on enabling extensions
   576   [255]
   601   [255]
       
   602 
       
   603 
   577   $ hg churn
   604   $ hg churn
   578   hg: unknown command 'churn'
   605   hg: unknown command 'churn'
   579   'churn' is provided by the following extension:
   606   'churn' is provided by the following extension:
   580   
   607   
   581       churn         command to display statistics about repository history
   608       churn         command to display statistics about repository history
   582   
   609   
   583   use "hg help extensions" for information on enabling extensions
   610   use "hg help extensions" for information on enabling extensions
   584   [255]
   611   [255]
   585 
   612 
       
   613 
       
   614 
   586 Disabled extensions:
   615 Disabled extensions:
   587 
   616 
   588   $ hg help churn
   617   $ hg help churn
   589   churn extension - command to display statistics about repository history
   618   churn extension - command to display statistics about repository history
   590   
   619   
   591   use "hg help extensions" for information on enabling extensions
   620   use "hg help extensions" for information on enabling extensions
       
   621 
   592   $ hg help patchbomb
   622   $ hg help patchbomb
   593   patchbomb extension - command to send changesets as (a series of) patch emails
   623   patchbomb extension - command to send changesets as (a series of) patch emails
   594   
   624   
   595   use "hg help extensions" for information on enabling extensions
   625   use "hg help extensions" for information on enabling extensions
       
   626 
   596 
   627 
   597 Broken disabled extension and command:
   628 Broken disabled extension and command:
   598 
   629 
   599   $ mkdir hgext
   630   $ mkdir hgext
   600   $ echo > hgext/__init__.py
   631   $ echo > hgext/__init__.py
   610 
   641 
   611   $ hg --config extensions.path=./path.py help broken
   642   $ hg --config extensions.path=./path.py help broken
   612   broken extension - (no help text available)
   643   broken extension - (no help text available)
   613   
   644   
   614   use "hg help extensions" for information on enabling extensions
   645   use "hg help extensions" for information on enabling extensions
       
   646 
   615 
   647 
   616   $ cat > hgext/forest.py <<EOF
   648   $ cat > hgext/forest.py <<EOF
   617   > cmdtable = None
   649   > cmdtable = None
   618   > EOF
   650   > EOF
   619   $ hg --config extensions.path=./path.py help foo > /dev/null
   651   $ hg --config extensions.path=./path.py help foo > /dev/null
   625   $ cat > throw.py <<EOF
   657   $ cat > throw.py <<EOF
   626   > from mercurial import cmdutil, commands
   658   > from mercurial import cmdutil, commands
   627   > cmdtable = {}
   659   > cmdtable = {}
   628   > command = cmdutil.command(cmdtable)
   660   > command = cmdutil.command(cmdtable)
   629   > class Bogon(Exception): pass
   661   > class Bogon(Exception): pass
   630   > 
       
   631   > @command('throw', [], 'hg throw', norepo=True)
   662   > @command('throw', [], 'hg throw', norepo=True)
   632   > def throw(ui, **opts):
   663   > def throw(ui, **opts):
   633   >     """throws an exception"""
   664   >     """throws an exception"""
   634   >     raise Bogon()
   665   >     raise Bogon()
   635   > EOF
   666   > EOF
   712   ** http://mercurial.selenic.com/wiki/BugTracker
   743   ** http://mercurial.selenic.com/wiki/BugTracker
   713   ** Python * (glob)
   744   ** Python * (glob)
   714   ** Mercurial Distributed SCM (*) (glob)
   745   ** Mercurial Distributed SCM (*) (glob)
   715   ** Extensions loaded: throw
   746   ** Extensions loaded: throw
   716 
   747 
       
   748 Test version number support in 'hg version':
       
   749   $ echo '__version__ = (1, 2, 3)' >> throw.py
       
   750   $ rm -f throw.pyc throw.pyo
       
   751   $ hg version -v --config extensions.throw=throw.py
       
   752   Mercurial Distributed SCM (version *) (glob)
       
   753   (see http://mercurial.selenic.com for more information)
       
   754   
       
   755   Copyright (C) 2005-* Matt Mackall and others (glob)
       
   756   This is free software; see the source for copying conditions. There is NO
       
   757   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
   758   
       
   759   Enabled extensions:
       
   760   
       
   761     throw  1.2.3
       
   762   $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
       
   763   $ rm -f throw.pyc throw.pyo
       
   764   $ hg version -v --config extensions.throw=throw.py
       
   765   Mercurial Distributed SCM (version *) (glob)
       
   766   (see http://mercurial.selenic.com for more information)
       
   767   
       
   768   Copyright (C) 2005-* Matt Mackall and others (glob)
       
   769   This is free software; see the source for copying conditions. There is NO
       
   770   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
   771   
       
   772   Enabled extensions:
       
   773   
       
   774     throw  1.twentythree
       
   775 
   717 Restore HGRCPATH
   776 Restore HGRCPATH
   718 
   777 
   719   $ HGRCPATH=$ORGHGRCPATH
   778   $ HGRCPATH=$ORGHGRCPATH
   720   $ export HGRCPATH
   779   $ export HGRCPATH
   721 
   780