39
39
from bzrlib.transport import LateReadError
42
from bzrlib import transport
45
_append_flags = os.O_CREAT | os.O_APPEND | os.O_WRONLY | osutils.O_BINARY | osutils.O_NOINHERIT
46
_put_non_atomic_flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | osutils.O_BINARY | osutils.O_NOINHERIT
49
class LocalTransport(transport.Transport):
42
from bzrlib.transport import Transport, Server
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
49
class LocalTransport(Transport):
50
50
"""This is the transport agent for local filesystem access."""
52
52
def __init__(self, base):
99
99
- relative_reference is url escaped.
101
101
if relative_reference in ('.', ''):
102
# _local_base normally has a trailing slash; strip it so that stat
103
# on a transport pointing to a symlink reads the link not the
104
# referent but be careful of / and c:\
105
return osutils.split(self._local_base)[0]
102
return self._local_base
106
103
return self._local_base + urlutils.unescape(relative_reference)
108
105
def abspath(self, relpath):
163
160
transport._file_streams[canonical_url].flush()
165
162
path = self._abspath(relpath)
166
return osutils.open_file(path, 'rb')
163
return open(path, 'rb')
167
164
except (IOError, OSError),e:
168
165
if e.errno == errno.EISDIR:
169
166
return LateReadError(relpath)
332
329
# initialise the file
333
330
self.put_bytes_non_atomic(relpath, "", mode=mode)
334
331
abspath = self._abspath(relpath)
335
handle = osutils.open_file(abspath, 'wb')
332
handle = open(abspath, 'wb')
336
333
if mode is not None:
337
334
self._check_mode_and_size(abspath, handle.fileno(), mode)
338
335
transport._file_streams[self.abspath(relpath)] = handle
403
400
def rename(self, rel_from, rel_to):
404
401
path_from = self._abspath(rel_from)
405
path_to = self._abspath(rel_to)
407
403
# *don't* call bzrlib.osutils.rename, because we want to
408
# detect conflicting names on rename, and osutils.rename tries to
409
# mask cross-platform differences there
410
os.rename(path_from, path_to)
404
# detect errors on rename
405
os.rename(path_from, self._abspath(rel_to))
411
406
except (IOError, OSError),e:
412
407
# TODO: What about path_to?
413
408
self._translate_error(e, path_from)
520
515
except (IOError, OSError),e:
521
516
self._translate_error(e, path)
523
if osutils.host_os_dereferences_symlinks():
524
def readlink(self, relpath):
525
"""See Transport.readlink."""
526
return osutils.readlink(self._abspath(relpath))
528
if osutils.hardlinks_good():
529
def hardlink(self, source, link_name):
530
"""See Transport.link."""
532
os.link(self._abspath(source), self._abspath(link_name))
533
except (IOError, OSError), e:
534
self._translate_error(e, source)
536
if osutils.has_symlinks():
537
def symlink(self, source, link_name):
538
"""See Transport.symlink."""
539
abs_link_dirpath = urlutils.dirname(self.abspath(link_name))
540
source_rel = urlutils.file_relpath(
541
urlutils.strip_trailing_slash(abs_link_dirpath),
542
urlutils.strip_trailing_slash(self.abspath(source))
546
os.symlink(source_rel, self._abspath(link_name))
547
except (IOError, OSError), e:
548
self._translate_error(e, source_rel)
550
518
def _can_roundtrip_unix_modebits(self):
551
519
if sys.platform == 'win32':
586
554
return EmulatedWin32LocalTransport(abspath)
557
class LocalURLServer(Server):
558
"""A pretend server for local transports, using file:// urls.
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.
564
def start_server(self):
568
"""See Transport.Server.get_url."""
569
return urlutils.local_path_to_url('')
589
572
def get_test_permutations():
590
573
"""Return the permutations to be used in testing."""
591
from bzrlib.tests import test_server
592
return [(LocalTransport, test_server.LocalURLServer),]
575
(LocalTransport, LocalURLServer),