##// END OF EJS Templates
tests: move baduisetup test inside "#if demandimport"...
Martin von Zweigbergk -
r33940:9d5d0401 default
parent child Browse files
Show More
@@ -1,1715 +1,1711 b''
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 commands, registrar
5 > from mercurial import commands, registrar
6 > cmdtable = {}
6 > cmdtable = {}
7 > command = registrar.command(cmdtable)
7 > command = registrar.command(cmdtable)
8 > configtable = {}
8 > configtable = {}
9 > configitem = registrar.configitem(configtable)
9 > configitem = registrar.configitem(configtable)
10 > configitem('tests', 'foo', default="Foo")
10 > configitem('tests', 'foo', default="Foo")
11 > def uisetup(ui):
11 > def uisetup(ui):
12 > ui.write("uisetup called\\n")
12 > ui.write("uisetup called\\n")
13 > ui.flush()
13 > ui.flush()
14 > def reposetup(ui, repo):
14 > def reposetup(ui, repo):
15 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
15 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
16 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
16 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
17 > ui.flush()
17 > ui.flush()
18 > @command(b'foo', [], 'hg foo')
18 > @command(b'foo', [], 'hg foo')
19 > def foo(ui, *args, **kwargs):
19 > def foo(ui, *args, **kwargs):
20 > foo = ui.config('tests', 'foo')
20 > foo = ui.config('tests', 'foo')
21 > ui.write(foo)
21 > ui.write(foo)
22 > ui.write("\\n")
22 > ui.write("\\n")
23 > @command(b'bar', [], 'hg bar', norepo=True)
23 > @command(b'bar', [], 'hg bar', norepo=True)
24 > def bar(ui, *args, **kwargs):
24 > def bar(ui, *args, **kwargs):
25 > ui.write("Bar\\n")
25 > ui.write("Bar\\n")
26 > EOF
26 > EOF
27 $ abspath=`pwd`/foobar.py
27 $ abspath=`pwd`/foobar.py
28
28
29 $ mkdir barfoo
29 $ mkdir barfoo
30 $ cp foobar.py barfoo/__init__.py
30 $ cp foobar.py barfoo/__init__.py
31 $ barfoopath=`pwd`/barfoo
31 $ barfoopath=`pwd`/barfoo
32
32
33 $ hg init a
33 $ hg init a
34 $ cd a
34 $ cd a
35 $ echo foo > file
35 $ echo foo > file
36 $ hg add file
36 $ hg add file
37 $ hg commit -m 'add file'
37 $ hg commit -m 'add file'
38
38
39 $ echo '[extensions]' >> $HGRCPATH
39 $ echo '[extensions]' >> $HGRCPATH
40 $ echo "foobar = $abspath" >> $HGRCPATH
40 $ echo "foobar = $abspath" >> $HGRCPATH
41 $ hg foo
41 $ hg foo
42 uisetup called
42 uisetup called
43 reposetup called for a
43 reposetup called for a
44 ui == repo.ui
44 ui == repo.ui
45 Foo
45 Foo
46
46
47 $ cd ..
47 $ cd ..
48 $ hg clone a b
48 $ hg clone a b
49 uisetup called
49 uisetup called
50 reposetup called for a
50 reposetup called for a
51 ui == repo.ui
51 ui == repo.ui
52 reposetup called for b
52 reposetup called for b
53 ui == repo.ui
53 ui == repo.ui
54 updating to branch default
54 updating to branch default
55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
56
56
57 $ hg bar
57 $ hg bar
58 uisetup called
58 uisetup called
59 Bar
59 Bar
60 $ echo 'foobar = !' >> $HGRCPATH
60 $ echo 'foobar = !' >> $HGRCPATH
61
61
62 module/__init__.py-style
62 module/__init__.py-style
63
63
64 $ echo "barfoo = $barfoopath" >> $HGRCPATH
64 $ echo "barfoo = $barfoopath" >> $HGRCPATH
65 $ cd a
65 $ cd a
66 $ hg foo
66 $ hg foo
67 uisetup called
67 uisetup called
68 reposetup called for a
68 reposetup called for a
69 ui == repo.ui
69 ui == repo.ui
70 Foo
70 Foo
71 $ echo 'barfoo = !' >> $HGRCPATH
71 $ echo 'barfoo = !' >> $HGRCPATH
72
72
73 Check that extensions are loaded in phases:
73 Check that extensions are loaded in phases:
74
74
75 $ cat > foo.py <<EOF
75 $ cat > foo.py <<EOF
76 > import os
76 > import os
77 > name = os.path.basename(__file__).rsplit('.', 1)[0]
77 > name = os.path.basename(__file__).rsplit('.', 1)[0]
78 > print("1) %s imported" % name)
78 > print("1) %s imported" % name)
79 > def uisetup(ui):
79 > def uisetup(ui):
80 > print("2) %s uisetup" % name)
80 > print("2) %s uisetup" % name)
81 > def extsetup():
81 > def extsetup():
82 > print("3) %s extsetup" % name)
82 > print("3) %s extsetup" % name)
83 > def reposetup(ui, repo):
83 > def reposetup(ui, repo):
84 > print("4) %s reposetup" % name)
84 > print("4) %s reposetup" % name)
85 >
85 >
86 > # custom predicate to check registration of functions at loading
86 > # custom predicate to check registration of functions at loading
87 > from mercurial import (
87 > from mercurial import (
88 > registrar,
88 > registrar,
89 > smartset,
89 > smartset,
90 > )
90 > )
91 > revsetpredicate = registrar.revsetpredicate()
91 > revsetpredicate = registrar.revsetpredicate()
92 > @revsetpredicate(name, safe=True) # safe=True for query via hgweb
92 > @revsetpredicate(name, safe=True) # safe=True for query via hgweb
93 > def custompredicate(repo, subset, x):
93 > def custompredicate(repo, subset, x):
94 > return smartset.baseset([r for r in subset if r in {0}])
94 > return smartset.baseset([r for r in subset if r in {0}])
95 > EOF
95 > EOF
96
96
97 $ cp foo.py bar.py
97 $ cp foo.py bar.py
98 $ echo 'foo = foo.py' >> $HGRCPATH
98 $ echo 'foo = foo.py' >> $HGRCPATH
99 $ echo 'bar = bar.py' >> $HGRCPATH
99 $ echo 'bar = bar.py' >> $HGRCPATH
100
100
101 Check normal command's load order of extensions and registration of functions
101 Check normal command's load order of extensions and registration of functions
102
102
103 $ hg log -r "foo() and bar()" -q
103 $ hg log -r "foo() and bar()" -q
104 1) foo imported
104 1) foo imported
105 1) bar imported
105 1) bar imported
106 2) foo uisetup
106 2) foo uisetup
107 2) bar uisetup
107 2) bar uisetup
108 3) foo extsetup
108 3) foo extsetup
109 3) bar extsetup
109 3) bar extsetup
110 4) foo reposetup
110 4) foo reposetup
111 4) bar reposetup
111 4) bar reposetup
112 0:c24b9ac61126
112 0:c24b9ac61126
113
113
114 Check hgweb's load order of extensions and registration of functions
114 Check hgweb's load order of extensions and registration of functions
115
115
116 $ cat > hgweb.cgi <<EOF
116 $ cat > hgweb.cgi <<EOF
117 > #!$PYTHON
117 > #!$PYTHON
118 > from mercurial import demandimport; demandimport.enable()
118 > from mercurial import demandimport; demandimport.enable()
119 > from mercurial.hgweb import hgweb
119 > from mercurial.hgweb import hgweb
120 > from mercurial.hgweb import wsgicgi
120 > from mercurial.hgweb import wsgicgi
121 > application = hgweb('.', 'test repo')
121 > application = hgweb('.', 'test repo')
122 > wsgicgi.launch(application)
122 > wsgicgi.launch(application)
123 > EOF
123 > EOF
124 $ . "$TESTDIR/cgienv"
124 $ . "$TESTDIR/cgienv"
125
125
126 $ PATH_INFO='/' SCRIPT_NAME='' $PYTHON hgweb.cgi \
126 $ PATH_INFO='/' SCRIPT_NAME='' $PYTHON hgweb.cgi \
127 > | grep '^[0-9]) ' # ignores HTML output
127 > | grep '^[0-9]) ' # ignores HTML output
128 1) foo imported
128 1) foo imported
129 1) bar imported
129 1) bar imported
130 2) foo uisetup
130 2) foo uisetup
131 2) bar uisetup
131 2) bar uisetup
132 3) foo extsetup
132 3) foo extsetup
133 3) bar extsetup
133 3) bar extsetup
134 4) foo reposetup
134 4) foo reposetup
135 4) bar reposetup
135 4) bar reposetup
136
136
137 (check that revset predicate foo() and bar() are available)
137 (check that revset predicate foo() and bar() are available)
138
138
139 #if msys
139 #if msys
140 $ PATH_INFO='//shortlog'
140 $ PATH_INFO='//shortlog'
141 #else
141 #else
142 $ PATH_INFO='/shortlog'
142 $ PATH_INFO='/shortlog'
143 #endif
143 #endif
144 $ export PATH_INFO
144 $ export PATH_INFO
145 $ SCRIPT_NAME='' QUERY_STRING='rev=foo() and bar()' $PYTHON hgweb.cgi \
145 $ SCRIPT_NAME='' QUERY_STRING='rev=foo() and bar()' $PYTHON hgweb.cgi \
146 > | grep '<a href="/rev/[0-9a-z]*">'
146 > | grep '<a href="/rev/[0-9a-z]*">'
147 <a href="/rev/c24b9ac61126">add file</a>
147 <a href="/rev/c24b9ac61126">add file</a>
148
148
149 $ echo 'foo = !' >> $HGRCPATH
149 $ echo 'foo = !' >> $HGRCPATH
150 $ echo 'bar = !' >> $HGRCPATH
150 $ echo 'bar = !' >> $HGRCPATH
151
151
152 Check "from __future__ import absolute_import" support for external libraries
152 Check "from __future__ import absolute_import" support for external libraries
153
153
154 #if windows
154 #if windows
155 $ PATHSEP=";"
155 $ PATHSEP=";"
156 #else
156 #else
157 $ PATHSEP=":"
157 $ PATHSEP=":"
158 #endif
158 #endif
159 $ export PATHSEP
159 $ export PATHSEP
160
160
161 $ mkdir $TESTTMP/libroot
161 $ mkdir $TESTTMP/libroot
162 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
162 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
163 $ mkdir $TESTTMP/libroot/mod
163 $ mkdir $TESTTMP/libroot/mod
164 $ touch $TESTTMP/libroot/mod/__init__.py
164 $ touch $TESTTMP/libroot/mod/__init__.py
165 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
165 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
166
166
167 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
167 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
168 > from __future__ import absolute_import
168 > from __future__ import absolute_import
169 > import ambig # should load "libroot/ambig.py"
169 > import ambig # should load "libroot/ambig.py"
170 > s = ambig.s
170 > s = ambig.s
171 > EOF
171 > EOF
172 $ cat > loadabs.py <<EOF
172 $ cat > loadabs.py <<EOF
173 > import mod.ambigabs as ambigabs
173 > import mod.ambigabs as ambigabs
174 > def extsetup():
174 > def extsetup():
175 > print('ambigabs.s=%s' % ambigabs.s)
175 > print('ambigabs.s=%s' % ambigabs.s)
176 > EOF
176 > EOF
177 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
177 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
178 ambigabs.s=libroot/ambig.py
178 ambigabs.s=libroot/ambig.py
179 $TESTTMP/a (glob)
179 $TESTTMP/a (glob)
180
180
181 #if no-py3k
181 #if no-py3k
182 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
182 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
183 > import ambig # should load "libroot/mod/ambig.py"
183 > import ambig # should load "libroot/mod/ambig.py"
184 > s = ambig.s
184 > s = ambig.s
185 > EOF
185 > EOF
186 $ cat > loadrel.py <<EOF
186 $ cat > loadrel.py <<EOF
187 > import mod.ambigrel as ambigrel
187 > import mod.ambigrel as ambigrel
188 > def extsetup():
188 > def extsetup():
189 > print('ambigrel.s=%s' % ambigrel.s)
189 > print('ambigrel.s=%s' % ambigrel.s)
190 > EOF
190 > EOF
191 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
191 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
192 ambigrel.s=libroot/mod/ambig.py
192 ambigrel.s=libroot/mod/ambig.py
193 $TESTTMP/a (glob)
193 $TESTTMP/a (glob)
194 #endif
194 #endif
195
195
196 Check absolute/relative import of extension specific modules
196 Check absolute/relative import of extension specific modules
197
197
198 $ mkdir $TESTTMP/extroot
198 $ mkdir $TESTTMP/extroot
199 $ cat > $TESTTMP/extroot/bar.py <<EOF
199 $ cat > $TESTTMP/extroot/bar.py <<EOF
200 > s = 'this is extroot.bar'
200 > s = 'this is extroot.bar'
201 > EOF
201 > EOF
202 $ mkdir $TESTTMP/extroot/sub1
202 $ mkdir $TESTTMP/extroot/sub1
203 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
203 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
204 > s = 'this is extroot.sub1.__init__'
204 > s = 'this is extroot.sub1.__init__'
205 > EOF
205 > EOF
206 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
206 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
207 > s = 'this is extroot.sub1.baz'
207 > s = 'this is extroot.sub1.baz'
208 > EOF
208 > EOF
209 $ cat > $TESTTMP/extroot/__init__.py <<EOF
209 $ cat > $TESTTMP/extroot/__init__.py <<EOF
210 > s = 'this is extroot.__init__'
210 > s = 'this is extroot.__init__'
211 > import foo
211 > import foo
212 > def extsetup(ui):
212 > def extsetup(ui):
213 > ui.write('(extroot) ', foo.func(), '\n')
213 > ui.write('(extroot) ', foo.func(), '\n')
214 > ui.flush()
214 > ui.flush()
215 > EOF
215 > EOF
216
216
217 $ cat > $TESTTMP/extroot/foo.py <<EOF
217 $ cat > $TESTTMP/extroot/foo.py <<EOF
218 > # test absolute import
218 > # test absolute import
219 > buf = []
219 > buf = []
220 > def func():
220 > def func():
221 > # "not locals" case
221 > # "not locals" case
222 > import extroot.bar
222 > import extroot.bar
223 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
223 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
224 > return '\n(extroot) '.join(buf)
224 > return '\n(extroot) '.join(buf)
225 > # "fromlist == ('*',)" case
225 > # "fromlist == ('*',)" case
226 > from extroot.bar import *
226 > from extroot.bar import *
227 > buf.append('from extroot.bar import *: %s' % s)
227 > buf.append('from extroot.bar import *: %s' % s)
228 > # "not fromlist" and "if '.' in name" case
228 > # "not fromlist" and "if '.' in name" case
229 > import extroot.sub1.baz
229 > import extroot.sub1.baz
230 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
230 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
231 > # "not fromlist" and NOT "if '.' in name" case
231 > # "not fromlist" and NOT "if '.' in name" case
232 > import extroot
232 > import extroot
233 > buf.append('import extroot: %s' % extroot.s)
233 > buf.append('import extroot: %s' % extroot.s)
234 > # NOT "not fromlist" and NOT "level != -1" case
234 > # NOT "not fromlist" and NOT "level != -1" case
235 > from extroot.bar import s
235 > from extroot.bar import s
236 > buf.append('from extroot.bar import s: %s' % s)
236 > buf.append('from extroot.bar import s: %s' % s)
237 > EOF
237 > EOF
238 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
238 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
239 (extroot) from extroot.bar import *: this is extroot.bar
239 (extroot) from extroot.bar import *: this is extroot.bar
240 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
240 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
241 (extroot) import extroot: this is extroot.__init__
241 (extroot) import extroot: this is extroot.__init__
242 (extroot) from extroot.bar import s: this is extroot.bar
242 (extroot) from extroot.bar import s: this is extroot.bar
243 (extroot) import extroot.bar in func(): this is extroot.bar
243 (extroot) import extroot.bar in func(): this is extroot.bar
244 $TESTTMP/a (glob)
244 $TESTTMP/a (glob)
245
245
246 #if no-py3k
246 #if no-py3k
247 $ rm "$TESTTMP"/extroot/foo.*
247 $ rm "$TESTTMP"/extroot/foo.*
248 $ rm -Rf "$TESTTMP/extroot/__pycache__"
248 $ rm -Rf "$TESTTMP/extroot/__pycache__"
249 $ cat > $TESTTMP/extroot/foo.py <<EOF
249 $ cat > $TESTTMP/extroot/foo.py <<EOF
250 > # test relative import
250 > # test relative import
251 > buf = []
251 > buf = []
252 > def func():
252 > def func():
253 > # "not locals" case
253 > # "not locals" case
254 > import bar
254 > import bar
255 > buf.append('import bar in func(): %s' % bar.s)
255 > buf.append('import bar in func(): %s' % bar.s)
256 > return '\n(extroot) '.join(buf)
256 > return '\n(extroot) '.join(buf)
257 > # "fromlist == ('*',)" case
257 > # "fromlist == ('*',)" case
258 > from bar import *
258 > from bar import *
259 > buf.append('from bar import *: %s' % s)
259 > buf.append('from bar import *: %s' % s)
260 > # "not fromlist" and "if '.' in name" case
260 > # "not fromlist" and "if '.' in name" case
261 > import sub1.baz
261 > import sub1.baz
262 > buf.append('import sub1.baz: %s' % sub1.baz.s)
262 > buf.append('import sub1.baz: %s' % sub1.baz.s)
263 > # "not fromlist" and NOT "if '.' in name" case
263 > # "not fromlist" and NOT "if '.' in name" case
264 > import sub1
264 > import sub1
265 > buf.append('import sub1: %s' % sub1.s)
265 > buf.append('import sub1: %s' % sub1.s)
266 > # NOT "not fromlist" and NOT "level != -1" case
266 > # NOT "not fromlist" and NOT "level != -1" case
267 > from bar import s
267 > from bar import s
268 > buf.append('from bar import s: %s' % s)
268 > buf.append('from bar import s: %s' % s)
269 > EOF
269 > EOF
270 $ hg --config extensions.extroot=$TESTTMP/extroot root
270 $ hg --config extensions.extroot=$TESTTMP/extroot root
271 (extroot) from bar import *: this is extroot.bar
271 (extroot) from bar import *: this is extroot.bar
272 (extroot) import sub1.baz: this is extroot.sub1.baz
272 (extroot) import sub1.baz: this is extroot.sub1.baz
273 (extroot) import sub1: this is extroot.sub1.__init__
273 (extroot) import sub1: this is extroot.sub1.__init__
274 (extroot) from bar import s: this is extroot.bar
274 (extroot) from bar import s: this is extroot.bar
275 (extroot) import bar in func(): this is extroot.bar
275 (extroot) import bar in func(): this is extroot.bar
276 $TESTTMP/a (glob)
276 $TESTTMP/a (glob)
277 #endif
277 #endif
278
278
279 #if demandimport
279 #if demandimport
280
280
281 Examine whether module loading is delayed until actual referring, even
281 Examine whether module loading is delayed until actual referring, even
282 though module is imported with "absolute_import" feature.
282 though module is imported with "absolute_import" feature.
283
283
284 Files below in each packages are used for described purpose:
284 Files below in each packages are used for described purpose:
285
285
286 - "called": examine whether "from MODULE import ATTR" works correctly
286 - "called": examine whether "from MODULE import ATTR" works correctly
287 - "unused": examine whether loading is delayed correctly
287 - "unused": examine whether loading is delayed correctly
288 - "used": examine whether "from PACKAGE import MODULE" works correctly
288 - "used": examine whether "from PACKAGE import MODULE" works correctly
289
289
290 Package hierarchy is needed to examine whether demand importing works
290 Package hierarchy is needed to examine whether demand importing works
291 as expected for "from SUB.PACK.AGE import MODULE".
291 as expected for "from SUB.PACK.AGE import MODULE".
292
292
293 Setup "external library" to be imported with "absolute_import"
293 Setup "external library" to be imported with "absolute_import"
294 feature.
294 feature.
295
295
296 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
296 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
297 $ touch $TESTTMP/extlibroot/__init__.py
297 $ touch $TESTTMP/extlibroot/__init__.py
298 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
298 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
299 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
299 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
300
300
301 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
301 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
302 > def func():
302 > def func():
303 > return "this is extlibroot.lsub1.lsub2.called.func()"
303 > return "this is extlibroot.lsub1.lsub2.called.func()"
304 > EOF
304 > EOF
305 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
305 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
306 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
306 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
307 > EOF
307 > EOF
308 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
308 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
309 > detail = "this is extlibroot.lsub1.lsub2.used"
309 > detail = "this is extlibroot.lsub1.lsub2.used"
310 > EOF
310 > EOF
311
311
312 Setup sub-package of "external library", which causes instantiation of
312 Setup sub-package of "external library", which causes instantiation of
313 demandmod in "recurse down the module chain" code path. Relative
313 demandmod in "recurse down the module chain" code path. Relative
314 importing with "absolute_import" feature isn't tested, because "level
314 importing with "absolute_import" feature isn't tested, because "level
315 >=1 " doesn't cause instantiation of demandmod.
315 >=1 " doesn't cause instantiation of demandmod.
316
316
317 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
317 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
318 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
318 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
319 > detail = "this is extlibroot.recursedown.abs.used"
319 > detail = "this is extlibroot.recursedown.abs.used"
320 > EOF
320 > EOF
321 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
321 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
322 > from __future__ import absolute_import
322 > from __future__ import absolute_import
323 > from extlibroot.recursedown.abs.used import detail
323 > from extlibroot.recursedown.abs.used import detail
324 > EOF
324 > EOF
325
325
326 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
326 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
327 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
327 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
328 > detail = "this is extlibroot.recursedown.legacy.used"
328 > detail = "this is extlibroot.recursedown.legacy.used"
329 > EOF
329 > EOF
330 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
330 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
331 > # legacy style (level == -1) import
331 > # legacy style (level == -1) import
332 > from extlibroot.recursedown.legacy.used import detail
332 > from extlibroot.recursedown.legacy.used import detail
333 > EOF
333 > EOF
334
334
335 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
335 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
336 > from __future__ import absolute_import
336 > from __future__ import absolute_import
337 > from extlibroot.recursedown.abs import detail as absdetail
337 > from extlibroot.recursedown.abs import detail as absdetail
338 > from .legacy import detail as legacydetail
338 > from .legacy import detail as legacydetail
339 > EOF
339 > EOF
340
340
341 Setup package that re-exports an attribute of its submodule as the same
341 Setup package that re-exports an attribute of its submodule as the same
342 name. This leaves 'shadowing.used' pointing to 'used.detail', but still
342 name. This leaves 'shadowing.used' pointing to 'used.detail', but still
343 the submodule 'used' should be somehow accessible. (issue5617)
343 the submodule 'used' should be somehow accessible. (issue5617)
344
344
345 $ mkdir -p $TESTTMP/extlibroot/shadowing
345 $ mkdir -p $TESTTMP/extlibroot/shadowing
346 $ cat > $TESTTMP/extlibroot/shadowing/used.py <<EOF
346 $ cat > $TESTTMP/extlibroot/shadowing/used.py <<EOF
347 > detail = "this is extlibroot.shadowing.used"
347 > detail = "this is extlibroot.shadowing.used"
348 > EOF
348 > EOF
349 $ cat > $TESTTMP/extlibroot/shadowing/proxied.py <<EOF
349 $ cat > $TESTTMP/extlibroot/shadowing/proxied.py <<EOF
350 > from __future__ import absolute_import
350 > from __future__ import absolute_import
351 > from extlibroot.shadowing.used import detail
351 > from extlibroot.shadowing.used import detail
352 > EOF
352 > EOF
353 $ cat > $TESTTMP/extlibroot/shadowing/__init__.py <<EOF
353 $ cat > $TESTTMP/extlibroot/shadowing/__init__.py <<EOF
354 > from __future__ import absolute_import
354 > from __future__ import absolute_import
355 > from .used import detail as used
355 > from .used import detail as used
356 > EOF
356 > EOF
357
357
358 Setup extension local modules to be imported with "absolute_import"
358 Setup extension local modules to be imported with "absolute_import"
359 feature.
359 feature.
360
360
361 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
361 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
362 $ touch $TESTTMP/absextroot/xsub1/__init__.py
362 $ touch $TESTTMP/absextroot/xsub1/__init__.py
363 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
363 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
364
364
365 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
365 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
366 > def func():
366 > def func():
367 > return "this is absextroot.xsub1.xsub2.called.func()"
367 > return "this is absextroot.xsub1.xsub2.called.func()"
368 > EOF
368 > EOF
369 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
369 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
370 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
370 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
371 > EOF
371 > EOF
372 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
372 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
373 > detail = "this is absextroot.xsub1.xsub2.used"
373 > detail = "this is absextroot.xsub1.xsub2.used"
374 > EOF
374 > EOF
375
375
376 Setup extension local modules to examine whether demand importing
376 Setup extension local modules to examine whether demand importing
377 works as expected in "level > 1" case.
377 works as expected in "level > 1" case.
378
378
379 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
379 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
380 > detail = "this is absextroot.relimportee"
380 > detail = "this is absextroot.relimportee"
381 > EOF
381 > EOF
382 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
382 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
383 > from __future__ import absolute_import
383 > from __future__ import absolute_import
384 > from ... import relimportee
384 > from ... import relimportee
385 > detail = "this relimporter imports %r" % (relimportee.detail)
385 > detail = "this relimporter imports %r" % (relimportee.detail)
386 > EOF
386 > EOF
387
387
388 Setup modules, which actually import extension local modules at
388 Setup modules, which actually import extension local modules at
389 runtime.
389 runtime.
390
390
391 $ cat > $TESTTMP/absextroot/absolute.py << EOF
391 $ cat > $TESTTMP/absextroot/absolute.py << EOF
392 > from __future__ import absolute_import
392 > from __future__ import absolute_import
393 >
393 >
394 > # import extension local modules absolutely (level = 0)
394 > # import extension local modules absolutely (level = 0)
395 > from absextroot.xsub1.xsub2 import used, unused
395 > from absextroot.xsub1.xsub2 import used, unused
396 > from absextroot.xsub1.xsub2.called import func
396 > from absextroot.xsub1.xsub2.called import func
397 >
397 >
398 > def getresult():
398 > def getresult():
399 > result = []
399 > result = []
400 > result.append(used.detail)
400 > result.append(used.detail)
401 > result.append(func())
401 > result.append(func())
402 > return result
402 > return result
403 > EOF
403 > EOF
404
404
405 $ cat > $TESTTMP/absextroot/relative.py << EOF
405 $ cat > $TESTTMP/absextroot/relative.py << EOF
406 > from __future__ import absolute_import
406 > from __future__ import absolute_import
407 >
407 >
408 > # import extension local modules relatively (level == 1)
408 > # import extension local modules relatively (level == 1)
409 > from .xsub1.xsub2 import used, unused
409 > from .xsub1.xsub2 import used, unused
410 > from .xsub1.xsub2.called import func
410 > from .xsub1.xsub2.called import func
411 >
411 >
412 > # import a module, which implies "importing with level > 1"
412 > # import a module, which implies "importing with level > 1"
413 > from .xsub1.xsub2 import relimporter
413 > from .xsub1.xsub2 import relimporter
414 >
414 >
415 > def getresult():
415 > def getresult():
416 > result = []
416 > result = []
417 > result.append(used.detail)
417 > result.append(used.detail)
418 > result.append(func())
418 > result.append(func())
419 > result.append(relimporter.detail)
419 > result.append(relimporter.detail)
420 > return result
420 > return result
421 > EOF
421 > EOF
422
422
423 Setup main procedure of extension.
423 Setup main procedure of extension.
424
424
425 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
425 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
426 > from __future__ import absolute_import
426 > from __future__ import absolute_import
427 > from mercurial import registrar
427 > from mercurial import registrar
428 > cmdtable = {}
428 > cmdtable = {}
429 > command = registrar.command(cmdtable)
429 > command = registrar.command(cmdtable)
430 >
430 >
431 > # "absolute" and "relative" shouldn't be imported before actual
431 > # "absolute" and "relative" shouldn't be imported before actual
432 > # command execution, because (1) they import same modules, and (2)
432 > # command execution, because (1) they import same modules, and (2)
433 > # preceding import (= instantiate "demandmod" object instead of
433 > # preceding import (= instantiate "demandmod" object instead of
434 > # real "module" object) might hide problem of succeeding import.
434 > # real "module" object) might hide problem of succeeding import.
435 >
435 >
436 > @command(b'showabsolute', [], norepo=True)
436 > @command(b'showabsolute', [], norepo=True)
437 > def showabsolute(ui, *args, **opts):
437 > def showabsolute(ui, *args, **opts):
438 > from absextroot import absolute
438 > from absextroot import absolute
439 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
439 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
440 >
440 >
441 > @command(b'showrelative', [], norepo=True)
441 > @command(b'showrelative', [], norepo=True)
442 > def showrelative(ui, *args, **opts):
442 > def showrelative(ui, *args, **opts):
443 > from . import relative
443 > from . import relative
444 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
444 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
445 >
445 >
446 > # import modules from external library
446 > # import modules from external library
447 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
447 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
448 > from extlibroot.lsub1.lsub2.called import func as lfunc
448 > from extlibroot.lsub1.lsub2.called import func as lfunc
449 > from extlibroot.recursedown import absdetail, legacydetail
449 > from extlibroot.recursedown import absdetail, legacydetail
450 > from extlibroot.shadowing import proxied
450 > from extlibroot.shadowing import proxied
451 >
451 >
452 > def uisetup(ui):
452 > def uisetup(ui):
453 > result = []
453 > result = []
454 > result.append(lused.detail)
454 > result.append(lused.detail)
455 > result.append(lfunc())
455 > result.append(lfunc())
456 > result.append(absdetail)
456 > result.append(absdetail)
457 > result.append(legacydetail)
457 > result.append(legacydetail)
458 > result.append(proxied.detail)
458 > result.append(proxied.detail)
459 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
459 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
460 > EOF
460 > EOF
461
461
462 Examine module importing.
462 Examine module importing.
463
463
464 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
464 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
465 LIB: this is extlibroot.lsub1.lsub2.used
465 LIB: this is extlibroot.lsub1.lsub2.used
466 LIB: this is extlibroot.lsub1.lsub2.called.func()
466 LIB: this is extlibroot.lsub1.lsub2.called.func()
467 LIB: this is extlibroot.recursedown.abs.used
467 LIB: this is extlibroot.recursedown.abs.used
468 LIB: this is extlibroot.recursedown.legacy.used
468 LIB: this is extlibroot.recursedown.legacy.used
469 LIB: this is extlibroot.shadowing.used
469 LIB: this is extlibroot.shadowing.used
470 ABS: this is absextroot.xsub1.xsub2.used
470 ABS: this is absextroot.xsub1.xsub2.used
471 ABS: this is absextroot.xsub1.xsub2.called.func()
471 ABS: this is absextroot.xsub1.xsub2.called.func()
472
472
473 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
473 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
474 LIB: this is extlibroot.lsub1.lsub2.used
474 LIB: this is extlibroot.lsub1.lsub2.used
475 LIB: this is extlibroot.lsub1.lsub2.called.func()
475 LIB: this is extlibroot.lsub1.lsub2.called.func()
476 LIB: this is extlibroot.recursedown.abs.used
476 LIB: this is extlibroot.recursedown.abs.used
477 LIB: this is extlibroot.recursedown.legacy.used
477 LIB: this is extlibroot.recursedown.legacy.used
478 LIB: this is extlibroot.shadowing.used
478 LIB: this is extlibroot.shadowing.used
479 REL: this is absextroot.xsub1.xsub2.used
479 REL: this is absextroot.xsub1.xsub2.used
480 REL: this is absextroot.xsub1.xsub2.called.func()
480 REL: this is absextroot.xsub1.xsub2.called.func()
481 REL: this relimporter imports 'this is absextroot.relimportee'
481 REL: this relimporter imports 'this is absextroot.relimportee'
482
482
483 Examine whether sub-module is imported relatively as expected.
483 Examine whether sub-module is imported relatively as expected.
484
484
485 See also issue5208 for detail about example case on Python 3.x.
485 See also issue5208 for detail about example case on Python 3.x.
486
486
487 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
487 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
488 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
488 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
489
489
490 $ cat > $TESTTMP/notexist.py <<EOF
490 $ cat > $TESTTMP/notexist.py <<EOF
491 > text = 'notexist.py at root is loaded unintentionally\n'
491 > text = 'notexist.py at root is loaded unintentionally\n'
492 > EOF
492 > EOF
493
493
494 $ cat > $TESTTMP/checkrelativity.py <<EOF
494 $ cat > $TESTTMP/checkrelativity.py <<EOF
495 > from mercurial import registrar
495 > from mercurial import registrar
496 > cmdtable = {}
496 > cmdtable = {}
497 > command = registrar.command(cmdtable)
497 > command = registrar.command(cmdtable)
498 >
498 >
499 > # demand import avoids failure of importing notexist here
499 > # demand import avoids failure of importing notexist here
500 > import extlibroot.lsub1.lsub2.notexist
500 > import extlibroot.lsub1.lsub2.notexist
501 >
501 >
502 > @command(b'checkrelativity', [], norepo=True)
502 > @command(b'checkrelativity', [], norepo=True)
503 > def checkrelativity(ui, *args, **opts):
503 > def checkrelativity(ui, *args, **opts):
504 > try:
504 > try:
505 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
505 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
506 > return 1 # unintentional success
506 > return 1 # unintentional success
507 > except ImportError:
507 > except ImportError:
508 > pass # intentional failure
508 > pass # intentional failure
509 > EOF
509 > EOF
510
510
511 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
511 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
512
512
513 Make sure a broken uisetup doesn't globally break hg:
514 $ cat > $TESTTMP/baduisetup.py <<EOF
515 > from mercurial import (
516 > bdiff,
517 > extensions,
518 > )
519 >
520 > def blockswrapper(orig, *args, **kwargs):
521 > return orig(*args, **kwargs)
522 >
523 > def uisetup(ui):
524 > extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
525 > EOF
526
527 Even though the extension fails during uisetup, hg is still basically usable:
528 $ hg --config extensions.baduisetup=$TESTTMP/baduisetup.py version
529 \*\*\* failed to set up extension baduisetup: No module named (mercurial\.)?bdiff (re)
530 Mercurial Distributed SCM (version *) (glob)
531 (see https://mercurial-scm.org for more information)
532
533 Copyright (C) 2005-2017 Matt Mackall and others
534 This is free software; see the source for copying conditions. There is NO
535 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
536
537 $ hg --config extensions.baduisetup=$TESTTMP/baduisetup.py version --traceback
538 Traceback (most recent call last):
539 File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
540 uisetup(ui)
541 File "$TESTTMP/baduisetup.py", line 10, in uisetup
542 extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
543 File "*/mercurial/extensions.py", line *, in wrapfunction (glob)
544 origfn = getattr(container, funcname)
545 File "*/hgdemandimport/demandimportpy2.py", line *, in __getattr__ (glob)
546 self._load()
547 File "*/hgdemandimport/demandimportpy2.py", line *, in _load (glob)
548 mod = _hgextimport(_origimport, head, globals, locals, None, level)
549 File "*/hgdemandimport/demandimportpy2.py", line *, in _hgextimport (glob)
550 return importfunc(name, globals, *args, **kwargs)
551 ImportError: No module named (mercurial\.)?bdiff (re)
552 \*\*\* failed to set up extension baduisetup: No module named (mercurial\.)?bdiff (re)
553 Mercurial Distributed SCM (version *) (glob)
554 (see https://mercurial-scm.org for more information)
555
556 Copyright (C) 2005-2017 Matt Mackall and others
557 This is free software; see the source for copying conditions. There is NO
558 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
559
513 #endif
560 #endif
514
561
515 $ cd ..
562 $ cd ..
516
563
517 hide outer repo
564 hide outer repo
518 $ hg init
565 $ hg init
519
566
520 $ cat > empty.py <<EOF
567 $ cat > empty.py <<EOF
521 > '''empty cmdtable
568 > '''empty cmdtable
522 > '''
569 > '''
523 > cmdtable = {}
570 > cmdtable = {}
524 > EOF
571 > EOF
525 $ emptypath=`pwd`/empty.py
572 $ emptypath=`pwd`/empty.py
526 $ echo "empty = $emptypath" >> $HGRCPATH
573 $ echo "empty = $emptypath" >> $HGRCPATH
527 $ hg help empty
574 $ hg help empty
528 empty extension - empty cmdtable
575 empty extension - empty cmdtable
529
576
530 no commands defined
577 no commands defined
531
578
532
579
533 $ echo 'empty = !' >> $HGRCPATH
580 $ echo 'empty = !' >> $HGRCPATH
534
581
535 $ cat > debugextension.py <<EOF
582 $ cat > debugextension.py <<EOF
536 > '''only debugcommands
583 > '''only debugcommands
537 > '''
584 > '''
538 > from mercurial import registrar
585 > from mercurial import registrar
539 > cmdtable = {}
586 > cmdtable = {}
540 > command = registrar.command(cmdtable)
587 > command = registrar.command(cmdtable)
541 > @command(b'debugfoobar', [], 'hg debugfoobar')
588 > @command(b'debugfoobar', [], 'hg debugfoobar')
542 > def debugfoobar(ui, repo, *args, **opts):
589 > def debugfoobar(ui, repo, *args, **opts):
543 > "yet another debug command"
590 > "yet another debug command"
544 > pass
591 > pass
545 > @command(b'foo', [], 'hg foo')
592 > @command(b'foo', [], 'hg foo')
546 > def foo(ui, repo, *args, **opts):
593 > def foo(ui, repo, *args, **opts):
547 > """yet another foo command
594 > """yet another foo command
548 > This command has been DEPRECATED since forever.
595 > This command has been DEPRECATED since forever.
549 > """
596 > """
550 > pass
597 > pass
551 > EOF
598 > EOF
552 $ debugpath=`pwd`/debugextension.py
599 $ debugpath=`pwd`/debugextension.py
553 $ echo "debugextension = $debugpath" >> $HGRCPATH
600 $ echo "debugextension = $debugpath" >> $HGRCPATH
554
601
555 $ hg help debugextension
602 $ hg help debugextension
556 hg debugextensions
603 hg debugextensions
557
604
558 show information about active extensions
605 show information about active extensions
559
606
560 options:
607 options:
561
608
562 (some details hidden, use --verbose to show complete help)
609 (some details hidden, use --verbose to show complete help)
563
610
564
611
565 $ hg --verbose help debugextension
612 $ hg --verbose help debugextension
566 hg debugextensions
613 hg debugextensions
567
614
568 show information about active extensions
615 show information about active extensions
569
616
570 options:
617 options:
571
618
572 -T --template TEMPLATE display with template (EXPERIMENTAL)
619 -T --template TEMPLATE display with template (EXPERIMENTAL)
573
620
574 global options ([+] can be repeated):
621 global options ([+] can be repeated):
575
622
576 -R --repository REPO repository root directory or name of overlay bundle
623 -R --repository REPO repository root directory or name of overlay bundle
577 file
624 file
578 --cwd DIR change working directory
625 --cwd DIR change working directory
579 -y --noninteractive do not prompt, automatically pick the first choice for
626 -y --noninteractive do not prompt, automatically pick the first choice for
580 all prompts
627 all prompts
581 -q --quiet suppress output
628 -q --quiet suppress output
582 -v --verbose enable additional output
629 -v --verbose enable additional output
583 --color TYPE when to colorize (boolean, always, auto, never, or
630 --color TYPE when to colorize (boolean, always, auto, never, or
584 debug)
631 debug)
585 --config CONFIG [+] set/override config option (use 'section.name=value')
632 --config CONFIG [+] set/override config option (use 'section.name=value')
586 --debug enable debugging output
633 --debug enable debugging output
587 --debugger start debugger
634 --debugger start debugger
588 --encoding ENCODE set the charset encoding (default: ascii)
635 --encoding ENCODE set the charset encoding (default: ascii)
589 --encodingmode MODE set the charset encoding mode (default: strict)
636 --encodingmode MODE set the charset encoding mode (default: strict)
590 --traceback always print a traceback on exception
637 --traceback always print a traceback on exception
591 --time time how long the command takes
638 --time time how long the command takes
592 --profile print command execution profile
639 --profile print command execution profile
593 --version output version information and exit
640 --version output version information and exit
594 -h --help display help and exit
641 -h --help display help and exit
595 --hidden consider hidden changesets
642 --hidden consider hidden changesets
596 --pager TYPE when to paginate (boolean, always, auto, or never)
643 --pager TYPE when to paginate (boolean, always, auto, or never)
597 (default: auto)
644 (default: auto)
598
645
599
646
600
647
601
648
602
649
603
650
604 $ hg --debug help debugextension
651 $ hg --debug help debugextension
605 hg debugextensions
652 hg debugextensions
606
653
607 show information about active extensions
654 show information about active extensions
608
655
609 options:
656 options:
610
657
611 -T --template TEMPLATE display with template (EXPERIMENTAL)
658 -T --template TEMPLATE display with template (EXPERIMENTAL)
612
659
613 global options ([+] can be repeated):
660 global options ([+] can be repeated):
614
661
615 -R --repository REPO repository root directory or name of overlay bundle
662 -R --repository REPO repository root directory or name of overlay bundle
616 file
663 file
617 --cwd DIR change working directory
664 --cwd DIR change working directory
618 -y --noninteractive do not prompt, automatically pick the first choice for
665 -y --noninteractive do not prompt, automatically pick the first choice for
619 all prompts
666 all prompts
620 -q --quiet suppress output
667 -q --quiet suppress output
621 -v --verbose enable additional output
668 -v --verbose enable additional output
622 --color TYPE when to colorize (boolean, always, auto, never, or
669 --color TYPE when to colorize (boolean, always, auto, never, or
623 debug)
670 debug)
624 --config CONFIG [+] set/override config option (use 'section.name=value')
671 --config CONFIG [+] set/override config option (use 'section.name=value')
625 --debug enable debugging output
672 --debug enable debugging output
626 --debugger start debugger
673 --debugger start debugger
627 --encoding ENCODE set the charset encoding (default: ascii)
674 --encoding ENCODE set the charset encoding (default: ascii)
628 --encodingmode MODE set the charset encoding mode (default: strict)
675 --encodingmode MODE set the charset encoding mode (default: strict)
629 --traceback always print a traceback on exception
676 --traceback always print a traceback on exception
630 --time time how long the command takes
677 --time time how long the command takes
631 --profile print command execution profile
678 --profile print command execution profile
632 --version output version information and exit
679 --version output version information and exit
633 -h --help display help and exit
680 -h --help display help and exit
634 --hidden consider hidden changesets
681 --hidden consider hidden changesets
635 --pager TYPE when to paginate (boolean, always, auto, or never)
682 --pager TYPE when to paginate (boolean, always, auto, or never)
636 (default: auto)
683 (default: auto)
637
684
638
685
639
686
640
687
641
688
642 $ echo 'debugextension = !' >> $HGRCPATH
689 $ echo 'debugextension = !' >> $HGRCPATH
643
690
644 Asking for help about a deprecated extension should do something useful:
691 Asking for help about a deprecated extension should do something useful:
645
692
646 $ hg help glog
693 $ hg help glog
647 'glog' is provided by the following extension:
694 'glog' is provided by the following extension:
648
695
649 graphlog command to view revision graphs from a shell (DEPRECATED)
696 graphlog command to view revision graphs from a shell (DEPRECATED)
650
697
651 (use 'hg help extensions' for information on enabling extensions)
698 (use 'hg help extensions' for information on enabling extensions)
652
699
653 Extension module help vs command help:
700 Extension module help vs command help:
654
701
655 $ echo 'extdiff =' >> $HGRCPATH
702 $ echo 'extdiff =' >> $HGRCPATH
656 $ hg help extdiff
703 $ hg help extdiff
657 hg extdiff [OPT]... [FILE]...
704 hg extdiff [OPT]... [FILE]...
658
705
659 use external program to diff repository (or selected files)
706 use external program to diff repository (or selected files)
660
707
661 Show differences between revisions for the specified files, using an
708 Show differences between revisions for the specified files, using an
662 external program. The default program used is diff, with default options
709 external program. The default program used is diff, with default options
663 "-Npru".
710 "-Npru".
664
711
665 To select a different program, use the -p/--program option. The program
712 To select a different program, use the -p/--program option. The program
666 will be passed the names of two directories to compare. To pass additional
713 will be passed the names of two directories to compare. To pass additional
667 options to the program, use -o/--option. These will be passed before the
714 options to the program, use -o/--option. These will be passed before the
668 names of the directories to compare.
715 names of the directories to compare.
669
716
670 When two revision arguments are given, then changes are shown between
717 When two revision arguments are given, then changes are shown between
671 those revisions. If only one revision is specified then that revision is
718 those revisions. If only one revision is specified then that revision is
672 compared to the working directory, and, when no revisions are specified,
719 compared to the working directory, and, when no revisions are specified,
673 the working directory files are compared to its parent.
720 the working directory files are compared to its parent.
674
721
675 (use 'hg help -e extdiff' to show help for the extdiff extension)
722 (use 'hg help -e extdiff' to show help for the extdiff extension)
676
723
677 options ([+] can be repeated):
724 options ([+] can be repeated):
678
725
679 -p --program CMD comparison program to run
726 -p --program CMD comparison program to run
680 -o --option OPT [+] pass option to comparison program
727 -o --option OPT [+] pass option to comparison program
681 -r --rev REV [+] revision
728 -r --rev REV [+] revision
682 -c --change REV change made by revision
729 -c --change REV change made by revision
683 --patch compare patches for two revisions
730 --patch compare patches for two revisions
684 -I --include PATTERN [+] include names matching the given patterns
731 -I --include PATTERN [+] include names matching the given patterns
685 -X --exclude PATTERN [+] exclude names matching the given patterns
732 -X --exclude PATTERN [+] exclude names matching the given patterns
686 -S --subrepos recurse into subrepositories
733 -S --subrepos recurse into subrepositories
687
734
688 (some details hidden, use --verbose to show complete help)
735 (some details hidden, use --verbose to show complete help)
689
736
690
737
691
738
692
739
693
740
694
741
695
742
696
743
697
744
698
745
699 $ hg help --extension extdiff
746 $ hg help --extension extdiff
700 extdiff extension - command to allow external programs to compare revisions
747 extdiff extension - command to allow external programs to compare revisions
701
748
702 The extdiff Mercurial extension allows you to use external programs to compare
749 The extdiff Mercurial extension allows you to use external programs to compare
703 revisions, or revision with working directory. The external diff programs are
750 revisions, or revision with working directory. The external diff programs are
704 called with a configurable set of options and two non-option arguments: paths
751 called with a configurable set of options and two non-option arguments: paths
705 to directories containing snapshots of files to compare.
752 to directories containing snapshots of files to compare.
706
753
707 The extdiff extension also allows you to configure new diff commands, so you
754 The extdiff extension also allows you to configure new diff commands, so you
708 do not need to type 'hg extdiff -p kdiff3' always.
755 do not need to type 'hg extdiff -p kdiff3' always.
709
756
710 [extdiff]
757 [extdiff]
711 # add new command that runs GNU diff(1) in 'context diff' mode
758 # add new command that runs GNU diff(1) in 'context diff' mode
712 cdiff = gdiff -Nprc5
759 cdiff = gdiff -Nprc5
713 ## or the old way:
760 ## or the old way:
714 #cmd.cdiff = gdiff
761 #cmd.cdiff = gdiff
715 #opts.cdiff = -Nprc5
762 #opts.cdiff = -Nprc5
716
763
717 # add new command called meld, runs meld (no need to name twice). If
764 # add new command called meld, runs meld (no need to name twice). If
718 # the meld executable is not available, the meld tool in [merge-tools]
765 # the meld executable is not available, the meld tool in [merge-tools]
719 # will be used, if available
766 # will be used, if available
720 meld =
767 meld =
721
768
722 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
769 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
723 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
770 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
724 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
771 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
725 # your .vimrc
772 # your .vimrc
726 vimdiff = gvim -f "+next" \
773 vimdiff = gvim -f "+next" \
727 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
774 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
728
775
729 Tool arguments can include variables that are expanded at runtime:
776 Tool arguments can include variables that are expanded at runtime:
730
777
731 $parent1, $plabel1 - filename, descriptive label of first parent
778 $parent1, $plabel1 - filename, descriptive label of first parent
732 $child, $clabel - filename, descriptive label of child revision
779 $child, $clabel - filename, descriptive label of child revision
733 $parent2, $plabel2 - filename, descriptive label of second parent
780 $parent2, $plabel2 - filename, descriptive label of second parent
734 $root - repository root
781 $root - repository root
735 $parent is an alias for $parent1.
782 $parent is an alias for $parent1.
736
783
737 The extdiff extension will look in your [diff-tools] and [merge-tools]
784 The extdiff extension will look in your [diff-tools] and [merge-tools]
738 sections for diff tool arguments, when none are specified in [extdiff].
785 sections for diff tool arguments, when none are specified in [extdiff].
739
786
740 [extdiff]
787 [extdiff]
741 kdiff3 =
788 kdiff3 =
742
789
743 [diff-tools]
790 [diff-tools]
744 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
791 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
745
792
746 You can use -I/-X and list of file or directory names like normal 'hg diff'
793 You can use -I/-X and list of file or directory names like normal 'hg diff'
747 command. The extdiff extension makes snapshots of only needed files, so
794 command. The extdiff extension makes snapshots of only needed files, so
748 running the external diff program will actually be pretty fast (at least
795 running the external diff program will actually be pretty fast (at least
749 faster than having to compare the entire tree).
796 faster than having to compare the entire tree).
750
797
751 list of commands:
798 list of commands:
752
799
753 extdiff use external program to diff repository (or selected files)
800 extdiff use external program to diff repository (or selected files)
754
801
755 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
802 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
756
803
757
804
758
805
759
806
760
807
761
808
762
809
763
810
764
811
765
812
766
813
767
814
768
815
769
816
770
817
771
818
772 $ echo 'extdiff = !' >> $HGRCPATH
819 $ echo 'extdiff = !' >> $HGRCPATH
773
820
774 Test help topic with same name as extension
821 Test help topic with same name as extension
775
822
776 $ cat > multirevs.py <<EOF
823 $ cat > multirevs.py <<EOF
777 > from mercurial import commands, registrar
824 > from mercurial import commands, registrar
778 > cmdtable = {}
825 > cmdtable = {}
779 > command = registrar.command(cmdtable)
826 > command = registrar.command(cmdtable)
780 > """multirevs extension
827 > """multirevs extension
781 > Big multi-line module docstring."""
828 > Big multi-line module docstring."""
782 > @command(b'multirevs', [], 'ARG', norepo=True)
829 > @command(b'multirevs', [], 'ARG', norepo=True)
783 > def multirevs(ui, repo, arg, *args, **opts):
830 > def multirevs(ui, repo, arg, *args, **opts):
784 > """multirevs command"""
831 > """multirevs command"""
785 > pass
832 > pass
786 > EOF
833 > EOF
787 $ echo "multirevs = multirevs.py" >> $HGRCPATH
834 $ echo "multirevs = multirevs.py" >> $HGRCPATH
788
835
789 $ hg help multirevs | tail
836 $ hg help multirevs | tail
790 bookmark (this works because the last revision of the revset is used):
837 bookmark (this works because the last revision of the revset is used):
791
838
792 hg update :@
839 hg update :@
793
840
794 - Show diff between tags 1.3 and 1.5 (this works because the first and the
841 - Show diff between tags 1.3 and 1.5 (this works because the first and the
795 last revisions of the revset are used):
842 last revisions of the revset are used):
796
843
797 hg diff -r 1.3::1.5
844 hg diff -r 1.3::1.5
798
845
799 use 'hg help -c multirevs' to see help for the multirevs command
846 use 'hg help -c multirevs' to see help for the multirevs command
800
847
801
848
802
849
803
850
804
851
805
852
806 $ hg help -c multirevs
853 $ hg help -c multirevs
807 hg multirevs ARG
854 hg multirevs ARG
808
855
809 multirevs command
856 multirevs command
810
857
811 (some details hidden, use --verbose to show complete help)
858 (some details hidden, use --verbose to show complete help)
812
859
813
860
814
861
815 $ hg multirevs
862 $ hg multirevs
816 hg multirevs: invalid arguments
863 hg multirevs: invalid arguments
817 hg multirevs ARG
864 hg multirevs ARG
818
865
819 multirevs command
866 multirevs command
820
867
821 (use 'hg multirevs -h' to show more help)
868 (use 'hg multirevs -h' to show more help)
822 [255]
869 [255]
823
870
824
871
825
872
826 $ echo "multirevs = !" >> $HGRCPATH
873 $ echo "multirevs = !" >> $HGRCPATH
827
874
828 Issue811: Problem loading extensions twice (by site and by user)
875 Issue811: Problem loading extensions twice (by site and by user)
829
876
830 $ cat <<EOF >> $HGRCPATH
877 $ cat <<EOF >> $HGRCPATH
831 > mq =
878 > mq =
832 > strip =
879 > strip =
833 > hgext.mq =
880 > hgext.mq =
834 > hgext/mq =
881 > hgext/mq =
835 > EOF
882 > EOF
836
883
837 Show extensions:
884 Show extensions:
838 (note that mq force load strip, also checking it's not loaded twice)
885 (note that mq force load strip, also checking it's not loaded twice)
839
886
840 $ hg debugextensions
887 $ hg debugextensions
841 mq
888 mq
842 strip
889 strip
843
890
844 For extensions, which name matches one of its commands, help
891 For extensions, which name matches one of its commands, help
845 message should ask '-v -e' to get list of built-in aliases
892 message should ask '-v -e' to get list of built-in aliases
846 along with extension help itself
893 along with extension help itself
847
894
848 $ mkdir $TESTTMP/d
895 $ mkdir $TESTTMP/d
849 $ cat > $TESTTMP/d/dodo.py <<EOF
896 $ cat > $TESTTMP/d/dodo.py <<EOF
850 > """
897 > """
851 > This is an awesome 'dodo' extension. It does nothing and
898 > This is an awesome 'dodo' extension. It does nothing and
852 > writes 'Foo foo'
899 > writes 'Foo foo'
853 > """
900 > """
854 > from mercurial import commands, registrar
901 > from mercurial import commands, registrar
855 > cmdtable = {}
902 > cmdtable = {}
856 > command = registrar.command(cmdtable)
903 > command = registrar.command(cmdtable)
857 > @command(b'dodo', [], 'hg dodo')
904 > @command(b'dodo', [], 'hg dodo')
858 > def dodo(ui, *args, **kwargs):
905 > def dodo(ui, *args, **kwargs):
859 > """Does nothing"""
906 > """Does nothing"""
860 > ui.write("I do nothing. Yay\\n")
907 > ui.write("I do nothing. Yay\\n")
861 > @command(b'foofoo', [], 'hg foofoo')
908 > @command(b'foofoo', [], 'hg foofoo')
862 > def foofoo(ui, *args, **kwargs):
909 > def foofoo(ui, *args, **kwargs):
863 > """Writes 'Foo foo'"""
910 > """Writes 'Foo foo'"""
864 > ui.write("Foo foo\\n")
911 > ui.write("Foo foo\\n")
865 > EOF
912 > EOF
866 $ dodopath=$TESTTMP/d/dodo.py
913 $ dodopath=$TESTTMP/d/dodo.py
867
914
868 $ echo "dodo = $dodopath" >> $HGRCPATH
915 $ echo "dodo = $dodopath" >> $HGRCPATH
869
916
870 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
917 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
871 $ hg help -e dodo
918 $ hg help -e dodo
872 dodo extension -
919 dodo extension -
873
920
874 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
921 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
875
922
876 list of commands:
923 list of commands:
877
924
878 dodo Does nothing
925 dodo Does nothing
879 foofoo Writes 'Foo foo'
926 foofoo Writes 'Foo foo'
880
927
881 (use 'hg help -v -e dodo' to show built-in aliases and global options)
928 (use 'hg help -v -e dodo' to show built-in aliases and global options)
882
929
883 Make sure that '-v -e' prints list of built-in aliases along with
930 Make sure that '-v -e' prints list of built-in aliases along with
884 extension help itself
931 extension help itself
885 $ hg help -v -e dodo
932 $ hg help -v -e dodo
886 dodo extension -
933 dodo extension -
887
934
888 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
935 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
889
936
890 list of commands:
937 list of commands:
891
938
892 dodo Does nothing
939 dodo Does nothing
893 foofoo Writes 'Foo foo'
940 foofoo Writes 'Foo foo'
894
941
895 global options ([+] can be repeated):
942 global options ([+] can be repeated):
896
943
897 -R --repository REPO repository root directory or name of overlay bundle
944 -R --repository REPO repository root directory or name of overlay bundle
898 file
945 file
899 --cwd DIR change working directory
946 --cwd DIR change working directory
900 -y --noninteractive do not prompt, automatically pick the first choice for
947 -y --noninteractive do not prompt, automatically pick the first choice for
901 all prompts
948 all prompts
902 -q --quiet suppress output
949 -q --quiet suppress output
903 -v --verbose enable additional output
950 -v --verbose enable additional output
904 --color TYPE when to colorize (boolean, always, auto, never, or
951 --color TYPE when to colorize (boolean, always, auto, never, or
905 debug)
952 debug)
906 --config CONFIG [+] set/override config option (use 'section.name=value')
953 --config CONFIG [+] set/override config option (use 'section.name=value')
907 --debug enable debugging output
954 --debug enable debugging output
908 --debugger start debugger
955 --debugger start debugger
909 --encoding ENCODE set the charset encoding (default: ascii)
956 --encoding ENCODE set the charset encoding (default: ascii)
910 --encodingmode MODE set the charset encoding mode (default: strict)
957 --encodingmode MODE set the charset encoding mode (default: strict)
911 --traceback always print a traceback on exception
958 --traceback always print a traceback on exception
912 --time time how long the command takes
959 --time time how long the command takes
913 --profile print command execution profile
960 --profile print command execution profile
914 --version output version information and exit
961 --version output version information and exit
915 -h --help display help and exit
962 -h --help display help and exit
916 --hidden consider hidden changesets
963 --hidden consider hidden changesets
917 --pager TYPE when to paginate (boolean, always, auto, or never)
964 --pager TYPE when to paginate (boolean, always, auto, or never)
918 (default: auto)
965 (default: auto)
919
966
920 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
967 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
921 $ hg help -v dodo
968 $ hg help -v dodo
922 hg dodo
969 hg dodo
923
970
924 Does nothing
971 Does nothing
925
972
926 (use 'hg help -e dodo' to show help for the dodo extension)
973 (use 'hg help -e dodo' to show help for the dodo extension)
927
974
928 options:
975 options:
929
976
930 --mq operate on patch repository
977 --mq operate on patch repository
931
978
932 global options ([+] can be repeated):
979 global options ([+] can be repeated):
933
980
934 -R --repository REPO repository root directory or name of overlay bundle
981 -R --repository REPO repository root directory or name of overlay bundle
935 file
982 file
936 --cwd DIR change working directory
983 --cwd DIR change working directory
937 -y --noninteractive do not prompt, automatically pick the first choice for
984 -y --noninteractive do not prompt, automatically pick the first choice for
938 all prompts
985 all prompts
939 -q --quiet suppress output
986 -q --quiet suppress output
940 -v --verbose enable additional output
987 -v --verbose enable additional output
941 --color TYPE when to colorize (boolean, always, auto, never, or
988 --color TYPE when to colorize (boolean, always, auto, never, or
942 debug)
989 debug)
943 --config CONFIG [+] set/override config option (use 'section.name=value')
990 --config CONFIG [+] set/override config option (use 'section.name=value')
944 --debug enable debugging output
991 --debug enable debugging output
945 --debugger start debugger
992 --debugger start debugger
946 --encoding ENCODE set the charset encoding (default: ascii)
993 --encoding ENCODE set the charset encoding (default: ascii)
947 --encodingmode MODE set the charset encoding mode (default: strict)
994 --encodingmode MODE set the charset encoding mode (default: strict)
948 --traceback always print a traceback on exception
995 --traceback always print a traceback on exception
949 --time time how long the command takes
996 --time time how long the command takes
950 --profile print command execution profile
997 --profile print command execution profile
951 --version output version information and exit
998 --version output version information and exit
952 -h --help display help and exit
999 -h --help display help and exit
953 --hidden consider hidden changesets
1000 --hidden consider hidden changesets
954 --pager TYPE when to paginate (boolean, always, auto, or never)
1001 --pager TYPE when to paginate (boolean, always, auto, or never)
955 (default: auto)
1002 (default: auto)
956
1003
957 In case when extension name doesn't match any of its commands,
1004 In case when extension name doesn't match any of its commands,
958 help message should ask for '-v' to get list of built-in aliases
1005 help message should ask for '-v' to get list of built-in aliases
959 along with extension help
1006 along with extension help
960 $ cat > $TESTTMP/d/dudu.py <<EOF
1007 $ cat > $TESTTMP/d/dudu.py <<EOF
961 > """
1008 > """
962 > This is an awesome 'dudu' extension. It does something and
1009 > This is an awesome 'dudu' extension. It does something and
963 > also writes 'Beep beep'
1010 > also writes 'Beep beep'
964 > """
1011 > """
965 > from mercurial import commands, registrar
1012 > from mercurial import commands, registrar
966 > cmdtable = {}
1013 > cmdtable = {}
967 > command = registrar.command(cmdtable)
1014 > command = registrar.command(cmdtable)
968 > @command(b'something', [], 'hg something')
1015 > @command(b'something', [], 'hg something')
969 > def something(ui, *args, **kwargs):
1016 > def something(ui, *args, **kwargs):
970 > """Does something"""
1017 > """Does something"""
971 > ui.write("I do something. Yaaay\\n")
1018 > ui.write("I do something. Yaaay\\n")
972 > @command(b'beep', [], 'hg beep')
1019 > @command(b'beep', [], 'hg beep')
973 > def beep(ui, *args, **kwargs):
1020 > def beep(ui, *args, **kwargs):
974 > """Writes 'Beep beep'"""
1021 > """Writes 'Beep beep'"""
975 > ui.write("Beep beep\\n")
1022 > ui.write("Beep beep\\n")
976 > EOF
1023 > EOF
977 $ dudupath=$TESTTMP/d/dudu.py
1024 $ dudupath=$TESTTMP/d/dudu.py
978
1025
979 $ echo "dudu = $dudupath" >> $HGRCPATH
1026 $ echo "dudu = $dudupath" >> $HGRCPATH
980
1027
981 $ hg help -e dudu
1028 $ hg help -e dudu
982 dudu extension -
1029 dudu extension -
983
1030
984 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1031 This is an awesome 'dudu' extension. It does something and also writes 'Beep
985 beep'
1032 beep'
986
1033
987 list of commands:
1034 list of commands:
988
1035
989 beep Writes 'Beep beep'
1036 beep Writes 'Beep beep'
990 something Does something
1037 something Does something
991
1038
992 (use 'hg help -v dudu' to show built-in aliases and global options)
1039 (use 'hg help -v dudu' to show built-in aliases and global options)
993
1040
994 In case when extension name doesn't match any of its commands,
1041 In case when extension name doesn't match any of its commands,
995 help options '-v' and '-v -e' should be equivalent
1042 help options '-v' and '-v -e' should be equivalent
996 $ hg help -v dudu
1043 $ hg help -v dudu
997 dudu extension -
1044 dudu extension -
998
1045
999 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1046 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1000 beep'
1047 beep'
1001
1048
1002 list of commands:
1049 list of commands:
1003
1050
1004 beep Writes 'Beep beep'
1051 beep Writes 'Beep beep'
1005 something Does something
1052 something Does something
1006
1053
1007 global options ([+] can be repeated):
1054 global options ([+] can be repeated):
1008
1055
1009 -R --repository REPO repository root directory or name of overlay bundle
1056 -R --repository REPO repository root directory or name of overlay bundle
1010 file
1057 file
1011 --cwd DIR change working directory
1058 --cwd DIR change working directory
1012 -y --noninteractive do not prompt, automatically pick the first choice for
1059 -y --noninteractive do not prompt, automatically pick the first choice for
1013 all prompts
1060 all prompts
1014 -q --quiet suppress output
1061 -q --quiet suppress output
1015 -v --verbose enable additional output
1062 -v --verbose enable additional output
1016 --color TYPE when to colorize (boolean, always, auto, never, or
1063 --color TYPE when to colorize (boolean, always, auto, never, or
1017 debug)
1064 debug)
1018 --config CONFIG [+] set/override config option (use 'section.name=value')
1065 --config CONFIG [+] set/override config option (use 'section.name=value')
1019 --debug enable debugging output
1066 --debug enable debugging output
1020 --debugger start debugger
1067 --debugger start debugger
1021 --encoding ENCODE set the charset encoding (default: ascii)
1068 --encoding ENCODE set the charset encoding (default: ascii)
1022 --encodingmode MODE set the charset encoding mode (default: strict)
1069 --encodingmode MODE set the charset encoding mode (default: strict)
1023 --traceback always print a traceback on exception
1070 --traceback always print a traceback on exception
1024 --time time how long the command takes
1071 --time time how long the command takes
1025 --profile print command execution profile
1072 --profile print command execution profile
1026 --version output version information and exit
1073 --version output version information and exit
1027 -h --help display help and exit
1074 -h --help display help and exit
1028 --hidden consider hidden changesets
1075 --hidden consider hidden changesets
1029 --pager TYPE when to paginate (boolean, always, auto, or never)
1076 --pager TYPE when to paginate (boolean, always, auto, or never)
1030 (default: auto)
1077 (default: auto)
1031
1078
1032 $ hg help -v -e dudu
1079 $ hg help -v -e dudu
1033 dudu extension -
1080 dudu extension -
1034
1081
1035 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1082 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1036 beep'
1083 beep'
1037
1084
1038 list of commands:
1085 list of commands:
1039
1086
1040 beep Writes 'Beep beep'
1087 beep Writes 'Beep beep'
1041 something Does something
1088 something Does something
1042
1089
1043 global options ([+] can be repeated):
1090 global options ([+] can be repeated):
1044
1091
1045 -R --repository REPO repository root directory or name of overlay bundle
1092 -R --repository REPO repository root directory or name of overlay bundle
1046 file
1093 file
1047 --cwd DIR change working directory
1094 --cwd DIR change working directory
1048 -y --noninteractive do not prompt, automatically pick the first choice for
1095 -y --noninteractive do not prompt, automatically pick the first choice for
1049 all prompts
1096 all prompts
1050 -q --quiet suppress output
1097 -q --quiet suppress output
1051 -v --verbose enable additional output
1098 -v --verbose enable additional output
1052 --color TYPE when to colorize (boolean, always, auto, never, or
1099 --color TYPE when to colorize (boolean, always, auto, never, or
1053 debug)
1100 debug)
1054 --config CONFIG [+] set/override config option (use 'section.name=value')
1101 --config CONFIG [+] set/override config option (use 'section.name=value')
1055 --debug enable debugging output
1102 --debug enable debugging output
1056 --debugger start debugger
1103 --debugger start debugger
1057 --encoding ENCODE set the charset encoding (default: ascii)
1104 --encoding ENCODE set the charset encoding (default: ascii)
1058 --encodingmode MODE set the charset encoding mode (default: strict)
1105 --encodingmode MODE set the charset encoding mode (default: strict)
1059 --traceback always print a traceback on exception
1106 --traceback always print a traceback on exception
1060 --time time how long the command takes
1107 --time time how long the command takes
1061 --profile print command execution profile
1108 --profile print command execution profile
1062 --version output version information and exit
1109 --version output version information and exit
1063 -h --help display help and exit
1110 -h --help display help and exit
1064 --hidden consider hidden changesets
1111 --hidden consider hidden changesets
1065 --pager TYPE when to paginate (boolean, always, auto, or never)
1112 --pager TYPE when to paginate (boolean, always, auto, or never)
1066 (default: auto)
1113 (default: auto)
1067
1114
1068 Disabled extension commands:
1115 Disabled extension commands:
1069
1116
1070 $ ORGHGRCPATH=$HGRCPATH
1117 $ ORGHGRCPATH=$HGRCPATH
1071 $ HGRCPATH=
1118 $ HGRCPATH=
1072 $ export HGRCPATH
1119 $ export HGRCPATH
1073 $ hg help email
1120 $ hg help email
1074 'email' is provided by the following extension:
1121 'email' is provided by the following extension:
1075
1122
1076 patchbomb command to send changesets as (a series of) patch emails
1123 patchbomb command to send changesets as (a series of) patch emails
1077
1124
1078 (use 'hg help extensions' for information on enabling extensions)
1125 (use 'hg help extensions' for information on enabling extensions)
1079
1126
1080
1127
1081 $ hg qdel
1128 $ hg qdel
1082 hg: unknown command 'qdel'
1129 hg: unknown command 'qdel'
1083 'qdelete' is provided by the following extension:
1130 'qdelete' is provided by the following extension:
1084
1131
1085 mq manage a stack of patches
1132 mq manage a stack of patches
1086
1133
1087 (use 'hg help extensions' for information on enabling extensions)
1134 (use 'hg help extensions' for information on enabling extensions)
1088 [255]
1135 [255]
1089
1136
1090
1137
1091 $ hg churn
1138 $ hg churn
1092 hg: unknown command 'churn'
1139 hg: unknown command 'churn'
1093 'churn' is provided by the following extension:
1140 'churn' is provided by the following extension:
1094
1141
1095 churn command to display statistics about repository history
1142 churn command to display statistics about repository history
1096
1143
1097 (use 'hg help extensions' for information on enabling extensions)
1144 (use 'hg help extensions' for information on enabling extensions)
1098 [255]
1145 [255]
1099
1146
1100
1147
1101
1148
1102 Disabled extensions:
1149 Disabled extensions:
1103
1150
1104 $ hg help churn
1151 $ hg help churn
1105 churn extension - command to display statistics about repository history
1152 churn extension - command to display statistics about repository history
1106
1153
1107 (use 'hg help extensions' for information on enabling extensions)
1154 (use 'hg help extensions' for information on enabling extensions)
1108
1155
1109 $ hg help patchbomb
1156 $ hg help patchbomb
1110 patchbomb extension - command to send changesets as (a series of) patch emails
1157 patchbomb extension - command to send changesets as (a series of) patch emails
1111
1158
1112 The series is started off with a "[PATCH 0 of N]" introduction, which
1159 The series is started off with a "[PATCH 0 of N]" introduction, which
1113 describes the series as a whole.
1160 describes the series as a whole.
1114
1161
1115 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1162 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1116 line of the changeset description as the subject text. The message contains
1163 line of the changeset description as the subject text. The message contains
1117 two or three body parts:
1164 two or three body parts:
1118
1165
1119 - The changeset description.
1166 - The changeset description.
1120 - [Optional] The result of running diffstat on the patch.
1167 - [Optional] The result of running diffstat on the patch.
1121 - The patch itself, as generated by 'hg export'.
1168 - The patch itself, as generated by 'hg export'.
1122
1169
1123 Each message refers to the first in the series using the In-Reply-To and
1170 Each message refers to the first in the series using the In-Reply-To and
1124 References headers, so they will show up as a sequence in threaded mail and
1171 References headers, so they will show up as a sequence in threaded mail and
1125 news readers, and in mail archives.
1172 news readers, and in mail archives.
1126
1173
1127 To configure other defaults, add a section like this to your configuration
1174 To configure other defaults, add a section like this to your configuration
1128 file:
1175 file:
1129
1176
1130 [email]
1177 [email]
1131 from = My Name <my@email>
1178 from = My Name <my@email>
1132 to = recipient1, recipient2, ...
1179 to = recipient1, recipient2, ...
1133 cc = cc1, cc2, ...
1180 cc = cc1, cc2, ...
1134 bcc = bcc1, bcc2, ...
1181 bcc = bcc1, bcc2, ...
1135 reply-to = address1, address2, ...
1182 reply-to = address1, address2, ...
1136
1183
1137 Use "[patchbomb]" as configuration section name if you need to override global
1184 Use "[patchbomb]" as configuration section name if you need to override global
1138 "[email]" address settings.
1185 "[email]" address settings.
1139
1186
1140 Then you can use the 'hg email' command to mail a series of changesets as a
1187 Then you can use the 'hg email' command to mail a series of changesets as a
1141 patchbomb.
1188 patchbomb.
1142
1189
1143 You can also either configure the method option in the email section to be a
1190 You can also either configure the method option in the email section to be a
1144 sendmail compatible mailer or fill out the [smtp] section so that the
1191 sendmail compatible mailer or fill out the [smtp] section so that the
1145 patchbomb extension can automatically send patchbombs directly from the
1192 patchbomb extension can automatically send patchbombs directly from the
1146 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1193 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1147
1194
1148 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1195 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1149 supply one via configuration or the command line. You can override this to
1196 supply one via configuration or the command line. You can override this to
1150 never prompt by configuring an empty value:
1197 never prompt by configuring an empty value:
1151
1198
1152 [email]
1199 [email]
1153 cc =
1200 cc =
1154
1201
1155 You can control the default inclusion of an introduction message with the
1202 You can control the default inclusion of an introduction message with the
1156 "patchbomb.intro" configuration option. The configuration is always
1203 "patchbomb.intro" configuration option. The configuration is always
1157 overwritten by command line flags like --intro and --desc:
1204 overwritten by command line flags like --intro and --desc:
1158
1205
1159 [patchbomb]
1206 [patchbomb]
1160 intro=auto # include introduction message if more than 1 patch (default)
1207 intro=auto # include introduction message if more than 1 patch (default)
1161 intro=never # never include an introduction message
1208 intro=never # never include an introduction message
1162 intro=always # always include an introduction message
1209 intro=always # always include an introduction message
1163
1210
1164 You can specify a template for flags to be added in subject prefixes. Flags
1211 You can specify a template for flags to be added in subject prefixes. Flags
1165 specified by --flag option are exported as "{flags}" keyword:
1212 specified by --flag option are exported as "{flags}" keyword:
1166
1213
1167 [patchbomb]
1214 [patchbomb]
1168 flagtemplate = "{separate(' ',
1215 flagtemplate = "{separate(' ',
1169 ifeq(branch, 'default', '', branch|upper),
1216 ifeq(branch, 'default', '', branch|upper),
1170 flags)}"
1217 flags)}"
1171
1218
1172 You can set patchbomb to always ask for confirmation by setting
1219 You can set patchbomb to always ask for confirmation by setting
1173 "patchbomb.confirm" to true.
1220 "patchbomb.confirm" to true.
1174
1221
1175 (use 'hg help extensions' for information on enabling extensions)
1222 (use 'hg help extensions' for information on enabling extensions)
1176
1223
1177
1224
1178 Broken disabled extension and command:
1225 Broken disabled extension and command:
1179
1226
1180 $ mkdir hgext
1227 $ mkdir hgext
1181 $ echo > hgext/__init__.py
1228 $ echo > hgext/__init__.py
1182 $ cat > hgext/broken.py <<EOF
1229 $ cat > hgext/broken.py <<EOF
1183 > "broken extension'
1230 > "broken extension'
1184 > EOF
1231 > EOF
1185 $ cat > path.py <<EOF
1232 $ cat > path.py <<EOF
1186 > import os, sys
1233 > import os, sys
1187 > sys.path.insert(0, os.environ['HGEXTPATH'])
1234 > sys.path.insert(0, os.environ['HGEXTPATH'])
1188 > EOF
1235 > EOF
1189 $ HGEXTPATH=`pwd`
1236 $ HGEXTPATH=`pwd`
1190 $ export HGEXTPATH
1237 $ export HGEXTPATH
1191
1238
1192 $ hg --config extensions.path=./path.py help broken
1239 $ hg --config extensions.path=./path.py help broken
1193 broken extension - (no help text available)
1240 broken extension - (no help text available)
1194
1241
1195 (use 'hg help extensions' for information on enabling extensions)
1242 (use 'hg help extensions' for information on enabling extensions)
1196
1243
1197
1244
1198 $ cat > hgext/forest.py <<EOF
1245 $ cat > hgext/forest.py <<EOF
1199 > cmdtable = None
1246 > cmdtable = None
1200 > EOF
1247 > EOF
1201 $ hg --config extensions.path=./path.py help foo > /dev/null
1248 $ hg --config extensions.path=./path.py help foo > /dev/null
1202 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1249 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1203 abort: no such help topic: foo
1250 abort: no such help topic: foo
1204 (try 'hg help --keyword foo')
1251 (try 'hg help --keyword foo')
1205 [255]
1252 [255]
1206
1253
1207 $ cat > throw.py <<EOF
1254 $ cat > throw.py <<EOF
1208 > from mercurial import commands, registrar, util
1255 > from mercurial import commands, registrar, util
1209 > cmdtable = {}
1256 > cmdtable = {}
1210 > command = registrar.command(cmdtable)
1257 > command = registrar.command(cmdtable)
1211 > class Bogon(Exception): pass
1258 > class Bogon(Exception): pass
1212 > @command(b'throw', [], 'hg throw', norepo=True)
1259 > @command(b'throw', [], 'hg throw', norepo=True)
1213 > def throw(ui, **opts):
1260 > def throw(ui, **opts):
1214 > """throws an exception"""
1261 > """throws an exception"""
1215 > raise Bogon()
1262 > raise Bogon()
1216 > EOF
1263 > EOF
1217
1264
1218 No declared supported version, extension complains:
1265 No declared supported version, extension complains:
1219 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1266 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1220 ** Unknown exception encountered with possibly-broken third-party extension throw
1267 ** Unknown exception encountered with possibly-broken third-party extension throw
1221 ** which supports versions unknown of Mercurial.
1268 ** which supports versions unknown of Mercurial.
1222 ** Please disable throw and try your action again.
1269 ** Please disable throw and try your action again.
1223 ** If that fixes the bug please report it to the extension author.
1270 ** If that fixes the bug please report it to the extension author.
1224 ** Python * (glob)
1271 ** Python * (glob)
1225 ** Mercurial Distributed SCM * (glob)
1272 ** Mercurial Distributed SCM * (glob)
1226 ** Extensions loaded: throw
1273 ** Extensions loaded: throw
1227
1274
1228 empty declaration of supported version, extension complains:
1275 empty declaration of supported version, extension complains:
1229 $ echo "testedwith = ''" >> throw.py
1276 $ echo "testedwith = ''" >> throw.py
1230 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1277 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1231 ** Unknown exception encountered with possibly-broken third-party extension throw
1278 ** Unknown exception encountered with possibly-broken third-party extension throw
1232 ** which supports versions unknown of Mercurial.
1279 ** which supports versions unknown of Mercurial.
1233 ** Please disable throw and try your action again.
1280 ** Please disable throw and try your action again.
1234 ** If that fixes the bug please report it to the extension author.
1281 ** If that fixes the bug please report it to the extension author.
1235 ** Python * (glob)
1282 ** Python * (glob)
1236 ** Mercurial Distributed SCM (*) (glob)
1283 ** Mercurial Distributed SCM (*) (glob)
1237 ** Extensions loaded: throw
1284 ** Extensions loaded: throw
1238
1285
1239 If the extension specifies a buglink, show that:
1286 If the extension specifies a buglink, show that:
1240 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1287 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1241 $ rm -f throw.pyc throw.pyo
1288 $ rm -f throw.pyc throw.pyo
1242 $ rm -Rf __pycache__
1289 $ rm -Rf __pycache__
1243 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1290 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1244 ** Unknown exception encountered with possibly-broken third-party extension throw
1291 ** Unknown exception encountered with possibly-broken third-party extension throw
1245 ** which supports versions unknown of Mercurial.
1292 ** which supports versions unknown of Mercurial.
1246 ** Please disable throw and try your action again.
1293 ** Please disable throw and try your action again.
1247 ** If that fixes the bug please report it to http://example.com/bts
1294 ** If that fixes the bug please report it to http://example.com/bts
1248 ** Python * (glob)
1295 ** Python * (glob)
1249 ** Mercurial Distributed SCM (*) (glob)
1296 ** Mercurial Distributed SCM (*) (glob)
1250 ** Extensions loaded: throw
1297 ** Extensions loaded: throw
1251
1298
1252 If the extensions declare outdated versions, accuse the older extension first:
1299 If the extensions declare outdated versions, accuse the older extension first:
1253 $ echo "from mercurial import util" >> older.py
1300 $ echo "from mercurial import util" >> older.py
1254 $ echo "util.version = lambda:'2.2'" >> older.py
1301 $ echo "util.version = lambda:'2.2'" >> older.py
1255 $ echo "testedwith = '1.9.3'" >> older.py
1302 $ echo "testedwith = '1.9.3'" >> older.py
1256 $ echo "testedwith = '2.1.1'" >> throw.py
1303 $ echo "testedwith = '2.1.1'" >> throw.py
1257 $ rm -f throw.pyc throw.pyo
1304 $ rm -f throw.pyc throw.pyo
1258 $ rm -Rf __pycache__
1305 $ rm -Rf __pycache__
1259 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1306 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1260 > throw 2>&1 | egrep '^\*\*'
1307 > throw 2>&1 | egrep '^\*\*'
1261 ** Unknown exception encountered with possibly-broken third-party extension older
1308 ** Unknown exception encountered with possibly-broken third-party extension older
1262 ** which supports versions 1.9 of Mercurial.
1309 ** which supports versions 1.9 of Mercurial.
1263 ** Please disable older and try your action again.
1310 ** Please disable older and try your action again.
1264 ** If that fixes the bug please report it to the extension author.
1311 ** If that fixes the bug please report it to the extension author.
1265 ** Python * (glob)
1312 ** Python * (glob)
1266 ** Mercurial Distributed SCM (version 2.2)
1313 ** Mercurial Distributed SCM (version 2.2)
1267 ** Extensions loaded: throw, older
1314 ** Extensions loaded: throw, older
1268
1315
1269 One extension only tested with older, one only with newer versions:
1316 One extension only tested with older, one only with newer versions:
1270 $ echo "util.version = lambda:'2.1'" >> older.py
1317 $ echo "util.version = lambda:'2.1'" >> older.py
1271 $ rm -f older.pyc older.pyo
1318 $ rm -f older.pyc older.pyo
1272 $ rm -Rf __pycache__
1319 $ rm -Rf __pycache__
1273 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1320 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1274 > throw 2>&1 | egrep '^\*\*'
1321 > throw 2>&1 | egrep '^\*\*'
1275 ** Unknown exception encountered with possibly-broken third-party extension older
1322 ** Unknown exception encountered with possibly-broken third-party extension older
1276 ** which supports versions 1.9 of Mercurial.
1323 ** which supports versions 1.9 of Mercurial.
1277 ** Please disable older and try your action again.
1324 ** Please disable older and try your action again.
1278 ** If that fixes the bug please report it to the extension author.
1325 ** If that fixes the bug please report it to the extension author.
1279 ** Python * (glob)
1326 ** Python * (glob)
1280 ** Mercurial Distributed SCM (version 2.1)
1327 ** Mercurial Distributed SCM (version 2.1)
1281 ** Extensions loaded: throw, older
1328 ** Extensions loaded: throw, older
1282
1329
1283 Older extension is tested with current version, the other only with newer:
1330 Older extension is tested with current version, the other only with newer:
1284 $ echo "util.version = lambda:'1.9.3'" >> older.py
1331 $ echo "util.version = lambda:'1.9.3'" >> older.py
1285 $ rm -f older.pyc older.pyo
1332 $ rm -f older.pyc older.pyo
1286 $ rm -Rf __pycache__
1333 $ rm -Rf __pycache__
1287 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1334 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1288 > throw 2>&1 | egrep '^\*\*'
1335 > throw 2>&1 | egrep '^\*\*'
1289 ** Unknown exception encountered with possibly-broken third-party extension throw
1336 ** Unknown exception encountered with possibly-broken third-party extension throw
1290 ** which supports versions 2.1 of Mercurial.
1337 ** which supports versions 2.1 of Mercurial.
1291 ** Please disable throw and try your action again.
1338 ** Please disable throw and try your action again.
1292 ** If that fixes the bug please report it to http://example.com/bts
1339 ** If that fixes the bug please report it to http://example.com/bts
1293 ** Python * (glob)
1340 ** Python * (glob)
1294 ** Mercurial Distributed SCM (version 1.9.3)
1341 ** Mercurial Distributed SCM (version 1.9.3)
1295 ** Extensions loaded: throw, older
1342 ** Extensions loaded: throw, older
1296
1343
1297 Ability to point to a different point
1344 Ability to point to a different point
1298 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1345 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1299 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1346 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1300 ** unknown exception encountered, please report by visiting
1347 ** unknown exception encountered, please report by visiting
1301 ** Your Local Goat Lenders
1348 ** Your Local Goat Lenders
1302 ** Python * (glob)
1349 ** Python * (glob)
1303 ** Mercurial Distributed SCM (*) (glob)
1350 ** Mercurial Distributed SCM (*) (glob)
1304 ** Extensions loaded: throw, older
1351 ** Extensions loaded: throw, older
1305
1352
1306 Declare the version as supporting this hg version, show regular bts link:
1353 Declare the version as supporting this hg version, show regular bts link:
1307 $ hgver=`hg debuginstall -T '{hgver}'`
1354 $ hgver=`hg debuginstall -T '{hgver}'`
1308 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1355 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1309 $ if [ -z "$hgver" ]; then
1356 $ if [ -z "$hgver" ]; then
1310 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1357 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1311 > fi
1358 > fi
1312 $ rm -f throw.pyc throw.pyo
1359 $ rm -f throw.pyc throw.pyo
1313 $ rm -Rf __pycache__
1360 $ rm -Rf __pycache__
1314 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1361 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1315 ** unknown exception encountered, please report by visiting
1362 ** unknown exception encountered, please report by visiting
1316 ** https://mercurial-scm.org/wiki/BugTracker
1363 ** https://mercurial-scm.org/wiki/BugTracker
1317 ** Python * (glob)
1364 ** Python * (glob)
1318 ** Mercurial Distributed SCM (*) (glob)
1365 ** Mercurial Distributed SCM (*) (glob)
1319 ** Extensions loaded: throw
1366 ** Extensions loaded: throw
1320
1367
1321 Patch version is ignored during compatibility check
1368 Patch version is ignored during compatibility check
1322 $ echo "testedwith = '3.2'" >> throw.py
1369 $ echo "testedwith = '3.2'" >> throw.py
1323 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1370 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1324 $ rm -f throw.pyc throw.pyo
1371 $ rm -f throw.pyc throw.pyo
1325 $ rm -Rf __pycache__
1372 $ rm -Rf __pycache__
1326 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1373 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1327 ** unknown exception encountered, please report by visiting
1374 ** unknown exception encountered, please report by visiting
1328 ** https://mercurial-scm.org/wiki/BugTracker
1375 ** https://mercurial-scm.org/wiki/BugTracker
1329 ** Python * (glob)
1376 ** Python * (glob)
1330 ** Mercurial Distributed SCM (*) (glob)
1377 ** Mercurial Distributed SCM (*) (glob)
1331 ** Extensions loaded: throw
1378 ** Extensions loaded: throw
1332
1379
1333 Test version number support in 'hg version':
1380 Test version number support in 'hg version':
1334 $ echo '__version__ = (1, 2, 3)' >> throw.py
1381 $ echo '__version__ = (1, 2, 3)' >> throw.py
1335 $ rm -f throw.pyc throw.pyo
1382 $ rm -f throw.pyc throw.pyo
1336 $ rm -Rf __pycache__
1383 $ rm -Rf __pycache__
1337 $ hg version -v
1384 $ hg version -v
1338 Mercurial Distributed SCM (version *) (glob)
1385 Mercurial Distributed SCM (version *) (glob)
1339 (see https://mercurial-scm.org for more information)
1386 (see https://mercurial-scm.org for more information)
1340
1387
1341 Copyright (C) 2005-* Matt Mackall and others (glob)
1388 Copyright (C) 2005-* Matt Mackall and others (glob)
1342 This is free software; see the source for copying conditions. There is NO
1389 This is free software; see the source for copying conditions. There is NO
1343 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1390 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1344
1391
1345 Enabled extensions:
1392 Enabled extensions:
1346
1393
1347
1394
1348 $ hg version -v --config extensions.throw=throw.py
1395 $ hg version -v --config extensions.throw=throw.py
1349 Mercurial Distributed SCM (version *) (glob)
1396 Mercurial Distributed SCM (version *) (glob)
1350 (see https://mercurial-scm.org for more information)
1397 (see https://mercurial-scm.org for more information)
1351
1398
1352 Copyright (C) 2005-* Matt Mackall and others (glob)
1399 Copyright (C) 2005-* Matt Mackall and others (glob)
1353 This is free software; see the source for copying conditions. There is NO
1400 This is free software; see the source for copying conditions. There is NO
1354 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1401 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1355
1402
1356 Enabled extensions:
1403 Enabled extensions:
1357
1404
1358 throw external 1.2.3
1405 throw external 1.2.3
1359 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1406 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1360 $ rm -f throw.pyc throw.pyo
1407 $ rm -f throw.pyc throw.pyo
1361 $ rm -Rf __pycache__
1408 $ rm -Rf __pycache__
1362 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1409 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1363 Mercurial Distributed SCM (version *) (glob)
1410 Mercurial Distributed SCM (version *) (glob)
1364 (see https://mercurial-scm.org for more information)
1411 (see https://mercurial-scm.org for more information)
1365
1412
1366 Copyright (C) 2005-* Matt Mackall and others (glob)
1413 Copyright (C) 2005-* Matt Mackall and others (glob)
1367 This is free software; see the source for copying conditions. There is NO
1414 This is free software; see the source for copying conditions. There is NO
1368 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1415 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1369
1416
1370 Enabled extensions:
1417 Enabled extensions:
1371
1418
1372 throw external 1.twentythree
1419 throw external 1.twentythree
1373 strip internal
1420 strip internal
1374
1421
1375 $ hg version -q --config extensions.throw=throw.py
1422 $ hg version -q --config extensions.throw=throw.py
1376 Mercurial Distributed SCM (version *) (glob)
1423 Mercurial Distributed SCM (version *) (glob)
1377
1424
1378 Test JSON output of version:
1425 Test JSON output of version:
1379
1426
1380 $ hg version -Tjson
1427 $ hg version -Tjson
1381 [
1428 [
1382 {
1429 {
1383 "extensions": [],
1430 "extensions": [],
1384 "ver": "*" (glob)
1431 "ver": "*" (glob)
1385 }
1432 }
1386 ]
1433 ]
1387
1434
1388 $ hg version --config extensions.throw=throw.py -Tjson
1435 $ hg version --config extensions.throw=throw.py -Tjson
1389 [
1436 [
1390 {
1437 {
1391 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1438 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1392 "ver": "3.2.2"
1439 "ver": "3.2.2"
1393 }
1440 }
1394 ]
1441 ]
1395
1442
1396 $ hg version --config extensions.strip= -Tjson
1443 $ hg version --config extensions.strip= -Tjson
1397 [
1444 [
1398 {
1445 {
1399 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1446 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1400 "ver": "*" (glob)
1447 "ver": "*" (glob)
1401 }
1448 }
1402 ]
1449 ]
1403
1450
1404 Test template output of version:
1451 Test template output of version:
1405
1452
1406 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1453 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1407 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1454 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1408 throw 1.twentythree (external)
1455 throw 1.twentythree (external)
1409 strip (internal)
1456 strip (internal)
1410
1457
1411 Refuse to load extensions with minimum version requirements
1458 Refuse to load extensions with minimum version requirements
1412
1459
1413 $ cat > minversion1.py << EOF
1460 $ cat > minversion1.py << EOF
1414 > from mercurial import util
1461 > from mercurial import util
1415 > util.version = lambda: '3.5.2'
1462 > util.version = lambda: '3.5.2'
1416 > minimumhgversion = '3.6'
1463 > minimumhgversion = '3.6'
1417 > EOF
1464 > EOF
1418 $ hg --config extensions.minversion=minversion1.py version
1465 $ hg --config extensions.minversion=minversion1.py version
1419 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1466 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1420 Mercurial Distributed SCM (version 3.5.2)
1467 Mercurial Distributed SCM (version 3.5.2)
1421 (see https://mercurial-scm.org for more information)
1468 (see https://mercurial-scm.org for more information)
1422
1469
1423 Copyright (C) 2005-* Matt Mackall and others (glob)
1470 Copyright (C) 2005-* Matt Mackall and others (glob)
1424 This is free software; see the source for copying conditions. There is NO
1471 This is free software; see the source for copying conditions. There is NO
1425 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1472 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1426
1473
1427 $ cat > minversion2.py << EOF
1474 $ cat > minversion2.py << EOF
1428 > from mercurial import util
1475 > from mercurial import util
1429 > util.version = lambda: '3.6'
1476 > util.version = lambda: '3.6'
1430 > minimumhgversion = '3.7'
1477 > minimumhgversion = '3.7'
1431 > EOF
1478 > EOF
1432 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1479 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1433 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1480 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1434
1481
1435 Can load version that is only off by point release
1482 Can load version that is only off by point release
1436
1483
1437 $ cat > minversion2.py << EOF
1484 $ cat > minversion2.py << EOF
1438 > from mercurial import util
1485 > from mercurial import util
1439 > util.version = lambda: '3.6.1'
1486 > util.version = lambda: '3.6.1'
1440 > minimumhgversion = '3.6'
1487 > minimumhgversion = '3.6'
1441 > EOF
1488 > EOF
1442 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1489 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1443 [1]
1490 [1]
1444
1491
1445 Can load minimum version identical to current
1492 Can load minimum version identical to current
1446
1493
1447 $ cat > minversion3.py << EOF
1494 $ cat > minversion3.py << EOF
1448 > from mercurial import util
1495 > from mercurial import util
1449 > util.version = lambda: '3.5'
1496 > util.version = lambda: '3.5'
1450 > minimumhgversion = '3.5'
1497 > minimumhgversion = '3.5'
1451 > EOF
1498 > EOF
1452 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1499 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1453 [1]
1500 [1]
1454
1501
1455 Restore HGRCPATH
1502 Restore HGRCPATH
1456
1503
1457 $ HGRCPATH=$ORGHGRCPATH
1504 $ HGRCPATH=$ORGHGRCPATH
1458 $ export HGRCPATH
1505 $ export HGRCPATH
1459
1506
1460 Commands handling multiple repositories at a time should invoke only
1507 Commands handling multiple repositories at a time should invoke only
1461 "reposetup()" of extensions enabling in the target repository.
1508 "reposetup()" of extensions enabling in the target repository.
1462
1509
1463 $ mkdir reposetup-test
1510 $ mkdir reposetup-test
1464 $ cd reposetup-test
1511 $ cd reposetup-test
1465
1512
1466 $ cat > $TESTTMP/reposetuptest.py <<EOF
1513 $ cat > $TESTTMP/reposetuptest.py <<EOF
1467 > from mercurial import extensions
1514 > from mercurial import extensions
1468 > def reposetup(ui, repo):
1515 > def reposetup(ui, repo):
1469 > ui.write('reposetup() for %s\n' % (repo.root))
1516 > ui.write('reposetup() for %s\n' % (repo.root))
1470 > ui.flush()
1517 > ui.flush()
1471 > EOF
1518 > EOF
1472 $ hg init src
1519 $ hg init src
1473 $ echo a > src/a
1520 $ echo a > src/a
1474 $ hg -R src commit -Am '#0 at src/a'
1521 $ hg -R src commit -Am '#0 at src/a'
1475 adding a
1522 adding a
1476 $ echo '[extensions]' >> src/.hg/hgrc
1523 $ echo '[extensions]' >> src/.hg/hgrc
1477 $ echo '# enable extension locally' >> src/.hg/hgrc
1524 $ echo '# enable extension locally' >> src/.hg/hgrc
1478 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1525 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1479 $ hg -R src status
1526 $ hg -R src status
1480 reposetup() for $TESTTMP/reposetup-test/src (glob)
1527 reposetup() for $TESTTMP/reposetup-test/src (glob)
1481
1528
1482 $ hg clone -U src clone-dst1
1529 $ hg clone -U src clone-dst1
1483 reposetup() for $TESTTMP/reposetup-test/src (glob)
1530 reposetup() for $TESTTMP/reposetup-test/src (glob)
1484 $ hg init push-dst1
1531 $ hg init push-dst1
1485 $ hg -q -R src push push-dst1
1532 $ hg -q -R src push push-dst1
1486 reposetup() for $TESTTMP/reposetup-test/src (glob)
1533 reposetup() for $TESTTMP/reposetup-test/src (glob)
1487 $ hg init pull-src1
1534 $ hg init pull-src1
1488 $ hg -q -R pull-src1 pull src
1535 $ hg -q -R pull-src1 pull src
1489 reposetup() for $TESTTMP/reposetup-test/src (glob)
1536 reposetup() for $TESTTMP/reposetup-test/src (glob)
1490
1537
1491 $ cat <<EOF >> $HGRCPATH
1538 $ cat <<EOF >> $HGRCPATH
1492 > [extensions]
1539 > [extensions]
1493 > # disable extension globally and explicitly
1540 > # disable extension globally and explicitly
1494 > reposetuptest = !
1541 > reposetuptest = !
1495 > EOF
1542 > EOF
1496 $ hg clone -U src clone-dst2
1543 $ hg clone -U src clone-dst2
1497 reposetup() for $TESTTMP/reposetup-test/src (glob)
1544 reposetup() for $TESTTMP/reposetup-test/src (glob)
1498 $ hg init push-dst2
1545 $ hg init push-dst2
1499 $ hg -q -R src push push-dst2
1546 $ hg -q -R src push push-dst2
1500 reposetup() for $TESTTMP/reposetup-test/src (glob)
1547 reposetup() for $TESTTMP/reposetup-test/src (glob)
1501 $ hg init pull-src2
1548 $ hg init pull-src2
1502 $ hg -q -R pull-src2 pull src
1549 $ hg -q -R pull-src2 pull src
1503 reposetup() for $TESTTMP/reposetup-test/src (glob)
1550 reposetup() for $TESTTMP/reposetup-test/src (glob)
1504
1551
1505 $ cat <<EOF >> $HGRCPATH
1552 $ cat <<EOF >> $HGRCPATH
1506 > [extensions]
1553 > [extensions]
1507 > # enable extension globally
1554 > # enable extension globally
1508 > reposetuptest = $TESTTMP/reposetuptest.py
1555 > reposetuptest = $TESTTMP/reposetuptest.py
1509 > EOF
1556 > EOF
1510 $ hg clone -U src clone-dst3
1557 $ hg clone -U src clone-dst3
1511 reposetup() for $TESTTMP/reposetup-test/src (glob)
1558 reposetup() for $TESTTMP/reposetup-test/src (glob)
1512 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1559 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1513 $ hg init push-dst3
1560 $ hg init push-dst3
1514 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1561 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1515 $ hg -q -R src push push-dst3
1562 $ hg -q -R src push push-dst3
1516 reposetup() for $TESTTMP/reposetup-test/src (glob)
1563 reposetup() for $TESTTMP/reposetup-test/src (glob)
1517 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1564 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1518 $ hg init pull-src3
1565 $ hg init pull-src3
1519 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1566 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1520 $ hg -q -R pull-src3 pull src
1567 $ hg -q -R pull-src3 pull src
1521 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1568 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1522 reposetup() for $TESTTMP/reposetup-test/src (glob)
1569 reposetup() for $TESTTMP/reposetup-test/src (glob)
1523
1570
1524 $ echo '[extensions]' >> src/.hg/hgrc
1571 $ echo '[extensions]' >> src/.hg/hgrc
1525 $ echo '# disable extension locally' >> src/.hg/hgrc
1572 $ echo '# disable extension locally' >> src/.hg/hgrc
1526 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1573 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1527 $ hg clone -U src clone-dst4
1574 $ hg clone -U src clone-dst4
1528 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1575 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1529 $ hg init push-dst4
1576 $ hg init push-dst4
1530 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1577 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1531 $ hg -q -R src push push-dst4
1578 $ hg -q -R src push push-dst4
1532 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1579 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1533 $ hg init pull-src4
1580 $ hg init pull-src4
1534 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1581 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1535 $ hg -q -R pull-src4 pull src
1582 $ hg -q -R pull-src4 pull src
1536 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1583 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1537
1584
1538 disabling in command line overlays with all configuration
1585 disabling in command line overlays with all configuration
1539 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1586 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1540 $ hg --config extensions.reposetuptest=! init push-dst5
1587 $ hg --config extensions.reposetuptest=! init push-dst5
1541 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1588 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1542 $ hg --config extensions.reposetuptest=! init pull-src5
1589 $ hg --config extensions.reposetuptest=! init pull-src5
1543 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1590 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1544
1591
1545 $ cat <<EOF >> $HGRCPATH
1592 $ cat <<EOF >> $HGRCPATH
1546 > [extensions]
1593 > [extensions]
1547 > # disable extension globally and explicitly
1594 > # disable extension globally and explicitly
1548 > reposetuptest = !
1595 > reposetuptest = !
1549 > EOF
1596 > EOF
1550 $ hg init parent
1597 $ hg init parent
1551 $ hg init parent/sub1
1598 $ hg init parent/sub1
1552 $ echo 1 > parent/sub1/1
1599 $ echo 1 > parent/sub1/1
1553 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1600 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1554 adding 1
1601 adding 1
1555 $ hg init parent/sub2
1602 $ hg init parent/sub2
1556 $ hg init parent/sub2/sub21
1603 $ hg init parent/sub2/sub21
1557 $ echo 21 > parent/sub2/sub21/21
1604 $ echo 21 > parent/sub2/sub21/21
1558 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1605 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1559 adding 21
1606 adding 21
1560 $ cat > parent/sub2/.hgsub <<EOF
1607 $ cat > parent/sub2/.hgsub <<EOF
1561 > sub21 = sub21
1608 > sub21 = sub21
1562 > EOF
1609 > EOF
1563 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1610 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1564 adding .hgsub
1611 adding .hgsub
1565 $ hg init parent/sub3
1612 $ hg init parent/sub3
1566 $ echo 3 > parent/sub3/3
1613 $ echo 3 > parent/sub3/3
1567 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1614 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1568 adding 3
1615 adding 3
1569 $ cat > parent/.hgsub <<EOF
1616 $ cat > parent/.hgsub <<EOF
1570 > sub1 = sub1
1617 > sub1 = sub1
1571 > sub2 = sub2
1618 > sub2 = sub2
1572 > sub3 = sub3
1619 > sub3 = sub3
1573 > EOF
1620 > EOF
1574 $ hg -R parent commit -Am '#0 at parent'
1621 $ hg -R parent commit -Am '#0 at parent'
1575 adding .hgsub
1622 adding .hgsub
1576 $ echo '[extensions]' >> parent/.hg/hgrc
1623 $ echo '[extensions]' >> parent/.hg/hgrc
1577 $ echo '# enable extension locally' >> parent/.hg/hgrc
1624 $ echo '# enable extension locally' >> parent/.hg/hgrc
1578 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1625 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1579 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1626 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1580 $ hg -R parent status -S -A
1627 $ hg -R parent status -S -A
1581 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1628 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1582 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1629 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1583 C .hgsub
1630 C .hgsub
1584 C .hgsubstate
1631 C .hgsubstate
1585 C sub1/1
1632 C sub1/1
1586 C sub2/.hgsub
1633 C sub2/.hgsub
1587 C sub2/.hgsubstate
1634 C sub2/.hgsubstate
1588 C sub2/sub21/21
1635 C sub2/sub21/21
1589 C sub3/3
1636 C sub3/3
1590
1637
1591 $ cd ..
1638 $ cd ..
1592
1639
1593 Prohibit registration of commands that don't use @command (issue5137)
1640 Prohibit registration of commands that don't use @command (issue5137)
1594
1641
1595 $ hg init deprecated
1642 $ hg init deprecated
1596 $ cd deprecated
1643 $ cd deprecated
1597
1644
1598 $ cat <<EOF > deprecatedcmd.py
1645 $ cat <<EOF > deprecatedcmd.py
1599 > def deprecatedcmd(repo, ui):
1646 > def deprecatedcmd(repo, ui):
1600 > pass
1647 > pass
1601 > cmdtable = {
1648 > cmdtable = {
1602 > 'deprecatedcmd': (deprecatedcmd, [], ''),
1649 > 'deprecatedcmd': (deprecatedcmd, [], ''),
1603 > }
1650 > }
1604 > EOF
1651 > EOF
1605 $ cat <<EOF > .hg/hgrc
1652 $ cat <<EOF > .hg/hgrc
1606 > [extensions]
1653 > [extensions]
1607 > deprecatedcmd = `pwd`/deprecatedcmd.py
1654 > deprecatedcmd = `pwd`/deprecatedcmd.py
1608 > mq = !
1655 > mq = !
1609 > hgext.mq = !
1656 > hgext.mq = !
1610 > hgext/mq = !
1657 > hgext/mq = !
1611 > EOF
1658 > EOF
1612
1659
1613 $ hg deprecatedcmd > /dev/null
1660 $ hg deprecatedcmd > /dev/null
1614 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1661 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1615 *** (use @command decorator to register 'deprecatedcmd')
1662 *** (use @command decorator to register 'deprecatedcmd')
1616 hg: unknown command 'deprecatedcmd'
1663 hg: unknown command 'deprecatedcmd'
1617 [255]
1664 [255]
1618
1665
1619 the extension shouldn't be loaded at all so the mq works:
1666 the extension shouldn't be loaded at all so the mq works:
1620
1667
1621 $ hg qseries --config extensions.mq= > /dev/null
1668 $ hg qseries --config extensions.mq= > /dev/null
1622 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1669 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1623 *** (use @command decorator to register 'deprecatedcmd')
1670 *** (use @command decorator to register 'deprecatedcmd')
1624
1671
1625 $ cd ..
1672 $ cd ..
1626
1673
1627 Test synopsis and docstring extending
1674 Test synopsis and docstring extending
1628
1675
1629 $ hg init exthelp
1676 $ hg init exthelp
1630 $ cat > exthelp.py <<EOF
1677 $ cat > exthelp.py <<EOF
1631 > from mercurial import commands, extensions
1678 > from mercurial import commands, extensions
1632 > def exbookmarks(orig, *args, **opts):
1679 > def exbookmarks(orig, *args, **opts):
1633 > return orig(*args, **opts)
1680 > return orig(*args, **opts)
1634 > def uisetup(ui):
1681 > def uisetup(ui):
1635 > synopsis = ' GREPME [--foo] [-x]'
1682 > synopsis = ' GREPME [--foo] [-x]'
1636 > docstring = '''
1683 > docstring = '''
1637 > GREPME make sure that this is in the help!
1684 > GREPME make sure that this is in the help!
1638 > '''
1685 > '''
1639 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1686 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1640 > synopsis, docstring)
1687 > synopsis, docstring)
1641 > EOF
1688 > EOF
1642 $ abspath=`pwd`/exthelp.py
1689 $ abspath=`pwd`/exthelp.py
1643 $ echo '[extensions]' >> $HGRCPATH
1690 $ echo '[extensions]' >> $HGRCPATH
1644 $ echo "exthelp = $abspath" >> $HGRCPATH
1691 $ echo "exthelp = $abspath" >> $HGRCPATH
1645 $ cd exthelp
1692 $ cd exthelp
1646 $ hg help bookmarks | grep GREPME
1693 $ hg help bookmarks | grep GREPME
1647 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1694 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1648 GREPME make sure that this is in the help!
1695 GREPME make sure that this is in the help!
1649 $ cd ..
1696 $ cd ..
1650
1697
1651 Show deprecation warning for the use of cmdutil.command
1698 Show deprecation warning for the use of cmdutil.command
1652
1699
1653 $ cat > nonregistrar.py <<EOF
1700 $ cat > nonregistrar.py <<EOF
1654 > from mercurial import cmdutil
1701 > from mercurial import cmdutil
1655 > cmdtable = {}
1702 > cmdtable = {}
1656 > command = cmdutil.command(cmdtable)
1703 > command = cmdutil.command(cmdtable)
1657 > @command(b'foo', [], norepo=True)
1704 > @command(b'foo', [], norepo=True)
1658 > def foo(ui):
1705 > def foo(ui):
1659 > pass
1706 > pass
1660 > EOF
1707 > EOF
1661
1708
1662 $ hg --config extensions.nonregistrar=`pwd`/nonregistrar.py version > /dev/null
1709 $ hg --config extensions.nonregistrar=`pwd`/nonregistrar.py version > /dev/null
1663 devel-warn: cmdutil.command is deprecated, use registrar.command to register 'foo'
1710 devel-warn: cmdutil.command is deprecated, use registrar.command to register 'foo'
1664 (compatibility will be dropped after Mercurial-4.6, update your code.) * (glob)
1711 (compatibility will be dropped after Mercurial-4.6, update your code.) * (glob)
1665
1666 Make sure a broken uisetup doesn't globally break hg:
1667 $ cat > $TESTTMP/baduisetup.py <<EOF
1668 > from mercurial import (
1669 > bdiff,
1670 > extensions,
1671 > )
1672 >
1673 > def blockswrapper(orig, *args, **kwargs):
1674 > return orig(*args, **kwargs)
1675 >
1676 > def uisetup(ui):
1677 > extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
1678 > EOF
1679 $ cat >> $HGRCPATH <<EOF
1680 > [extensions]
1681 > baduisetup = $TESTTMP/baduisetup.py
1682 > EOF
1683
1684 Even though the extension fails during uisetup, hg is still basically usable:
1685 $ hg version
1686 \*\*\* failed to set up extension baduisetup: No module named (mercurial\.)?bdiff (re)
1687 Mercurial Distributed SCM (version *) (glob)
1688 (see https://mercurial-scm.org for more information)
1689
1690 Copyright (C) 2005-2017 Matt Mackall and others
1691 This is free software; see the source for copying conditions. There is NO
1692 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1693
1694 $ hg version --traceback
1695 Traceback (most recent call last):
1696 File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
1697 uisetup(ui)
1698 File "$TESTTMP/baduisetup.py", line 10, in uisetup
1699 extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
1700 File "*/mercurial/extensions.py", line *, in wrapfunction (glob)
1701 origfn = getattr(container, funcname)
1702 File "*/hgdemandimport/demandimportpy2.py", line *, in __getattr__ (glob)
1703 self._load()
1704 File "*/hgdemandimport/demandimportpy2.py", line *, in _load (glob)
1705 mod = _hgextimport(_origimport, head, globals, locals, None, level)
1706 File "*/hgdemandimport/demandimportpy2.py", line *, in _hgextimport (glob)
1707 return importfunc(name, globals, *args, **kwargs)
1708 ImportError: No module named (mercurial\.)?bdiff (re)
1709 \*\*\* failed to set up extension baduisetup: No module named (mercurial\.)?bdiff (re)
1710 Mercurial Distributed SCM (version *) (glob)
1711 (see https://mercurial-scm.org for more information)
1712
1713 Copyright (C) 2005-2017 Matt Mackall and others
1714 This is free software; see the source for copying conditions. There is NO
1715 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
General Comments 0
You need to be logged in to leave comments. Login now