~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Martin Pool
  • Date: 2005-06-22 06:37:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050622063743-e395f04c4db8977f
- move old blackbox code from testbzr into bzrlib.selftest.blackbox

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tree classes, representing directory at point in time.
18
18
"""
19
19
 
20
 
import os
21
 
from cStringIO import StringIO
 
20
from sets import Set
 
21
import os.path, os, fnmatch, time
 
22
 
 
23
from osutils import pumpfile, filesize, quotefn, sha_file, \
 
24
     joinpath, splitpath, appendpath, isdir, isfile, file_kind, fingerprint_file
 
25
import errno
 
26
from stat import S_ISREG, S_ISDIR, ST_MODE, ST_SIZE
 
27
 
 
28
from bzrlib.inventory import Inventory
 
29
from bzrlib.trace import mutter, note
 
30
from bzrlib.errors import BzrError
 
31
import branch
22
32
 
23
33
import bzrlib
24
 
from bzrlib.trace import mutter, note
25
 
from bzrlib.errors import BzrError, BzrCheckError
26
 
from bzrlib.inventory import Inventory
27
 
from bzrlib.osutils import pumpfile, appendpath, fingerprint_file
28
 
 
29
34
 
30
35
exporters = {}
31
36
 
68
73
 
69
74
    def _get_inventory(self):
70
75
        return self._inventory
71
 
    
72
 
    def get_file_by_path(self, path):
73
 
        return self.get_file(self._inventory.path2id(path))
74
76
 
75
77
    inventory = property(_get_inventory,
76
78
                         doc="Inventory of this Tree")
93
95
                     "store is probably damaged/corrupt"])
94
96
 
95
97
 
96
 
    def print_file(self, file_id):
97
 
        """Print file with id `file_id` to stdout."""
 
98
    def print_file(self, fileid):
 
99
        """Print file with id `fileid` to stdout."""
98
100
        import sys
99
 
        sys.stdout.write(self.get_file_text(file_id))
100
 
        
101
 
        
102
 
    def export(self, dest, format='dir', root=None):
 
101
        pumpfile(self.get_file(fileid), sys.stdout)
 
102
        
 
103
        
 
104
    def export(self, dest, format='dir'):
103
105
        """Export this tree."""
104
106
        try:
105
107
            exporter = exporters[format]
106
108
        except KeyError:
107
 
            from bzrlib.errors import BzrCommandError
108
109
            raise BzrCommandError("export format %r not supported" % format)
109
 
        exporter(self, dest, root)
 
110
        exporter(self, dest)
110
111
 
111
112
 
112
113
 
120
121
           or at least passing a description to the constructor.
121
122
    """
122
123
    
123
 
    def __init__(self, weave_store, inv, revision_id):
124
 
        self._weave_store = weave_store
 
124
    def __init__(self, store, inv):
 
125
        self._store = store
125
126
        self._inventory = inv
126
 
        self._revision_id = revision_id
127
 
 
128
 
    def get_weave(self, file_id):
129
 
        return self._weave_store.get_weave(file_id)
130
 
        
131
 
 
132
 
    def get_file_text(self, file_id):
133
 
        ie = self._inventory[file_id]
134
 
        weave = self.get_weave(file_id)
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
143
127
 
144
128
    def get_file(self, file_id):
145
 
        return StringIO(self.get_file_text(file_id))
 
129
        ie = self._inventory[file_id]
 
130
        f = self._store[ie.text_id]
 
131
        mutter("  get fileid{%s} from %r" % (file_id, self))
 
132
        self._check_retrieved(ie, f)
 
133
        return f
146
134
 
147
135
    def get_file_size(self, file_id):
148
136
        return self._inventory[file_id].text_size
149
137
 
150
138
    def get_file_sha1(self, file_id):
151
139
        ie = self._inventory[file_id]
152
 
        if ie.kind == "file":
153
 
            return ie.text_sha1
 
