Rev 1231: Remove more dependencies on the standard python bindings. in http://people.samba.org/bzr/jelmer/bzr-svn/0.4/

Jelmer Vernooij jelmer at samba.org
Mon Jun 16 18:04:22 BST 2008


At http://people.samba.org/bzr/jelmer/bzr-svn/0.4/

------------------------------------------------------------
revno: 1231
revision-id: jelmer at samba.org-20080616170417-e1cxsfte1g1os84c
parent: jelmer at samba.org-20080616165902-67sd4k56ppvyfslc
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Mon 2008-06-16 19:04:17 +0200
message:
  Remove more dependencies on the standard python bindings.
modified:
  branch.py                      svnbranch.py-20051017135706-11c749eb0dab04a7
  core.py                        core.py-20080615010310-67lnibnp889hlarb-1
  ra.py                          ra.py-20080615005305-t5221niknu8rm6bt-1
  transport.py                   transport.py-20060406231150-b3472d06b3a0818d
=== modified file 'branch.py'
--- a/branch.py	2008-06-15 02:11:24 +0000
+++ b/branch.py	2008-06-16 17:04:17 +0000
@@ -33,7 +33,8 @@
 from bzrlib.plugins.svn.errors import NotSvnBranchPath, ERR_FS_NO_SUCH_REVISION
 from bzrlib.plugins.svn.format import get_rich_root_format
 from bzrlib.plugins.svn.repository import SvnRepository
-from bzrlib.plugins.svn.transport import bzr_to_svn_url, create_svn_client
+from bzrlib.plugins.svn.ra import create_svn_client
+from bzrlib.plugins.svn.transport import bzr_to_svn_url
 
 
 class FakeControlFiles(object):

=== modified file 'core.py'
--- a/core.py	2008-06-15 01:46:28 +0000
+++ b/core.py	2008-06-16 17:04:17 +0000
@@ -22,3 +22,4 @@
 
 SubversionException = svn.core.SubversionException
 time_to_cstring = svn.core.svn_time_to_cstring
+get_config = svn.core.svn_config_get_config

=== modified file 'ra.py'
--- a/ra.py	2008-06-15 02:48:51 +0000
+++ b/ra.py	2008-06-16 17:04:17 +0000
@@ -13,7 +13,16 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import svn.core, svn.client, svn.delta
+import svn.core, svn.client, svn.delta, svn.ra
+
+from bzrlib import debug, urlutils
+from bzrlib.trace import mutter
+from bzrlib.errors import InvalidURL
+
+from bzrlib.plugins.svn import properties
+from bzrlib.plugins.svn.core import get_config, SubversionException
+
+import bzrlib.plugins.svn.errors as svn_errors
 
 get_username_prompt_provider = svn.core.svn_auth_get_username_prompt_provider
 get_simple_prompt_provider = svn.core.svn_auth_get_simple_prompt_provider
@@ -29,6 +38,84 @@
 
 DIRENT_KIND = 0x0001
 
