transport.py
160 lines
| 5.2 KiB
| text/x-python
|
PythonLexer
|
r4764 | # -*- coding: utf-8 -*- | ||
# Copyright (C) 2007 Daniel Holth <dholth@fastmail.fm> | ||||
# This is a stripped-down version of the original bzr-svn transport.py, | ||||
# Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org> | ||||
# This program is free software; you can redistribute it and/or modify | ||||
# it under the terms of the GNU General Public License as published by | ||||
# the Free Software Foundation; either version 2 of the License, or | ||||
# (at your option) any later version. | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# You should have received a copy of the GNU General Public License | ||||
|
r15782 | # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
|
r4764 | |||
|
r50744 | # pytype: disable=import-error | ||
|
r4938 | import svn.client | ||
|
r4764 | import svn.core | ||
|
r28412 | import svn.ra | ||
|
r50744 | # pytype: enable=import-error | ||
|
r28412 | Pool = svn.core.Pool | ||
SubversionException = svn.core.SubversionException | ||||
|
r4764 | |||
|
r43359 | from mercurial.pycompat import getattr | ||
|
r43346 | from mercurial import util | ||
|
r28461 | |||
|
r4957 | # Some older versions of the Python bindings need to be | ||
|
r4764 | # explicitly initialized. But what we want to do probably | ||
# won't work worth a darn against those libraries anyway! | ||||
svn.ra.initialize() | ||||
|
r29668 | svn_config = None | ||
|
r4764 | |||
|
r43346 | |||
|
r4764 | def _create_auth_baton(pool): | ||
|
r47856 | """Create a Subversion authentication baton.""" | ||
|
r50744 | import svn.client # pytype: disable=import-error | ||
|
r43346 | |||
|
r4764 | # Give the client context baton a suite of authentication | ||
# providers.h | ||||
providers = [ | ||||
svn.client.get_simple_provider(pool), | ||||
svn.client.get_username_provider(pool), | ||||
svn.client.get_ssl_client_cert_file_provider(pool), | ||||
svn.client.get_ssl_client_cert_pw_file_provider(pool), | ||||
svn.client.get_ssl_server_trust_file_provider(pool), | ||||
|
r43346 | ] | ||
|
r17481 | # Platform-dependent authentication methods | ||
|
r43346 | getprovider = getattr( | ||
svn.core, 'svn_auth_get_platform_specific_provider', None | ||||
) | ||||
|
r8120 | if getprovider: | ||
# Available in svn >= 1.6 | ||||
|
r43347 | for name in (b'gnome_keyring', b'keychain', b'kwallet', b'windows'): | ||
for type in (b'simple', b'ssl_client_cert_pw', b'ssl_server_trust'): | ||||
|
r8120 | p = getprovider(name, type, pool) | ||
if p: | ||||
providers.append(p) | ||||
else: | ||||
|
r43347 | if util.safehasattr(svn.client, b'get_windows_simple_provider'): | ||
|
r8120 | providers.append(svn.client.get_windows_simple_provider(pool)) | ||
|
r5126 | |||
|
r4764 | return svn.core.svn_auth_open(providers, pool) | ||
|
r43346 | |||
|
r4764 | class NotBranchError(SubversionException): | ||
pass | ||||
|
r43346 | |||
|
r49801 | class SvnRaTransport: | ||
|
r4764 | """ | ||
Open an ra connection to a Subversion repository. | ||||
""" | ||||
|
r43346 | |||
|
r43347 | def __init__(self, url=b"", ra=None): | ||
|
r4764 | self.pool = Pool() | ||
self.svn_url = url | ||||
|
r43347 | self.username = b'' | ||
self.password = b'' | ||||
|
r4764 | |||
# Only Subversion 1.4 has reparent() | ||||
|
r43347 | if ra is None or not util.safehasattr(svn.ra, b'reparent'): | ||
|
r4938 | self.client = svn.client.create_context(self.pool) | ||
ab = _create_auth_baton(self.pool) | ||||
self.client.auth_baton = ab | ||||
|
r29668 | global svn_config | ||
if svn_config is None: | ||||
svn_config = svn.core.svn_config_get_config(None) | ||||
|
r4938 | self.client.config = svn_config | ||
|
r4764 | try: | ||
|
r4938 | self.ra = svn.client.open_ra_session( | ||
|
r43346 | self.svn_url, self.client, self.pool | ||
) | ||||
|
r25660 | except SubversionException as xxx_todo_changeme: | ||
(inst, num) = xxx_todo_changeme.args | ||||
|
r43346 | if num in ( | ||
svn.core.SVN_ERR_RA_ILLEGAL_URL, | ||||
svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, | ||||
svn.core.SVN_ERR_BAD_URL, | ||||
): | ||||
|
r4764 | raise NotBranchError(url) | ||
raise | ||||
else: | ||||
self.ra = ra | ||||
svn.ra.reparent(self.ra, self.svn_url.encode('utf8')) | ||||
|
r49801 | class Reporter: | ||
|
r11498 | def __init__(self, reporter_data): | ||
self._reporter, self._baton = reporter_data | ||||
|
r4764 | |||
def set_path(self, path, revnum, start_empty, lock_token, pool=None): | ||||
|
r43346 | svn.ra.reporter2_invoke_set_path( | ||
self._reporter, | ||||
self._baton, | ||||
path, | ||||
revnum, | ||||
start_empty, | ||||
lock_token, | ||||
pool, | ||||
) | ||||
|
r4764 | |||
def delete_path(self, path, pool=None): | ||||
|
r43346 | svn.ra.reporter2_invoke_delete_path( | ||
self._reporter, self._baton, path, pool | ||||
) | ||||
|
r4764 | |||
|
r43346 | 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, | ||||
) | ||||
|
r4764 | |||
def finish_report(self, pool=None): | ||||
|
r43346 | svn.ra.reporter2_invoke_finish_report( | ||
self._reporter, self._baton, pool | ||||
) | ||||
|
r4764 | |||
def abort_report(self, pool=None): | ||||
|
r43346 | svn.ra.reporter2_invoke_abort_report( | ||
self._reporter, self._baton, pool | ||||
) | ||||
|
r4764 | |||
def do_update(self, revnum, path, *args, **kwargs): | ||||
|
r43346 | return self.Reporter( | ||
svn.ra.do_update(self.ra, revnum, path, *args, **kwargs) | ||||
) | ||||