270
247
new_url, check = opener.policy.transformFallbackLocation(branch, url)
272
return opener.checkAndFollowBranchReference(new_url)
249
return opener.checkAndFollowBranchReference(new_url,
250
getattr(cls._threading_data, "open_dir"))
276
254
def runWithTransformFallbackLocationHookInstalled(
277
self, callable, *args, **kw):
255
self, open_dir, callable, *args, **kw):
278
256
assert (self.transformFallbackLocationHook in
279
257
Branch.hooks['transform_fallback_location'])
280
258
self._threading_data.opener = self
259
self._threading_data.open_dir = open_dir
282
261
return callable(*args, **kw)
263
del self._threading_data.open_dir
284
264
del self._threading_data.opener
285
265
# We reset _seen_urls here to avoid multiple calls to open giving
286
266
# spurious loop exceptions.
287
267
self._seen_urls = set()
289
def followReference(self, url):
269
def followReference(self, url, open_dir=None):
290
270
"""Get the branch-reference value at the specified url.
292
272
This exists as a separate method only to be overriden in unit tests.
294
bzrdir = self._open_dir(url)
275
open_dir = BzrDir.open
276
bzrdir = open_dir(url)
295
277
return bzrdir.get_branch_reference()
297
def _open_dir(self, url):
298
"""Simple BzrDir.open clone that only uses specific probers.
300
:param url: URL to open
301
:return: ControlDir instance
303
def redirected(transport, e, redirection_notice):
304
self.policy.checkOneURL(e.target)
305
redirected_transport = transport._redirected_to(
307
if redirected_transport is None:
308
raise errors.NotBranchError(e.source)
309
trace.note('%s is%s redirected to %s',
310
transport.base, e.permanently, redirected_transport.base)
311
return redirected_transport
313
def find_format(transport):
314
last_error = errors.NotBranchError(transport.base)
315
for prober_kls in self.probers:
316
prober = prober_kls()
318
return transport, prober.probe_transport(transport)
319
except errors.NotBranchError, e:
323
transport = get_transport(url)
324
transport, format = do_catching_redirections(find_format, transport,
326
return format.open(transport)
279
def open(self, url, open_dir=None):
329
280
"""Open the Bazaar branch at url, first checking for safety.
331
282
What safety means is defined by a subclasses `followReference` and
332
283
`checkOneURL` methods.
285
:param open_dir: Optional function to use for opening control
286
directories (defaults to BzrDir.open)
334
url = self.checkAndFollowBranchReference(url)
288
url = self.checkAndFollowBranchReference(url, open_dir=open_dir)
290
open_dir = BzrDir.open
336
292
def open_branch(url):
337
dir = self._open_dir(url)
338
294
return dir.open_branch()
339
295
return self.runWithTransformFallbackLocationHookInstalled(
296
open_dir, open_branch, url)
343
299
def safe_open(allowed_scheme, url):