+class Editor(object):
+    """Simple object wrapper around the Subversion delta editor interface."""
+    def __init__(self, connection, (editor, editor_baton)):
+        self.editor = editor
+        self.editor_baton = editor_baton
+        self.recent_baton = []
+        self._connection = connection
+
+    def open_root(self, base_revnum):
+        assert self.recent_baton == [], "root already opened"
+        baton = svn.delta.editor_invoke_open_root(self.editor, 
+                self.editor_baton, base_revnum)
+        self.recent_baton.append(baton)
+        return baton
+
+    def close_directory(self, baton, *args, **kwargs):
+        assert self.recent_baton.pop() == baton, \
+                "only most recently opened baton can be closed"
+        svn.delta.editor_invoke_close_directory(self.editor, baton, *args, **kwargs)
+
+    def close(self):
+        assert self.recent_baton == []
+        svn.delta.editor_invoke_close_edit(self.editor, self.editor_baton)
+        self._connection._unmark_busy()
+
+    def apply_textdelta(self, baton, *args, **kwargs):
+        assert self.recent_baton[-1] == baton
+        return svn.delta.editor_invoke_apply_textdelta(self.editor, baton,
+                *args, **kwargs)
+
+    def change_dir_prop(self, baton, name, value, pool=None):
+        assert self.recent_baton[-1] == baton
+        return svn.delta.editor_invoke_change_dir_prop(self.editor, baton, 
+                                                       name, value, pool)
+
+    def delete_entry(self, *args, **kwargs):
+        return svn.delta.editor_invoke_delete_entry(self.editor, *args, **kwargs)
+
+    def add_file(self, path, parent_baton, *args, **kwargs):
+        assert self.recent_baton[-1] == parent_baton
+        baton = svn.delta.editor_invoke_add_file(self.editor, path, 
+            parent_baton, *args, **kwargs)
+        self.recent_baton.append(baton)
+        return baton
+
+    def open_file(self, path, parent_baton, *args, **kwargs):
+        assert self.recent_baton[-1] == parent_baton
+        baton = svn.delta.editor_invoke_open_file(self.editor, path, 
+                                                 parent_baton, *args, **kwargs)
+        self.recent_baton.append(baton)
+        return baton
+
+    def change_file_prop(self, baton, name, value, pool=None):
+        assert self.recent_baton[-1] == baton
+        svn.delta.editor_invoke_change_file_prop(self.editor, baton, name, 
+                                                 value, pool)
+
+    def close_file(self, baton, *args, **kwargs):
+        assert self.recent_baton.pop() == baton
+        svn.delta.editor_invoke_close_file(self.editor, baton, *args, **kwargs)
+
+    def add_directory(self, path, parent_baton, *args, **kwargs):
+        assert self.recent_baton[-1] == parent_baton
+        baton = svn.delta.editor_invoke_add_directory(self.editor, path, 
+            parent_baton, *args, **kwargs)
+        self.recent_baton.append(baton)
+        return baton
+
+    def open_directory(self, path, parent_baton, *args, **kwargs):
+        assert self.recent_baton[-1] == parent_baton
+        baton = svn.delta.editor_invoke_open_directory(self.editor, path, 
+            parent_baton, *args, **kwargs)
+        self.recent_baton.append(baton)
+        return baton
+
+
+
+
 class Auth:
     def __init__(self, providers=[]):
         self.providers = providers
@@ -42,3 +129,287 @@
 
     def get_parameter(self, name):
         return svn.core.svn_auth_get_parameter(self.auth_baton, name)
