Merge lp:~jelmer/brz/probe-svn into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/probe-svn
Merge into: lp:brz
Diff against target: 238 lines (+211/-0)
3 files modified
breezy/plugins/svn/__init__.py (+197/-0)
breezy/transport/http/__init__.py (+11/-0)
doc/en/release-notes/brz-3.1.txt (+3/-0)
To merge this branch: bzr merge lp:~jelmer/brz/probe-svn
Reviewer Review Type Date Requested Status
Peter J. Mello (community) bystander Approve
Jelmer Vernooij Approve
Review via email: mp+375183@code.launchpad.net

Commit message

Add basic svn plugin that warns the user when they attempt to access a svn working tree.

Description of the change

Add basic svn plugin that warns the user when they attempt to access a svn working tree.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve
Revision history for this message
Peter J. Mello (roguescholar) wrote :

LGTM. Came looking to see if this was in the works after, that's right, issuing `brz-svn checkout yadayadaURL` and getting decidedly no satisfaction as a result. Happy New Year to you as well.

review: Approve (bystander)
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'breezy/plugins/svn'
2=== added file 'breezy/plugins/svn/__init__.py'
3--- breezy/plugins/svn/__init__.py 1970-01-01 00:00:00 +0000
4+++ breezy/plugins/svn/__init__.py 2020-01-13 00:27:28 +0000
5@@ -0,0 +1,197 @@
6+# Copyright (C) 2019 Jelmer Vernooij <jelmer@samba.org>
7+#
8+# This program is free software; you can redistribute it and/or modify
9+# it under the terms of the GNU General Public License as published by
10+# the Free Software Foundation; version 3 of the License or
11+# (at your option) a later version.
12+#
13+# This program is distributed in the hope that it will be useful,
14+# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+# GNU General Public License for more details.
17+#
18+# You should have received a copy of the GNU General Public License
19+# along with this program; if not, write to the Free Software
20+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21+
22+"""Subversion foreign branch support.
23+
24+Currently only tells the user that Subversion is not supported.
25+"""
26+
27+from __future__ import absolute_import
28+
29+from ... import version_info # noqa: F401
30+
31+from ... import (
32+ controldir,
33+ errors,
34+ transport as _mod_transport,
35+ )
36+
37+
38+class SubversionUnsupportedError(errors.UnsupportedFormatError):
39+
40+ _fmt = ('Subversion branches are not yet supported. '
41+ 'To convert Subversion branches to Bazaar branches or vice versa, '
42+ 'use the fastimport format.')
43+
44+
45+class SvnWorkingTreeDirFormat(controldir.ControlDirFormat):
46+ """Subversion directory format."""
47+
48+ def get_converter(self):
49+ raise NotImplementedError(self.get_converter)
50+
51+ def get_format_description(self):
52+ return "Subversion working directory"
53+
54+ def initialize_on_transport(self, transport):
55+ raise errors.UninitializableFormat(self)
56+
57+ def is_supported(self):
58+ return False
59+
60+ def supports_transport(self, transport):
61+ return False
62+
63+ def check_support_status(self, allow_unsupported, recommend_upgrade=True,
64+ basedir=None):
65+ raise SubversionUnsupportedError()
66+
67+ def open(self, transport):
68+ # Raise NotBranchError if there is nothing there
69+ SvnWorkingTreeProber().probe_transport(transport)
70+ raise NotImplementedError(self.open)
71+
72+
73+class SvnWorkingTreeProber(controldir.Prober):
74+
75+ @classmethod
76+ def priority(klass, transport):
77+ return 100
78+
79+ def probe_transport(self, transport):
80+ try:
81+ transport.local_abspath('.')
82+ except errors.NotLocalUrl:
83+ raise errors.NotBranchError(path=transport.base)
84+ else:
85+ if transport.has(".svn"):
86+ return SvnWorkingTreeDirFormat()
87+ raise errors.NotBranchError(path=transport.base)
88+
89+ @classmethod
90+ def known_formats(cls):
91+ return [SvnWorkingTreeDirFormat()]
92+
93+
94+class SvnRepositoryFormat(controldir.ControlDirFormat):
95+ """Subversion directory format."""
96+
97+ def get_converter(self):
98+ raise NotImplementedError(self.get_converter)
99+
100+ def get_format_description(self):
101+ return "Subversion repository"
102+
103+ def initialize_on_transport(self, transport):
104+ raise errors.UninitializableFormat(self)
105+
106+ def is_supported(self):
107+ return False
108+
109+ def supports_transport(self, transport):
110+ return False
111+
112+ def check_support_status(self, allow_unsupported, recommend_upgrade=True,
113+ basedir=None):
114+ raise SubversionUnsupportedError()
115+
116+ def open(self, transport):
117+ # Raise NotBranchError if there is nothing there
118+ SvnRepositoryProber().probe_transport(transport)
119+ raise NotImplementedError(self.open)
120+
121+
122+class SvnRepositoryProber(controldir.Prober):
123+
124+ _supported_schemes = ["http", "https", "file", "svn"]
125+
126+ @classmethod
127+ def priority(klass, transport):
128+ if 'svn' in transport.base:
129+ return 90
130+ return 100
131+
132+ def probe_transport(self, transport):
133+ try:
134+ url = transport.external_url()
135+ except errors.InProcessTransport:
136+ raise errors.NotBranchError(path=transport.base)
137+
138+ scheme = url.split(":")[0]
139+ if scheme.startswith("svn+") or scheme == "svn":
140+ raise SubversionUnsupportedError()
141+
142+ if scheme not in self._supported_schemes:
143+ raise errors.NotBranchError(path=transport.base)
144+
145+ if scheme == 'file':
146+ # Cheaper way to figure out if there is a svn repo
147+ maybe = False
148+ subtransport = transport
149+ while subtransport:
150+ try:
151+ if all([subtransport.has(name)
152+ for name in ["format", "db", "conf"]]):
153+ maybe = True
154+ break
155+ except UnicodeEncodeError:
156+ pass
157+ prevsubtransport = subtransport
158+ subtransport = prevsubtransport.clone("..")
159+ if subtransport.base == prevsubtransport.base:
160+ break
161+ if not maybe:
162+ raise errors.NotBranchError(path=transport.base)
163+
164+ # If this is a HTTP transport, use the existing connection to check
165+ # that the remote end supports version control.
166+ if scheme in ("http", "https"):
167+ priv_transport = getattr(transport, "_decorated", transport)
168+ try:
169+ headers = priv_transport._options('.')
170+ except (errors.InProcessTransport, errors.NoSuchFile,
171+ errors.InvalidHttpResponse):
172+ raise errors.NotBranchError(path=transport.base)
173+ else:
174+ dav_entries = set()
175+ for key, value in headers:
176+ if key.upper() == 'DAV':
177+ dav_entries.update(
178+ [x.strip() for x in value.split(',')])
179+ if "version-control" not in dav_entries:
180+ raise errors.NotBranchError(path=transport.base)
181+
182+ return SvnRepositoryFormat()
183+
184+ @classmethod
185+ def known_formats(cls):
186+ return [SvnRepositoryFormat()]
187+
188+
189+controldir.ControlDirFormat.register_prober(SvnWorkingTreeProber)
190+controldir.ControlDirFormat.register_prober(SvnRepositoryProber)
191+
192+
193+_mod_transport.register_transport_proto(
194+ 'svn+ssh://',
195+ help="Access using the Subversion smart server tunneled over SSH.")
196+_mod_transport.register_transport_proto(
197+ 'svn+http://')
198+_mod_transport.register_transport_proto(
199+ 'svn+https://')
200+_mod_transport.register_transport_proto(
201+ 'svn://',
202+ help="Access using the Subversion smart server.")
203
204=== modified file 'breezy/transport/http/__init__.py'
205--- breezy/transport/http/__init__.py 2020-01-11 14:41:16 +0000
206+++ breezy/transport/http/__init__.py 2020-01-13 00:27:28 +0000
207@@ -2579,6 +2579,17 @@
208 target_path)
209 return transport.get_transport_from_url(new_url)
210
211+ def _options(self, relpath):
212+ abspath = self._remote_path(relpath)
213+ resp = self.request('OPTIONS', abspath)
214+ if resp.status == 404:
215+ raise errors.NoSuchFile(abspath)
216+ if resp.status in (403, 405):
217+ raise errors.InvalidHttpResponse(
218+ abspath,
219+ "OPTIONS not supported or forbidden for remote URL")
220+ return resp.getheaders()
221+
222
223 # TODO: May be better located in smart/medium.py with the other
224 # SmartMedium classes
225
226=== modified file 'doc/en/release-notes/brz-3.1.txt'
227--- doc/en/release-notes/brz-3.1.txt 2020-01-12 13:56:10 +0000
228+++ doc/en/release-notes/brz-3.1.txt 2020-01-13 00:27:28 +0000
229@@ -46,6 +46,9 @@
230 have installed and speeds up import time since psutil brings in
231 various other modules. (Jelmer Vernooij)
232
233+ * Warn the user when they attempt to use Breezy in a Subversion
234+ working copy. (Jelmer Vernooij)
235+
236 * Add a basic Mercurial plugin that mentions that .hg repositories
237 are unsupported when the user attempts to access one.
238 (Jelmer Vernooij)

Subscribers

People subscribed via source and target branches