~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/memory.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-10-24 12:49:17 UTC
  • mfrom: (2935.1.1 ianc-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20071024124917-xb75eckyxx6vkrlg
Makefile fixes - hooks.html generation & allow python to be overridden (Ian Clatworthy)

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
so this is primarily useful for testing.
21
21
"""
22
22
 
23
 
from copy import copy
24
23
import os
25
24
import errno
26
25
import re
28
27
from cStringIO import StringIO
29
28
import warnings
30
29
 
31
 
from bzrlib.errors import TransportError, NoSuchFile, FileExists, LockError
 
30
from bzrlib.errors import (
 
31
    FileExists,
 
32
    LockError,
 
33
    InProcessTransport,
 
34
    NoSuchFile,
 
35
    TransportError,
 
36
    )
32
37
from bzrlib.trace import mutter
33
 
from bzrlib.transport import (Transport, register_transport, Server)
 
38
from bzrlib.transport import (
 
39
    AppendBasedFileStream,
 
40
    _file_streams,
 
41
    LateReadError,
 
42
    register_transport,
 
43
    Server,
 
44
    Transport,
 
45
    )
34
46
import bzrlib.urlutils as urlutils
35
47
 
36
48
 
59
71
        if url[-1] != '/':
60
72
            url = url + '/'
61
73
        super(MemoryTransport, self).__init__(url)
62
 
        self._cwd = url[url.find(':') + 3:]
 
74
        split = url.find(':') + 3
 
75
        self._scheme = url[:split]
 
76
        self._cwd = url[split:]
63
77
        # dictionaries from absolute path to file mode
64
78
        self._dirs = {'/':None}
65
79
        self._files = {}
67
81
 
68
82
    def clone(self, offset=None):
69
83
        """See Transport.clone()."""
70
 
        if offset is None or offset == '':
71
 
            return copy(self)
72
 
        segments = offset.split('/')
73
 
        cwdsegments = self._cwd.split('/')[:-1]
74
 
        while len(segments):
75
 
            segment = segments.pop(0)
76
 
            if segment == '.':
77
 
                continue
78
 
            if segment == '..':
79
 
                if len(cwdsegments) > 1:
80
 
                    cwdsegments.pop()
81
 
                continue
82
 
            cwdsegments.append(segment)
83
 
        url = self.base[:self.base.find(':') + 3] + '/'.join(cwdsegments) + '/'
 
84
        path = self._combine_paths(self._cwd, offset)
 
85
        if len(path) == 0 or path[-1] != '/':
 
86
            path += '/'
 
87
        url = self._scheme + path
84
88
        result = MemoryTransport(url)
85
89
        result._dirs = self._dirs
86
90
        result._files = self._files
98
102
        else:
99
103
            return temp_t.base[:-1]
100
104
 
101
 
    def append(self, relpath, f, mode=None):
102
 
        """See Transport.append()."""
 
105
    def append_file(self, relpath, f, mode=None):
 
106
        """See Transport.append_file()."""
103
107
        _abspath = self._abspath(relpath)
104
108
        self._check_parent(_abspath)
105
109
        orig_content, orig_mode = self._files.get(_abspath, ("", None))
117
121
    def has(self, relpath):
118
122
        """See Transport.has()."""
119
123
        _abspath = self._abspath(relpath)
120
 
        return _abspath in self._files or _abspath in self._dirs
 
124
        return (_abspath in self._files) or (_abspath in self._dirs)
121
125
 
122
126
    def delete(self, relpath):
123
127
        """See Transport.delete()."""
126
130
            raise NoSuchFile(relpath)
127
131
        del self._files[_abspath]
128
132
 
 
133
    def external_url(self):
 
134
        """See bzrlib.transport.Transport.external_url."""
 
135
        # MemoryTransport's are only accessible in-process
 
136
        # so we raise here
 
137
        raise InProcessTransport(self)
 
138
 
129
139
    def get(self, relpath):
130
140
        """See Transport.get()."""
131
141
        _abspath = self._abspath(relpath)
132
142
        if not _abspath in self._files:
133
 
            raise NoSuchFile(relpath)
 
143
            if _abspath in self._dirs:
 
144
                return LateReadError(relpath)
 
145
            else:
 
146
                raise NoSuchFile(relpath)
134
147
        return StringIO(self._files[_abspath][0])
135
148
 
136
 
    def put(self, relpath, f, mode=None):
137
 
        """See Transport.put()."""
 
149
    def put_file(self, relpath, f, mode=None):
 
150
        """See Transport.put_file()."""
138
151
        _abspath = self._abspath(relpath)
139
152
        self._check_parent(_abspath)
140
 
        self._files[_abspath] = (f.read(), mode)
 
153
        bytes = f.read()
 
154
        if type(bytes) is not str:
 
155
            # Although not strictly correct, we raise UnicodeEncodeError to be
 
156
            # compatible with other transports.
 
157
            raise UnicodeEncodeError(
 
158
                'undefined', bytes, 0, 1,
 
159
                'put_file must be given a file of bytes, not unicode.')
 
160
        self._files[_abspath] = (bytes, mode)
 
161
        return len(bytes)
141
162
 
142
163
    def mkdir(self, relpath, mode=None):
143
164
        """See Transport.mkdir()."""
147
168
            raise FileExists(relpath)
148
169
        self._dirs[_abspath]=mode
149
170
 
 
171
    def open_write_stream(self, relpath, mode=None):
 
172
        """See Transport.open_write_stream."""
 
173
        self.put_bytes(relpath, "", mode)
 
174
        result = AppendBasedFileStream(self, relpath)
 
175
        _file_streams[self.abspath(relpath)] = result
 
176
        return result
 
177
 
150
178
    def listable(self):
151
179
        """See Transport.listable."""
152
180
        return True
154
182
    def iter_files_recursive(self):
155
183
        for file in self._files:
156
184
            if file.startswith(self._cwd):
157
 
                yield file[len(self._cwd):]
 
185
                yield urlutils.escape(file[len(self._cwd):])
158
186
    
159
187
    def list_dir(self, relpath):
160
188
        """See Transport.list_dir()."""
162
190
        if _abspath != '/' and _abspath not in self._dirs:
163
191
            raise NoSuchFile(relpath)
164
192
        result = []
165
 
        for path in self._files:
166
 
            if (path.startswith(_abspath) and 
167
 
                path[len(_abspath) + 1:].find('/') == -1 and
168
 
                len(path) > len(_abspath)):
169
 
                result.append(path[len(_abspath) + 1:])
170
 
        for path in self._dirs:
171
 
            if (path.startswith(_abspath) and 
172
 
                path[len(_abspath) + 1:].find('/') == -1 and
173
 
                len(path) > len(_abspath) and
174
 
                path[len(_abspath)] == '/'):
175
 
                result.append(path[len(_abspath) + 1:])
176
 
        return result
 
193
 
 
194
        if not _abspath.endswith('/'):
 
195
            _abspath += '/'
 
196
 
 
197
        for path_group in self._files, self._dirs:
 
198
            for path in path_group:
 
199
                if path.startswith(_abspath):
 
200
                    trailing = path[len(_abspath):]
 
201
                    if trailing and '/' not in trailing:
 
202
                        result.append(trailing)
 
203
        return map(urlutils.escape, result)
177
204
 
178
205
    def rename(self, rel_from, rel_to):
179
206
        """Rename a file or directory; fail if the destination exists"""
202
229
        if _abspath in self._files:
203
230
            self._translate_error(IOError(errno.ENOTDIR, relpath), relpath)
204
231
        for path in self._files:
205
 
            if path.startswith(_abspath):
 
232
            if path.startswith(_abspath + '/'):
206
233
                self._translate_error(IOError(errno.ENOTEMPTY, relpath),
207
234
                                      relpath)
208
235
        for path in self._dirs:
209
 
            if path.startswith(_abspath) and path != _abspath:
 
236
            if path.startswith(_abspath + '/') and path != _abspath:
210
237
                self._translate_error(IOError(errno.ENOTEMPTY, relpath), relpath)
211
238
        if not _abspath in self._dirs:
212
239
            raise NoSuchFile(relpath)
236
263
        relpath = urlutils.unescape(relpath)
237
264
        if relpath.find('..') != -1:
238
265
            raise AssertionError('relpath contains ..')
 
266
        if relpath == '':
 
267
            return '/'
 
268
        if relpath[0] == '/':
 
269
            return relpath
239
270
        if relpath == '.':
240
271
            if (self._cwd == '/'):
241
272
                return self._cwd