~bzr-pqm/bzr/bzr.dev

1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
1
# Copyright (C) 2005, 2006 Canonical Ltd
1185.11.19 by John Arbash Meinel
Testing put and append, also testing agaist file-like objects as well as strings.
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
16
17
"""Transport for the local filesystem.
18
1755.1.3 by Robert Collins
Fix regression in LocalTransport to allow merging.
19
This is a fairly thin wrapper on regular file IO.
20
"""
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
21
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
22
import os
23
import shutil
1608.2.5 by Martin Pool
Add Transport.supports_unix_modebits, so tests can
24
import sys
1442.1.44 by Robert Collins
Many transport related tweaks:
25
from stat import ST_MODE, S_ISDIR, ST_SIZE
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
26
import tempfile
27
1551.2.56 by Aaron Bentley
Better illegal pathname check for Windows
28
from bzrlib.osutils import (abspath, realpath, normpath, pathjoin, rename, 
1685.1.52 by John Arbash Meinel
[merge] bzr.dev 1704
29
                            check_legal_path, rmtree)
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
30
from bzrlib.symbol_versioning import warn
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
31
from bzrlib.trace import mutter
32
from bzrlib.transport import Transport, Server
33
import bzrlib.urlutils as urlutils
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
34
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
35
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
36
class LocalTransport(Transport):
37
    """This is the transport agent for local filesystem access."""
38
39
    def __init__(self, base):
40
        """Set the base path where files will be stored."""
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
41
        if not base.startswith('file://'):
42
            warn("Instantiating LocalTransport with a filesystem path"
43
                " is deprecated as of bzr 0.8."
44
                " Please use bzrlib.transport.get_transport()"
45
                " or pass in a file:// url.",
46
                 DeprecationWarning,
47
                 stacklevel=2
48
                 )
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
49
            base = urlutils.local_path_to_url(base)
1530.1.3 by Robert Collins
transport implementations now tested consistently.
50
        if base[-1] != '/':
51
            base = base + '/'
52
        super(LocalTransport, self).__init__(base)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
53
        self._local_base = urlutils.local_path_from_url(base)
1711.4.6 by John Arbash Meinel
Removing hacks for _win32_abspath, on real win32 abspath handles unicode just fine, it doesn't handle encoding into 'mbcs'
54
        ## mutter("_local_base: %r => %r", base, self._local_base)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
55
907.1.32 by John Arbash Meinel
Renaming is_remote to should_cache as it is more appropriate.
56
    def should_cache(self):
907.1.22 by John Arbash Meinel
Fixed some encoding issues, added is_remote function for Transport objects.
57
        return False
58
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
59
    def clone(self, offset=None):
60
        """Return a new LocalTransport with root at self.base + offset
61
        Because the local filesystem does not require a connection, 
62
        we can just return a new object.
63
        """
64
        if offset is None:
65
            return LocalTransport(self.base)
66
        else:
67
            return LocalTransport(self.abspath(offset))
68
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
69
    def _abspath(self, relative_reference):
70
        """Return a path for use in os calls.
71
72
        Several assumptions are made:
73
         - relative_reference does not contain '..'
74
         - relative_reference is url escaped.
75
        """
1755.1.3 by Robert Collins
Fix regression in LocalTransport to allow merging.
76
        if relative_reference in ('.', ''):
77
            return self._local_base
1755.1.2 by Robert Collins
(robertc, ab)Merge some commit and fetch tuning steps.
78
        return self._local_base + urlutils.unescape(relative_reference)
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
79
907.1.8 by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport
80
    def abspath(self, relpath):
1636.1.1 by Robert Collins
Fix calling relpath() and abspath() on transports at their root.
81
        """Return the full url to the given relative URL."""
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
82
        # TODO: url escape the result. RBC 20060523.
1185.12.70 by Aaron Bentley
Removed b
83
        assert isinstance(relpath, basestring), (type(relpath), relpath)
1685.1.12 by John Arbash Meinel
Some more work to get LocalTransport to only support URLs
84
        # jam 20060426 Using normpath on the real path, because that ensures
85
        #       proper handling of stuff like
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
86
        path = normpath(pathjoin(self._local_base, urlutils.unescape(relpath)))
87
        return urlutils.local_path_to_url(path)
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
88
89
    def local_abspath(self, relpath):
