~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/__init__.py

merge integration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
import errno
23
23
from copy import deepcopy
 
24
import sys
24
25
from unittest import TestSuite
25
26
 
26
27
from bzrlib.trace import mutter
66
67
        if hasattr(e, 'errno'):
67
68
            if e.errno in (errno.ENOENT, errno.ENOTDIR):
68
69
                raise errors.NoSuchFile(path, extra=e)
 
70
            # I would rather use errno.EFOO, but there doesn't seem to be
 
71
            # any matching for 267
 
72
            # This is the error when doing a listdir on a file:
 
73
            # WindowsError: [Errno 267] The directory name is invalid
 
74
            if sys.platform == 'win32' and e.errno in (errno.ESRCH, 267):
 
75
                raise errors.NoSuchFile(path, extra=e)
69
76
            if e.errno == errno.EEXIST:
70
77
                raise errors.FileExists(path, extra=e)
71
78
            if e.errno == errno.EACCES:
219
226
            yield self.get(relpath)
220
227
            count += 1
221
228
 
222
 
    def put(self, relpath, f):
 
229
    def put(self, relpath, f, mode=None):
223
230
        """Copy the file-like or string object into the location.
224
231
 
225
232
        :param relpath: Location to put the contents, relative to base.
226
233
        :param f:       File-like or string object.
 
234
        :param mode: The mode for the newly created file, 
 
235
                     None means just use the default
227
236
        """
228
237
        raise NotImplementedError
229
238
 
230
 
    def put_multi(self, files, pb=None):
 
239
    def put_multi(self, files, mode=None, pb=None):
231
240
        """Put a set of files into the location.
232
241
 
233
242
        :param files: A list of tuples of relpath, file object [(path1, file1), (path2, file2),...]
234
243
        :param pb:  An optional ProgressBar for indicating percent done.
 
244
        :param mode: The mode for the newly created files
235
245
        :return: The number of files copied.
236
246
        """
237
 
        return self._iterate_over(files, self.put, pb, 'put', expand=True)
 
247
        def put(path, f):
 
248
            self.put(path, f, mode=mode)
 
249
        return self._iterate_over(files, put, pb, 'put', expand=True)
238
250
 
239
 
    def mkdir(self, relpath):
 
251
    def mkdir(self, relpath, mode=None):
240
252
        """Create a directory at the given path."""
241
253
        raise NotImplementedError
242
254
 
243
 
    def mkdir_multi(self, relpaths, pb=None):
 
255
    def mkdir_multi(self, relpaths, mode=None, pb=None):
244
256
        """Create a group of directories"""
245
 
        return self._iterate_over(relpaths, self.mkdir, pb, 'mkdir', expand=False)
 
257
        def mkdir(path):
 
258
            self.mkdir(path, mode=mode)
 
259
        return self._iterate_over(relpaths, mkdir, pb, 'mkdir', expand=False)
246
260
 
247
261
    def append(self, relpath, f):
248
262
        """Append the text in the file-like or string object to 
276
290
        # implementors don't have to implement everything.
277
291
        return self._iterate_over(relpaths, self.copy, pb, 'copy', expand=True)
278
292
 
279
 
    def copy_to(self, relpaths, other, pb=None):
 
293
    def copy_to(self, relpaths, other, mode=None, pb=None):
280
294
        """Copy a set of entries from self into another Transport.
281
295
 
282
296
        :param relpaths: A list/generator of entries to be copied.
 
297
        :param mode: This is the target mode for the newly created files
283
298
        TODO: This interface needs to be updated so that the target location
284
299
              can be different from the source location.
285
300
        """
286
301
        # The dummy implementation just does a simple get + put
287
302
        def copy_entry(path):
288
 
            other.put(path, self.get(path))
 
303
            other.put(path, self.get(path), mode=mode)
289
304
 
290
305
        return self._iterate_over(relpaths, copy_entry, pb, 'copy_to', expand=False)
291
306
 
390
405
    global _protocol_handlers
391
406
    if base is None:
392
407
        base = u'.'
 
408
    else:
 
409
        base = unicode(base)
393
410
    for proto, klass in _protocol_handlers.iteritems():
394
411
        if proto is not None and base.startswith(proto):
395
412
            return klass(base)