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