140
        return ie.text_sha1
154
141
 
155
142
    def has_filename(self, filename):
156
143
        return bool(self.inventory.path2id(filename))
172
159
        if False:  # just to make it a generator
173
160
            yield None
174
161
    
175
 
    def __contains__(self, file_id):
176
 
        return file_id in self._inventory
177
 
 
178
 
    def get_file_sha1(self, file_id):
179
 
        assert self._inventory[file_id].kind == "root_directory"
180
 
        return None
181
 
 
182
 
 
183
162
 
184
163
 
185
164
######################################################################
251
230
######################################################################
252
231
# export
253
232
 
254
 
def dir_exporter(tree, dest, root):
 
233
def dir_exporter(tree, dest):
255
234
    """Export this tree to a new directory.
256
235
 
257
236
    `dest` should not exist, and will be created holding the
263
242
    :note: If the export fails, the destination directory will be
264
243
           left in a half-assed state.
265
244
    """
266
 
    import os
267
245
    os.mkdir(dest)
268
246
    mutter('export version %r' % tree)
269
247
    inv = tree.inventory
284
262
except ImportError:
285
263
    pass
286
264
else:
287
 
    def get_root_name(dest):
288
 
        """Get just the root name for a tarball.
289
 
 
290
 
        >>> get_root_name('mytar.tar')
291
 
        'mytar'
292
 
        >>> get_root_name('mytar.tar.bz2')
293
 
        'mytar'
294
 
        >>> get_root_name('tar.tar.tar.tgz')
295
 
        'tar.tar.tar'
296
 
        >>> get_root_name('bzr-0.0.5.tar.gz')
297
 
        'bzr-0.0.5'
298
 
        >>> get_root_name('a/long/path/mytar.tgz')
299
 
        'mytar'
300
 
        >>> get_root_name('../parent/../dir/other.tbz2')
301
 
        'other'
302
 
        """
303
 
        endings = ['.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2']
304
 
        dest = os.path.basename(dest)
305
 
        for end in endings:
306
 
            if dest.endswith(end):
307
 
                return dest[:-len(end)]
308
 
 
309
 
    def tar_exporter(tree, dest, root, compression=None):
 
265
    def tar_exporter(tree, dest, compression=None):
310
266
        """Export this tree to a new tar file.
311
267
 
312
268
        `dest` will be created holding the contents of this tree; if it
313
269
        already exists, it will be clobbered, like with "tar -c".
314
270
        """
315
 
        from time import time
316
 
        now = time()
 
271
        now = time.time()
317
272
        compression = str(compression or '')
318
 
        if root is None:
319
 
            root = get_root_name(dest)
320
273
        try:
321
274
            ball = tarfile.open(dest, 'w:' + compression)
322
275
        except tarfile.CompressionError, e:
325
278
        inv = tree.inventory
326
279
        for dp, ie in inv.iter_entries():
327
280
            mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
328
 
            item = tarfile.TarInfo(os.path.join(root, dp))
 
281
            item = tarfile.TarInfo(dp)
329
282
            # TODO: would be cool to actually set it to the timestamp of the
330
283
            # revision it was last changed
331
284
            item.mtime = now
348
301
        ball.close()
349
302
    exporters['tar'] = tar_exporter
350
303
 
351
 
    def tgz_exporter(tree, dest, root):
352
 
        tar_exporter(tree, dest, root, compression='gz')
 
304
    def tgz_exporter(tree, dest):
 
305
        tar_exporter(tree, dest, compression='gz')
353
306
    exporters['tgz'] = tgz_exporter
354
307
 
355
 
    def tbz_exporter(tree, dest, root):
356
 
        tar_exporter(tree, dest, root, compression='bz2')
 
308
    def tbz_exporter(tree, dest):
 
309
        tar_exporter(tree, dest, compression='bz2')
357
310
    exporters['tbz2'] = tbz_exporter
358
311
 
359
312