+
+
+def needs_busy(unbound):
+    """Decorator that marks a connection as busy before running a methd on it.
+    """
+    def convert(self, *args, **kwargs):
+        self._mark_busy()
+        try:
+            return unbound(self, *args, **kwargs)
+        finally:
+            self._unmark_busy()
+
+    convert.__doc__ = unbound.__doc__
+    convert.__name__ = unbound.__name__
+    return convert
+
+
+def create_svn_client(url):
+    from bzrlib.plugins.svn.auth import create_auth_baton
+    client = svn.client.create_context()
+    client.auth_baton = create_auth_baton(url)
+    client.config = get_config(None)
+    return client
+
+
+class RemoteAccess(object):
+    """An single connection to a Subversion repository. This usually can 
+    only do one operation at a time."""
+    def __init__(self, url):
+        self._busy = False
+        self._root = None
+        self._client = create_svn_client(url)
+        self._unbusy_handler = None
+        try:
+            self.mutter('opening SVN RA connection to %r', url)
+            self._ra = svn.client.open_ra_session(url.encode('utf8'), 
+                    self._client)
+        except SubversionException, (_, num):
+            if num == svn_errors.ERR_RA_SVN_REPOS_NOT_FOUND:
+                raise NoSvnRepositoryPresent(url=url)
+            if num == svn_errors.ERR_BAD_URL:
+                raise InvalidURL(url)
+            raise
+        self.url = url
+
+    class Reporter(object):
+        def __init__(self, connection, (reporter, report_baton)):
+            self._reporter = reporter
+            self._baton = report_baton
+            self._connection = connection
+
+        def set_path(self, path, revnum, start_empty, lock_token, pool=None):
+            svn.ra.reporter2_invoke_set_path(self._reporter, self._baton, 
+                        path, revnum, start_empty, lock_token, pool)
+
+        def delete_path(self, path, pool=None):
+            svn.ra.reporter2_invoke_delete_path(self._reporter, self._baton,
+                    path, pool)
+
+        def link_path(self, path, url, revision, start_empty, lock_token, 
+                      pool=None):
+            svn.ra.reporter2_invoke_link_path(self._reporter, self._baton,
+                    path, url, revision, start_empty, lock_token,
+                    pool)
+
+        def finish_report(self, pool=None):
+            try:
+                svn.ra.reporter2_invoke_finish_report(self._reporter, 
+                        self._baton, pool)
+            finally:
+                self._connection._unmark_busy()
+
+        def abort_report(self, pool=None):
+            try:
+                svn.ra.reporter2_invoke_abort_report(self._reporter, 
+                        self._baton, pool)
+            finally:
+                self._connection._unmark_busy()
+
+    def is_busy(self):
+        return self._busy
+
+    def _mark_busy(self):
+        assert not self._busy, "already busy"
+        self._busy = True
+
+    def set_unbusy_handler(self, handler):
+        self._unbusy_handler = handler
+
+    def _unmark_busy(self):
+        assert self._busy, "not busy"
+        self._busy = False
+        if self._unbusy_handler is not None:
+            self._unbusy_handler()
+            self._unbusy_handler = None
+
+    def mutter(self, text, *args):
+        if 'transport' in debug.debug_flags:
+            mutter(text, *args)
+
+    @needs_busy
+    def get_uuid(self):
+        self.mutter('svn get-uuid')
+        return svn.ra.get_uuid(self._ra)
+
+    @needs_busy
+    def get_repos_root(self):
+        if self._root is None:
+            self.mutter("svn get-repos-root")
+            self._root = svn.ra.get_repos_root(self._ra)
+        return self._root
+
+    @needs_busy
+    def get_latest_revnum(self):
+        self.mutter("svn get-latest-revnum")
+        return svn.ra.get_latest_revnum(self._ra)
+
+    def _make_editor(self, editor, pool=None):
+        edit, edit_baton = svn.delta.make_editor(editor, pool)
+        self._edit = edit
+        self._edit_baton = edit_baton
+        return self._edit, self._edit_baton
+
+    def do_switch(self, switch_rev, recurse, switch_url, editor, pool=None):
+        self.mutter('svn switch -r %d -> %r', switch_rev, switch_url)
+        self._mark_busy()
+        edit, edit_baton = self._make_editor(editor, pool)
+        return self.Reporter(self, svn.ra.do_switch(self._ra, switch_rev, "", 
+                             recurse, switch_url, edit, edit_baton, pool))
+
+    def change_rev_prop(self, revnum, name, value, pool=None):
+        self.mutter('svn revprop -r%d --set %s=%s', revnum, name, value)
+        svn.ra.change_rev_prop(self._ra, revnum, name, value)
+
+    @needs_busy
+    def get_lock(self, path):
+        return svn.ra.get_lock(self._ra, path)
+
+    @needs_busy
+    def unlock(self, locks, break_lock=False):
+        def lock_cb(baton, path, do_lock, lock, ra_err, pool):
+            pass
+        return svn.ra.unlock(self._ra, locks, break_lock, lock_cb)
+ 
+    @needs_busy
+    def get_dir(self, path, revnum, pool=None, kind=False):
+        self.mutter("svn ls -r %d '%r'", revnum, path)
+        assert len(path) == 0 or path[0] != "/"
+        # ra_dav backends fail with strange errors if the path starts with a 
+        # slash while other backends don't.
+        if hasattr(svn.ra, 'get_dir2'):
+            fields = 0
+            if kind:
+                fields += DIRENT_KIND
+            return svn.ra.get_dir2(self._ra, path, revnum, fields)
+        else:
+            return svn.ra.get_dir(self._ra, path, revnum)
+
+    @needs_busy
+    def check_path(self, path, revnum):
+        assert len(path) == 0 or path[0] != "/"
+        self.mutter("svn check_path -r%d %s", revnum, path)
+        return svn.ra.check_path(self._ra, path.encode('utf-8'), revnum)
+
+    @needs_busy
+    def mkdir(self, relpath, mode=None):
+        assert len(relpath) == 0 or relpath[0] != "/"
+        path = urlutils.join(self.url, relpath)
+        try:
+            svn.client.mkdir([path.encode("utf-8")], self._client)
+        except SubversionException, (msg, num):
+            if num == svn_errors.ERR_FS_NOT_FOUND:
+                raise NoSuchFile(path)
+            if num == svn_errors.ERR_FS_ALREADY_EXISTS:
+                raise FileExists(path)
+            raise
+
+    def replay(self, revision, low_water_mark, send_deltas, editor, pool=None):
+        self.mutter('svn replay -r%r:%r', low_water_mark, revision)
+        self._mark_busy()
+        edit, edit_baton = self._make_editor(editor, pool)
+        svn.ra.replay(self._ra, revision, low_water_mark, send_deltas,
+                      edit, edit_baton, pool)
+
+    def do_update(self, revnum, recurse, editor, pool=None):
+        self.mutter('svn update -r %r', revnum)
+        self._mark_busy()
+        edit, edit_baton = self._make_editor(editor, pool)
+        return self.Reporter(self, svn.ra.do_update(self._ra, revnum, "", 
+                             recurse, edit, edit_baton, pool))
+
+    def has_capability(self, cap):
+        return svn.ra.has_capability(self._ra, cap)
+
+    def revprop_list(self, revnum, pool=None):
+        self.mutter('svn revprop-list -r %r', revnum)
+        return svn.ra.rev_proplist(self._ra, revnum, pool)
+
+    def get_commit_editor(self, revprops, done_cb, lock_token, keep_locks):
+        self._mark_busy()
+        try:
+            if hasattr(svn.ra, 'get_commit_editor3'):
+                editor = svn.ra.get_commit_editor3(self._ra, revprops, done_cb, 
+                                                  lock_token, keep_locks)
+            elif revprops.keys() != [properties.PROP_REVISION_LOG]:
+                raise NotImplementedError()
+            else:
+                editor = svn.ra.get_commit_editor2(self._ra, 
+                            revprops[properties.PROP_REVISION_LOG],
+                            done_cb, lock_token, keep_locks)
+
+            return Editor(self, editor)
+        except:
+            self._unmark_busy()
+            raise
+
+    class SvnLock(object):
+        def __init__(self, connection, tokens):
+            self._tokens = tokens
+            self._connection = connection
+
+        def unlock(self):
+            self._connection.unlock(self.locks)
+
+    @needs_busy
+    def lock_write(self, path_revs, comment=None, steal_lock=False):
+        tokens = {}
+        def lock_cb(baton, path, do_lock, lock, ra_err, pool):
+            tokens[path] = lock
+        svn.ra.lock(self._ra, path_revs, comment, steal_lock, lock_cb)
+        return SvnLock(self, tokens)
+
+    @needs_busy
+    def get_log(self, paths, from_revnum, to_revnum, limit, 
+                discover_changed_paths, strict_node_history, revprops, rcvr, 
+                pool=None):
+        # No paths starting with slash, please
+        assert paths is None or all([not p.startswith("/") for p in paths])
+        if (paths is None and 
+            (svn.core.SVN_VER_MINOR < 6 or (
+             svn.core.SVN_VER_REVISION < 31470 and svn.core.SVN_VER_REVISION != 0))):
+            paths = ["/"]
+        self.mutter('svn log %r:%r %r (limit: %r)', from_revnum, to_revnum, paths, limit)
+        if hasattr(svn.ra, 'get_log2'):
+            return svn.ra.get_log2(self._ra, paths, 
+                           from_revnum, to_revnum, limit, 
+                           discover_changed_paths, strict_node_history, False, 
+                           revprops, rcvr, pool)
+
+        class LogEntry(object):
+            def __init__(self, changed_paths, rev, author, date, message):
+                self.changed_paths = changed_paths
+                self.revprops = {}
+                if properties.PROP_REVISION_AUTHOR in revprops:
+                    self.revprops[properties.PROP_REVISION_AUTHOR] = author
+                if properties.PROP_REVISION_LOG in revprops:
+                    self.revprops[properties.PROP_REVISION_LOG] = message
+                if properties.PROP_REVISION_DATE in revprops:
+                    self.revprops[properties.PROP_REVISION_DATE] = date
+                # FIXME: Check other revprops
+                # FIXME: Handle revprops is None
+                self.revision = rev
+                self.has_children = None
+
+        def rcvr_convert(orig_paths, rev, author, date, message, pool):
+            rcvr(LogEntry(orig_paths, rev, author, date, message), pool)
+
+        return svn.ra.get_log(self._ra, paths, 
+                              from_revnum, to_revnum, limit, discover_changed_paths, 
+                              strict_node_history, rcvr_convert, pool)
+
+    @needs_busy
+    def reparent(self, url):
+        if self.url == url:
+            return
+        if hasattr(svn.ra, 'reparent'):
+            self.mutter('svn reparent %r', url)
+            svn.ra.reparent(self._ra, url)
+            self.url = url
+        else:
+            raise NotImplementedError(self.reparent)
+
+
+

