changeset 235:2969a20e0eef

Add support for user:pass@url repositories to be hg-like
author Daniel Tang <dytang@cs.purdue.edu>
date Mon, 06 Apr 2009 11:19:51 -0400
parents 33e885f5f86a
children c34abd2448b7
files svnwrap/svn_swig_wrapper.py tests/run.py tests/test_urls.py
diffstat 3 files changed, 47 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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)
 
--- 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__':
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)