changeset 920:6507d2a6be0a

util: add heuristic method to determine if a uri is git This add the ability to copy & paste from github's (and other git-style) urls. Due to how we need to handle this, we need to also ensure that paths that end with .git are stripped of their extension.
author Sean Farley <sean@farley.io>
date Wed, 01 Jul 2015 13:55:59 -0700
parents f5dc1730e4d3
children 0e975d03f8ca
files hggit/__init__.py hggit/util.py
diffstat 2 files changed, 51 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/hggit/__init__.py
+++ b/hggit/__init__.py
@@ -75,8 +75,7 @@
 
 # support for `hg clone git://github.com/defunkt/facebox.git`
 # also hg clone git+ssh://git@github.com/schacon/simplegit.git
-_gitschemes = ('git', 'git+ssh', 'git+http', 'git+https')
-for _scheme in _gitschemes:
+for _scheme in util.gitschemes:
     hg.schemes[_scheme] = gitrepo
 
 # support for `hg clone localgitrepo`
@@ -109,10 +108,13 @@
 
 hgdefaultdest = hg.defaultdest
 def defaultdest(source):
-    for scheme in _gitschemes:
+    for scheme in util.gitschemes:
         if source.startswith('%s://' % scheme) and source.endswith('.git'):
-            source = source[:-4]
-            break
+            return hgdefaultdest(source[:-4])
+
+    if source.endswith('.git'):
+        return hgdefaultdest(source[:-4])
+
     return hgdefaultdest(source)
 hg.defaultdest = defaultdest
 
--- a/hggit/util.py
+++ b/hggit/util.py
@@ -1,5 +1,7 @@
 """Compatibility functions for old Mercurial versions and other utility
 functions."""
+import re
+
 from dulwich import errors
 from mercurial import util as hgutil
 try:
@@ -7,6 +9,8 @@
 except ImportError:
     from ordereddict import OrderedDict
 
+gitschemes = ('git', 'git+ssh', 'git+http', 'git+https')
+
 def parse_hgsub(lines):
     """Fills OrderedDict with hgsub file content passed as list of lines"""
     rv = OrderedDict()
@@ -45,3 +49,43 @@
         except errors.NotGitRepository:
             raise hgutil.Abort('not a git repository')
     return inner
+
+def isgitsshuri(uri):
+    """Method that returns True if a uri looks like git-style uri
+
+    Tests:
+
+    >>> print isgitsshuri('http://fqdn.com/hg')
+    False
+    >>> print isgitsshuri('http://fqdn.com/test.git')
+    False
+    >>> print isgitsshuri('git@github.com:user/repo.git')
+    True
+    >>> print isgitsshuri('github-123.com:user/repo.git')
+    True
+    >>> print isgitsshuri('git@127.0.0.1:repo.git')
+    True
+    >>> print isgitsshuri('git@[2001:db8::1]:repository.git')
+    True
+    """
+    for scheme in gitschemes:
+        if uri.startswith('%s://' % scheme):
+            return False
+
+    if uri.startswith('http:') or uri.startswith('https:'):
+        return False
+
+    m = re.match(r'(?:.+@)*([\[]?[\w\d\.\:\-]+[\]]?):(.*)', uri)
+    if m:
+        # here we're being fairly conservative about what we consider to be git
+        # urls
+        giturl, repopath = m.groups()
+        # definitely a git repo
+        if repopath.endswith('.git'):
+            return True
+        # use a simple regex to check if it is a fqdn regex
+        fqdn_re = (r'(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}'
+                   r'(?<!-)\.)+[a-zA-Z]{2,63}$)')
+        if re.match(fqdn_re, giturl):
+            return True
+    return False