/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/transport/remote.py

Merge test-run support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
from ..bzr import (
38
38
    remote,
39
39
    )
40
 
from ..sixish import PY3
41
40
from ..bzr.smart import client, medium
42
41
 
43
42
 
66
65
    """
67
66
 
68
67
    # When making a readv request, cap it at requesting 5MB of data
69
 
    _max_readv_bytes = 5 * 1024 * 1024
 
68
    _max_readv_bytes = 5*1024*1024
70
69
 
71
70
    # IMPORTANT FOR IMPLEMENTORS: RemoteTransport MUST NOT be given encoding
72
71
    # responsibilities: Put those on SmartClient or similar. This is vital for
102
101
        # what we want to share is really the shared connection.
103
102
 
104
103
        if (_from_transport is not None
105
 
                and isinstance(_from_transport, RemoteTransport)):
 
104
            and isinstance(_from_transport, RemoteTransport)):
106
105
            _client = _from_transport._client
107
106
        elif _from_transport is None:
108
107
            # If no _from_transport is specified, we need to intialize the
188
187
        except errors.ErrorFromSmartServer as err:
189
188
            # The first argument, if present, is always a path.
190
189
            if args:
191
 
                context = {'relpath': args[0].decode('utf-8')}
 
190
                context = {'relpath': args[0]}
192
191
            else:
193
192
                context = {}
194
193
            self._translate_error(err, **context)
228
227
    def get_bytes(self, relpath):
229
228
        remote = self._remote_path(relpath)
230
229
        try:
231
 
            resp, response_handler = self._client.call_expecting_body(
232
 
                b'get', remote)
 
230
            resp, response_handler = self._client.call_expecting_body(b'get', remote)
233
231
        except errors.ErrorFromSmartServer as err:
234
232
            self._translate_error(err, relpath)
235
233
        if resp != (b'ok', ):
245
243
 
246
244
    def mkdir(self, relpath, mode=None):
247
245
        resp = self._call2(b'mkdir', self._remote_path(relpath),
248
 
                           self._serialise_optional_mode(mode))
 
246
            self._serialise_optional_mode(mode))
249
247
 
250
248
    def open_write_stream(self, relpath, mode=None):
251
249
        """See Transport.open_write_stream."""
332
330
 
333
331
        sorted_offsets = sorted(offsets)
334
332
        coalesced = list(self._coalesce_offsets(sorted_offsets,
335
 
                                                limit=self._max_readv_combine,
336
 
                                                fudge_factor=self._bytes_to_read_before_seek,
337
 
                                                max_size=self._max_readv_bytes))
 
333
                               limit=self._max_readv_combine,
 
334
                               fudge_factor=self._bytes_to_read_before_seek,
 
335
                               max_size=self._max_readv_bytes))
338
336
 
339
337
        # now that we've coallesced things, avoid making enormous requests
340
338
        requests = []
390
388
        for c_offset in coalesced:
391
389
            if len(data) < c_offset.length:
392
390
                raise errors.ShortReadvError(relpath, c_offset.start,
393
 
                                             c_offset.length, actual=len(data))
 
391
                            c_offset.length, actual=len(data))
394
392
            for suboffset, subsize in c_offset.ranges:
395
 
                key = (c_offset.start + suboffset, subsize)
396
 
                this_data = data[data_offset + suboffset:
397
 
                                 data_offset + suboffset + subsize]
 
393
                key = (c_offset.start+suboffset, subsize)
 
394
                this_data = data[data_offset+suboffset:
 
395
                                 data_offset+suboffset+subsize]
398
396
                # Special case when the data is in-order, rather than packing
399
397
                # into a map and then back out again. Benchmarking shows that
400
398
                # this has 100% hit rate, but leave in the data_map work just
404
402
                #       not have a real string.
405
403
                if key == cur_offset_and_size:
406
404
                    yield cur_offset_and_size[0], this_data
407
 
                    try:
408
 
                        cur_offset_and_size = next_offset[0] = next(
409
 
                            offset_stack)
410
 
                    except StopIteration:
411
 
                        return
 
405
                    cur_offset_and_size = next_offset[0] = next(offset_stack)
412
406
                else:
413
407
                    data_map[key] = this_data
414
408
            data_offset += c_offset.length
417
411
            while cur_offset_and_size in data_map:
418
412
                this_data = data_map.pop(cur_offset_and_size)
419
413
                yield cur_offset_and_size[0], this_data
420
 
                try:
421
 
                    cur_offset_and_size = next_offset[0] = next(offset_stack)
422
 
                except StopIteration:
423
 
                    return
 
414
                cur_offset_and_size = next_offset[0] = next(offset_stack)
424
415
 
425
416
    def rename(self, rel_from, rel_to):
426
417
        self._call(b'rename',
453
444
            return _SmartStat(int(resp[1]), int(resp[2], 8))
454
445
        raise errors.UnexpectedSmartServerResponse(resp)
455
446
 
456
 
    # def lock_read(self, relpath):
457
 
    # """Lock the given file for shared (read) access.