=== modified file 'transport.py'
--- a/transport.py	2008-06-15 02:11:24 +0000
+++ b/transport.py	2008-06-16 17:04:17 +0000
@@ -22,32 +22,22 @@
 from bzrlib.transport import Transport
 
 from svn.core import Pool
-import svn.ra
 import svn.core
 import svn.client
 
-from bzrlib.plugins.svn import properties
-from bzrlib.plugins.svn.core import SubversionException
+from bzrlib.plugins.svn.core import SubversionException, get_config
 from bzrlib.plugins.svn.errors import convert_svn_error, NoSvnRepositoryPresent, ERR_BAD_URL, ERR_RA_SVN_REPOS_NOT_FOUND, ERR_FS_ALREADY_EXISTS, ERR_FS_NOT_FOUND, ERR_FS_NOT_DIRECTORY
-from bzrlib.plugins.svn.ra import DIRENT_KIND
+from bzrlib.plugins.svn.ra import DIRENT_KIND, RemoteAccess
 import urlparse
 import urllib
 
-svn_config = svn.core.svn_config_get_config(None)
+svn_config = get_config(None)
 
 def get_client_string():
     """Return a string that can be send as part of the User Agent string."""
     return "bzr%s+bzr-svn%s" % (bzrlib.__version__, bzrlib.plugins.svn.__version__)
 
  
