~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to upstream_import.py

  • Committer: Aaron Bentley
  • Date: 2011-01-26 01:15:21 UTC
  • Revision ID: aaron@aaronbentley.com-20110126011521-nl09rwxzrymt2gva
Update version to 2.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""Import upstream source into a branch"""
2
2
 
 
3
from bz2 import BZ2File
3
4
import errno
4
5
import os
5
 
import re
6
6
from StringIO import StringIO
7
7
import stat
8
8
import tarfile
17
17
from bzrlib.transform import TreeTransform, resolve_conflicts, cook_conflicts
18
18
from bzrlib.workingtree import WorkingTree
19
19
from bzrlib.plugins.bzrtools.bzrtools import open_from_url
20
 
from bzrlib.plugins.bzrtools import errors
21
20
 
22
21
class ZipFileWrapper(object):
23
22
 
183
182
    dir_file = DirWrapper(dir_input)
184
183
    import_archive(tree, dir_file)
185
184
 
186
 
 
187
185
def import_archive(tree, archive_file):
 
186
    prefix = common_directory(names_of_files(archive_file))
188
187
    tt = TreeTransform(tree)
189
 
    try:
190
 
        import_archive_to_transform(tree, archive_file, tt)
191
 
        tt.apply()
192
 
    finally:
193
 
        tt.finalize()
194
 
 
195
 
 
196
 
def import_archive_to_transform(tree, archive_file, tt):
197
 
    prefix = common_directory(names_of_files(archive_file))
 
188
 
198
189
    removed = set()
199
190
    for path, entry in tree.inventory.iter_entries():
200
191
        if entry.parent_id is None:
210
201
        if member.type == 'g':
211
202
            # type 'g' is a header
212
203
            continue
213
 
        # Inverse functionality in bzr uses utf-8.  We could also
214
 
        # interpret relative to fs encoding, which would match native
215
 
        # behaviour better.
216
 
        relative_path = member.name.decode('utf-8')
 
204
        relative_path = member.name
217
205
        if prefix is not None:
218
206
            relative_path = relative_path[len(prefix)+1:]
219
207
            relative_path = relative_path.rstrip('/')
261
249
 
262
250
    for conflict in cook_conflicts(resolve_conflicts(tt), tt):
263
251
        warning(conflict)
 
252
    tt.apply()
264
253
 
265
254
 
266
255
def do_import(source, tree_directory=None):
280
269
        if tree.changes_from(tree.basis_tree()).has_changed():
281
270
            raise BzrCommandError("Working tree has uncommitted changes.")
282
271
 
283
 
        try:
284
 
            archive, external_compressor = get_archive_type(source)
285
 
        except errors.NotArchiveType:
286
 
            if file_kind(source) == 'directory':
287
 
                s = StringIO(source)
288
 
                s.seek(0)
289
 
                import_dir(tree, s)
290
 
            else:
291
 
                raise BzrCommandError('Unhandled import source')
 
272
        if (source.endswith('.tar') or source.endswith('.tar.gz') or
 
273
            source.endswith('.tar.bz2')) or source.endswith('.tgz'):
 
274
            try:
 
275
                tar_input = open_from_url(source)
 
276
                if source.endswith('.bz2'):
 
277
                    tar_input = StringIO(tar_input.read().decode('bz2'))
 
278
            except IOError, e:
 
279
                if e.errno == errno.ENOENT:
 
280
                    raise NoSuchFile(source)
 
281
            try:
 
282
                import_tar(tree, tar_input)
 
283
            finally:
 
284
                tar_input.close()
 
285
        elif source.endswith('.zip'):
 
286
            import_zip(tree, open_from_url(source))
 
287
        elif file_kind(source) == 'directory':
 
288
            s = StringIO(source)
 
289
            s.seek(0)
 
290
            import_dir(tree, s)
292
291
        else:
293
 
            if archive == 'zip':
294
 
                import_zip(tree, open_from_url(source))
295
 
            elif archive == 'tar':
296
 
                try:
297
 
                    tar_input = open_from_url(source)
298
 
                    if external_compressor == 'bz2':
299
 
                        import bz2
300
 
                        tar_input = StringIO(bz2.decompress(tar_input.read()))
301
 
                    elif external_compressor == 'lzma':
302
 
                        import lzma
303
 
                        tar_input = StringIO(lzma.decompress(tar_input.read()))
304
 
                except IOError, e:
305
 
                    if e.errno == errno.ENOENT:
306
 
                        raise NoSuchFile(source)
307
 
                try:
308
 
                    import_tar(tree, tar_input)
309
 
                finally:
310
 
                    tar_input.close()
 
292
            raise BzrCommandError('Unhandled import source')
311
293
    finally:
312
294
        tree.unlock()
313
 
 
314
 
 
315
 
def get_archive_type(path):
316
 
    """Return the type of archive and compressor indicated by path name.
317
 
 
318
 
    Only external compressors are returned, so zip files are only
319
 
    ('zip', None).  .tgz is treated as ('tar', 'gz') and '.tar.xz' is treated
320
 
    as ('tar', 'lzma').
321
 
    """
322
 
    matches = re.match(r'.*\.(zip|tgz|tar(.(gz|bz2|lzma|xz))?)$', path)
323
 
    if not matches:
324
 
        raise errors.NotArchiveType(path)
325
 
    external_compressor = None
326
 
    if matches.group(3) is not None:
327
 
        archive = 'tar'
328
 
        external_compressor = matches.group(3)
329
 
        if external_compressor == 'xz':
330
 
            external_compressor = 'lzma'
331
 
    elif matches.group(1) == 'tgz':
332
 
        return 'tar', 'gz'
333
 
    else:
334
 
        archive = matches.group(1)
335
 
    return archive, external_compressor