~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/local.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-07-18 17:20:33 UTC
  • mfrom: (6031.1.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20110718172033-l9zmherfao7q80yp
(jam) Merge lp:bzr/2.4 into lp:bzr after fixing up release-notes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
"""
21
21
 
22
22
import os
23
 
from stat import ST_MODE, S_ISDIR, ST_SIZE, S_IMODE
 
23
from stat import ST_MODE, S_ISDIR, S_IMODE
24
24
import sys
25
25
 
26
26
from bzrlib.lazy_import import lazy_import
33
33
    osutils,
34
34
    urlutils,
35
35
    symbol_versioning,
36
 
    transport,
37
36
    )
38
 
from bzrlib.trace import mutter
39
37
from bzrlib.transport import LateReadError
40
38
""")
41
39
 
42
 
from bzrlib.transport import Transport, Server
43
 
 
44
 
 
45
 
_append_flags = os.O_CREAT | os.O_APPEND | os.O_WRONLY | osutils.O_BINARY
46
 
_put_non_atomic_flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | osutils.O_BINARY
47
 
 
48
 
 
49
 
class LocalTransport(Transport):
 
40
from bzrlib import transport
 
41
 
 
42
 
 
43
_append_flags = os.O_CREAT | os.O_APPEND | os.O_WRONLY | osutils.O_BINARY | osutils.O_NOINHERIT
 
44
_put_non_atomic_flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | osutils.O_BINARY | osutils.O_NOINHERIT
 
45
 
 
46
 
 
47
class LocalTransport(transport.Transport):
50
48
    """This is the transport agent for local filesystem access."""
51
49
 
52
50
    def __init__(self, base):
99
97
         - relative_reference is url escaped.
100
98
        """
101
99
        if relative_reference in ('.', ''):
102
 
            return self._local_base
 
100
            # _local_base normally has a trailing slash; strip it so that stat
 
101
            # on a transport pointing to a symlink reads the link not the
 
102
            # referent but be careful of / and c:\
 
103
            return osutils.split(self._local_base)[0]
103
104
        return self._local_base + urlutils.unescape(relative_reference)
104
105
 
105
106
    def abspath(self, relpath):
160
161
            transport._file_streams[canonical_url].flush()
161
162
        try:
162
163
            path = self._abspath(relpath)
163
 
            return open(path, 'rb')
 
164
            return osutils.open_file(path, 'rb')
164
165
        except (IOError, OSError),e:
165
166
            if e.errno == errno.EISDIR:
166
167
                return LateReadError(relpath)
329
330
        # initialise the file
330
331
        self.put_bytes_non_atomic(relpath, "", mode=mode)
331
332
        abspath = self._abspath(relpath)
332
 
        handle = open(abspath, 'wb')
 
333
        handle = osutils.open_file(abspath, 'wb')
333
334
        if mode is not None:
334
335
            self._check_mode_and_size(abspath, handle.fileno(), mode)
335
336
        transport._file_streams[self.abspath(relpath)] = handle
399
400
 
400
401
    def rename(self, rel_from, rel_to):
401
402
        path_from = self._abspath(rel_from)
 
403
        path_to = self._abspath(rel_to)
402
404
        try:
403
405
            # *don't* call bzrlib.osutils.rename, because we want to
404
 
            # detect errors on rename
405
 
            os.rename(path_from, self._abspath(rel_to))
 
406
            # detect conflicting names on rename, and osutils.rename tries to
 
407
            # mask cross-platform differences there
 
408
            os.rename(path_from, path_to)
406
409
        except (IOError, OSError),e:
407
410
            # TODO: What about path_to?
408
411
            self._translate_error(e, path_from)
481
484
        path = relpath
482
485
        try:
483
486
            path = self._abspath(relpath)
484
 
            return os.stat(path)
 
487
            return os.lstat(path)
485
488
        except (IOError, OSError),e:
486
489
            self._translate_error(e, path)
487
490
 
515
518
        except (IOError, OSError),e:
516
519
            self._translate_error(e, path)
517
520
 
 
521
    if osutils.host_os_dereferences_symlinks():
 
522
        def readlink(self, relpath):
 
523
            """See Transport.readlink."""
 
524
            return osutils.readlink(self._abspath(relpath))
 
525
 
 
526
    if osutils.hardlinks_good():
 
527
        def hardlink(self, source, link_name):
 
528
            """See Transport.link."""
 
529
            try:
 
530
                os.link(self._abspath(source), self._abspath(link_name))
 
531
            except (IOError, OSError), e:
 
532
                self._translate_error(e, source)
 
533
 
 
534
    if osutils.has_symlinks():
 
535
        def symlink(self, source, link_name):
 
536
            """See Transport.symlink."""
 
537
            abs_link_dirpath = urlutils.dirname(self.abspath(link_name))
 
538
            source_rel = urlutils.file_relpath(
 
539
                urlutils.strip_trailing_slash(abs_link_dirpath),
 
540
                urlutils.strip_trailing_slash(self.abspath(source))
 
541
            )
 
542
 
 
543
            try:
 
544
                os.symlink(source_rel, self._abspath(link_name))
 
545
            except (IOError, OSError), e:
 
546
                self._translate_error(e, source_rel)
 
547
 
518
548
    def _can_roundtrip_unix_modebits(self):
519
549
        if sys.platform == 'win32':
520
550
            # anyone else?
554
584
            return EmulatedWin32LocalTransport(abspath)
555
585
 
556
586
 
557
 
class LocalURLServer(Server):
558
 
    """A pretend server for local transports, using file:// urls.
559
 
 
560
 
    Of course no actual server is required to access the local filesystem, so
561
 
    this just exists to tell the test code how to get to it.
562
 
    """
563
 
 
564
 
    def setUp(self):
565
 
        """Setup the server to service requests.
566
 
 
567
 
        :param decorated_transport: ignored by this implementation.
568
 
        """
569
 
 
570
 
    def get_url(self):
571
 
        """See Transport.Server.get_url."""
572
 
        return urlutils.local_path_to_url('')
573
 
 
574
 
 
575
587
def get_test_permutations():
576
588
    """Return the permutations to be used in testing."""
577
 
    return [
578
 
            (LocalTransport, LocalURLServer),
579
 
            ]
 
589
    from bzrlib.tests import test_server
 
590
    return [(LocalTransport, test_server.LocalURLServer),]