90
        """Transform the given relative path URL into the actual path on disk
91
92
        This function only exists for the LocalTransport, since it is
93
        the only one that has direct local access.
94
        This is mostly for stuff like WorkingTree which needs to know
95
        the local working directory.
1725.2.9 by Robert Collins
Merge current head.
96
        
97
        This function is quite expensive: it calls realpath which resolves
98
        symlinks.
1685.1.9 by John Arbash Meinel
Updated LocalTransport so that it's base is now a URL rather than a local path. This helps consistency with all other functions. To do so, I added local_abspath() which returns the local path, and local_path_to/from_url
99
        """
100
        absurl = self.abspath(relpath)
101
        # mutter(u'relpath %s => base: %s, absurl %s', relpath, self.base, absurl)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
102
        return urlutils.local_path_from_url(absurl)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
103
907.1.24 by John Arbash Meinel
Remote functionality work.
104
    def relpath(self, abspath):
105
        """Return the local path portion from a given absolute path.
106
        """
1442.1.64 by Robert Collins
Branch.open_containing now returns a tuple (Branch, relative-path).
107
        if abspath is None:
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
108
            abspath = u'.'
1551.2.53 by abentley
Strip trailing slashes in a platform-sensible way
109
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
110
        return urlutils.file_relpath(
111
            urlutils.strip_trailing_slash(self.base), 
112
            urlutils.strip_trailing_slash(abspath))
907.1.24 by John Arbash Meinel
Remote functionality work.
113
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
114
    def has(self, relpath):
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
115
        return os.access(self._abspath(relpath), os.F_OK)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
116
907.1.50 by John Arbash Meinel
Removed encode/decode from Transport.put/get, added more exceptions that can be thrown.
117
    def get(self, relpath):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
118
        """Get the file at the given relative path.
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
119
120
        :param relpath: The relative path to the file
121
        """
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
122
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
123
            path = self._abspath(relpath)
907.1.50 by John Arbash Meinel
Removed encode/decode from Transport.put/get, added more exceptions that can be thrown.
124
            return open(path, 'rb')
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
125
        except (IOError, OSError),e:
126
            self._translate_error(e, path)
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
127
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
128
    def put(self, relpath, f, mode=None):
907.1.20 by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8
129
        """Copy the file-like or string object into the location.
130
131
        :param relpath: Location to put the contents, relative to base.
132
        :param f:       File-like or string object.
133
        """
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
134
        from bzrlib.atomicfile import AtomicFile
135
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
136
        path = relpath
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
137
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
138
            path = self._abspath(relpath)
1551.2.56 by Aaron Bentley
Better illegal pathname check for Windows
139
            check_legal_path(path)
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
140
            fp = AtomicFile(path, 'wb', new_mode=mode)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
141
        except (IOError, OSError),e:
142
            self._translate_error(e, path)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
143
        try:
144
            self._pump(f, fp)
145
            fp.commit()
146
        finally:
147
            fp.close()
148
1442.1.44 by Robert Collins
Many transport related tweaks:
149
    def iter_files_recursive(self):
150
        """Iter the relative paths of files in the transports sub-tree."""
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
151
        queue = list(self.list_dir(u'.'))
1442.1.44 by Robert Collins
Many transport related tweaks:
152
        while queue:
1608.1.1 by Martin Pool
[patch] LocalTransport.list_dir should return url-quoted strings (ddaa)
153
            relpath = queue.pop(0)
1442.1.44 by Robert Collins
Many transport related tweaks:
154
            st = self.stat(relpath)
155
            if S_ISDIR(st[ST_MODE]):
156
                for i, basename in enumerate(self.list_dir(relpath)):
157
                    queue.insert(i, relpath+'/'+basename)
158
            else:
159
                yield relpath
160
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
161
    def mkdir(self, relpath, mode=None):
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
162
        """Create a directory at the given path."""
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
163
        path = relpath
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
164
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
165
            path = self._abspath(relpath)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
166
            os.mkdir(path)
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
167
            if mode is not None:
168
                os.chmod(path, mode)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
169
        except (IOError, OSError),e:
170
            self._translate_error(e, path)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
171
1666.1.6 by Robert Collins
Make knit the default format.
172
    def append(self, relpath, f, mode=None):
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
173
        """Append the text in the file-like object into the final location."""
