##// END OF EJS Templates
tests: glob copyright years in test-extension.t...
av6 -
r35791:eb878d86 default
parent child Browse files
Show More
@@ -1,1714 +1,1714 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
183 $TESTTMP/a
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
197 $TESTTMP/a
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
248 $TESTTMP/a
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
280 $TESTTMP/a
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
517 #endif
518
518
519 Make sure a broken uisetup doesn't globally break hg:
519 Make sure a broken uisetup doesn't globally break hg:
520 $ cat > $TESTTMP/baduisetup.py <<EOF
520 $ cat > $TESTTMP/baduisetup.py <<EOF
521 > def uisetup(ui):
521 > def uisetup(ui):
522 > 1/0
522 > 1/0
523 > EOF
523 > EOF
524
524
525 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:
526 $ hg --config extensions.baduisetup=$TESTTMP/baduisetup.py version
526 $ hg --config extensions.baduisetup=$TESTTMP/baduisetup.py version
527 Traceback (most recent call last):
527 Traceback (most recent call last):
528 File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
528 File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
529 uisetup(ui)
529 uisetup(ui)
530 File "$TESTTMP/baduisetup.py", line 2, in uisetup
530 File "$TESTTMP/baduisetup.py", line 2, in uisetup
531 1/0
531 1/0
532 ZeroDivisionError: integer division or modulo by zero
532 ZeroDivisionError: integer division or modulo by zero
533 *** failed to set up extension baduisetup: integer division or modulo by zero
533 *** failed to set up extension baduisetup: integer division or modulo by zero
534 Mercurial Distributed SCM (version *) (glob)
534 Mercurial Distributed SCM (version *) (glob)
535 (see https://mercurial-scm.org for more information)
535 (see https://mercurial-scm.org for more information)
536
536
537 Copyright (C) 2005-2017 Matt Mackall and others
537 Copyright (C) 2005-* Matt Mackall and others (glob)
538 This is free software; see the source for copying conditions. There is NO
538 This is free software; see the source for copying conditions. There is NO
539 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
539 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
540
540
541 $ cd ..
541 $ cd ..
542
542
543 hide outer repo
543 hide outer repo
544 $ hg init
544 $ hg init
545
545
546 $ cat > empty.py <<EOF
546 $ cat > empty.py <<EOF
547 > '''empty cmdtable
547 > '''empty cmdtable
548 > '''
548 > '''
549 > cmdtable = {}
549 > cmdtable = {}
550 > EOF
550 > EOF
551 $ emptypath=`pwd`/empty.py
551 $ emptypath=`pwd`/empty.py
552 $ echo "empty = $emptypath" >> $HGRCPATH
552 $ echo "empty = $emptypath" >> $HGRCPATH
553 $ hg help empty
553 $ hg help empty
554 empty extension - empty cmdtable
554 empty extension - empty cmdtable
555
555
556 no commands defined
556 no commands defined
557
557
558
558
559 $ echo 'empty = !' >> $HGRCPATH
559 $ echo 'empty = !' >> $HGRCPATH
560
560
561 $ cat > debugextension.py <<EOF
561 $ cat > debugextension.py <<EOF
562 > '''only debugcommands
562 > '''only debugcommands
563 > '''
563 > '''
564 > from mercurial import registrar
564 > from mercurial import registrar
565 > cmdtable = {}
565 > cmdtable = {}
566 > command = registrar.command(cmdtable)
566 > command = registrar.command(cmdtable)
567 > @command(b'debugfoobar', [], 'hg debugfoobar')
567 > @command(b'debugfoobar', [], 'hg debugfoobar')
568 > def debugfoobar(ui, repo, *args, **opts):
568 > def debugfoobar(ui, repo, *args, **opts):
569 > "yet another debug command"
569 > "yet another debug command"
570 > pass
570 > pass
571 > @command(b'foo', [], 'hg foo')
571 > @command(b'foo', [], 'hg foo')
572 > def foo(ui, repo, *args, **opts):
572 > def foo(ui, repo, *args, **opts):
573 > """yet another foo command
573 > """yet another foo command
574 > This command has been DEPRECATED since forever.
574 > This command has been DEPRECATED since forever.
575 > """
575 > """
576 > pass
576 > pass
577 > EOF
577 > EOF
578 $ debugpath=`pwd`/debugextension.py
578 $ debugpath=`pwd`/debugextension.py
579 $ echo "debugextension = $debugpath" >> $HGRCPATH
579 $ echo "debugextension = $debugpath" >> $HGRCPATH
580
580
581 $ hg help debugextension
581 $ hg help debugextension
582 hg debugextensions
582 hg debugextensions
583
583
584 show information about active extensions
584 show information about active extensions
585
585
586 options:
586 options:
587
587
588 (some details hidden, use --verbose to show complete help)
588 (some details hidden, use --verbose to show complete help)
589
589
590
590
591 $ hg --verbose help debugextension
591 $ hg --verbose help debugextension
592 hg debugextensions
592 hg debugextensions
593
593
594 show information about active extensions
594 show information about active extensions
595
595
596 options:
596 options:
597
597
598 -T --template TEMPLATE display with template (EXPERIMENTAL)
598 -T --template TEMPLATE display with template (EXPERIMENTAL)
599
599
600 global options ([+] can be repeated):
600 global options ([+] can be repeated):
601
601
602 -R --repository REPO repository root directory or name of overlay bundle
602 -R --repository REPO repository root directory or name of overlay bundle
603 file
603 file
604 --cwd DIR change working directory
604 --cwd DIR change working directory
605 -y --noninteractive do not prompt, automatically pick the first choice for
605 -y --noninteractive do not prompt, automatically pick the first choice for
606 all prompts
606 all prompts
607 -q --quiet suppress output
607 -q --quiet suppress output
608 -v --verbose enable additional output
608 -v --verbose enable additional output
609 --color TYPE when to colorize (boolean, always, auto, never, or
609 --color TYPE when to colorize (boolean, always, auto, never, or
610 debug)
610 debug)
611 --config CONFIG [+] set/override config option (use 'section.name=value')
611 --config CONFIG [+] set/override config option (use 'section.name=value')
612 --debug enable debugging output
612 --debug enable debugging output
613 --debugger start debugger
613 --debugger start debugger
614 --encoding ENCODE set the charset encoding (default: ascii)
614 --encoding ENCODE set the charset encoding (default: ascii)
615 --encodingmode MODE set the charset encoding mode (default: strict)
615 --encodingmode MODE set the charset encoding mode (default: strict)
616 --traceback always print a traceback on exception
616 --traceback always print a traceback on exception
617 --time time how long the command takes
617 --time time how long the command takes
618 --profile print command execution profile
618 --profile print command execution profile
619 --version output version information and exit
619 --version output version information and exit
620 -h --help display help and exit
620 -h --help display help and exit
621 --hidden consider hidden changesets
621 --hidden consider hidden changesets
622 --pager TYPE when to paginate (boolean, always, auto, or never)
622 --pager TYPE when to paginate (boolean, always, auto, or never)
623 (default: auto)
623 (default: auto)
624
624
625
625
626
626
627
627
628
628
629
629
630 $ hg --debug help debugextension
630 $ hg --debug help debugextension
631 hg debugextensions
631 hg debugextensions
632
632
633 show information about active extensions
633 show information about active extensions
634
634
635 options:
635 options:
636
636
637 -T --template TEMPLATE display with template (EXPERIMENTAL)
637 -T --template TEMPLATE display with template (EXPERIMENTAL)
638
638
639 global options ([+] can be repeated):
639 global options ([+] can be repeated):
640
640
641 -R --repository REPO repository root directory or name of overlay bundle
641 -R --repository REPO repository root directory or name of overlay bundle
642 file
642 file
643 --cwd DIR change working directory
643 --cwd DIR change working directory
644 -y --noninteractive do not prompt, automatically pick the first choice for
644 -y --noninteractive do not prompt, automatically pick the first choice for
645 all prompts
645 all prompts
646 -q --quiet suppress output
646 -q --quiet suppress output
647 -v --verbose enable additional output
647 -v --verbose enable additional output
648 --color TYPE when to colorize (boolean, always, auto, never, or
648 --color TYPE when to colorize (boolean, always, auto, never, or
649 debug)
649 debug)
650 --config CONFIG [+] set/override config option (use 'section.name=value')
650 --config CONFIG [+] set/override config option (use 'section.name=value')
651 --debug enable debugging output
651 --debug enable debugging output
652 --debugger start debugger
652 --debugger start debugger
653 --encoding ENCODE set the charset encoding (default: ascii)
653 --encoding ENCODE set the charset encoding (default: ascii)
654 --encodingmode MODE set the charset encoding mode (default: strict)
654 --encodingmode MODE set the charset encoding mode (default: strict)
655 --traceback always print a traceback on exception
655 --traceback always print a traceback on exception
656 --time time how long the command takes
656 --time time how long the command takes
657 --profile print command execution profile
657 --profile print command execution profile
658 --version output version information and exit
658 --version output version information and exit
659 -h --help display help and exit
659 -h --help display help and exit
660 --hidden consider hidden changesets
660 --hidden consider hidden changesets
661 --pager TYPE when to paginate (boolean, always, auto, or never)
661 --pager TYPE when to paginate (boolean, always, auto, or never)
662 (default: auto)
662 (default: auto)
663
663
664
664
665
665
666
666
667
667
668 $ echo 'debugextension = !' >> $HGRCPATH
668 $ echo 'debugextension = !' >> $HGRCPATH
669
669
670 Asking for help about a deprecated extension should do something useful:
670 Asking for help about a deprecated extension should do something useful:
671
671
672 $ hg help glog
672 $ hg help glog
673 'glog' is provided by the following extension:
673 'glog' is provided by the following extension:
674
674
675 graphlog command to view revision graphs from a shell (DEPRECATED)
675 graphlog command to view revision graphs from a shell (DEPRECATED)
676
676
677 (use 'hg help extensions' for information on enabling extensions)
677 (use 'hg help extensions' for information on enabling extensions)
678
678
679 Extension module help vs command help:
679 Extension module help vs command help:
680
680
681 $ echo 'extdiff =' >> $HGRCPATH
681 $ echo 'extdiff =' >> $HGRCPATH
682 $ hg help extdiff
682 $ hg help extdiff
683 hg extdiff [OPT]... [FILE]...
683 hg extdiff [OPT]... [FILE]...
684
684
685 use external program to diff repository (or selected files)
685 use external program to diff repository (or selected files)
686
686
687 Show differences between revisions for the specified files, using an
687 Show differences between revisions for the specified files, using an
688 external program. The default program used is diff, with default options
688 external program. The default program used is diff, with default options
689 "-Npru".
689 "-Npru".
690
690
691 To select a different program, use the -p/--program option. The program
691 To select a different program, use the -p/--program option. The program
692 will be passed the names of two directories to compare. To pass additional
692 will be passed the names of two directories to compare. To pass additional
693 options to the program, use -o/--option. These will be passed before the
693 options to the program, use -o/--option. These will be passed before the
694 names of the directories to compare.
694 names of the directories to compare.
695
695
696 When two revision arguments are given, then changes are shown between
696 When two revision arguments are given, then changes are shown between
697 those revisions. If only one revision is specified then that revision is
697 those revisions. If only one revision is specified then that revision is
698 compared to the working directory, and, when no revisions are specified,
698 compared to the working directory, and, when no revisions are specified,
699 the working directory files are compared to its parent.
699 the working directory files are compared to its parent.
700
700
701 (use 'hg help -e extdiff' to show help for the extdiff extension)
701 (use 'hg help -e extdiff' to show help for the extdiff extension)
702
702
703 options ([+] can be repeated):
703 options ([+] can be repeated):
704
704
705 -p --program CMD comparison program to run
705 -p --program CMD comparison program to run
706 -o --option OPT [+] pass option to comparison program
706 -o --option OPT [+] pass option to comparison program
707 -r --rev REV [+] revision
707 -r --rev REV [+] revision
708 -c --change REV change made by revision
708 -c --change REV change made by revision
709 --patch compare patches for two revisions
709 --patch compare patches for two revisions
710 -I --include PATTERN [+] include names matching the given patterns
710 -I --include PATTERN [+] include names matching the given patterns
711 -X --exclude PATTERN [+] exclude names matching the given patterns
711 -X --exclude PATTERN [+] exclude names matching the given patterns
712 -S --subrepos recurse into subrepositories
712 -S --subrepos recurse into subrepositories
713
713
714 (some details hidden, use --verbose to show complete help)
714 (some details hidden, use --verbose to show complete help)
715
715
716
716
717
717
718
718
719
719
720
720
721
721
722
722
723
723
724
724
725 $ hg help --extension extdiff
725 $ hg help --extension extdiff
726 extdiff extension - command to allow external programs to compare revisions
726 extdiff extension - command to allow external programs to compare revisions
727
727
728 The extdiff Mercurial extension allows you to use external programs to compare
728 The extdiff Mercurial extension allows you to use external programs to compare
729 revisions, or revision with working directory. The external diff programs are
729 revisions, or revision with working directory. The external diff programs are
730 called with a configurable set of options and two non-option arguments: paths
730 called with a configurable set of options and two non-option arguments: paths
731 to directories containing snapshots of files to compare.
731 to directories containing snapshots of files to compare.
732
732
733 The extdiff extension also allows you to configure new diff commands, so you
733 The extdiff extension also allows you to configure new diff commands, so you
734 do not need to type 'hg extdiff -p kdiff3' always.
734 do not need to type 'hg extdiff -p kdiff3' always.
735
735
736 [extdiff]
736 [extdiff]
737 # add new command that runs GNU diff(1) in 'context diff' mode
737 # add new command that runs GNU diff(1) in 'context diff' mode
738 cdiff = gdiff -Nprc5
738 cdiff = gdiff -Nprc5
739 ## or the old way:
739 ## or the old way:
740 #cmd.cdiff = gdiff
740 #cmd.cdiff = gdiff
741 #opts.cdiff = -Nprc5
741 #opts.cdiff = -Nprc5
742
742
743 # add new command called meld, runs meld (no need to name twice). If
743 # add new command called meld, runs meld (no need to name twice). If
744 # the meld executable is not available, the meld tool in [merge-tools]
744 # the meld executable is not available, the meld tool in [merge-tools]
745 # will be used, if available
745 # will be used, if available
746 meld =
746 meld =
747
747
748 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
748 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
749 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
749 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
750 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
750 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
751 # your .vimrc
751 # your .vimrc
752 vimdiff = gvim -f "+next" \
752 vimdiff = gvim -f "+next" \
753 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
753 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
754
754
755 Tool arguments can include variables that are expanded at runtime:
755 Tool arguments can include variables that are expanded at runtime:
756
756
757 $parent1, $plabel1 - filename, descriptive label of first parent
757 $parent1, $plabel1 - filename, descriptive label of first parent
758 $child, $clabel - filename, descriptive label of child revision
758 $child, $clabel - filename, descriptive label of child revision
759 $parent2, $plabel2 - filename, descriptive label of second parent
759 $parent2, $plabel2 - filename, descriptive label of second parent
760 $root - repository root
760 $root - repository root
761 $parent is an alias for $parent1.
761 $parent is an alias for $parent1.
762
762
763 The extdiff extension will look in your [diff-tools] and [merge-tools]
763 The extdiff extension will look in your [diff-tools] and [merge-tools]
764 sections for diff tool arguments, when none are specified in [extdiff].
764 sections for diff tool arguments, when none are specified in [extdiff].
765
765
766 [extdiff]
766 [extdiff]
767 kdiff3 =
767 kdiff3 =
768
768
769 [diff-tools]
769 [diff-tools]
770 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
770 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
771
771
772 You can use -I/-X and list of file or directory names like normal 'hg diff'
772 You can use -I/-X and list of file or directory names like normal 'hg diff'
773 command. The extdiff extension makes snapshots of only needed files, so
773 command. The extdiff extension makes snapshots of only needed files, so
774 running the external diff program will actually be pretty fast (at least
774 running the external diff program will actually be pretty fast (at least
775 faster than having to compare the entire tree).
775 faster than having to compare the entire tree).
776
776
777 list of commands:
777 list of commands:
778
778
779 extdiff use external program to diff repository (or selected files)
779 extdiff use external program to diff repository (or selected files)
780
780
781 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
781 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
782
782
783
783
784
784
785
785
786
786
787
787
788
788
789
789
790
790
791
791
792
792
793
793
794
794
795
795
796
796
797
797
798 $ echo 'extdiff = !' >> $HGRCPATH
798 $ echo 'extdiff = !' >> $HGRCPATH
799
799
800 Test help topic with same name as extension
800 Test help topic with same name as extension
801
801
802 $ cat > multirevs.py <<EOF
802 $ cat > multirevs.py <<EOF
803 > from mercurial import commands, registrar
803 > from mercurial import commands, registrar
804 > cmdtable = {}
804 > cmdtable = {}
805 > command = registrar.command(cmdtable)
805 > command = registrar.command(cmdtable)
806 > """multirevs extension
806 > """multirevs extension
807 > Big multi-line module docstring."""
807 > Big multi-line module docstring."""
808 > @command(b'multirevs', [], 'ARG', norepo=True)
808 > @command(b'multirevs', [], 'ARG', norepo=True)
809 > def multirevs(ui, repo, arg, *args, **opts):
809 > def multirevs(ui, repo, arg, *args, **opts):
810 > """multirevs command"""
810 > """multirevs command"""
811 > pass
811 > pass
812 > EOF
812 > EOF
813 $ echo "multirevs = multirevs.py" >> $HGRCPATH
813 $ echo "multirevs = multirevs.py" >> $HGRCPATH
814
814
815 $ hg help multirevs | tail
815 $ hg help multirevs | tail
816 used):
816 used):
817
817
818 hg update :@
818 hg update :@
819
819
820 - Show diff between tags 1.3 and 1.5 (this works because the first and the
820 - Show diff between tags 1.3 and 1.5 (this works because the first and the
821 last revisions of the revset are used):
821 last revisions of the revset are used):
822
822
823 hg diff -r 1.3::1.5
823 hg diff -r 1.3::1.5
824
824
825 use 'hg help -c multirevs' to see help for the multirevs command
825 use 'hg help -c multirevs' to see help for the multirevs command
826
826
827
827
828
828
829
829
830
830
831
831
832 $ hg help -c multirevs
832 $ hg help -c multirevs
833 hg multirevs ARG
833 hg multirevs ARG
834
834
835 multirevs command
835 multirevs command
836
836
837 (some details hidden, use --verbose to show complete help)
837 (some details hidden, use --verbose to show complete help)
838
838
839
839
840
840
841 $ hg multirevs
841 $ hg multirevs
842 hg multirevs: invalid arguments
842 hg multirevs: invalid arguments
843 hg multirevs ARG
843 hg multirevs ARG
844
844
845 multirevs command
845 multirevs command
846
846
847 (use 'hg multirevs -h' to show more help)
847 (use 'hg multirevs -h' to show more help)
848 [255]
848 [255]
849
849
850
850
851
851
852 $ echo "multirevs = !" >> $HGRCPATH
852 $ echo "multirevs = !" >> $HGRCPATH
853
853
854 Issue811: Problem loading extensions twice (by site and by user)
854 Issue811: Problem loading extensions twice (by site and by user)
855
855
856 $ cat <<EOF >> $HGRCPATH
856 $ cat <<EOF >> $HGRCPATH
857 > mq =
857 > mq =
858 > strip =
858 > strip =
859 > hgext.mq =
859 > hgext.mq =
860 > hgext/mq =
860 > hgext/mq =
861 > EOF
861 > EOF
862
862
863 Show extensions:
863 Show extensions:
864 (note that mq force load strip, also checking it's not loaded twice)
864 (note that mq force load strip, also checking it's not loaded twice)
865
865
866 $ hg debugextensions
866 $ hg debugextensions
867 mq
867 mq
868 strip
868 strip
869
869
870 For extensions, which name matches one of its commands, help
870 For extensions, which name matches one of its commands, help
871 message should ask '-v -e' to get list of built-in aliases
871 message should ask '-v -e' to get list of built-in aliases
872 along with extension help itself
872 along with extension help itself
873
873
874 $ mkdir $TESTTMP/d
874 $ mkdir $TESTTMP/d
875 $ cat > $TESTTMP/d/dodo.py <<EOF
875 $ cat > $TESTTMP/d/dodo.py <<EOF
876 > """
876 > """
877 > This is an awesome 'dodo' extension. It does nothing and
877 > This is an awesome 'dodo' extension. It does nothing and
878 > writes 'Foo foo'
878 > writes 'Foo foo'
879 > """
879 > """
880 > from mercurial import commands, registrar
880 > from mercurial import commands, registrar
881 > cmdtable = {}
881 > cmdtable = {}
882 > command = registrar.command(cmdtable)
882 > command = registrar.command(cmdtable)
883 > @command(b'dodo', [], 'hg dodo')
883 > @command(b'dodo', [], 'hg dodo')
884 > def dodo(ui, *args, **kwargs):
884 > def dodo(ui, *args, **kwargs):
885 > """Does nothing"""
885 > """Does nothing"""
886 > ui.write("I do nothing. Yay\\n")
886 > ui.write("I do nothing. Yay\\n")
887 > @command(b'foofoo', [], 'hg foofoo')
887 > @command(b'foofoo', [], 'hg foofoo')
888 > def foofoo(ui, *args, **kwargs):
888 > def foofoo(ui, *args, **kwargs):
889 > """Writes 'Foo foo'"""
889 > """Writes 'Foo foo'"""
890 > ui.write("Foo foo\\n")
890 > ui.write("Foo foo\\n")
891 > EOF
891 > EOF
892 $ dodopath=$TESTTMP/d/dodo.py
892 $ dodopath=$TESTTMP/d/dodo.py
893
893
894 $ echo "dodo = $dodopath" >> $HGRCPATH
894 $ echo "dodo = $dodopath" >> $HGRCPATH
895
895
896 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
896 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
897 $ hg help -e dodo
897 $ hg help -e dodo
898 dodo extension -
898 dodo extension -
899
899
900 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
900 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
901
901
902 list of commands:
902 list of commands:
903
903
904 dodo Does nothing
904 dodo Does nothing
905 foofoo Writes 'Foo foo'
905 foofoo Writes 'Foo foo'
906
906
907 (use 'hg help -v -e dodo' to show built-in aliases and global options)
907 (use 'hg help -v -e dodo' to show built-in aliases and global options)
908
908
909 Make sure that '-v -e' prints list of built-in aliases along with
909 Make sure that '-v -e' prints list of built-in aliases along with
910 extension help itself
910 extension help itself
911 $ hg help -v -e dodo
911 $ hg help -v -e dodo
912 dodo extension -
912 dodo extension -
913
913
914 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
914 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
915
915
916 list of commands:
916 list of commands:
917
917
918 dodo Does nothing
918 dodo Does nothing
919 foofoo Writes 'Foo foo'
919 foofoo Writes 'Foo foo'
920
920
921 global options ([+] can be repeated):
921 global options ([+] can be repeated):
922
922
923 -R --repository REPO repository root directory or name of overlay bundle
923 -R --repository REPO repository root directory or name of overlay bundle
924 file
924 file
925 --cwd DIR change working directory
925 --cwd DIR change working directory
926 -y --noninteractive do not prompt, automatically pick the first choice for
926 -y --noninteractive do not prompt, automatically pick the first choice for
927 all prompts
927 all prompts
928 -q --quiet suppress output
928 -q --quiet suppress output
929 -v --verbose enable additional output
929 -v --verbose enable additional output
930 --color TYPE when to colorize (boolean, always, auto, never, or
930 --color TYPE when to colorize (boolean, always, auto, never, or
931 debug)
931 debug)
932 --config CONFIG [+] set/override config option (use 'section.name=value')
932 --config CONFIG [+] set/override config option (use 'section.name=value')
933 --debug enable debugging output
933 --debug enable debugging output
934 --debugger start debugger
934 --debugger start debugger
935 --encoding ENCODE set the charset encoding (default: ascii)
935 --encoding ENCODE set the charset encoding (default: ascii)
936 --encodingmode MODE set the charset encoding mode (default: strict)
936 --encodingmode MODE set the charset encoding mode (default: strict)
937 --traceback always print a traceback on exception
937 --traceback always print a traceback on exception
938 --time time how long the command takes
938 --time time how long the command takes
939 --profile print command execution profile
939 --profile print command execution profile
940 --version output version information and exit
940 --version output version information and exit
941 -h --help display help and exit
941 -h --help display help and exit
942 --hidden consider hidden changesets
942 --hidden consider hidden changesets
943 --pager TYPE when to paginate (boolean, always, auto, or never)
943 --pager TYPE when to paginate (boolean, always, auto, or never)
944 (default: auto)
944 (default: auto)
945
945
946 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
946 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
947 $ hg help -v dodo
947 $ hg help -v dodo
948 hg dodo
948 hg dodo
949
949
950 Does nothing
950 Does nothing
951
951
952 (use 'hg help -e dodo' to show help for the dodo extension)
952 (use 'hg help -e dodo' to show help for the dodo extension)
953
953
954 options:
954 options:
955
955
956 --mq operate on patch repository
956 --mq operate on patch repository
957
957
958 global options ([+] can be repeated):
958 global options ([+] can be repeated):
959
959
960 -R --repository REPO repository root directory or name of overlay bundle
960 -R --repository REPO repository root directory or name of overlay bundle
961 file
961 file
962 --cwd DIR change working directory
962 --cwd DIR change working directory
963 -y --noninteractive do not prompt, automatically pick the first choice for
963 -y --noninteractive do not prompt, automatically pick the first choice for
964 all prompts
964 all prompts
965 -q --quiet suppress output
965 -q --quiet suppress output
966 -v --verbose enable additional output
966 -v --verbose enable additional output
967 --color TYPE when to colorize (boolean, always, auto, never, or
967 --color TYPE when to colorize (boolean, always, auto, never, or
968 debug)
968 debug)
969 --config CONFIG [+] set/override config option (use 'section.name=value')
969 --config CONFIG [+] set/override config option (use 'section.name=value')
970 --debug enable debugging output
970 --debug enable debugging output
971 --debugger start debugger
971 --debugger start debugger
972 --encoding ENCODE set the charset encoding (default: ascii)
972 --encoding ENCODE set the charset encoding (default: ascii)
973 --encodingmode MODE set the charset encoding mode (default: strict)
973 --encodingmode MODE set the charset encoding mode (default: strict)
974 --traceback always print a traceback on exception
974 --traceback always print a traceback on exception
975 --time time how long the command takes
975 --time time how long the command takes
976 --profile print command execution profile
976 --profile print command execution profile
977 --version output version information and exit
977 --version output version information and exit
978 -h --help display help and exit
978 -h --help display help and exit
979 --hidden consider hidden changesets
979 --hidden consider hidden changesets
980 --pager TYPE when to paginate (boolean, always, auto, or never)
980 --pager TYPE when to paginate (boolean, always, auto, or never)
981 (default: auto)
981 (default: auto)
982
982
983 In case when extension name doesn't match any of its commands,
983 In case when extension name doesn't match any of its commands,
984 help message should ask for '-v' to get list of built-in aliases
984 help message should ask for '-v' to get list of built-in aliases
985 along with extension help
985 along with extension help
986 $ cat > $TESTTMP/d/dudu.py <<EOF
986 $ cat > $TESTTMP/d/dudu.py <<EOF
987 > """
987 > """
988 > This is an awesome 'dudu' extension. It does something and
988 > This is an awesome 'dudu' extension. It does something and
989 > also writes 'Beep beep'
989 > also writes 'Beep beep'
990 > """
990 > """
991 > from mercurial import commands, registrar
991 > from mercurial import commands, registrar
992 > cmdtable = {}
992 > cmdtable = {}
993 > command = registrar.command(cmdtable)
993 > command = registrar.command(cmdtable)
994 > @command(b'something', [], 'hg something')
994 > @command(b'something', [], 'hg something')
995 > def something(ui, *args, **kwargs):
995 > def something(ui, *args, **kwargs):
996 > """Does something"""
996 > """Does something"""
997 > ui.write("I do something. Yaaay\\n")
997 > ui.write("I do something. Yaaay\\n")
998 > @command(b'beep', [], 'hg beep')
998 > @command(b'beep', [], 'hg beep')
999 > def beep(ui, *args, **kwargs):
999 > def beep(ui, *args, **kwargs):
1000 > """Writes 'Beep beep'"""
1000 > """Writes 'Beep beep'"""
1001 > ui.write("Beep beep\\n")
1001 > ui.write("Beep beep\\n")
1002 > EOF
1002 > EOF
1003 $ dudupath=$TESTTMP/d/dudu.py
1003 $ dudupath=$TESTTMP/d/dudu.py
1004
1004
1005 $ echo "dudu = $dudupath" >> $HGRCPATH
1005 $ echo "dudu = $dudupath" >> $HGRCPATH
1006
1006
1007 $ hg help -e dudu
1007 $ hg help -e dudu
1008 dudu extension -
1008 dudu extension -
1009
1009
1010 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1010 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1011 beep'
1011 beep'
1012
1012
1013 list of commands:
1013 list of commands:
1014
1014
1015 beep Writes 'Beep beep'
1015 beep Writes 'Beep beep'
1016 something Does something
1016 something Does something
1017
1017
1018 (use 'hg help -v dudu' to show built-in aliases and global options)
1018 (use 'hg help -v dudu' to show built-in aliases and global options)
1019
1019
1020 In case when extension name doesn't match any of its commands,
1020 In case when extension name doesn't match any of its commands,
1021 help options '-v' and '-v -e' should be equivalent
1021 help options '-v' and '-v -e' should be equivalent
1022 $ hg help -v dudu
1022 $ hg help -v dudu
1023 dudu extension -
1023 dudu extension -
1024
1024
1025 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1025 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1026 beep'
1026 beep'
1027
1027
1028 list of commands:
1028 list of commands:
1029
1029
1030 beep Writes 'Beep beep'
1030 beep Writes 'Beep beep'
1031 something Does something
1031 something Does something
1032
1032
1033 global options ([+] can be repeated):
1033 global options ([+] can be repeated):
1034
1034
1035 -R --repository REPO repository root directory or name of overlay bundle
1035 -R --repository REPO repository root directory or name of overlay bundle
1036 file
1036 file
1037 --cwd DIR change working directory
1037 --cwd DIR change working directory
1038 -y --noninteractive do not prompt, automatically pick the first choice for
1038 -y --noninteractive do not prompt, automatically pick the first choice for
1039 all prompts
1039 all prompts
1040 -q --quiet suppress output
1040 -q --quiet suppress output
1041 -v --verbose enable additional output
1041 -v --verbose enable additional output
1042 --color TYPE when to colorize (boolean, always, auto, never, or
1042 --color TYPE when to colorize (boolean, always, auto, never, or
1043 debug)
1043 debug)
1044 --config CONFIG [+] set/override config option (use 'section.name=value')
1044 --config CONFIG [+] set/override config option (use 'section.name=value')
1045 --debug enable debugging output
1045 --debug enable debugging output
1046 --debugger start debugger
1046 --debugger start debugger
1047 --encoding ENCODE set the charset encoding (default: ascii)
1047 --encoding ENCODE set the charset encoding (default: ascii)
1048 --encodingmode MODE set the charset encoding mode (default: strict)
1048 --encodingmode MODE set the charset encoding mode (default: strict)
1049 --traceback always print a traceback on exception
1049 --traceback always print a traceback on exception
1050 --time time how long the command takes
1050 --time time how long the command takes
1051 --profile print command execution profile
1051 --profile print command execution profile
1052 --version output version information and exit
1052 --version output version information and exit
1053 -h --help display help and exit
1053 -h --help display help and exit
1054 --hidden consider hidden changesets
1054 --hidden consider hidden changesets
1055 --pager TYPE when to paginate (boolean, always, auto, or never)
1055 --pager TYPE when to paginate (boolean, always, auto, or never)
1056 (default: auto)
1056 (default: auto)
1057
1057
1058 $ hg help -v -e dudu
1058 $ hg help -v -e dudu
1059 dudu extension -
1059 dudu extension -
1060
1060
1061 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1061 This is an awesome 'dudu' extension. It does something and also writes 'Beep
1062 beep'
1062 beep'
1063
1063
1064 list of commands:
1064 list of commands:
1065
1065
1066 beep Writes 'Beep beep'
1066 beep Writes 'Beep beep'
1067 something Does something
1067 something Does something
1068
1068
1069 global options ([+] can be repeated):
1069 global options ([+] can be repeated):
1070
1070
1071 -R --repository REPO repository root directory or name of overlay bundle
1071 -R --repository REPO repository root directory or name of overlay bundle
1072 file
1072 file
1073 --cwd DIR change working directory
1073 --cwd DIR change working directory
1074 -y --noninteractive do not prompt, automatically pick the first choice for
1074 -y --noninteractive do not prompt, automatically pick the first choice for
1075 all prompts
1075 all prompts
1076 -q --quiet suppress output
1076 -q --quiet suppress output
1077 -v --verbose enable additional output
1077 -v --verbose enable additional output
1078 --color TYPE when to colorize (boolean, always, auto, never, or
1078 --color TYPE when to colorize (boolean, always, auto, never, or
1079 debug)
1079 debug)
1080 --config CONFIG [+] set/override config option (use 'section.name=value')
1080 --config CONFIG [+] set/override config option (use 'section.name=value')
1081 --debug enable debugging output
1081 --debug enable debugging output
1082 --debugger start debugger
1082 --debugger start debugger
1083 --encoding ENCODE set the charset encoding (default: ascii)
1083 --encoding ENCODE set the charset encoding (default: ascii)
1084 --encodingmode MODE set the charset encoding mode (default: strict)
1084 --encodingmode MODE set the charset encoding mode (default: strict)
1085 --traceback always print a traceback on exception
1085 --traceback always print a traceback on exception
1086 --time time how long the command takes
1086 --time time how long the command takes
1087 --profile print command execution profile
1087 --profile print command execution profile
1088 --version output version information and exit
1088 --version output version information and exit
1089 -h --help display help and exit
1089 -h --help display help and exit
1090 --hidden consider hidden changesets
1090 --hidden consider hidden changesets
1091 --pager TYPE when to paginate (boolean, always, auto, or never)
1091 --pager TYPE when to paginate (boolean, always, auto, or never)
1092 (default: auto)
1092 (default: auto)
1093
1093
1094 Disabled extension commands:
1094 Disabled extension commands:
1095
1095
1096 $ ORGHGRCPATH=$HGRCPATH
1096 $ ORGHGRCPATH=$HGRCPATH
1097 $ HGRCPATH=
1097 $ HGRCPATH=
1098 $ export HGRCPATH
1098 $ export HGRCPATH
1099 $ hg help email
1099 $ hg help email
1100 'email' is provided by the following extension:
1100 'email' is provided by the following extension:
1101
1101
1102 patchbomb command to send changesets as (a series of) patch emails
1102 patchbomb command to send changesets as (a series of) patch emails
1103
1103
1104 (use 'hg help extensions' for information on enabling extensions)
1104 (use 'hg help extensions' for information on enabling extensions)
1105
1105
1106
1106
1107 $ hg qdel
1107 $ hg qdel
1108 hg: unknown command 'qdel'
1108 hg: unknown command 'qdel'
1109 'qdelete' is provided by the following extension:
1109 'qdelete' is provided by the following extension:
1110
1110
1111 mq manage a stack of patches
1111 mq manage a stack of patches
1112
1112
1113 (use 'hg help extensions' for information on enabling extensions)
1113 (use 'hg help extensions' for information on enabling extensions)
1114 [255]
1114 [255]
1115
1115
1116
1116
1117 $ hg churn
1117 $ hg churn
1118 hg: unknown command 'churn'
1118 hg: unknown command 'churn'
1119 'churn' is provided by the following extension:
1119 'churn' is provided by the following extension:
1120
1120
1121 churn command to display statistics about repository history
1121 churn command to display statistics about repository history
1122
1122
1123 (use 'hg help extensions' for information on enabling extensions)
1123 (use 'hg help extensions' for information on enabling extensions)
1124 [255]
1124 [255]
1125
1125
1126
1126
1127
1127
1128 Disabled extensions:
1128 Disabled extensions:
1129
1129
1130 $ hg help churn
1130 $ hg help churn
1131 churn extension - command to display statistics about repository history
1131 churn extension - command to display statistics about repository history
1132
1132
1133 (use 'hg help extensions' for information on enabling extensions)
1133 (use 'hg help extensions' for information on enabling extensions)
1134
1134
1135 $ hg help patchbomb
1135 $ hg help patchbomb
1136 patchbomb extension - command to send changesets as (a series of) patch emails
1136 patchbomb extension - command to send changesets as (a series of) patch emails
1137
1137
1138 The series is started off with a "[PATCH 0 of N]" introduction, which
1138 The series is started off with a "[PATCH 0 of N]" introduction, which
1139 describes the series as a whole.
1139 describes the series as a whole.
1140
1140
1141 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1141 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1142 line of the changeset description as the subject text. The message contains
1142 line of the changeset description as the subject text. The message contains
1143 two or three body parts:
1143 two or three body parts:
1144
1144
1145 - The changeset description.
1145 - The changeset description.
1146 - [Optional] The result of running diffstat on the patch.
1146 - [Optional] The result of running diffstat on the patch.
1147 - The patch itself, as generated by 'hg export'.
1147 - The patch itself, as generated by 'hg export'.
1148
1148
1149 Each message refers to the first in the series using the In-Reply-To and
1149 Each message refers to the first in the series using the In-Reply-To and
1150 References headers, so they will show up as a sequence in threaded mail and
1150 References headers, so they will show up as a sequence in threaded mail and
1151 news readers, and in mail archives.
1151 news readers, and in mail archives.
1152
1152
1153 To configure other defaults, add a section like this to your configuration
1153 To configure other defaults, add a section like this to your configuration
1154 file:
1154 file:
1155
1155
1156 [email]
1156 [email]
1157 from = My Name <my@email>
1157 from = My Name <my@email>
1158 to = recipient1, recipient2, ...
1158 to = recipient1, recipient2, ...
1159 cc = cc1, cc2, ...
1159 cc = cc1, cc2, ...
1160 bcc = bcc1, bcc2, ...
1160 bcc = bcc1, bcc2, ...
1161 reply-to = address1, address2, ...
1161 reply-to = address1, address2, ...
1162
1162
1163 Use "[patchbomb]" as configuration section name if you need to override global
1163 Use "[patchbomb]" as configuration section name if you need to override global
1164 "[email]" address settings.
1164 "[email]" address settings.
1165
1165
1166 Then you can use the 'hg email' command to mail a series of changesets as a
1166 Then you can use the 'hg email' command to mail a series of changesets as a
1167 patchbomb.
1167 patchbomb.
1168
1168
1169 You can also either configure the method option in the email section to be a
1169 You can also either configure the method option in the email section to be a
1170 sendmail compatible mailer or fill out the [smtp] section so that the
1170 sendmail compatible mailer or fill out the [smtp] section so that the
1171 patchbomb extension can automatically send patchbombs directly from the
1171 patchbomb extension can automatically send patchbombs directly from the
1172 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1172 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1173
1173
1174 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1174 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1175 supply one via configuration or the command line. You can override this to
1175 supply one via configuration or the command line. You can override this to
1176 never prompt by configuring an empty value:
1176 never prompt by configuring an empty value:
1177
1177
1178 [email]
1178 [email]
1179 cc =
1179 cc =
1180
1180
1181 You can control the default inclusion of an introduction message with the
1181 You can control the default inclusion of an introduction message with the
1182 "patchbomb.intro" configuration option. The configuration is always
1182 "patchbomb.intro" configuration option. The configuration is always
1183 overwritten by command line flags like --intro and --desc:
1183 overwritten by command line flags like --intro and --desc:
1184
1184
1185 [patchbomb]
1185 [patchbomb]
1186 intro=auto # include introduction message if more than 1 patch (default)
1186 intro=auto # include introduction message if more than 1 patch (default)
1187 intro=never # never include an introduction message
1187 intro=never # never include an introduction message
1188 intro=always # always include an introduction message
1188 intro=always # always include an introduction message
1189
1189
1190 You can specify a template for flags to be added in subject prefixes. Flags
1190 You can specify a template for flags to be added in subject prefixes. Flags
1191 specified by --flag option are exported as "{flags}" keyword:
1191 specified by --flag option are exported as "{flags}" keyword:
1192
1192
1193 [patchbomb]
1193 [patchbomb]
1194 flagtemplate = "{separate(' ',
1194 flagtemplate = "{separate(' ',
1195 ifeq(branch, 'default', '', branch|upper),
1195 ifeq(branch, 'default', '', branch|upper),
1196 flags)}"
1196 flags)}"
1197
1197
1198 You can set patchbomb to always ask for confirmation by setting
1198 You can set patchbomb to always ask for confirmation by setting
1199 "patchbomb.confirm" to true.
1199 "patchbomb.confirm" to true.
1200
1200
1201 (use 'hg help extensions' for information on enabling extensions)
1201 (use 'hg help extensions' for information on enabling extensions)
1202
1202
1203
1203
1204 Broken disabled extension and command:
1204 Broken disabled extension and command:
1205
1205
1206 $ mkdir hgext
1206 $ mkdir hgext
1207 $ echo > hgext/__init__.py
1207 $ echo > hgext/__init__.py
1208 $ cat > hgext/broken.py <<EOF
1208 $ cat > hgext/broken.py <<EOF
1209 > "broken extension'
1209 > "broken extension'
1210 > EOF
1210 > EOF
1211 $ cat > path.py <<EOF
1211 $ cat > path.py <<EOF
1212 > import os, sys
1212 > import os, sys
1213 > sys.path.insert(0, os.environ['HGEXTPATH'])
1213 > sys.path.insert(0, os.environ['HGEXTPATH'])
1214 > EOF
1214 > EOF
1215 $ HGEXTPATH=`pwd`
1215 $ HGEXTPATH=`pwd`
1216 $ export HGEXTPATH
1216 $ export HGEXTPATH
1217
1217
1218 $ hg --config extensions.path=./path.py help broken
1218 $ hg --config extensions.path=./path.py help broken
1219 broken extension - (no help text available)
1219 broken extension - (no help text available)
1220
1220
1221 (use 'hg help extensions' for information on enabling extensions)
1221 (use 'hg help extensions' for information on enabling extensions)
1222
1222
1223
1223
1224 $ cat > hgext/forest.py <<EOF
1224 $ cat > hgext/forest.py <<EOF
1225 > cmdtable = None
1225 > cmdtable = None
1226 > EOF
1226 > EOF
1227 $ hg --config extensions.path=./path.py help foo > /dev/null
1227 $ hg --config extensions.path=./path.py help foo > /dev/null
1228 warning: error finding commands in $TESTTMP/hgext/forest.py
1228 warning: error finding commands in $TESTTMP/hgext/forest.py
1229 abort: no such help topic: foo
1229 abort: no such help topic: foo
1230 (try 'hg help --keyword foo')
1230 (try 'hg help --keyword foo')
1231 [255]
1231 [255]
1232
1232
1233 $ cat > throw.py <<EOF
1233 $ cat > throw.py <<EOF
1234 > from mercurial import commands, registrar, util
1234 > from mercurial import commands, registrar, util
1235 > cmdtable = {}
1235 > cmdtable = {}
1236 > command = registrar.command(cmdtable)
1236 > command = registrar.command(cmdtable)
1237 > class Bogon(Exception): pass
1237 > class Bogon(Exception): pass
1238 > @command(b'throw', [], 'hg throw', norepo=True)
1238 > @command(b'throw', [], 'hg throw', norepo=True)
1239 > def throw(ui, **opts):
1239 > def throw(ui, **opts):
1240 > """throws an exception"""
1240 > """throws an exception"""
1241 > raise Bogon()
1241 > raise Bogon()
1242 > EOF
1242 > EOF
1243
1243
1244 No declared supported version, extension complains:
1244 No declared supported version, extension complains:
1245 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1245 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1246 ** Unknown exception encountered with possibly-broken third-party extension throw
1246 ** Unknown exception encountered with possibly-broken third-party extension throw
1247 ** which supports versions unknown of Mercurial.
1247 ** which supports versions unknown of Mercurial.
1248 ** Please disable throw and try your action again.
1248 ** Please disable throw and try your action again.
1249 ** If that fixes the bug please report it to the extension author.
1249 ** If that fixes the bug please report it to the extension author.
1250 ** Python * (glob)
1250 ** Python * (glob)
1251 ** Mercurial Distributed SCM * (glob)
1251 ** Mercurial Distributed SCM * (glob)
1252 ** Extensions loaded: throw
1252 ** Extensions loaded: throw
1253
1253
1254 empty declaration of supported version, extension complains:
1254 empty declaration of supported version, extension complains:
1255 $ echo "testedwith = ''" >> throw.py
1255 $ echo "testedwith = ''" >> throw.py
1256 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1256 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1257 ** Unknown exception encountered with possibly-broken third-party extension throw
1257 ** Unknown exception encountered with possibly-broken third-party extension throw
1258 ** which supports versions unknown of Mercurial.
1258 ** which supports versions unknown of Mercurial.
1259 ** Please disable throw and try your action again.
1259 ** Please disable throw and try your action again.
1260 ** If that fixes the bug please report it to the extension author.
1260 ** If that fixes the bug please report it to the extension author.
1261 ** Python * (glob)
1261 ** Python * (glob)
1262 ** Mercurial Distributed SCM (*) (glob)
1262 ** Mercurial Distributed SCM (*) (glob)
1263 ** Extensions loaded: throw
1263 ** Extensions loaded: throw
1264
1264
1265 If the extension specifies a buglink, show that:
1265 If the extension specifies a buglink, show that:
1266 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1266 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1267 $ rm -f throw.pyc throw.pyo
1267 $ rm -f throw.pyc throw.pyo
1268 $ rm -Rf __pycache__
1268 $ rm -Rf __pycache__
1269 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1269 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1270 ** Unknown exception encountered with possibly-broken third-party extension throw
1270 ** Unknown exception encountered with possibly-broken third-party extension throw
1271 ** which supports versions unknown of Mercurial.
1271 ** which supports versions unknown of Mercurial.
1272 ** Please disable throw and try your action again.
1272 ** Please disable throw and try your action again.
1273 ** If that fixes the bug please report it to http://example.com/bts
1273 ** If that fixes the bug please report it to http://example.com/bts
1274 ** Python * (glob)
1274 ** Python * (glob)
1275 ** Mercurial Distributed SCM (*) (glob)
1275 ** Mercurial Distributed SCM (*) (glob)
1276 ** Extensions loaded: throw
1276 ** Extensions loaded: throw
1277
1277
1278 If the extensions declare outdated versions, accuse the older extension first:
1278 If the extensions declare outdated versions, accuse the older extension first:
1279 $ echo "from mercurial import util" >> older.py
1279 $ echo "from mercurial import util" >> older.py
1280 $ echo "util.version = lambda:'2.2'" >> older.py
1280 $ echo "util.version = lambda:'2.2'" >> older.py
1281 $ echo "testedwith = '1.9.3'" >> older.py
1281 $ echo "testedwith = '1.9.3'" >> older.py
1282 $ echo "testedwith = '2.1.1'" >> throw.py
1282 $ echo "testedwith = '2.1.1'" >> throw.py
1283 $ rm -f throw.pyc throw.pyo
1283 $ rm -f throw.pyc throw.pyo
1284 $ rm -Rf __pycache__
1284 $ rm -Rf __pycache__
1285 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1285 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1286 > throw 2>&1 | egrep '^\*\*'
1286 > throw 2>&1 | egrep '^\*\*'
1287 ** Unknown exception encountered with possibly-broken third-party extension older
1287 ** Unknown exception encountered with possibly-broken third-party extension older
1288 ** which supports versions 1.9 of Mercurial.
1288 ** which supports versions 1.9 of Mercurial.
1289 ** Please disable older and try your action again.
1289 ** Please disable older and try your action again.
1290 ** If that fixes the bug please report it to the extension author.
1290 ** If that fixes the bug please report it to the extension author.
1291 ** Python * (glob)
1291 ** Python * (glob)
1292 ** Mercurial Distributed SCM (version 2.2)
1292 ** Mercurial Distributed SCM (version 2.2)
1293 ** Extensions loaded: throw, older
1293 ** Extensions loaded: throw, older
1294
1294
1295 One extension only tested with older, one only with newer versions:
1295 One extension only tested with older, one only with newer versions:
1296 $ echo "util.version = lambda:'2.1'" >> older.py
1296 $ echo "util.version = lambda:'2.1'" >> older.py
1297 $ rm -f older.pyc older.pyo
1297 $ rm -f older.pyc older.pyo
1298 $ rm -Rf __pycache__
1298 $ rm -Rf __pycache__
1299 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1299 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1300 > throw 2>&1 | egrep '^\*\*'
1300 > throw 2>&1 | egrep '^\*\*'
1301 ** Unknown exception encountered with possibly-broken third-party extension older
1301 ** Unknown exception encountered with possibly-broken third-party extension older
1302 ** which supports versions 1.9 of Mercurial.
1302 ** which supports versions 1.9 of Mercurial.
1303 ** Please disable older and try your action again.
1303 ** Please disable older and try your action again.
1304 ** If that fixes the bug please report it to the extension author.
1304 ** If that fixes the bug please report it to the extension author.
1305 ** Python * (glob)
1305 ** Python * (glob)
1306 ** Mercurial Distributed SCM (version 2.1)
1306 ** Mercurial Distributed SCM (version 2.1)
1307 ** Extensions loaded: throw, older
1307 ** Extensions loaded: throw, older
1308
1308
1309 Older extension is tested with current version, the other only with newer:
1309 Older extension is tested with current version, the other only with newer:
1310 $ echo "util.version = lambda:'1.9.3'" >> older.py
1310 $ echo "util.version = lambda:'1.9.3'" >> older.py
1311 $ rm -f older.pyc older.pyo
1311 $ rm -f older.pyc older.pyo
1312 $ rm -Rf __pycache__
1312 $ rm -Rf __pycache__
1313 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1313 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1314 > throw 2>&1 | egrep '^\*\*'
1314 > throw 2>&1 | egrep '^\*\*'
1315 ** Unknown exception encountered with possibly-broken third-party extension throw
1315 ** Unknown exception encountered with possibly-broken third-party extension throw
1316 ** which supports versions 2.1 of Mercurial.
1316 ** which supports versions 2.1 of Mercurial.
1317 ** Please disable throw and try your action again.
1317 ** Please disable throw and try your action again.
1318 ** If that fixes the bug please report it to http://example.com/bts
1318 ** If that fixes the bug please report it to http://example.com/bts
1319 ** Python * (glob)
1319 ** Python * (glob)
1320 ** Mercurial Distributed SCM (version 1.9.3)
1320 ** Mercurial Distributed SCM (version 1.9.3)
1321 ** Extensions loaded: throw, older
1321 ** Extensions loaded: throw, older
1322
1322
1323 Ability to point to a different point
1323 Ability to point to a different point
1324 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1324 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1325 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1325 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1326 ** unknown exception encountered, please report by visiting
1326 ** unknown exception encountered, please report by visiting
1327 ** Your Local Goat Lenders
1327 ** Your Local Goat Lenders
1328 ** Python * (glob)
1328 ** Python * (glob)
1329 ** Mercurial Distributed SCM (*) (glob)
1329 ** Mercurial Distributed SCM (*) (glob)
1330 ** Extensions loaded: throw, older
1330 ** Extensions loaded: throw, older
1331
1331
1332 Declare the version as supporting this hg version, show regular bts link:
1332 Declare the version as supporting this hg version, show regular bts link:
1333 $ hgver=`hg debuginstall -T '{hgver}'`
1333 $ hgver=`hg debuginstall -T '{hgver}'`
1334 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1334 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1335 $ if [ -z "$hgver" ]; then
1335 $ if [ -z "$hgver" ]; then
1336 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1336 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1337 > fi
1337 > fi
1338 $ rm -f throw.pyc throw.pyo
1338 $ rm -f throw.pyc throw.pyo
1339 $ rm -Rf __pycache__
1339 $ rm -Rf __pycache__
1340 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1340 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1341 ** unknown exception encountered, please report by visiting
1341 ** unknown exception encountered, please report by visiting
1342 ** https://mercurial-scm.org/wiki/BugTracker
1342 ** https://mercurial-scm.org/wiki/BugTracker
1343 ** Python * (glob)
1343 ** Python * (glob)
1344 ** Mercurial Distributed SCM (*) (glob)
1344 ** Mercurial Distributed SCM (*) (glob)
1345 ** Extensions loaded: throw
1345 ** Extensions loaded: throw
1346
1346
1347 Patch version is ignored during compatibility check
1347 Patch version is ignored during compatibility check
1348 $ echo "testedwith = '3.2'" >> throw.py
1348 $ echo "testedwith = '3.2'" >> throw.py
1349 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1349 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1350 $ rm -f throw.pyc throw.pyo
1350 $ rm -f throw.pyc throw.pyo
1351 $ rm -Rf __pycache__
1351 $ rm -Rf __pycache__
1352 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1352 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1353 ** unknown exception encountered, please report by visiting
1353 ** unknown exception encountered, please report by visiting
1354 ** https://mercurial-scm.org/wiki/BugTracker
1354 ** https://mercurial-scm.org/wiki/BugTracker
1355 ** Python * (glob)
1355 ** Python * (glob)
1356 ** Mercurial Distributed SCM (*) (glob)
1356 ** Mercurial Distributed SCM (*) (glob)
1357 ** Extensions loaded: throw
1357 ** Extensions loaded: throw
1358
1358
1359 Test version number support in 'hg version':
1359 Test version number support in 'hg version':
1360 $ echo '__version__ = (1, 2, 3)' >> throw.py
1360 $ echo '__version__ = (1, 2, 3)' >> throw.py
1361 $ rm -f throw.pyc throw.pyo
1361 $ rm -f throw.pyc throw.pyo
1362 $ rm -Rf __pycache__
1362 $ rm -Rf __pycache__
1363 $ hg version -v
1363 $ hg version -v
1364 Mercurial Distributed SCM (version *) (glob)
1364 Mercurial Distributed SCM (version *) (glob)
1365 (see https://mercurial-scm.org for more information)
1365 (see https://mercurial-scm.org for more information)
1366
1366
1367 Copyright (C) 2005-* Matt Mackall and others (glob)
1367 Copyright (C) 2005-* Matt Mackall and others (glob)
1368 This is free software; see the source for copying conditions. There is NO
1368 This is free software; see the source for copying conditions. There is NO
1369 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1369 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1370
1370
1371 Enabled extensions:
1371 Enabled extensions:
1372
1372
1373
1373
1374 $ hg version -v --config extensions.throw=throw.py
1374 $ hg version -v --config extensions.throw=throw.py
1375 Mercurial Distributed SCM (version *) (glob)
1375 Mercurial Distributed SCM (version *) (glob)
1376 (see https://mercurial-scm.org for more information)
1376 (see https://mercurial-scm.org for more information)
1377
1377
1378 Copyright (C) 2005-* Matt Mackall and others (glob)
1378 Copyright (C) 2005-* Matt Mackall and others (glob)
1379 This is free software; see the source for copying conditions. There is NO
1379 This is free software; see the source for copying conditions. There is NO
1380 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1380 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1381
1381
1382 Enabled extensions:
1382 Enabled extensions:
1383
1383
1384 throw external 1.2.3
1384 throw external 1.2.3
1385 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1385 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1386 $ rm -f throw.pyc throw.pyo
1386 $ rm -f throw.pyc throw.pyo
1387 $ rm -Rf __pycache__
1387 $ rm -Rf __pycache__
1388 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1388 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1389 Mercurial Distributed SCM (version *) (glob)
1389 Mercurial Distributed SCM (version *) (glob)
1390 (see https://mercurial-scm.org for more information)
1390 (see https://mercurial-scm.org for more information)
1391
1391
1392 Copyright (C) 2005-* Matt Mackall and others (glob)
1392 Copyright (C) 2005-* Matt Mackall and others (glob)
1393 This is free software; see the source for copying conditions. There is NO
1393 This is free software; see the source for copying conditions. There is NO
1394 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1394 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1395
1395
1396 Enabled extensions:
1396 Enabled extensions:
1397
1397
1398 throw external 1.twentythree
1398 throw external 1.twentythree
1399 strip internal
1399 strip internal
1400
1400
1401 $ hg version -q --config extensions.throw=throw.py
1401 $ hg version -q --config extensions.throw=throw.py
1402 Mercurial Distributed SCM (version *) (glob)
1402 Mercurial Distributed SCM (version *) (glob)
1403
1403
1404 Test JSON output of version:
1404 Test JSON output of version:
1405
1405
1406 $ hg version -Tjson
1406 $ hg version -Tjson
1407 [
1407 [
1408 {
1408 {
1409 "extensions": [],
1409 "extensions": [],
1410 "ver": "*" (glob)
1410 "ver": "*" (glob)
1411 }
1411 }
1412 ]
1412 ]
1413
1413
1414 $ hg version --config extensions.throw=throw.py -Tjson
1414 $ hg version --config extensions.throw=throw.py -Tjson
1415 [
1415 [
1416 {
1416 {
1417 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1417 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1418 "ver": "3.2.2"
1418 "ver": "3.2.2"
1419 }
1419 }
1420 ]
1420 ]
1421
1421
1422 $ hg version --config extensions.strip= -Tjson
1422 $ hg version --config extensions.strip= -Tjson
1423 [
1423 [
1424 {
1424 {
1425 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1425 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1426 "ver": "*" (glob)
1426 "ver": "*" (glob)
1427 }
1427 }
1428 ]
1428 ]
1429
1429
1430 Test template output of version:
1430 Test template output of version:
1431
1431
1432 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1432 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1433 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1433 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1434 throw 1.twentythree (external)
1434 throw 1.twentythree (external)
1435 strip (internal)
1435 strip (internal)
1436
1436
1437 Refuse to load extensions with minimum version requirements
1437 Refuse to load extensions with minimum version requirements
1438
1438
1439 $ cat > minversion1.py << EOF
1439 $ cat > minversion1.py << EOF
1440 > from mercurial import util
1440 > from mercurial import util
1441 > util.version = lambda: '3.5.2'
1441 > util.version = lambda: '3.5.2'
1442 > minimumhgversion = '3.6'
1442 > minimumhgversion = '3.6'
1443 > EOF
1443 > EOF
1444 $ hg --config extensions.minversion=minversion1.py version
1444 $ hg --config extensions.minversion=minversion1.py version
1445 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1445 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1446 Mercurial Distributed SCM (version 3.5.2)
1446 Mercurial Distributed SCM (version 3.5.2)
1447 (see https://mercurial-scm.org for more information)
1447 (see https://mercurial-scm.org for more information)
1448
1448
1449 Copyright (C) 2005-* Matt Mackall and others (glob)
1449 Copyright (C) 2005-* Matt Mackall and others (glob)
1450 This is free software; see the source for copying conditions. There is NO
1450 This is free software; see the source for copying conditions. There is NO
1451 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1451 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1452
1452
1453 $ cat > minversion2.py << EOF
1453 $ cat > minversion2.py << EOF
1454 > from mercurial import util
1454 > from mercurial import util
1455 > util.version = lambda: '3.6'
1455 > util.version = lambda: '3.6'
1456 > minimumhgversion = '3.7'
1456 > minimumhgversion = '3.7'
1457 > EOF
1457 > EOF
1458 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1458 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1459 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1459 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1460
1460
1461 Can load version that is only off by point release
1461 Can load version that is only off by point release
1462
1462
1463 $ cat > minversion2.py << EOF
1463 $ cat > minversion2.py << EOF
1464 > from mercurial import util
1464 > from mercurial import util
1465 > util.version = lambda: '3.6.1'
1465 > util.version = lambda: '3.6.1'
1466 > minimumhgversion = '3.6'
1466 > minimumhgversion = '3.6'
1467 > EOF
1467 > EOF
1468 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1468 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1469 [1]
1469 [1]
1470
1470
1471 Can load minimum version identical to current
1471 Can load minimum version identical to current
1472
1472
1473 $ cat > minversion3.py << EOF
1473 $ cat > minversion3.py << EOF
1474 > from mercurial import util
1474 > from mercurial import util
1475 > util.version = lambda: '3.5'
1475 > util.version = lambda: '3.5'
1476 > minimumhgversion = '3.5'
1476 > minimumhgversion = '3.5'
1477 > EOF
1477 > EOF
1478 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1478 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1479 [1]
1479 [1]
1480
1480
1481 Restore HGRCPATH
1481 Restore HGRCPATH
1482
1482
1483 $ HGRCPATH=$ORGHGRCPATH
1483 $ HGRCPATH=$ORGHGRCPATH
1484 $ export HGRCPATH
1484 $ export HGRCPATH
1485
1485
1486 Commands handling multiple repositories at a time should invoke only
1486 Commands handling multiple repositories at a time should invoke only
1487 "reposetup()" of extensions enabling in the target repository.
1487 "reposetup()" of extensions enabling in the target repository.
1488
1488
1489 $ mkdir reposetup-test
1489 $ mkdir reposetup-test
1490 $ cd reposetup-test
1490 $ cd reposetup-test
1491
1491
1492 $ cat > $TESTTMP/reposetuptest.py <<EOF
1492 $ cat > $TESTTMP/reposetuptest.py <<EOF
1493 > from mercurial import extensions
1493 > from mercurial import extensions
1494 > def reposetup(ui, repo):
1494 > def reposetup(ui, repo):
1495 > ui.write('reposetup() for %s\n' % (repo.root))
1495 > ui.write('reposetup() for %s\n' % (repo.root))
1496 > ui.flush()
1496 > ui.flush()
1497 > EOF
1497 > EOF
1498 $ hg init src
1498 $ hg init src
1499 $ echo a > src/a
1499 $ echo a > src/a
1500 $ hg -R src commit -Am '#0 at src/a'
1500 $ hg -R src commit -Am '#0 at src/a'
1501 adding a
1501 adding a
1502 $ echo '[extensions]' >> src/.hg/hgrc
1502 $ echo '[extensions]' >> src/.hg/hgrc
1503 $ echo '# enable extension locally' >> src/.hg/hgrc
1503 $ echo '# enable extension locally' >> src/.hg/hgrc
1504 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1504 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1505 $ hg -R src status
1505 $ hg -R src status
1506 reposetup() for $TESTTMP/reposetup-test/src
1506 reposetup() for $TESTTMP/reposetup-test/src
1507 reposetup() for $TESTTMP/reposetup-test/src (chg !)
1507 reposetup() for $TESTTMP/reposetup-test/src (chg !)
1508
1508
1509 $ hg clone -U src clone-dst1
1509 $ hg clone -U src clone-dst1
1510 reposetup() for $TESTTMP/reposetup-test/src
1510 reposetup() for $TESTTMP/reposetup-test/src
1511 $ hg init push-dst1
1511 $ hg init push-dst1
1512 $ hg -q -R src push push-dst1
1512 $ hg -q -R src push push-dst1
1513 reposetup() for $TESTTMP/reposetup-test/src
1513 reposetup() for $TESTTMP/reposetup-test/src
1514 $ hg init pull-src1
1514 $ hg init pull-src1
1515 $ hg -q -R pull-src1 pull src
1515 $ hg -q -R pull-src1 pull src
1516 reposetup() for $TESTTMP/reposetup-test/src
1516 reposetup() for $TESTTMP/reposetup-test/src
1517
1517
1518 $ cat <<EOF >> $HGRCPATH
1518 $ cat <<EOF >> $HGRCPATH
1519 > [extensions]
1519 > [extensions]
1520 > # disable extension globally and explicitly
1520 > # disable extension globally and explicitly
1521 > reposetuptest = !
1521 > reposetuptest = !
1522 > EOF
1522 > EOF
1523 $ hg clone -U src clone-dst2
1523 $ hg clone -U src clone-dst2
1524 reposetup() for $TESTTMP/reposetup-test/src
1524 reposetup() for $TESTTMP/reposetup-test/src
1525 $ hg init push-dst2
1525 $ hg init push-dst2
1526 $ hg -q -R src push push-dst2
1526 $ hg -q -R src push push-dst2
1527 reposetup() for $TESTTMP/reposetup-test/src
1527 reposetup() for $TESTTMP/reposetup-test/src
1528 $ hg init pull-src2
1528 $ hg init pull-src2
1529 $ hg -q -R pull-src2 pull src
1529 $ hg -q -R pull-src2 pull src
1530 reposetup() for $TESTTMP/reposetup-test/src
1530 reposetup() for $TESTTMP/reposetup-test/src
1531
1531
1532 $ cat <<EOF >> $HGRCPATH
1532 $ cat <<EOF >> $HGRCPATH
1533 > [extensions]
1533 > [extensions]
1534 > # enable extension globally
1534 > # enable extension globally
1535 > reposetuptest = $TESTTMP/reposetuptest.py
1535 > reposetuptest = $TESTTMP/reposetuptest.py
1536 > EOF
1536 > EOF
1537 $ hg clone -U src clone-dst3
1537 $ hg clone -U src clone-dst3
1538 reposetup() for $TESTTMP/reposetup-test/src
1538 reposetup() for $TESTTMP/reposetup-test/src
1539 reposetup() for $TESTTMP/reposetup-test/clone-dst3
1539 reposetup() for $TESTTMP/reposetup-test/clone-dst3
1540 $ hg init push-dst3
1540 $ hg init push-dst3
1541 reposetup() for $TESTTMP/reposetup-test/push-dst3
1541 reposetup() for $TESTTMP/reposetup-test/push-dst3
1542 $ hg -q -R src push push-dst3
1542 $ hg -q -R src push push-dst3
1543 reposetup() for $TESTTMP/reposetup-test/src
1543 reposetup() for $TESTTMP/reposetup-test/src
1544 reposetup() for $TESTTMP/reposetup-test/push-dst3
1544 reposetup() for $TESTTMP/reposetup-test/push-dst3
1545 $ hg init pull-src3
1545 $ hg init pull-src3
1546 reposetup() for $TESTTMP/reposetup-test/pull-src3
1546 reposetup() for $TESTTMP/reposetup-test/pull-src3
1547 $ hg -q -R pull-src3 pull src
1547 $ hg -q -R pull-src3 pull src
1548 reposetup() for $TESTTMP/reposetup-test/pull-src3
1548 reposetup() for $TESTTMP/reposetup-test/pull-src3
1549 reposetup() for $TESTTMP/reposetup-test/src
1549 reposetup() for $TESTTMP/reposetup-test/src
1550
1550
1551 $ echo '[extensions]' >> src/.hg/hgrc
1551 $ echo '[extensions]' >> src/.hg/hgrc
1552 $ echo '# disable extension locally' >> src/.hg/hgrc
1552 $ echo '# disable extension locally' >> src/.hg/hgrc
1553 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1553 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1554 $ hg clone -U src clone-dst4
1554 $ hg clone -U src clone-dst4
1555 reposetup() for $TESTTMP/reposetup-test/clone-dst4
1555 reposetup() for $TESTTMP/reposetup-test/clone-dst4
1556 $ hg init push-dst4
1556 $ hg init push-dst4
1557 reposetup() for $TESTTMP/reposetup-test/push-dst4
1557 reposetup() for $TESTTMP/reposetup-test/push-dst4
1558 $ hg -q -R src push push-dst4
1558 $ hg -q -R src push push-dst4
1559 reposetup() for $TESTTMP/reposetup-test/push-dst4
1559 reposetup() for $TESTTMP/reposetup-test/push-dst4
1560 $ hg init pull-src4
1560 $ hg init pull-src4
1561 reposetup() for $TESTTMP/reposetup-test/pull-src4
1561 reposetup() for $TESTTMP/reposetup-test/pull-src4
1562 $ hg -q -R pull-src4 pull src
1562 $ hg -q -R pull-src4 pull src
1563 reposetup() for $TESTTMP/reposetup-test/pull-src4
1563 reposetup() for $TESTTMP/reposetup-test/pull-src4
1564
1564
1565 disabling in command line overlays with all configuration
1565 disabling in command line overlays with all configuration
1566 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1566 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1567 $ hg --config extensions.reposetuptest=! init push-dst5
1567 $ hg --config extensions.reposetuptest=! init push-dst5
1568 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1568 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1569 $ hg --config extensions.reposetuptest=! init pull-src5
1569 $ hg --config extensions.reposetuptest=! init pull-src5
1570 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1570 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1571
1571
1572 $ cat <<EOF >> $HGRCPATH
1572 $ cat <<EOF >> $HGRCPATH
1573 > [extensions]
1573 > [extensions]
1574 > # disable extension globally and explicitly
1574 > # disable extension globally and explicitly
1575 > reposetuptest = !
1575 > reposetuptest = !
1576 > EOF
1576 > EOF
1577 $ hg init parent
1577 $ hg init parent
1578 $ hg init parent/sub1
1578 $ hg init parent/sub1
1579 $ echo 1 > parent/sub1/1
1579 $ echo 1 > parent/sub1/1
1580 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1580 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1581 adding 1
1581 adding 1
1582 $ hg init parent/sub2
1582 $ hg init parent/sub2
1583 $ hg init parent/sub2/sub21
1583 $ hg init parent/sub2/sub21
1584 $ echo 21 > parent/sub2/sub21/21
1584 $ echo 21 > parent/sub2/sub21/21
1585 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1585 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1586 adding 21
1586 adding 21
1587 $ cat > parent/sub2/.hgsub <<EOF
1587 $ cat > parent/sub2/.hgsub <<EOF
1588 > sub21 = sub21
1588 > sub21 = sub21
1589 > EOF
1589 > EOF
1590 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1590 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1591 adding .hgsub
1591 adding .hgsub
1592 $ hg init parent/sub3
1592 $ hg init parent/sub3
1593 $ echo 3 > parent/sub3/3
1593 $ echo 3 > parent/sub3/3
1594 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1594 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1595 adding 3
1595 adding 3
1596 $ cat > parent/.hgsub <<EOF
1596 $ cat > parent/.hgsub <<EOF
1597 > sub1 = sub1
1597 > sub1 = sub1
1598 > sub2 = sub2
1598 > sub2 = sub2
1599 > sub3 = sub3
1599 > sub3 = sub3
1600 > EOF
1600 > EOF
1601 $ hg -R parent commit -Am '#0 at parent'
1601 $ hg -R parent commit -Am '#0 at parent'
1602 adding .hgsub
1602 adding .hgsub
1603 $ echo '[extensions]' >> parent/.hg/hgrc
1603 $ echo '[extensions]' >> parent/.hg/hgrc
1604 $ echo '# enable extension locally' >> parent/.hg/hgrc
1604 $ echo '# enable extension locally' >> parent/.hg/hgrc
1605 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1605 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1606 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1606 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1607 $ hg -R parent status -S -A
1607 $ hg -R parent status -S -A
1608 reposetup() for $TESTTMP/reposetup-test/parent
1608 reposetup() for $TESTTMP/reposetup-test/parent
1609 reposetup() for $TESTTMP/reposetup-test/parent/sub2
1609 reposetup() for $TESTTMP/reposetup-test/parent/sub2
1610 C .hgsub
1610 C .hgsub
1611 C .hgsubstate
1611 C .hgsubstate
1612 C sub1/1
1612 C sub1/1
1613 C sub2/.hgsub
1613 C sub2/.hgsub
1614 C sub2/.hgsubstate
1614 C sub2/.hgsubstate
1615 C sub2/sub21/21
1615 C sub2/sub21/21
1616 C sub3/3
1616 C sub3/3
1617
1617
1618 $ cd ..
1618 $ cd ..
1619
1619
1620 Prohibit registration of commands that don't use @command (issue5137)
1620 Prohibit registration of commands that don't use @command (issue5137)
1621
1621
1622 $ hg init deprecated
1622 $ hg init deprecated
1623 $ cd deprecated
1623 $ cd deprecated
1624
1624
1625 $ cat <<EOF > deprecatedcmd.py
1625 $ cat <<EOF > deprecatedcmd.py
1626 > def deprecatedcmd(repo, ui):
1626 > def deprecatedcmd(repo, ui):
1627 > pass
1627 > pass
1628 > cmdtable = {
1628 > cmdtable = {
1629 > 'deprecatedcmd': (deprecatedcmd, [], ''),
1629 > 'deprecatedcmd': (deprecatedcmd, [], ''),
1630 > }
1630 > }
1631 > EOF
1631 > EOF
1632 $ cat <<EOF > .hg/hgrc
1632 $ cat <<EOF > .hg/hgrc
1633 > [extensions]
1633 > [extensions]
1634 > deprecatedcmd = `pwd`/deprecatedcmd.py
1634 > deprecatedcmd = `pwd`/deprecatedcmd.py
1635 > mq = !
1635 > mq = !
1636 > hgext.mq = !
1636 > hgext.mq = !
1637 > hgext/mq = !
1637 > hgext/mq = !
1638 > EOF
1638 > EOF
1639
1639
1640 $ hg deprecatedcmd > /dev/null
1640 $ hg deprecatedcmd > /dev/null
1641 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1641 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1642 *** (use @command decorator to register 'deprecatedcmd')
1642 *** (use @command decorator to register 'deprecatedcmd')
1643 hg: unknown command 'deprecatedcmd'
1643 hg: unknown command 'deprecatedcmd'
1644 [255]
1644 [255]
1645
1645
1646 the extension shouldn't be loaded at all so the mq works:
1646 the extension shouldn't be loaded at all so the mq works:
1647
1647
1648 $ hg qseries --config extensions.mq= > /dev/null
1648 $ hg qseries --config extensions.mq= > /dev/null
1649 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1649 *** failed to import extension deprecatedcmd from $TESTTMP/deprecated/deprecatedcmd.py: missing attributes: norepo, optionalrepo, inferrepo
1650 *** (use @command decorator to register 'deprecatedcmd')
1650 *** (use @command decorator to register 'deprecatedcmd')
1651
1651
1652 $ cd ..
1652 $ cd ..
1653
1653
1654 Test synopsis and docstring extending
1654 Test synopsis and docstring extending
1655
1655
1656 $ hg init exthelp
1656 $ hg init exthelp
1657 $ cat > exthelp.py <<EOF
1657 $ cat > exthelp.py <<EOF
1658 > from mercurial import commands, extensions
1658 > from mercurial import commands, extensions
1659 > def exbookmarks(orig, *args, **opts):
1659 > def exbookmarks(orig, *args, **opts):
1660 > return orig(*args, **opts)
1660 > return orig(*args, **opts)
1661 > def uisetup(ui):
1661 > def uisetup(ui):
1662 > synopsis = ' GREPME [--foo] [-x]'
1662 > synopsis = ' GREPME [--foo] [-x]'
1663 > docstring = '''
1663 > docstring = '''
1664 > GREPME make sure that this is in the help!
1664 > GREPME make sure that this is in the help!
1665 > '''
1665 > '''
1666 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1666 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1667 > synopsis, docstring)
1667 > synopsis, docstring)
1668 > EOF
1668 > EOF
1669 $ abspath=`pwd`/exthelp.py
1669 $ abspath=`pwd`/exthelp.py
1670 $ echo '[extensions]' >> $HGRCPATH
1670 $ echo '[extensions]' >> $HGRCPATH
1671 $ echo "exthelp = $abspath" >> $HGRCPATH
1671 $ echo "exthelp = $abspath" >> $HGRCPATH
1672 $ cd exthelp
1672 $ cd exthelp
1673 $ hg help bookmarks | grep GREPME
1673 $ hg help bookmarks | grep GREPME
1674 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1674 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1675 GREPME make sure that this is in the help!
1675 GREPME make sure that this is in the help!
1676 $ cd ..
1676 $ cd ..
1677
1677
1678 Show deprecation warning for the use of cmdutil.command
1678 Show deprecation warning for the use of cmdutil.command
1679
1679
1680 $ cat > nonregistrar.py <<EOF
1680 $ cat > nonregistrar.py <<EOF
1681 > from mercurial import cmdutil
1681 > from mercurial import cmdutil
1682 > cmdtable = {}
1682 > cmdtable = {}
1683 > command = cmdutil.command(cmdtable)
1683 > command = cmdutil.command(cmdtable)
1684 > @command(b'foo', [], norepo=True)
1684 > @command(b'foo', [], norepo=True)
1685 > def foo(ui):
1685 > def foo(ui):
1686 > pass
1686 > pass
1687 > EOF
1687 > EOF
1688
1688
1689 $ hg --config extensions.nonregistrar=`pwd`/nonregistrar.py version > /dev/null
1689 $ hg --config extensions.nonregistrar=`pwd`/nonregistrar.py version > /dev/null
1690 devel-warn: cmdutil.command is deprecated, use registrar.command to register 'foo'
1690 devel-warn: cmdutil.command is deprecated, use registrar.command to register 'foo'
1691 (compatibility will be dropped after Mercurial-4.6, update your code.) * (glob)
1691 (compatibility will be dropped after Mercurial-4.6, update your code.) * (glob)
1692
1692
1693 Prohibit the use of unicode strings as the default value of options
1693 Prohibit the use of unicode strings as the default value of options
1694
1694
1695 $ hg init $TESTTMP/opt-unicode-default
1695 $ hg init $TESTTMP/opt-unicode-default
1696
1696
1697 $ cat > $TESTTMP/test_unicode_default_value.py << EOF
1697 $ cat > $TESTTMP/test_unicode_default_value.py << EOF
1698 > from mercurial import registrar
1698 > from mercurial import registrar
1699 > cmdtable = {}
1699 > cmdtable = {}
1700 > command = registrar.command(cmdtable)
1700 > command = registrar.command(cmdtable)
1701 > @command('dummy', [('', 'opt', u'value', u'help')], 'ext [OPTIONS]')
1701 > @command('dummy', [('', 'opt', u'value', u'help')], 'ext [OPTIONS]')
1702 > def ext(*args, **opts):
1702 > def ext(*args, **opts):
1703 > print(opts['opt'])
1703 > print(opts['opt'])
1704 > EOF
1704 > EOF
1705 $ cat > $TESTTMP/opt-unicode-default/.hg/hgrc << EOF
1705 $ cat > $TESTTMP/opt-unicode-default/.hg/hgrc << EOF
1706 > [extensions]
1706 > [extensions]
1707 > test_unicode_default_value = $TESTTMP/test_unicode_default_value.py
1707 > test_unicode_default_value = $TESTTMP/test_unicode_default_value.py
1708 > EOF
1708 > EOF
1709 $ hg -R $TESTTMP/opt-unicode-default dummy
1709 $ hg -R $TESTTMP/opt-unicode-default dummy
1710 *** failed to import extension test_unicode_default_value from $TESTTMP/test_unicode_default_value.py: option 'dummy.opt' has a unicode default value
1710 *** failed to import extension test_unicode_default_value from $TESTTMP/test_unicode_default_value.py: option 'dummy.opt' has a unicode default value
1711 *** (change the dummy.opt default value to a non-unicode string)
1711 *** (change the dummy.opt default value to a non-unicode string)
1712 hg: unknown command 'dummy'
1712 hg: unknown command 'dummy'
1713 (did you mean summary?)
1713 (did you mean summary?)
1714 [255]
1714 [255]
General Comments 0
You need to be logged in to leave comments. Login now