##// END OF EJS Templates
schemes: add debugexpandscheme command, resolving a scheme to canonical form
Jason R. Coombs -
r27982:bf1d5c22 default
parent child Browse files
Show More
@@ -1,111 +1,122 b''
1 # Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
1 # Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5
5
6 """extend schemes with shortcuts to repository swarms
6 """extend schemes with shortcuts to repository swarms
7
7
8 This extension allows you to specify shortcuts for parent URLs with a
8 This extension allows you to specify shortcuts for parent URLs with a
9 lot of repositories to act like a scheme, for example::
9 lot of repositories to act like a scheme, for example::
10
10
11 [schemes]
11 [schemes]
12 py = http://code.python.org/hg/
12 py = http://code.python.org/hg/
13
13
14 After that you can use it like::
14 After that you can use it like::
15
15
16 hg clone py://trunk/
16 hg clone py://trunk/
17
17
18 Additionally there is support for some more complex schemas, for
18 Additionally there is support for some more complex schemas, for
19 example used by Google Code::
19 example used by Google Code::
20
20
21 [schemes]
21 [schemes]
22 gcode = http://{1}.googlecode.com/hg/
22 gcode = http://{1}.googlecode.com/hg/
23
23
24 The syntax is taken from Mercurial templates, and you have unlimited
24 The syntax is taken from Mercurial templates, and you have unlimited
25 number of variables, starting with ``{1}`` and continuing with
25 number of variables, starting with ``{1}`` and continuing with
26 ``{2}``, ``{3}`` and so on. This variables will receive parts of URL
26 ``{2}``, ``{3}`` and so on. This variables will receive parts of URL
27 supplied, split by ``/``. Anything not specified as ``{part}`` will be
27 supplied, split by ``/``. Anything not specified as ``{part}`` will be
28 just appended to an URL.
28 just appended to an URL.
29
29
30 For convenience, the extension adds these schemes by default::
30 For convenience, the extension adds these schemes by default::
31
31
32 [schemes]
32 [schemes]
33 py = http://hg.python.org/
33 py = http://hg.python.org/
34 bb = https://bitbucket.org/
34 bb = https://bitbucket.org/
35 bb+ssh = ssh://hg@bitbucket.org/
35 bb+ssh = ssh://hg@bitbucket.org/
36 gcode = https://{1}.googlecode.com/hg/
36 gcode = https://{1}.googlecode.com/hg/
37 kiln = https://{1}.kilnhg.com/Repo/
37 kiln = https://{1}.kilnhg.com/Repo/
38
38
39 You can override a predefined scheme by defining a new scheme with the
39 You can override a predefined scheme by defining a new scheme with the
40 same name.
40 same name.
41 """
41 """
42
42
43 import os, re
43 import os, re
44 from mercurial import extensions, hg, templater, util, error
44 from mercurial import extensions, hg, templater, util, error, cmdutil
45 from mercurial.i18n import _
45 from mercurial.i18n import _
46
46
47 cmdtable = {}
48 command = cmdutil.command(cmdtable)
47 # Note for extension authors: ONLY specify testedwith = 'internal' for
49 # Note for extension authors: ONLY specify testedwith = 'internal' for
48 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
50 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
49 # be specifying the version(s) of Mercurial they are tested with, or
51 # be specifying the version(s) of Mercurial they are tested with, or
50 # leave the attribute unspecified.
52 # leave the attribute unspecified.
51 testedwith = 'internal'
53 testedwith = 'internal'
52
54
53
55
54 class ShortRepository(object):
56 class ShortRepository(object):
55 def __init__(self, url, scheme, templater):
57 def __init__(self, url, scheme, templater):
56 self.scheme = scheme
58 self.scheme = scheme
57 self.templater = templater
59 self.templater = templater
58 self.url = url
60 self.url = url
59 try:
61 try:
60 self.parts = max(map(int, re.findall(r'\{(\d+)\}', self.url)))
62 self.parts = max(map(int, re.findall(r'\{(\d+)\}', self.url)))
61 except ValueError:
63 except ValueError:
62 self.parts = 0
64 self.parts = 0
63
65
64 def __repr__(self):
66 def __repr__(self):
65 return '<ShortRepository: %s>' % self.scheme
67 return '<ShortRepository: %s>' % self.scheme
66
68
67 def instance(self, ui, url, create):
69 def instance(self, ui, url, create):
68 url = self.resolve(url)
70 url = self.resolve(url)
69 return hg._peerlookup(url).instance(ui, url, create)
71 return hg._peerlookup(url).instance(ui, url, create)
70
72
71 def resolve(self, url):
73 def resolve(self, url):
72 # Should this use the util.url class, or is manual parsing better?
74 # Should this use the util.url class, or is manual parsing better?
73 try:
75 try:
74 url = url.split('://', 1)[1]
76 url = url.split('://', 1)[1]
75 except IndexError:
77 except IndexError:
76 raise error.Abort(_("no '://' in scheme url '%s'") % url)
78 raise error.Abort(_("no '://' in scheme url '%s'") % url)
77 parts = url.split('/', self.parts)
79 parts = url.split('/', self.parts)
78 if len(parts) > self.parts:
80 if len(parts) > self.parts:
79 tail = parts[-1]
81 tail = parts[-1]
80 parts = parts[:-1]
82 parts = parts[:-1]
81 else:
83 else:
82 tail = ''
84 tail = ''
83 context = dict((str(i + 1), v) for i, v in enumerate(parts))
85 context = dict((str(i + 1), v) for i, v in enumerate(parts))
84 return ''.join(self.templater.process(self.url, context)) + tail
86 return ''.join(self.templater.process(self.url, context)) + tail
85
87
86 def hasdriveletter(orig, path):
88 def hasdriveletter(orig, path):
87 if path:
89 if path:
88 for scheme in schemes:
90 for scheme in schemes:
89 if path.startswith(scheme + ':'):
91 if path.startswith(scheme + ':'):
90 return False
92 return False
91 return orig(path)
93 return orig(path)
92
94
93 schemes = {
95 schemes = {
94 'py': 'http://hg.python.org/',
96 'py': 'http://hg.python.org/',
95 'bb': 'https://bitbucket.org/',
97 'bb': 'https://bitbucket.org/',
96 'bb+ssh': 'ssh://hg@bitbucket.org/',
98 'bb+ssh': 'ssh://hg@bitbucket.org/',
97 'gcode': 'https://{1}.googlecode.com/hg/',
99 'gcode': 'https://{1}.googlecode.com/hg/',
98 'kiln': 'https://{1}.kilnhg.com/Repo/'
100 'kiln': 'https://{1}.kilnhg.com/Repo/'
99 }
101 }
100
102
101 def extsetup(ui):
103 def extsetup(ui):
102 schemes.update(dict(ui.configitems('schemes')))
104 schemes.update(dict(ui.configitems('schemes')))
103 t = templater.engine(lambda x: x)
105 t = templater.engine(lambda x: x)
104 for scheme, url in schemes.items():
106 for scheme, url in schemes.items():
105 if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha()
107 if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha()
106 and os.path.exists('%s:\\' % scheme)):
108 and os.path.exists('%s:\\' % scheme)):
107 raise error.Abort(_('custom scheme %s:// conflicts with drive '
109 raise error.Abort(_('custom scheme %s:// conflicts with drive '
108 'letter %s:\\\n') % (scheme, scheme.upper()))
110 'letter %s:\\\n') % (scheme, scheme.upper()))
109 hg.schemes[scheme] = ShortRepository(url, scheme, t)
111 hg.schemes[scheme] = ShortRepository(url, scheme, t)
110
112
111 extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter)
113 extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter)
114
115 @command('debugexpandscheme', norepo=True)
116 def expandscheme(ui, url, **opts):
117 """given a repo path, provide the scheme-expanded path
118 """
119 repo = hg._peerlookup(url)
120 if isinstance(repo, ShortRepository):
121 url = repo.resolve(url)
122 ui.write(url + '\n')
@@ -1,59 +1,74 b''
1 #require serve
1 #require serve
2
2
3 $ cat <<EOF >> $HGRCPATH
3 $ cat <<EOF >> $HGRCPATH
4 > [extensions]
4 > [extensions]
5 > schemes=
5 > schemes=
6 >
6 >
7 > [schemes]
7 > [schemes]
8 > l = http://localhost:$HGPORT/
8 > l = http://localhost:$HGPORT/
9 > parts = http://{1}:$HGPORT/
9 > parts = http://{1}:$HGPORT/
10 > z = file:\$PWD/
10 > z = file:\$PWD/
11 > EOF
11 > EOF
12 $ hg init test
12 $ hg init test
13 $ cd test
13 $ cd test
14 $ echo a > a
14 $ echo a > a
15 $ hg ci -Am initial
15 $ hg ci -Am initial
16 adding a
16 adding a
17
17
18 invalid scheme
18 invalid scheme
19
19
20 $ hg log -R z:z
20 $ hg log -R z:z
21 abort: no '://' in scheme url 'z:z'
21 abort: no '://' in scheme url 'z:z'
22 [255]
22 [255]
23
23
24 http scheme
24 http scheme
25
25
26 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
26 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
27 $ cat hg.pid >> $DAEMON_PIDS
27 $ cat hg.pid >> $DAEMON_PIDS
28 $ hg incoming l://
28 $ hg incoming l://
29 comparing with l://
29 comparing with l://
30 searching for changes
30 searching for changes
31 no changes found
31 no changes found
32 [1]
32 [1]
33
33
34 check that {1} syntax works
34 check that {1} syntax works
35
35
36 $ hg incoming --debug parts://localhost
36 $ hg incoming --debug parts://localhost
37 using http://localhost:$HGPORT/
37 using http://localhost:$HGPORT/
38 sending capabilities command
38 sending capabilities command
39 comparing with parts://localhost/
39 comparing with parts://localhost/
40 query 1; heads
40 query 1; heads
41 sending batch command
41 sending batch command
42 searching for changes
42 searching for changes
43 all remote heads known locally
43 all remote heads known locally
44 no changes found
44 no changes found
45 [1]
45 [1]
46
46
47 check that paths are expanded
47 check that paths are expanded
48
48
49 $ PWD=`pwd` hg incoming z://
49 $ PWD=`pwd` hg incoming z://
50 comparing with z://
50 comparing with z://
51 searching for changes
51 searching for changes
52 no changes found
52 no changes found
53 [1]
53 [1]
54
54
55 check that debugexpandscheme outputs the canonical form
56
57 $ hg debugexpandscheme bb://user/repo
58 https://bitbucket.org/user/repo
59
60 expanding an unknown scheme emits the input
61
62 $ hg debugexpandscheme foobar://this/that
63 foobar://this/that
64
65 expanding a canonical URL emits the input
66
67 $ hg debugexpandscheme https://bitbucket.org/user/repo
68 https://bitbucket.org/user/repo
69
55 errors
70 errors
56
71
57 $ cat errors.log
72 $ cat errors.log
58
73
59 $ cd ..
74 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now