174
        abspath = self._abspath(relpath)
1530.1.4 by Robert Collins
integrate Memory tests into transport interface tests.
175
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
176
            fp = open(abspath, 'ab')
177
            # FIXME should we really be chmodding every time ? RBC 20060523
1666.1.6 by Robert Collins
Make knit the default format.
178
            if mode is not None:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
179
                os.chmod(abspath, mode)
1530.1.4 by Robert Collins
integrate Memory tests into transport interface tests.
180
        except (IOError, OSError),e:
181
            self._translate_error(e, relpath)
1551.2.38 by abentley
Fixed win32 bug with tell
182
        # win32 workaround (tell on an unwritten file returns 0)
183
        fp.seek(0, 2)
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
184
        result = fp.tell()
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
185
        self._pump(f, fp)
1563.2.3 by Robert Collins
Change the return signature of transport.append and append_multi to return the length of the pre-append content.
186
        return result
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
187
188
    def copy(self, rel_from, rel_to):
189
        """Copy the item at rel_from to the location at rel_to"""
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
190
        path_from = self._abspath(rel_from)
191
        path_to = self._abspath(rel_to)
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
192
        try:
193
            shutil.copy(path_from, path_to)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
194
        except (IOError, OSError),e:
195
            # TODO: What about path_to?
196
            self._translate_error(e, path_from)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
197
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
198
    def rename(self, rel_from, rel_to):
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
199
        path_from = self._abspath(rel_from)
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
200
        try:
201
            # *don't* call bzrlib.osutils.rename, because we want to 
202
            # detect errors on rename
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
203
            os.rename(path_from, self._abspath(rel_to))
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
204
        except (IOError, OSError),e:
205
            # TODO: What about path_to?
206
            self._translate_error(e, path_from)
207
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
208
    def move(self, rel_from, rel_to):
209
        """Move the item at rel_from to the location at rel_to"""
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
210
        path_from = self._abspath(rel_from)
211
        path_to = self._abspath(rel_to)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
212
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
213
        try:
1553.5.13 by Martin Pool
New Transport.rename that mustn't overwrite
214
            # this version will delete the destination if necessary
1185.31.58 by John Arbash Meinel
Updating for new transport tests so that they pass on win32
215
            rename(path_from, path_to)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
216
        except (IOError, OSError),e:
217
            # TODO: What about path_to?
218
            self._translate_error(e, path_from)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
219
220
    def delete(self, relpath):
221
        """Delete the item at relpath"""
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
222
        path = relpath
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
223
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
224
            path = self._abspath(relpath)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
225
            os.remove(path)
226
        except (IOError, OSError),e:
227
            self._translate_error(e, path)
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
228
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
229
    def copy_to(self, relpaths, other, mode=None, pb=None):
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
230
        """Copy a set of entries from self into another Transport.
231
232
        :param relpaths: A list/generator of entries to be copied.
233
        """
234
        if isinstance(other, LocalTransport):
235
            # Both from & to are on the local filesystem
236
            # Unfortunately, I can't think of anything faster than just
237
            # copying them across, one by one :(
238
            total = self._get_total(relpaths)
239
            count = 0
240
            for path in relpaths:
241
                self._update_pb(pb, 'copy-to', count, total)
1185.16.158 by John Arbash Meinel
Added a test that copy_to raises NoSuchFile when a directory is missing (not IOError)
242
                try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
243
                    mypath = self._abspath(path)
244
                    otherpath = other._abspath(path)
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
245
                    shutil.copy(mypath, otherpath)
246
                    if mode is not None:
247
                        os.chmod(otherpath, mode)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
248
                except (IOError, OSError),e:
249
                    self._translate_error(e, path)
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
250
                count += 1
251
            return count
252
        else:
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
253
            return super(LocalTransport, self).copy_to(relpaths, other, mode=mode, pb=pb)
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
254
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
255
    def listable(self):
256
        """See Transport.listable."""
257
        return True
907.1.28 by John Arbash Meinel
Added pb to function that were missing, implemented a basic double-dispatch copy_to function.
258
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
259
    def list_dir(self, relpath):
260
        """Return a list of all files at the given location.
261
        WARNING: many transports do not support this, so trying avoid using
262
        it if at all possible.
263
        """
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
264
        path = self._abspath(relpath)
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
265
        try:
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
266
            return [urlutils.escape(entry) for entry in os.listdir(path)]
