~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/memory.py

  • Committer: Patch Queue Manager
  • Date: 2012-09-17 11:14:25 UTC
  • mfrom: (6554.1.1 stack-remove-unknown)
  • Revision ID: pqm@pqm.ubuntu.com-20120917111425-4i6r0ze0v9zm33bu
(vila) Fix obscure and misleading warning when trying to delete an unknown
 config option. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Implementation of Transport that uses memory for its storage.
18
18
 
20
20
so this is primarily useful for testing.
21
21
"""
22
22
 
 
23
from __future__ import absolute_import
 
24
 
23
25
import os
24
26
import errno
25
 
import re
26
27
from stat import S_IFREG, S_IFDIR
27
28
from cStringIO import StringIO
28
 
import warnings
29
29
 
 
30
from bzrlib import (
 
31
    transport,
 
32
    urlutils,
 
33
    )
30
34
from bzrlib.errors import (
31
35
    FileExists,
32
36
    LockError,
33
37
    InProcessTransport,
34
38
    NoSuchFile,
35
 
    TransportError,
36
39
    )
37
 
from bzrlib.trace import mutter
38
40
from bzrlib.transport import (
 
41
    AppendBasedFileStream,
 
42
    _file_streams,
39
43
    LateReadError,
40
 
    register_transport,
41
 
    Server,
42
 
    Transport,
43
44
    )
44
 
import bzrlib.urlutils as urlutils
45
45
 
46
46
 
47
47
 
59
59
            self.st_mode = S_IFDIR | perms
60
60
 
61
61
 
62
 
class MemoryTransport(Transport):
 
62
class MemoryTransport(transport.Transport):
63
63
    """This is an in memory file system for transient data storage."""
64
64
 
65
65
    def __init__(self, url=""):
79
79
 
80
80
    def clone(self, offset=None):
81
81
        """See Transport.clone()."""
82
 
        path = self._combine_paths(self._cwd, offset)
 
82
        path = urlutils.URL._combine_paths(self._cwd, offset)
83
83
        if len(path) == 0 or path[-1] != '/':
84
84
            path += '/'
85
85
        url = self._scheme + path
86
 
        result = MemoryTransport(url)
 
86
        result = self.__class__(url)
87
87
        result._dirs = self._dirs
88
88
        result._files = self._files
89
89
        result._locks = self._locks
156
156
                'undefined', bytes, 0, 1,
157
157
                'put_file must be given a file of bytes, not unicode.')
158
158
        self._files[_abspath] = (bytes, mode)
 
159
        return len(bytes)
159
160
 
160
161
    def mkdir(self, relpath, mode=None):
161
162
        """See Transport.mkdir()."""
165
166
            raise FileExists(relpath)
166
167
        self._dirs[_abspath]=mode
167
168
 
 
169
    def open_write_stream(self, relpath, mode=None):
 
170
        """See Transport.open_write_stream."""
 
171
        self.put_bytes(relpath, "", mode)
 
172
        result = AppendBasedFileStream(self, relpath)
 
173
        _file_streams[self.abspath(relpath)] = result
 
174
        return result
 
175
 
168
176
    def listable(self):
169
177
        """See Transport.listable."""
170
178
        return True
173
181
        for file in self._files:
174
182
            if file.startswith(self._cwd):
175
183
                yield urlutils.escape(file[len(self._cwd):])
176
 
    
 
184
 
177
185
    def list_dir(self, relpath):
178
186
        """See Transport.list_dir()."""
179
187
        _abspath = self._abspath(relpath)
212
220
                    del container[path]
213
221
        do_renames(self._files)
214
222
        do_renames(self._dirs)
215
 
    
 
223
 
216
224
    def rmdir(self, relpath):
217
225
        """See Transport.rmdir."""
218
226
        _abspath = self._abspath(relpath)
233
241
        """See Transport.stat()."""
234
242
        _abspath = self._abspath(relpath)
235
243
        if _abspath in self._files:
236
 
            return MemoryStat(len(self._files[_abspath][0]), False, 
 
244
            return MemoryStat(len(self._files[_abspath][0]), False,
237
245
                              self._files[_abspath][1])
238
246
        elif _abspath in self._dirs:
239
247
            return MemoryStat(0, True, self._dirs[_abspath])
251
259
    def _abspath(self, relpath):
252
260
        """Generate an internal absolute path."""
253
261
        relpath = urlutils.unescape(relpath)
254
 
        if relpath.find('..') != -1:
255
 
            raise AssertionError('relpath contains ..')
256
 
        if relpath == '':
257
 
            return '/'
258
 
        if relpath[0] == '/':
 
262
        if relpath[:1] == '/':
259
263
            return relpath
260
 
        if relpath == '.':
261
 
            if (self._cwd == '/'):
262
 
                return self._cwd
263
 
            return self._cwd[:-1]
264
 
        if relpath.endswith('/'):
265
 
            relpath = relpath[:-1]
266
 
        if relpath.startswith('./'):
267
 
            relpath = relpath[2:]
268
 
        return self._cwd + relpath
 
264
        cwd_parts = self._cwd.split('/')
 
265
        rel_parts = relpath.split('/')
 
266
        r = []
 
267
        for i in cwd_parts + rel_parts:
 
268
            if i == '..':
 
269
                if not r:
 
270
                    raise ValueError("illegal relpath %r under %r"
 
271
                        % (relpath, self._cwd))
 
272
                r = r[:-1]
 
273
            elif i == '.' or i == '':
 
274
                pass
 
275
            else:
 
276
                r.append(i)
 
277
        return '/' + '/'.join(r)
269
278
 
270
279
 
271
280
class _MemoryLock(object):
272
281
    """This makes a lock."""
273
282
 
274
283
    def __init__(self, path, transport):
275
 
        assert isinstance(transport, MemoryTransport)
276
284
        self.path = path
277
285
        self.transport = transport
278
286
        if self.path in self.transport._locks:
279
287
            raise LockError('File %r already locked' % (self.path,))
280
288
        self.transport._locks[self.path] = self
281
289
 
282
 
    def __del__(self):
283
 
        # Should this warn, or actually try to cleanup?
284
 
        if self.transport:
285
 
            warnings.warn("MemoryLock %r not explicitly unlocked" % (self.path,))
286
 
            self.unlock()
287
 
 
288
290
    def unlock(self):
289
291
        del self.transport._locks[self.path]
290
292
        self.transport = None
291
293
 
292
294
 
293
 
class MemoryServer(Server):
 
295
class MemoryServer(transport.Server):
294
296
    """Server for the MemoryTransport for testing with."""
295
297
 
296
 
    def setUp(self):
297
 
        """See bzrlib.transport.Server.setUp."""
 
298
    def start_server(self):
298
299
        self._dirs = {'/':None}
299
300
        self._files = {}
300
301
        self._locks = {}
301
302
        self._scheme = "memory+%s:///" % id(self)
302
303
        def memory_factory(url):
303
 
            result = MemoryTransport(url)
 
304
            from bzrlib.transport import memory
 
305
            result = memory.MemoryTransport(url)
304
306
            result._dirs = self._dirs
305
307
            result._files = self._files
306
308
            result._locks = self._locks
307
309
            return result
308
 
        register_transport(self._scheme, memory_factory)
 
310
        self._memory_factory = memory_factory
 
311
        transport.register_transport(self._scheme, self._memory_factory)
309
312
 
310
 
    def tearDown(self):
311
 
        """See bzrlib.transport.Server.tearDown."""
 
313
    def stop_server(self):
312
314
        # unregister this server
 
315
        transport.unregister_transport(self._scheme, self._memory_factory)
313
316
 
314
317
    def get_url(self):
315
318
        """See bzrlib.transport.Server.get_url."""
316
319
        return self._scheme
317
320
 
 
321
    def get_bogus_url(self):
 
322
        raise NotImplementedError
 
323
 
318
324
 
319
325
def get_test_permutations():
320
326
    """Return the permutations to be used in testing."""