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