##// END OF EJS Templates
wrapfunction: use sysstr instead of bytes as argument in "schemes"...
marmoute -
r51684:d51a76b5 default
parent child Browse files
Show More
@@ -1,175 +1,175 b''
1 1 # Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5
6 6 """extend schemes with shortcuts to repository swarms
7 7
8 8 This extension allows you to specify shortcuts for parent URLs with a
9 9 lot of repositories to act like a scheme, for example::
10 10
11 11 [schemes]
12 12 py = http://code.python.org/hg/
13 13
14 14 After that you can use it like::
15 15
16 16 hg clone py://trunk/
17 17
18 18 Additionally there is support for some more complex schemas, for
19 19 example used by Google Code::
20 20
21 21 [schemes]
22 22 gcode = http://{1}.googlecode.com/hg/
23 23
24 24 The syntax is taken from Mercurial templates, and you have unlimited
25 25 number of variables, starting with ``{1}`` and continuing with
26 26 ``{2}``, ``{3}`` and so on. This variables will receive parts of URL
27 27 supplied, split by ``/``. Anything not specified as ``{part}`` will be
28 28 just appended to an URL.
29 29
30 30 For convenience, the extension adds these schemes by default::
31 31
32 32 [schemes]
33 33 py = http://hg.python.org/
34 34 bb = https://bitbucket.org/
35 35 bb+ssh = ssh://hg@bitbucket.org/
36 36 gcode = https://{1}.googlecode.com/hg/
37 37 kiln = https://{1}.kilnhg.com/Repo/
38 38
39 39 You can override a predefined scheme by defining a new scheme with the
40 40 same name.
41 41 """
42 42
43 43 import os
44 44 import re
45 45
46 46 from mercurial.i18n import _
47 47 from mercurial import (
48 48 error,
49 49 extensions,
50 50 hg,
51 51 pycompat,
52 52 registrar,
53 53 templater,
54 54 )
55 55 from mercurial.utils import (
56 56 urlutil,
57 57 )
58 58
59 59 cmdtable = {}
60 60 command = registrar.command(cmdtable)
61 61 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
62 62 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
63 63 # be specifying the version(s) of Mercurial they are tested with, or
64 64 # leave the attribute unspecified.
65 65 testedwith = b'ships-with-hg-core'
66 66
67 67 _partre = re.compile(br'{(\d+)\}')
68 68
69 69
70 70 class ShortRepository:
71 71 def __init__(self, url, scheme, templater):
72 72 self.scheme = scheme
73 73 self.templater = templater
74 74 self.url = url
75 75 try:
76 76 self.parts = max(map(int, _partre.findall(self.url)))
77 77 except ValueError:
78 78 self.parts = 0
79 79
80 80 def __repr__(self):
81 81 return b'<ShortRepository: %s>' % self.scheme
82 82
83 83 def make_peer(self, ui, path, *args, **kwargs):
84 84 new_url = self.resolve(path.rawloc)
85 85 path = path.copy(new_raw_location=new_url)
86 86 cls = hg.peer_schemes.get(path.url.scheme)
87 87 if cls is not None:
88 88 return cls.make_peer(ui, path, *args, **kwargs)
89 89 return None
90 90
91 91 def instance(self, ui, url, create, intents=None, createopts=None):
92 92 url = self.resolve(url)
93 93 u = urlutil.url(url)
94 94 scheme = u.scheme or b'file'
95 95 if scheme in hg.peer_schemes:
96 96 cls = hg.peer_schemes[scheme]
97 97 elif scheme in hg.repo_schemes:
98 98 cls = hg.repo_schemes[scheme]
99 99 else:
100 100 cls = hg.LocalFactory
101 101 return cls.instance(
102 102 ui, url, create, intents=intents, createopts=createopts
103 103 )
104 104
105 105 def resolve(self, url):
106 106 # Should this use the urlutil.url class, or is manual parsing better?
107 107 try:
108 108 url = url.split(b'://', 1)[1]
109 109 except IndexError:
110 110 raise error.Abort(_(b"no '://' in scheme url '%s'") % url)
111 111 parts = url.split(b'/', self.parts)
112 112 if len(parts) > self.parts:
113 113 tail = parts[-1]
114 114 parts = parts[:-1]
115 115 else:
116 116 tail = b''
117 117 context = {b'%d' % (i + 1): v for i, v in enumerate(parts)}
118 118 return b''.join(self.templater.process(self.url, context)) + tail
119 119
120 120
121 121 def hasdriveletter(orig, path):
122 122 if path:
123 123 for scheme in schemes:
124 124 if path.startswith(scheme + b':'):
125 125 return False
126 126 return orig(path)
127 127
128 128
129 129 schemes = {
130 130 b'py': b'http://hg.python.org/',
131 131 b'bb': b'https://bitbucket.org/',
132 132 b'bb+ssh': b'ssh://hg@bitbucket.org/',
133 133 b'gcode': b'https://{1}.googlecode.com/hg/',
134 134 b'kiln': b'https://{1}.kilnhg.com/Repo/',
135 135 }
136 136
137 137
138 138 def _check_drive_letter(scheme: bytes) -> None:
139 139 """check if a scheme conflict with a Windows drive letter"""
140 140 if (
141 141 pycompat.iswindows
142 142 and len(scheme) == 1
143 143 and scheme.isalpha()
144 144 and os.path.exists(b'%s:\\' % scheme)
145 145 ):
146 146 msg = _(b'custom scheme %s:// conflicts with drive letter %s:\\\n')
147 147 msg %= (scheme, scheme.upper())
148 148 raise error.Abort(msg)
149 149
150 150
151 151 def extsetup(ui):
152 152 schemes.update(dict(ui.configitems(b'schemes')))
153 153 t = templater.engine(templater.parse)
154 154 for scheme, url in schemes.items():
155 155 _check_drive_letter(scheme)
156 156 url_scheme = urlutil.url(url).scheme
157 157 if url_scheme in hg.peer_schemes:
158 158 hg.peer_schemes[scheme] = ShortRepository(url, scheme, t)
159 159 else:
160 160 hg.repo_schemes[scheme] = ShortRepository(url, scheme, t)
161 161
162 extensions.wrapfunction(urlutil, b'hasdriveletter', hasdriveletter)
162 extensions.wrapfunction(urlutil, 'hasdriveletter', hasdriveletter)
163 163
164 164
165 165 @command(b'debugexpandscheme', norepo=True)
166 166 def expandscheme(ui, url, **opts):
167 167 """given a repo path, provide the scheme-expanded path"""
168 168 scheme = urlutil.url(url).scheme
169 169 if scheme in hg.peer_schemes:
170 170 cls = hg.peer_schemes[scheme]
171 171 else:
172 172 cls = hg.repo_schemes.get(scheme)
173 173 if cls is not None and isinstance(cls, ShortRepository):
174 174 url = cls.resolve(url)
175 175 ui.write(url + b'\n')
General Comments 0
You need to be logged in to leave comments. Login now