~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Martin Pool
  • Date: 2005-09-15 08:57:46 UTC
  • Revision ID: mbp@sourcefrog.net-20050915085746-89170eabc66f8b89
- clean up imports

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
from bzrlib.trace import mutter, note
25
25
from bzrlib.errors import BzrError, BzrCheckError
26
26
from bzrlib.inventory import Inventory
27
 
from bzrlib.osutils import appendpath, fingerprint_file
 
27
from bzrlib.osutils import pumpfile, appendpath, fingerprint_file
28
28
 
29
29
 
30
30
exporters = {}
58
58
    def has_id(self, file_id):
59
59
        return self.inventory.has_id(file_id)
60
60
 
61
 
    def has_or_had_id(self, file_id):
62
 
        if file_id == self.inventory.root.file_id:
63
 
            return True
64
 
        return self.inventory.has_id(file_id)
65
 
 
66
61
    __contains__ = has_id
67
62
 
68
63
    def __iter__(self):
71
66
    def id2path(self, file_id):
72
67
        return self.inventory.id2path(file_id)
73
68
 
74
 
    def kind(self, file_id):
75
 
        raise NotImplementedError("subclasses must implement kind")
76
 
 
77
69
    def _get_inventory(self):
78
70
        return self._inventory
79
71
    
84
76
                         doc="Inventory of this Tree")
85
77
 
86
78
    def _check_retrieved(self, ie, f):
87
 
        if not __debug__:
88
 
            return  
89
79
        fp = fingerprint_file(f)
90
80
        f.seek(0)
91
81
        
136
126
        self._revision_id = revision_id
137
127
 
138
128
    def get_weave(self, file_id):
139
 
        # FIXME: RevisionTree should be given a branch
140
 
        # not a store, or the store should know the branch.
141
 
        import bzrlib.transactions as transactions
142
 
        return self._weave_store.get_weave(file_id,
143
 
            transactions.PassThroughTransaction())
144
 
 
145
 
 
146
 
    def get_file_lines(self, file_id):
 
129
        return self._weave_store.get_weave(file_id)
 
130
        
 
131
 
 
132
    def get_file_text(self, file_id):
147
133
        ie = self._inventory[file_id]
148
134
        weave = self.get_weave(file_id)
149
 
        return weave.get(ie.revision)
150
 
        
151
 
 
152
 
    def get_file_text(self, file_id):
153
 
        return ''.join(self.get_file_lines(file_id))
154
 
 
 
135
        idx = weave.lookup(ie.text_version)
 
136
        content = weave.get_text(idx)
 
137
        if len(content) != ie.text_size:
 
138
            raise BzrCheckError('mismatched size on revision %s of file %s: '
 
139
                                '%d vs %d bytes'
 
140
                                % (self._revision_id, file_id, len(content),
 
141
                                   ie.text_size))
 
142
        return content
155
143
 
156
144
    def get_file(self, file_id):
157
145
        return StringIO(self.get_file_text(file_id))
164
152
        if ie.kind == "file":
165
153
            return ie.text_sha1
166
154
 
167
 
    def is_executable(self, file_id):
168
 
        ie = self._inventory[file_id]
169
 
        if ie.kind != "file":
170
 
            return None 
171
 
        return self._inventory[file_id].executable
172
 
 
173
155
    def has_filename(self, filename):
174
156
        return bool(self.inventory.path2id(filename))
175
157
 
176
158
    def list_files(self):
177
159
        # The only files returned by this are those from the version
178
160
        for path, entry in self.inventory.iter_entries():
179
 
            yield path, 'V', entry.kind, entry.file_id, entry
180
 
 
181
 
    def get_symlink_target(self, file_id):
182
 
        ie = self._inventory[file_id]
183
 
        return ie.symlink_target;
184
 
 
185
 
    def kind(self, file_id):
186
 
        return self._inventory[file_id].kind
 
161
            yield path, 'V', entry.kind, entry.file_id
187
162
 
188
163
 
189
164
class EmptyTree(Tree):
190
165
    def __init__(self):
191
166
        self._inventory = Inventory()
192
167
 
193
 
    def get_symlink_target(self, file_id):
194
 
        return None
195
 
 
196
168
    def has_filename(self, filename):
197
169
        return False
198
170
 
199
 
    def kind(self, file_id):
200
 
        assert self._inventory[file_id].kind == "root_directory"
201
 
        return "root_directory"
202
 
 
203
171
    def list_files(self):
204
 
        return iter([])
 
172
        if False:  # just to make it a generator
 
173
            yield None
205
174
    
206
175
    def __contains__(self, file_id):
207
176
        return file_id in self._inventory
211
180
        return None
212
181
 
213
182
 
 
183
 
 
184
 
214
185
######################################################################
215
186
# diff
216
187
 
297
268
    mutter('export version %r' % tree)
298
269
    inv = tree.inventory
299
270
    for dp, ie in inv.iter_entries():
300
 
        ie.put_on_disk(dest, dp, tree)
301
 
 
 
271
        kind = ie.kind
 
272
        fullpath = appendpath(dest, dp)
 
273
        if kind == 'directory':
 
274
            os.mkdir(fullpath)
 
275
        elif kind == 'file':
 
276
            pumpfile(tree.get_file(ie.file_id), file(fullpath, 'wb'))
 
277
        else:
 
278
            raise BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, kind))
 
279
        mutter("  export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
302
280
exporters['dir'] = dir_exporter
303
281
 
304
282
try:
347
325
        inv = tree.inventory
348
326
        for dp, ie in inv.iter_entries():
349
327
            mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
350
 
            item, fileobj = ie.get_tar_item(root, dp, now, tree)
 
328
            item = tarfile.TarInfo(os.path.join(root, dp))
 
329
            # TODO: would be cool to actually set it to the timestamp of the
 
330
            # revision it was last changed
 
331
            item.mtime = now
 
332
            if ie.kind == 'directory':
 
333
                item.type = tarfile.DIRTYPE
 
334
                fileobj = None
 
335
                item.name += '/'
 
336
                item.size = 0
 
337
                item.mode = 0755
 
338
            elif ie.kind == 'file':
 
339
                item.type = tarfile.REGTYPE
 
340
                fileobj = tree.get_file(ie.file_id)
 
341
                item.size = _find_file_size(fileobj)
 
342
                item.mode = 0644
 
343
            else:
 
344
                raise BzrError("don't know how to export {%s} of kind %r" %
 
345
                        (ie.file_id, ie.kind))
 
346
 
351
347
            ball.addfile(item, fileobj)
352
348
        ball.close()
353
 
 
354
349
    exporters['tar'] = tar_exporter
355
350
 
356
351
    def tgz_exporter(tree, dest, root):
360
355
    def tbz_exporter(tree, dest, root):
361
356
        tar_exporter(tree, dest, root, compression='bz2')
362
357
    exporters['tbz2'] = tbz_exporter
 
358
 
 
359
 
 
360
def _find_file_size(fileobj):
 
361
    offset = fileobj.tell()
 
362
    try:
 
363
        fileobj.seek(0, 2)
 
364
        size = fileobj.tell()
 
365
    except TypeError:
 
366
        # gzip doesn't accept second argument to seek()
 
367
        fileobj.seek(0)
 
368
        size = 0
 
369
        while True:
 
370
            nread = len(fileobj.read())
 
371
            if nread == 0:
 
372
                break
 
373
            size += nread
 
374
    fileobj.seek(offset)
 
375
    return size