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