~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to upstream_import.py

  • Committer: Aaron Bentley
  • Date: 2013-08-20 03:02:43 UTC
  • Revision ID: aaron@aaronbentley.com-20130820030243-r8v1xfbcnd8f10p4
Fix zap command for 2.6/7

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
4
3
import errno
5
4
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
20
21
 
21
22
class ZipFileWrapper(object):
22
23
 
182
183
    dir_file = DirWrapper(dir_input)
183
184
    import_archive(tree, dir_file)
184
185
 
 
186
 
185
187
def import_archive(tree, archive_file):
 
188
    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):
186
197
    prefix = common_directory(names_of_files(archive_file))
187
 
    tt = TreeTransform(tree)
188
 
 
189
198
    removed = set()
190
 
    for path, entry in tree.inventory.iter_entries():
 
199
    for path, entry in tree.iter_entries_by_dir():
191
200
        if entry.parent_id is None:
192
201
            continue
193
202
        trans_id = tt.trans_id_tree_path(path)
201
210
        if member.type == 'g':
202
211
            # type 'g' is a header
203
212
            continue
204
 
        relative_path = member.name
 
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')
205
217
        if prefix is not None:
206
218
            relative_path = relative_path[len(prefix)+1:]
207
219
            relative_path = relative_path.rstrip('/')
249
261
 
250
262
    for conflict in cook_conflicts(resolve_conflicts(tt), tt):
251
263
        warning(conflict)
252
 
    tt.apply()
253
264
 
254
265
 
255
266
def do_import(source, tree_directory=None):
269
280
        if tree.changes_from(tree.basis_tree()).has_changed():
270
281
            raise BzrCommandError("Working tree has uncommitted changes.")
271
282
 
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)
 
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')
291
292
        else:
292
 
            raise BzrCommandError('Unhandled import source')
 
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()
293
311
    finally:
294
312
        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