return refs
-def get_transport_and_path(uri, **kwargs):
- """Obtain a git client from a URI or path.
+def get_transport_and_path_from_url(url, **kwargs):
+ """Obtain a git client from a URL.
:param uri: URI or path
:param thin_packs: Whether or not thin packs should be retrieved
activity.
:return: Tuple with client instance and relative path.
"""
- parsed = urlparse.urlparse(uri)
+ parsed = urlparse.urlparse(url)
if parsed.scheme == 'git':
return (TCPGitClient(parsed.hostname, port=parsed.port, **kwargs),
parsed.path)
username=parsed.username, **kwargs), path
elif parsed.scheme in ('http', 'https'):
return HttpGitClient(urlparse.urlunparse(parsed), **kwargs), parsed.path
+ elif parsed.scheme == 'file':
+ return SubprocessGitClient(**kwargs), parsed.path
- if parsed.scheme and not parsed.netloc:
+ raise ValueError("unknown scheme '%s'" % parsed.scheme)
+
+
+def get_transport_and_path(location, **kwargs):
+ """Obtain a git client from a URL.
+
+ :param location: URL or path
+ :param thin_packs: Whether or not thin packs should be retrieved
+ :param report_activity: Optional callback for reporting transport
+ activity.
+ :return: Tuple with client instance and relative path.
+ """
+ # First, try to parse it as a URL
+ try:
+ return get_transport_and_path_from_url(location, **kwargs)
+ except ValueError:
+ pass
+
+ if ':' in location and not '@' in location:
# SSH with no user@, zero or one leading slash.
- return SSHGitClient(parsed.scheme, **kwargs), parsed.path
- elif parsed.scheme:
- raise ValueError('Unknown git protocol scheme: %s' % parsed.scheme)
- elif '@' in parsed.path and ':' in parsed.path:
+ (hostname, path) = location.split(':')
+ return SSHGitClient(hostname, **kwargs), path
+ elif '@' in location and ':' in location:
# SSH with user@host:foo.
- user_host, path = parsed.path.split(':')
+ user_host, path = location.split(':')
user, host = user_host.rsplit('@')
return SSHGitClient(host, username=user, **kwargs), path
# Otherwise, assume it's a local path.
- return SubprocessGitClient(**kwargs), uri
+ return SubprocessGitClient(**kwargs), location
SendPackError,
UpdateRefsError,
get_transport_and_path,
+ get_transport_and_path_from_url,
)
from dulwich.tests import (
TestCase,
def test_get_transport_and_path_error(self):
# Need to use a known urlparse.uses_netloc URL scheme to get the
# expected parsing of the URL on Python versions less than 2.6.5
- self.assertRaises(ValueError, get_transport_and_path,
- 'prospero://bar/baz')
+ client, path = get_transport_and_path('prospero://bar/baz')
+ self.assertTrue(isinstance(client, SSHGitClient))
def test_get_transport_and_path_http(self):
url = 'https://github.com/jelmer/dulwich'
self.assertEqual(self.rout.getvalue(), '0000')
+class TestGetTransportAndPathFromUrl(TestCase):
+
+ def test_tcp(self):
+ c, path = get_transport_and_path_from_url('git://foo.com/bar/baz')
+ self.assertTrue(isinstance(c, TCPGitClient))
+ self.assertEqual('foo.com', c._host)
+ self.assertEqual(TCP_GIT_PORT, c._port)
+ self.assertEqual('/bar/baz', path)
+
+ def test_tcp_port(self):
+ c, path = get_transport_and_path_from_url('git://foo.com:1234/bar/baz')
+ self.assertTrue(isinstance(c, TCPGitClient))
+ self.assertEqual('foo.com', c._host)
+ self.assertEqual(1234, c._port)
+ self.assertEqual('/bar/baz', path)
+
+ def test_ssh_explicit(self):
+ c, path = get_transport_and_path_from_url('git+ssh://foo.com/bar/baz')
+ self.assertTrue(isinstance(c, SSHGitClient))
+ self.assertEqual('foo.com', c.host)
+ self.assertEqual(None, c.port)
+ self.assertEqual(None, c.username)
+ self.assertEqual('bar/baz', path)
+
+ def test_ssh_port_explicit(self):
+ c, path = get_transport_and_path_from_url(
+ 'git+ssh://foo.com:1234/bar/baz')
+ self.assertTrue(isinstance(c, SSHGitClient))
+ self.assertEqual('foo.com', c.host)
+ self.assertEqual(1234, c.port)
+ self.assertEqual('bar/baz', path)
+
+ def test_ssh_abspath_explicit(self):
+ c, path = get_transport_and_path_from_url('git+ssh://foo.com//bar/baz')
+ self.assertTrue(isinstance(c, SSHGitClient))
+ self.assertEqual('foo.com', c.host)
+ self.assertEqual(None, c.port)
+ self.assertEqual(None, c.username)
+ self.assertEqual('/bar/baz', path)
+
+ def test_ssh_port_abspath_explicit(self):
+ c, path = get_transport_and_path_from_url(
+ 'git+ssh://foo.com:1234//bar/baz')
+ self.assertTrue(isinstance(c, SSHGitClient))
+ self.assertEqual('foo.com', c.host)
+ self.assertEqual(1234, c.port)
+ self.assertEqual('/bar/baz', path)
+
+ def test_ssh_host_relpath(self):
+ self.assertRaises(ValueError, get_transport_and_path_from_url,
+ 'foo.com:bar/baz')
+
+ def test_ssh_user_host_relpath(self):
+ self.assertRaises(ValueError, get_transport_and_path_from_url,
+ 'user@foo.com:bar/baz')
+
+ def test_local_path(self):
+ self.assertRaises(ValueError, get_transport_and_path_from_url,
+ 'foo.bar/baz')
+
+ def test_error(self):
+ # Need to use a known urlparse.uses_netloc URL scheme to get the
+ # expected parsing of the URL on Python versions less than 2.6.5
+ self.assertRaises(ValueError, get_transport_and_path_from_url,
+ 'prospero://bar/baz')
+
+ def test_http(self):
+ url = 'https://github.com/jelmer/dulwich'
+ c, path = get_transport_and_path_from_url(url)
+ self.assertTrue(isinstance(c, HttpGitClient))
+ self.assertEqual('/jelmer/dulwich', path)
+
+ def test_file(self):
+ c, path = get_transport_and_path_from_url('file:///home/jelmer/foo')
+ self.assertTrue(isinstance(c, SubprocessGitClient))
+ self.assertEqual('/home/jelmer/foo', path)
+
+
class TestSSHVendor(object):
def __init__(self):