~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Aaron Bentley
  • Date: 2005-10-04 04:32:32 UTC
  • mfrom: (1185.12.6)
  • mto: (1185.12.13)
  • mto: This revision was merged to the branch mainline in revision 1419.
  • Revision ID: aaron.bentley@utoronto.ca-20051004043231-40302a149769263b
merged my own changes

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
    
136
128
        self._revision_id = revision_id
137
129
 
138
130
    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())
 
131
        return self._weave_store.get_weave(file_id)
144
132
 
145
133
 
146
134
    def get_file_lines(self, file_id):
165
153
            return ie.text_sha1
166
154
 
167
155
    def is_executable(self, file_id):
168
 
        ie = self._inventory[file_id]
169
 
        if ie.kind != "file":
170
 
            return None 
171
156
        return self._inventory[file_id].executable
172
157
 
173
158
    def has_filename(self, filename):
176
161
    def list_files(self):
177
162
        # The only files returned by this are those from the version
178
163
        for path, entry in self.inventory.iter_entries():
179
 
            yield path, 'V', entry.kind, entry.file_id, entry
 
164
            yield path, 'V', entry.kind, entry.file_id
180
165
 
181
166
    def get_symlink_target(self, file_id):
182
167
        ie = self._inventory[file_id]
183
168
        return ie.symlink_target;
184
169
 
185
 
    def kind(self, file_id):
186
 
        return self._inventory[file_id].kind
187
 
 
188
 
 
189
170
class EmptyTree(Tree):
190
171
    def __init__(self):
191
172
        self._inventory = Inventory()
196
177
    def has_filename(self, filename):
197
178
        return False
198
179
 
199
 
    def kind(self, file_id):
200
 
        assert self._inventory[file_id].kind == "root_directory"
201
 
        return "root_directory"
202
 
 
203
180
    def list_files(self):
204
 
        return iter([])
 
181
        if False:  # just to make it a generator
 
182
            yield None
205
183
    
206
184
    def __contains__(self, file_id):
207
185
        return file_id in self._inventory
211
189
        return None
212
190
 
213
191
 
 
192
 
 
193
 
214
194
######################################################################
215
195
# diff
216
196
 
297
277
    mutter('export version %r' % tree)
298
278
    inv = tree.inventory
299
279
    for dp, ie in inv.iter_entries():
300
 
        ie.put_on_disk(dest, dp, tree)
301
 
 
 
280
        kind = ie.kind
 
281
        fullpath = appendpath(dest, dp)
 
282
        if kind == 'directory':
 
283
            os.mkdir(fullpath)
 
284
        elif kind == 'file':
 
285
            pumpfile(tree.get_file(ie.file_id), file(fullpath, 'wb'))
 
286
            if tree.is_executable(ie.file_id):
 
287
                os.chmod(fullpath, 0755)
 
288
        elif kind == 'symlink':
 
289
            try:
 
290
                os.symlink(ie.symlink_target, fullpath)
 
291
            except OSError,e:
 
292
                raise BzrError("Failed to create symlink %r -> %r, error: %s" % (fullpath, ie.symlink_target, e))
 
293
        else:
 
294
            raise BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, kind))
 
295
        mutter("  export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
302
296
exporters['dir'] = dir_exporter
303
297
 
304
298
try:
347
341
        inv = tree.inventory
348
342
        for dp, ie in inv.iter_entries():
349
343
            mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
350
 
            item, fileobj = ie.get_tar_item(root, dp, now, tree)
 
344
            item = tarfile.TarInfo(os.path.join(root, dp))
 
345
            # TODO: would be cool to actually set it to the timestamp of the
 
346
            # revision it was last changed
 
347
            item.mtime = now
 
348
            if ie.kind == 'directory':
 
349
                item.type = tarfile.DIRTYPE
 
350
                fileobj = None
 
351
                item.name += '/'
 
352
                item.size = 0
 
353
                item.mode = 0755
 
354
            elif ie.kind == 'file':
 
355
                item.type = tarfile.REGTYPE
 
356
                fileobj = tree.get_file(ie.file_id)
 
357
                item.size = _find_file_size(fileobj)
 
358
                if tree.is_executable(ie.file_id):
 
359
                    item.mode = 0755
 
360
                else:
 
361
                    item.mode = 0644
 
362
            else:
 
363
                raise BzrError("don't know how to export {%s} of kind %r" %
 
364
                        (ie.file_id, ie.kind))
 
365
 
351
366
            ball.addfile(item, fileobj)
352
367
        ball.close()
353
 
 
354
368
    exporters['tar'] = tar_exporter
355
369
 
356
370
    def tgz_exporter(tree, dest, root):
360
374
    def tbz_exporter(tree, dest, root):
361
375
        tar_exporter(tree, dest, root, compression='bz2')
362
376
    exporters['tbz2'] = tbz_exporter
 
377
 
 
378
 
 
379
def _find_file_size(fileobj):
 
380
    offset = fileobj.tell()
 
381
    try:
 
382
        fileobj.seek(0, 2)
 
383
        size = fileobj.tell()
 
384
    except TypeError:
 
385
        # gzip doesn't accept second argument to seek()
 
386
        fileobj.seek(0)
 
387
        size = 0
 
388
        while True:
 
389
            nread = len(fileobj.read())
 
390
            if nread == 0:
 
391
                break
 
392
            size += nread
 
393
    fileobj.seek(offset)
 
394
    return size