##// END OF EJS Templates
scheme: move the drive letter checking in its own function...
marmoute -
r50585:1863584f default
parent child Browse files
Show More
@@ -1,158 +1,159 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 instance(self, ui, url, create, intents=None, createopts=None):
84 84 url = self.resolve(url)
85 85 return hg._peerlookup(url).instance(
86 86 ui, url, create, intents=intents, createopts=createopts
87 87 )
88 88
89 89 def resolve(self, url):
90 90 # Should this use the urlutil.url class, or is manual parsing better?
91 91 try:
92 92 url = url.split(b'://', 1)[1]
93 93 except IndexError:
94 94 raise error.Abort(_(b"no '://' in scheme url '%s'") % url)
95 95 parts = url.split(b'/', self.parts)
96 96 if len(parts) > self.parts:
97 97 tail = parts[-1]
98 98 parts = parts[:-1]
99 99 else:
100 100 tail = b''
101 101 context = {b'%d' % (i + 1): v for i, v in enumerate(parts)}
102 102 return b''.join(self.templater.process(self.url, context)) + tail
103 103
104 104
105 105 def hasdriveletter(orig, path):
106 106 if path:
107 107 for scheme in schemes:
108 108 if path.startswith(scheme + b':'):
109 109 return False
110 110 return orig(path)
111 111
112 112
113 113 schemes = {
114 114 b'py': b'http://hg.python.org/',
115 115 b'bb': b'https://bitbucket.org/',
116 116 b'bb+ssh': b'ssh://hg@bitbucket.org/',
117 117 b'gcode': b'https://{1}.googlecode.com/hg/',
118 118 b'kiln': b'https://{1}.kilnhg.com/Repo/',
119 119 }
120 120
121 121
122 def _check_drive_letter(scheme):
123 """check if a scheme conflict with a Windows drive letter"""
124 if (
125 pycompat.iswindows
126 and len(scheme) == 1
127 and scheme.isalpha()
128 and os.path.exists(b'%s:\\' % scheme)
129 ):
130 msg = _(b'custom scheme %s:// conflicts with drive letter %s:\\\n')
131 msg %= (scheme, scheme.upper())
132 raise error.Abort(msg)
133
134
122 135 def extsetup(ui):
123 136 schemes.update(dict(ui.configitems(b'schemes')))
124 137 t = templater.engine(templater.parse)
125 138 for scheme, url in schemes.items():
126 if (
127 pycompat.iswindows
128 and len(scheme) == 1
129 and scheme.isalpha()
130 and os.path.exists(b'%s:\\' % scheme)
131 ):
132 raise error.Abort(
133 _(
134 b'custom scheme %s:// conflicts with drive '
135 b'letter %s:\\\n'
136 )
137 % (scheme, scheme.upper())
138 )
139 _check_drive_letter(schemes)
139 140 url_scheme = urlutil.url(url).scheme
140 141 if url_scheme in hg.peer_schemes:
141 142 hg.peer_schemes[scheme] = ShortRepository(url, scheme, t)
142 143 else:
143 144 hg.repo_schemes[scheme] = ShortRepository(url, scheme, t)
144 145
145 146 extensions.wrapfunction(urlutil, b'hasdriveletter', hasdriveletter)
146 147
147 148
148 149 @command(b'debugexpandscheme', norepo=True)
149 150 def expandscheme(ui, url, **opts):
150 151 """given a repo path, provide the scheme-expanded path"""
151 152 scheme = urlutil.url(url).scheme
152 153 if scheme in hg.peer_schemes:
153 154 cls = hg.peer_schemes[scheme]
154 155 else:
155 156 cls = hg.repo_schemes.get(scheme)
156 157 if cls is not None and isinstance(cls, ShortRepository):
157 158 url = cls.resolve(url)
158 159 ui.write(url + b'\n')
General Comments 0
You need to be logged in to leave comments. Login now