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