16
16
"""Implementation of Transport for the local filesystem.
22
from stat import ST_MODE, S_ISDIR, ST_SIZE
25
from bzrlib.trace import mutter
19
26
from bzrlib.transport import Transport, register_transport, \
20
27
TransportError, NoSuchFile, FileExists
23
30
class LocalTransportError(TransportError):
26
34
class LocalTransport(Transport):
27
35
"""This is the transport agent for local filesystem access."""
59
67
def relpath(self, abspath):
60
68
"""Return the local path portion from a given absolute path.
62
from bzrlib.branch import _relpath
63
return _relpath(self.base, abspath)
70
from bzrlib.osutils import relpath
71
return relpath(self.base, abspath)
65
73
def has(self, relpath):
66
74
return os.access(self.abspath(relpath), os.F_OK)
78
86
raise NoSuchFile('File or directory %r does not exist' % path, orig_error=e)
79
87
raise LocalTransportError(orig_error=e)
81
def get_partial(self, relpath, start, length=None):
82
"""Get just part of a file.
84
:param relpath: Path to the file, relative to base
85
:param start: The starting position to read from
86
:param length: The length to read. A length of None indicates
87
read to the end of the file.
88
:return: A file-like object containing at least the specified bytes.
89
Some implementations may return objects which can be read
90
past this length, but this is not guaranteed.
92
# LocalTransport.get_partial() doesn't care about the length
93
# argument, because it is using a local file, and thus just
94
# returns the file seek'ed to the appropriate location.
96
path = self.abspath(relpath)
101
if e.errno == errno.ENOENT:
102
raise NoSuchFile('File %r does not exist' % path, orig_error=e)
103
raise LocalTransportError(orig_error=e)
105
89
def put(self, relpath, f):
106
90
"""Copy the file-like or string object into the location.
110
def iter_files_recursive(self):
111
"""Iter the relative paths of files in the transports sub-tree."""
112
queue = list(self.list_dir('.'))
114
relpath = queue.pop(0)
115
st = self.stat(relpath)
116
if S_ISDIR(st[ST_MODE]):
117
for i, basename in enumerate(self.list_dir(relpath)):
118
queue.insert(i, relpath+'/'+basename)
126
122
def mkdir(self, relpath):
127
123
"""Create a directory at the given path."""
227
223
from bzrlib.lock import WriteLock
228
224
return WriteLock(self.abspath(relpath))
227
class ScratchTransport(LocalTransport):
228
"""A transport that works in a temporary dir and cleans up after itself.
230
The dir only exists for the lifetime of the Python object.
231
Obviously you should not put anything precious in it.
234
def __init__(self, base=None):
236
base = tempfile.mkdtemp()
237
super(ScratchTransport, self).__init__(base)
240
shutil.rmtree(self.base, ignore_errors=True)
241
mutter("%r destroyed" % self)
230
243
# If nothing else matches, try the LocalTransport
231
244
register_transport(None, LocalTransport)
232
245
register_transport('file://', LocalTransport)