458
 
    # :return: A lock object, which should be passed to Transport.unlock()
459
 
    # """
460
 
    # The old RemoteBranch ignore lock for reading, so we will
461
 
    # continue that tradition and return a bogus lock object.
462
 
    # class BogusLock(object):
463
 
    # def __init__(self, path):
 
447
    ## def lock_read(self, relpath):
 
448
    ##     """Lock the given file for shared (read) access.
 
449
    ##     :return: A lock object, which should be passed to Transport.unlock()
 
450
    ##     """
 
451
    ##     # The old RemoteBranch ignore lock for reading, so we will
 
452
    ##     # continue that tradition and return a bogus lock object.
 
453
    ##     class BogusLock(object):
 
454
    ##         def __init__(self, path):
464
455
    ##             self.path = path
465
 
    # def unlock(self):
466
 
    # pass
467
 
    # return BogusLock(relpath)
 
456
    ##         def unlock(self):
 
457
    ##             pass
 
458
    ##     return BogusLock(relpath)
468
459
 
469
460
    def listable(self):
470
461
        return True
472
463
    def list_dir(self, relpath):
473
464
        resp = self._call2(b'list_dir', self._remote_path(relpath))
474
465
        if resp[0] == b'names':
475
 
            return [name.decode('utf-8') if PY3 else name for name in resp[1:]]
 
466
            return [name.encode('ascii') for name in resp[1:]]
476
467
        raise errors.UnexpectedSmartServerResponse(resp)
477
468
 
478
469
    def iter_files_recursive(self):
479
470
        resp = self._call2(b'iter_files_recursive', self._remote_path(''))
480
471
        if resp[0] == b'names':
481
 
            return [name.decode('utf-8') if PY3 else name for name in resp[1:]]
 
472
            return resp[1:]
482
473
        raise errors.UnexpectedSmartServerResponse(resp)
483
474
 
484
475
 
524
515
        if user is None:
525
516
            auth = config.AuthenticationConfig()
526
517
            user = auth.get_user('ssh', self._parsed_url.host,
527
 
                                 self._parsed_url.port)
 
518
                self._parsed_url.port)
528
519
        ssh_params = medium.SSHParams(self._parsed_url.host,
529
 
                                      self._parsed_url.port, user, self._parsed_url.password,
530
 
                                      bzr_remote_path)
 
520
                self._parsed_url.port, user, self._parsed_url.password,
 
521
                bzr_remote_path)
531
522
        client_medium = medium.SmartSSHClientMedium(self.base, ssh_params)
532
523
        return client_medium, (user, self._parsed_url.password)
533
524
 
593
584
        """See transport._redirected_to"""
594
585
        redirected = self._http_transport._redirected_to(source, target)
595
586
        if (redirected is not None
596
 
                and isinstance(redirected, type(self._http_transport))):
 
587
            and isinstance(redirected, type(self._http_transport))):
597
588
            return RemoteHTTPTransport('bzr+' + redirected.external_url(),
598
589
                                       http_transport=redirected)
599
590
        else:
602
593
 
603
594
 
604
595
class HintingSSHTransport(transport.Transport):
605
 
    """Simple transport that handles ssh:// and points out bzr+ssh:// and git+ssh://."""
606
 
 
607
 
    # TODO(jelmer): Implement support for detecting whether the repository at the
608
 
    # other end is a git or bzr repository.
 
596
    """Simple transport that handles ssh:// and points out bzr+ssh://."""
609
597
 
610
598
    def __init__(self, url):
611
 
        raise errors.UnsupportedProtocol(
612
 
            url, 'Use bzr+ssh for Bazaar operations over SSH, e.g. "bzr+%s". '
613
 
            'Use git+ssh for Git operations over SSH, e.g. "git+%s".' % (url, url))
 
599
        raise errors.UnsupportedProtocol(url,
 
600
            'bzr supports bzr+ssh to operate over ssh, use "bzr+%s".' % url)
614
601
 
615
602
 
616
603
def get_test_permutations():
617
604
    """Return (transport, server) permutations for testing."""
618
 
    # We may need a little more test framework support to construct an
619
 
    # appropriate RemoteTransport in the future.
 
605
    ### We may need a little more test framework support to construct an
 
606
    ### appropriate RemoteTransport in the future.
620
607
    from ..tests import test_server
621
608
    return [(RemoteTCPTransport, test_server.SmartTCPServer_for_testing)]