-def create_svn_client(url):
-    from bzrlib.plugins.svn.auth import create_auth_baton
-    client = svn.client.create_context()
-    client.auth_baton = create_auth_baton(url)
-    client.config = svn_config
-    return client
-
-
 # Don't run any tests on SvnTransport as it is not intended to be 
 # a full implementation of Transport
 def get_test_permutations():
@@ -88,390 +78,6 @@
     return url
 
 
-def needs_busy(unbound):
-    """Decorator that marks a connection as busy before running a methd on it.
-    """
-    def convert(self, *args, **kwargs):
-        self._mark_busy()
-        try:
-            return unbound(self, *args, **kwargs)
-        finally:
-            self._unmark_busy()
-
-    convert.__doc__ = unbound.__doc__
-    convert.__name__ = unbound.__name__
-    return convert
-
-
-class Editor(object):
-    """Simple object wrapper around the Subversion delta editor interface."""
-    def __init__(self, connection, (editor, editor_baton)):
-        self.editor = editor
-        self.editor_baton = editor_baton
-        self.recent_baton = []
-        self._connection = connection
-
-    @convert_svn_error
-    def open_root(self, base_revnum):
-        assert self.recent_baton == [], "root already opened"
-        baton = svn.delta.editor_invoke_open_root(self.editor, 
-                self.editor_baton, base_revnum)
-        self.recent_baton.append(baton)
-        return baton
-
-    @convert_svn_error
-    def close_directory(self, baton, *args, **kwargs):
-        assert self.recent_baton.pop() == baton, \
-                "only most recently opened baton can be closed"
-        svn.delta.editor_invoke_close_directory(self.editor, baton, *args, **kwargs)
-
-    @convert_svn_error
-    def close(self):
-        assert self.recent_baton == []
-        svn.delta.editor_invoke_close_edit(self.editor, self.editor_baton)
-        self._connection._unmark_busy()
-
-    @convert_svn_error
-    def apply_textdelta(self, baton, *args, **kwargs):
-        assert self.recent_baton[-1] == baton
-        return svn.delta.editor_invoke_apply_textdelta(self.editor, baton,
-                *args, **kwargs)
-
-    @convert_svn_error
-    def change_dir_prop(self, baton, name, value, pool=None):
-        assert self.recent_baton[-1] == baton
-        return svn.delta.editor_invoke_change_dir_prop(self.editor, baton, 
-                                                       name, value, pool)
-
-    @convert_svn_error
-    def delete_entry(self, *args, **kwargs):
-        return svn.delta.editor_invoke_delete_entry(self.editor, *args, **kwargs)
-
-    @convert_svn_error
-    def add_file(self, path, parent_baton, *args, **kwargs):
-        assert self.recent_baton[-1] == parent_baton
-        baton = svn.delta.editor_invoke_add_file(self.editor, path, 
-            parent_baton, *args, **kwargs)
-        self.recent_baton.append(baton)
-        return baton
-
-    @convert_svn_error
-    def open_file(self, path, parent_baton, *args, **kwargs):
-        assert self.recent_baton[-1] == parent_baton
-        baton = svn.delta.editor_invoke_open_file(self.editor, path, 
-                                                 parent_baton, *args, **kwargs)
-        self.recent_baton.append(baton)
-        return baton
-
-    @convert_svn_error
-    def change_file_prop(self, baton, name, value, pool=None):
-        assert self.recent_baton[-1] == baton
-        svn.delta.editor_invoke_change_file_prop(self.editor, baton, name, 
-                                                 value, pool)
-
-    @convert_svn_error
-    def close_file(self, baton, *args, **kwargs):
-        assert self.recent_baton.pop() == baton
-        svn.delta.editor_invoke_close_file(self.editor, baton, *args, **kwargs)
-
-    @convert_svn_error
-    def add_directory(self, path, parent_baton, *args, **kwargs):
-        assert self.recent_baton[-1] == parent_baton
-        baton = svn.delta.editor_invoke_add_directory(self.editor, path, 
-            parent_baton, *args, **kwargs)
-        self.recent_baton.append(baton)
-        return baton
-
-    @convert_svn_error
-    def open_directory(self, path, parent_baton, *args, **kwargs):
-        assert self.recent_baton[-1] == parent_baton
-        baton = svn.delta.editor_invoke_open_directory(self.editor, path, 
-            parent_baton, *args, **kwargs)
-        self.recent_baton.append(baton)
-        return baton
-
-
-class Connection(object):
-    """An single connection to a Subversion repository. This usually can 
-    only do one operation at a time."""
-    def __init__(self, url):
-        self._busy = False
-        self._root = None
-        self._client = create_svn_client(url)
-        self._unbusy_handler = None
-        try:
-            self.mutter('opening SVN RA connection to %r', url)
-            self._ra = svn.client.open_ra_session(url.encode('utf8'), 
-                    self._client)
-        except SubversionException, (_, num):
-            if num == ERR_RA_SVN_REPOS_NOT_FOUND:
-                raise NoSvnRepositoryPresent(url=url)
-            if num == ERR_BAD_URL:
-                raise InvalidURL(url)
-            raise
-        self.url = url
-
-    class Reporter(object):
-        def __init__(self, connection, (reporter, report_baton)):
-            self._reporter = reporter
-            self._baton = report_baton
-            self._connection = connection
-
-        @convert_svn_error
-        def set_path(self, path, revnum, start_empty, lock_token, pool=None):
-            svn.ra.reporter2_invoke_set_path(self._reporter, self._baton, 
-                        path, revnum, start_empty, lock_token, pool)
-
-        @convert_svn_error
-        def delete_path(self, path, pool=None):
-            svn.ra.reporter2_invoke_delete_path(self._reporter, self._baton,
-                    path, pool)
-
-        @convert_svn_error
-        def link_path(self, path, url, revision, start_empty, lock_token, 
-                      pool=None):
-            svn.ra.reporter2_invoke_link_path(self._reporter, self._baton,
-                    path, url, revision, start_empty, lock_token,
-                    pool)
-
-        @convert_svn_error
-        def finish_report(self, pool=None):
-            try:
-                svn.ra.reporter2_invoke_finish_report(self._reporter, 
-                        self._baton, pool)
-            finally:
-                self._connection._unmark_busy()
-
-        @convert_svn_error
-        def abort_report(self, pool=None):
-            try:
-                svn.ra.reporter2_invoke_abort_report(self._reporter, 
-                        self._baton, pool)
-            finally:
-                self._connection._unmark_busy()
-
-    def is_busy(self):
-        return self._busy
-
-    def _mark_busy(self):
-        assert not self._busy, "already busy"
-        self._busy = True
-
-    def set_unbusy_handler(self, handler):
-        self._unbusy_handler = handler
-
-    def _unmark_busy(self):
-        assert self._busy, "not busy"
-        self._busy = False
-        if self._unbusy_handler is not None:
-            self._unbusy_handler()
-            self._unbusy_handler = None
-
-    def mutter(self, text, *args):
-        if 'transport' in debug.debug_flags:
-            mutter(text, *args)
-
-    @convert_svn_error
-    @needs_busy
-    def get_uuid(self):
-        self.mutter('svn get-uuid')
-        return svn.ra.get_uuid(self._ra)
-
-    @convert_svn_error
-    @needs_busy
-    def get_repos_root(self):
-        if self._root is None:
-            self.mutter("svn get-repos-root")
-            self._root = svn.ra.get_repos_root(self._ra)
-        return self._root
-
-    @convert_svn_error
-    @needs_busy
-    def get_latest_revnum(self):
-        self.mutter("svn get-latest-revnum")
-        return svn.ra.get_latest_revnum(self._ra)
-
-    def _make_editor(self, editor, pool=None):
-        edit, edit_baton = svn.delta.make_editor(editor, pool)
-        self._edit = edit
-        self._edit_baton = edit_baton
-        return self._edit, self._edit_baton
-
-    @convert_svn_error
-    def do_switch(self, switch_rev, recurse, switch_url, editor, pool=None):
-        self.mutter('svn switch -r %d -> %r', switch_rev, switch_url)
-        self._mark_busy()
-        edit, edit_baton = self._make_editor(editor, pool)
-        return self.Reporter(self, svn.ra.do_switch(self._ra, switch_rev, "", 
-                             recurse, switch_url, edit, edit_baton, pool))
-
-    @convert_svn_error
-    def change_rev_prop(self, revnum, name, value, pool=None):
-        self.mutter('svn revprop -r%d --set %s=%s', revnum, name, value)
-        svn.ra.change_rev_prop(self._ra, revnum, name, value)
-
-    @convert_svn_error
-    @needs_busy
-    def get_lock(self, path):
-        return svn.ra.get_lock(self._ra, path)
-
-    @convert_svn_error
-    @needs_busy
-    def unlock(self, locks, break_lock=False):
-        def lock_cb(baton, path, do_lock, lock, ra_err, pool):
-            pass
-        return svn.ra.unlock(self._ra, locks, break_lock, lock_cb)
- 
-    @convert_svn_error
-    @needs_busy
-    def get_dir(self, path, revnum, pool=None, kind=False):
-        self.mutter("svn ls -r %d '%r'", revnum, path)
-        assert len(path) == 0 or path[0] != "/"
-        # ra_dav backends fail with strange errors if the path starts with a 
-        # slash while other backends don't.
-        if hasattr(svn.ra, 'get_dir2'):
-            fields = 0
-            if kind:
-                fields += DIRENT_KIND
-            return svn.ra.get_dir2(self._ra, path, revnum, fields)
-        else:
-            return svn.ra.get_dir(self._ra, path, revnum)
-
-    @convert_svn_error
-    @needs_busy
-    def check_path(self, path, revnum):
-        assert len(path) == 0 or path[0] != "/"
-        self.mutter("svn check_path -r%d %s", revnum, path)
-        return svn.ra.check_path(self._ra, path.encode('utf-8'), revnum)
-
-    @convert_svn_error
-    @needs_busy
-    def mkdir(self, relpath, mode=None):
-        assert len(relpath) == 0 or relpath[0] != "/"
-        path = urlutils.join(self.url, relpath)
-        try:
-            svn.client.mkdir([path.encode("utf-8")], self._client)
-        except SubversionException, (msg, num):
-            if num == ERR_FS_NOT_FOUND:
-                raise NoSuchFile(path)
-            if num == ERR_FS_ALREADY_EXISTS:
-                raise FileExists(path)
-            raise
-
-    @convert_svn_error
-    def replay(self, revision, low_water_mark, send_deltas, editor, pool=None):
-        self.mutter('svn replay -r%r:%r', low_water_mark, revision)
-        self._mark_busy()
-        edit, edit_baton = self._make_editor(editor, pool)
-        svn.ra.replay(self._ra, revision, low_water_mark, send_deltas,
-                      edit, edit_baton, pool)
-
-    @convert_svn_error
-    def do_update(self, revnum, recurse, editor, pool=None):
-        self.mutter('svn update -r %r', revnum)
-        self._mark_busy()
-        edit, edit_baton = self._make_editor(editor, pool)
-        return self.Reporter(self, svn.ra.do_update(self._ra, revnum, "", 
-                             recurse, edit, edit_baton, pool))
-
-    @convert_svn_error
-    def has_capability(self, cap):
-        return svn.ra.has_capability(self._ra, cap)
-
-    @convert_svn_error
-    def revprop_list(self, revnum, pool=None):
-        self.mutter('svn revprop-list -r %r', revnum)
-        return svn.ra.rev_proplist(self._ra, revnum, pool)
-
-    @convert_svn_error
-    def get_commit_editor(self, revprops, done_cb, lock_token, keep_locks):
-        self._mark_busy()
-        try:
-            if hasattr(svn.ra, 'get_commit_editor3'):
-                editor = svn.ra.get_commit_editor3(self._ra, revprops, done_cb, 
-                                                  lock_token, keep_locks)
-            elif revprops.keys() != [properties.PROP_REVISION_LOG]:
-                raise NotImplementedError()
-            else:
-                editor = svn.ra.get_commit_editor2(self._ra, 
-                            revprops[properties.PROP_REVISION_LOG],
-                            done_cb, lock_token, keep_locks)
-
-            return Editor(self, editor)
-        except:
-            self._unmark_busy()
-            raise
-
-    class SvnLock(object):
-        def __init__(self, connection, tokens):
-            self._tokens = tokens
-            self._connection = connection
-
-        def unlock(self):
-            self._connection.unlock(self.locks)
-
-    @convert_svn_error
-    @needs_busy
-    def lock_write(self, path_revs, comment=None, steal_lock=False):
-        tokens = {}
-        def lock_cb(baton, path, do_lock, lock, ra_err, pool):
-            tokens[path] = lock
-        svn.ra.lock(self._ra, path_revs, comment, steal_lock, lock_cb)
-        return SvnLock(self, tokens)
-
-    @convert_svn_error
-    @needs_busy
-    def get_log(self, paths, from_revnum, to_revnum, limit, 
-                discover_changed_paths, strict_node_history, revprops, rcvr, 
-                pool=None):
-        # No paths starting with slash, please
-        assert paths is None or all([not p.startswith("/") for p in paths])
-        if (paths is None and 
-            (svn.core.SVN_VER_MINOR < 6 or (
-             svn.core.SVN_VER_REVISION < 31470 and svn.core.SVN_VER_REVISION != 0))):
-            paths = ["/"]
-        self.mutter('svn log %r:%r %r (limit: %r)', from_revnum, to_revnum, paths, limit)
-        if hasattr(svn.ra, 'get_log2'):
-            return svn.ra.get_log2(self._ra, paths, 
-                           from_revnum, to_revnum, limit, 
-                           discover_changed_paths, strict_node_history, False, 
-                           revprops, rcvr, pool)
-
-        class LogEntry(object):
-            def __init__(self, changed_paths, rev, author, date, message):
-                self.changed_paths = changed_paths
-                self.revprops = {}
-                if properties.PROP_REVISION_AUTHOR in revprops:
-                    self.revprops[properties.PROP_REVISION_AUTHOR] = author
-                if properties.PROP_REVISION_LOG in revprops:
-                    self.revprops[properties.PROP_REVISION_LOG] = message
-                if properties.PROP_REVISION_DATE in revprops:
-                    self.revprops[properties.PROP_REVISION_DATE] = date
-                # FIXME: Check other revprops
-                # FIXME: Handle revprops is None
-                self.revision = rev
-                self.has_children = None
-
-        def rcvr_convert(orig_paths, rev, author, date, message, pool):
-            rcvr(LogEntry(orig_paths, rev, author, date, message), pool)
-
-        return svn.ra.get_log(self._ra, paths, 
-                              from_revnum, to_revnum, limit, discover_changed_paths, 
-                              strict_node_history, rcvr_convert, pool)
-
-    @convert_svn_error
-    @needs_busy
-    def reparent(self, url):
-        if self.url == url:
-            return
-        if hasattr(svn.ra, 'reparent'):
-            self.mutter('svn reparent %r', url)
-            svn.ra.reparent(self._ra, url)
-            self.url = url
-        else:
-            raise NotImplementedError(self.reparent)
-
-
 class ConnectionPool(object):
     """Collection of connections to a Subversion repository."""
     def __init__(self):
@@ -486,14 +92,14 @@
                 return c
         # Nothing available? Just pick an existing one and reparent:
         if len(self.connections) == 0:
-            return Connection(url)
+            return RemoteAccess(url)
         c = self.connections.pop()
         try:
             c.reparent(url)
             return c
         except NotImplementedError:
             self.connections.add(c)
-            return Connection(url)
+            return RemoteAccess(url)
         except:
             self.connections.add(c)
             raise




More information about the bazaar-commits mailing list