1607.1.3 by Robert Collins
Apply David Allouches list_dir quoting fix.
267
        except (IOError, OSError), e:
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
268
            self._translate_error(e, path)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
269
270
    def stat(self, relpath):
271
        """Return the stat information for a file.
272
        """
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
273
        path = relpath
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
274
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
275
            path = self._abspath(relpath)
1185.31.44 by John Arbash Meinel
Cleaned up Exceptions for all transports.
276
            return os.stat(path)
277
        except (IOError, OSError),e:
278
            self._translate_error(e, path)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
279
907.1.24 by John Arbash Meinel
Remote functionality work.
280
    def lock_read(self, relpath):
281
        """Lock the given file for shared (read) access.
282
        :return: A lock object, which should be passed to Transport.unlock()
283
        """
284
        from bzrlib.lock import ReadLock
1185.65.29 by Robert Collins
Implement final review suggestions.
285
        path = relpath
286
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
287
            path = self._abspath(relpath)
1185.65.29 by Robert Collins
Implement final review suggestions.
288
            return ReadLock(path)
289
        except (IOError, OSError), e:
290
            self._translate_error(e, path)
907.1.24 by John Arbash Meinel
Remote functionality work.
291
292
    def lock_write(self, relpath):
293
        """Lock the given file for exclusive (write) access.
294
        WARNING: many transports do not support this, so trying avoid using it
295
296
        :return: A lock object, which should be passed to Transport.unlock()
297
        """
298
        from bzrlib.lock import WriteLock
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
299
        return WriteLock(self._abspath(relpath))
907.1.24 by John Arbash Meinel
Remote functionality work.
300
1534.4.15 by Robert Collins
Remove shutil dependency in upgrade - create a delete_tree method for transports.
301
    def rmdir(self, relpath):
302
        """See Transport.rmdir."""
303
        path = relpath
304
        try:
1725.2.1 by Robert Collins
Make LocalTransport faster by not normpathing every internal path translation.
305
            path = self._abspath(relpath)
1534.4.15 by Robert Collins
Remove shutil dependency in upgrade - create a delete_tree method for transports.
306
            os.rmdir(path)
307
        except (IOError, OSError),e:
308
            self._translate_error(e, path)
1442.1.41 by Robert Collins
move duplicate scratch logic into a scratch transport
309
1608.2.7 by Martin Pool
Rename supports_unix_modebits to _can_roundtrip_unix_modebits for clarity
310
    def _can_roundtrip_unix_modebits(self):
1608.2.5 by Martin Pool
Add Transport.supports_unix_modebits, so tests can
311
        if sys.platform == 'win32':
312
            # anyone else?
313
            return False
314
        else:
315
            return True
316
317
1530.1.3 by Robert Collins
transport implementations now tested consistently.
318
class LocalRelpathServer(Server):
1530.1.1 by Robert Collins
Minimal infrastructure to test TransportTestProviderAdapter.
319
    """A pretend server for local transports, using relpaths."""
320
1530.1.3 by Robert Collins
transport implementations now tested consistently.
321
    def get_url(self):
322
        """See Transport.Server.get_url."""
323
        return "."
324
325
326
class LocalAbspathServer(Server):
1530.1.1 by Robert Collins
Minimal infrastructure to test TransportTestProviderAdapter.
327
    """A pretend server for local transports, using absolute paths."""
328
1530.1.3 by Robert Collins
transport implementations now tested consistently.
329
    def get_url(self):
330
        """See Transport.Server.get_url."""
331
        return os.path.abspath("")
332
333
334
class LocalURLServer(Server):
1530.1.1 by Robert Collins
Minimal infrastructure to test TransportTestProviderAdapter.
335
    """A pretend server for local transports, using file:// urls."""
1530.1.3 by Robert Collins
transport implementations now tested consistently.
336
337
    def get_url(self):
338
        """See Transport.Server.get_url."""
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
339
        return urlutils.local_path_to_url('')
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
340
341
342
def get_test_permutations():
343
    """Return the permutations to be used in testing."""
344
    return [(LocalTransport, LocalRelpathServer),
345
            (LocalTransport, LocalAbspathServer),
346
            (LocalTransport, LocalURLServer),
347
            ]