~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_file_text(self, file_id):
129
 
        ie = self._inventory[file_id]
130
 
        weave = self._weave_store.get_weave(file_id)
131
 
        idx = weave.lookup(self._revision_id)
132
 
        content = weave.get_text(idx)
133
 
        if len(content) != ie.text_size:
134
 
            raise BzrCheckError('mismatched size on revision %s of file %s: '
135
 
                                '%d vs %d bytes'
136
 
                                % (self._revision_id, file_id, len(content),
137
 
                                   ie.text_size))
138
 
        return content
139
127
 
140
128
    def get_file(self, file_id):
141
 
        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
142
134
 
143
135
    def get_file_size(self, file_id):
144
136
        return self._inventory[file_id].text_size
145
137
 
146
138
    def get_file_sha1(self, file_id):
147
139
        ie = self._inventory[file_id]
148
 
        if ie.kind == "file":
149
 
            return ie.text_sha1
 
140
        return ie.text_sha1
150
141
 
151
142
    def has_filename(self, filename):
152
143
        return bool(self.inventory.path2id(filename))
168
159
        if False:  # just to make it a generator
169
160
            yield None
170
161
    
171
 
    def __contains__(self, file_id):
172
 
        return file_id in self._inventory
173
 
 
174
 
    def get_file_sha1(self, file_id):
175
 
        assert self._inventory[file_id].kind == "root_directory"
176
 
        return None
177
 
 
178
 
 
179
162
 
180
163
 
181
164
######################################################################
247
230
######################################################################
248
231
# export
249
232
 
250
 
def dir_exporter(tree, dest, root):
 
233
def dir_exporter(tree, dest):
251
234
    """Export this tree to a new directory.
252
235
 
253
236
    `dest` should not exist, and will be created holding the
259
242
    :note: If the export fails, the destination directory will be
260
243
           left in a half-assed state.
261
244
    """
262
 
    import os
263
245
    os.mkdir(dest)
264
246
    mutter('export version %r' % tree)
265
247
    inv = tree.inventory
280
262
except ImportError:
281
263
    pass
282
264
else:
283
 
    def get_root_name(dest):
284
 
        """Get just the root name for a tarball.
285
 
 
286
 
        >>> get_root_name('mytar.tar')
287
 
        'mytar'
288
 
        >>> get_root_name('mytar.tar.bz2')
289
 
        'mytar'
290
 
        >>> get_root_name('tar.tar.tar.tgz')
291
 
        'tar.tar.tar'
292
 
        >>> get_root_name('bzr-0.0.5.tar.gz')
293
 
        'bzr-0.0.5'
294
 
        >>> get_root_name('a/long/path/mytar.tgz')
295
 
        'mytar'
296
 
        >>> get_root_name('../parent/../dir/other.tbz2')
297
 
        'other'
298
 
        """
299
 
        endings = ['.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2']
300
 
        dest = os.path.basename(dest)
301
 
        for end in endings:
302
 
            if dest.endswith(end):
303
 
                return dest[:-len(end)]
304
 
 
305
 
    def tar_exporter(tree, dest, root, compression=None):
 
265
    def tar_exporter(tree, dest, compression=None):
306
266
        """Export this tree to a new tar file.
307
267
 
308
268
        `dest` will be created holding the contents of this tree; if it
309
269
        already exists, it will be clobbered, like with "tar -c".
310
270
        """
311
 
        from time import time
312
 
        now = time()
 
271
        now = time.time()
313
272
        compression = str(compression or '')
314
 
        if root is None:
315
 
            root = get_root_name(dest)
316
273
        try:
317
274
            ball = tarfile.open(dest, 'w:' + compression)
318
275
        except tarfile.CompressionError, e:
321
278
        inv = tree.inventory
322
279
        for dp, ie in inv.iter_entries():
323
280
            mutter("  export {%s} kind %s to %s" % (ie.file_id, ie.kind, dest))
324
 
            item = tarfile.TarInfo(os.path.join(root, dp))
 
281
            item = tarfile.TarInfo(dp)
325
282
            # TODO: would be cool to actually set it to the timestamp of the
326
283
            # revision it was last changed
327
284
            item.mtime = now
344
301
        ball.close()
345
302
    exporters['tar'] = tar_exporter
346
303
 
347
 
    def tgz_exporter(tree, dest, root):
348
 
        tar_exporter(tree, dest, root, compression='gz')
 
304
    def tgz_exporter(tree, dest):
 
305
        tar_exporter(tree, dest, compression='gz')
349
306
    exporters['tgz'] = tgz_exporter
350
307
 
351
 
    def tbz_exporter(tree, dest, root):
352
 
        tar_exporter(tree, dest, root, compression='bz2')
 
308
    def tbz_exporter(tree, dest):
 
309
        tar_exporter(tree, dest, compression='bz2')
353
310
    exporters['tbz2'] = tbz_exporter
354
311
 
355
312