schemes: prevent one letter schemes from being interpreted as drive letters
authorBrodie Rao <brodie@bitheap.org>
Wed, 30 Mar 2011 20:01:47 -0700
changeset 13822 fbf32a6c903e
parent 13821 a35aff48d577
child 13823 ad179644750f
schemes: prevent one letter schemes from being interpreted as drive letters To allow one letter schemes, this makes the extension override url.has_drive_letter() to return False for any schemes defined. On Windows, the extension will raise util.Abort for any schemes that conflict with existing drive letters.
hgext/schemes.py
--- a/hgext/schemes.py	Wed Mar 30 20:01:46 2011 -0700
+++ b/hgext/schemes.py	Wed Mar 30 20:01:47 2011 -0700
@@ -40,8 +40,9 @@
 same name.
 """
 
-import re
-from mercurial import hg, templater
+import os, re
+from mercurial import extensions, hg, templater, url as urlmod, util
+from mercurial.i18n import _
 
 
 class ShortRepository(object):
@@ -58,6 +59,7 @@
         return '<ShortRepository: %s>' % self.scheme
 
     def instance(self, ui, url, create):
+        # Should this use urlmod.url(), or is manual parsing better?
         url = url.split('://', 1)[1]
         parts = url.split('/', self.parts)
         if len(parts) > self.parts:
@@ -69,6 +71,12 @@
         url = ''.join(self.templater.process(self.url, context)) + tail
         return hg._lookup(url).instance(ui, url, create)
 
+def has_drive_letter(orig, path):
+    for scheme in schemes:
+        if path.startswith(scheme + ':'):
+            return False
+    return orig(path)
+
 schemes = {
     'py': 'http://hg.python.org/',
     'bb': 'https://bitbucket.org/',
@@ -81,4 +89,10 @@
     schemes.update(dict(ui.configitems('schemes')))
     t = templater.engine(lambda x: x)
     for scheme, url in schemes.items():
+        if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha()
+            and os.path.exists('%s:\\' % scheme)):
+            raise util.Abort(_('custom scheme %s:// conflicts with drive '
+                               'letter %s:\\\n') % (scheme, scheme.upper()))
         hg.schemes[scheme] = ShortRepository(url, scheme, t)
+
+    extensions.wrapfunction(urlmod, 'has_drive_letter', has_drive_letter)