# HG changeset patch # User Daniel Tang # Date 1239031191 14400 # Node ID 2969a20e0eefe45a3931bf6d7cfbdc4ead1bff95 # Parent 33e885f5f86a77fc5c55eb0da2b16588f57b4a38 Add support for user:pass@url repositories to be hg-like diff --git a/svnwrap/svn_swig_wrapper.py b/svnwrap/svn_swig_wrapper.py --- a/svnwrap/svn_swig_wrapper.py +++ b/svnwrap/svn_swig_wrapper.py @@ -5,6 +5,7 @@ import shutil import sys import tempfile import hashlib +import urlparse from svn import client from svn import core @@ -91,6 +92,20 @@ def _create_auth_baton(pool): return core.svn_auth_open(providers, pool) +def parse_url(url): + """Parse a URL and return a tuple (username, password, url) + """ + scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) + user, passwd = None, None + if '@' in netloc: + userpass, netloc = netloc.split('@') + if ':' in userpass: + user, passwd = userpass.split(':') + user, passwd = urlparse.unquote(user) or None, urlparse.unquote(passwd) or None + else: + user = urlparse.unquote(userpass) or None + url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) + return (user, passwd, url) class Revision(object): """Wrapper for a Subversion revision. @@ -119,9 +134,11 @@ class SubversionRepo(object): It takes a required param, the URL. """ def __init__(self, url='', username='', password=''): - self.svn_url = url - self.username = username - self.password = password + parsed = parse_url(url) + # --username and --password override URL credentials + self.username = username or parsed[0] + self.password = password or parsed[1] + self.svn_url = parsed[2] self.auth_baton_pool = core.Pool() self.auth_baton = _create_auth_baton(self.auth_baton_pool) diff --git a/tests/run.py b/tests/run.py --- a/tests/run.py +++ b/tests/run.py @@ -22,6 +22,7 @@ import test_push_eol import test_rebuildmeta import test_tags import test_utility_commands +import test_urls def suite(): return unittest.TestSuite([test_binaryfiles.suite(), @@ -42,6 +43,7 @@ def suite(): test_rebuildmeta.suite(), test_tags.suite(), test_utility_commands.suite(), + test_urls.suite(), ]) if __name__ == '__main__': diff --git a/tests/test_urls.py b/tests/test_urls.py new file mode 100644 --- /dev/null +++ b/tests/test_urls.py @@ -0,0 +1,25 @@ +import test_util +import unittest +from svnwrap.svn_swig_wrapper import parse_url + +class TestSubversionUrls(test_util.TestBase): + def test_standard_url(self): + self.assertEqual((None, None, 'file:///var/svn/repo'), + parse_url('file:///var/svn/repo')) + + def test_user_url(self): + self.assertEqual(('joe', None, 'https://svn.testurl.com/repo'), + parse_url('https://joe@svn.testurl.com/repo')) + + def test_password_url(self): + self.assertEqual((None, 't3stpw', 'svn+ssh://svn.testurl.com/repo'), + parse_url('svn+ssh://:t3stpw@svn.testurl.com/repo')) + + def test_user_password_url(self): + self.assertEqual(('joe', 't3stpw', 'https://svn.testurl.com/repo'), + parse_url('https://joe:t3stpw@svn.testurl.com/repo')) + + +def suite(): + all = [unittest.TestLoader().loadTestsFromTestCase(TestSubversionUrls)] + return unittest.TestSuite(all)