~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to baz_import.py

  • Committer: Aaron Bentley
  • Date: 2006-03-22 22:18:19 UTC
  • Revision ID: abentley@panoramicfeedback.com-20060322221819-0e627e73d1232926
Added zap command

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
from progress import *
58
58
 
59
59
class ImportCommitReporter(NullCommitReporter):
 
60
    def __init__(self, pb):
 
61
        self.pb = pb
60
62
 
61
63
    def escaped(self, escape_count, message):
 
64
        self.pb.clear()
62
65
        bzrlib.trace.warning("replaced %d control characters in message" %
63
66
                             escape_count)
64
67
 
287
290
        branch = Branch.open(output_dir)
288
291
        last_patch = get_last_revision(branch)
289
292
        if last_patch is None:
290
 
            if branch.last_revision() != None:
291
 
                raise NotPreviousImport(branch.base)
292
 
        elif version is None:
 
293
            raise NotPreviousImport(branch.base)
 
294
        if version is None:
293
295
            version = last_patch.version
294
296
    elif version is None:
295
297
        raise UserError("No version specified, and directory does not exist.")
343
345
###    possible later.
344
346
###    """
345
347
###
346
 
###    def __init__(self, output_dir, version, fast=False,
 
348
###    def __init__(self, output_dir, version, printer, fancy=True, fast=False,
347
349
###                 verbose=False, dry_run=False, max_count=None, 
348
350
###                   reuse_history_from=[]):
349
351
###        self.output_dir = output_dir
351
353
###        self.
352
354
 
353
355
 
354
 
def import_version(output_dir, version, fast=False,
 
356
def import_version(output_dir, version, printer, fancy=True, fast=False,
355
357
                   verbose=False, dry_run=False, max_count=None,
356
358
                   reuse_history_from=[], standalone=True):
357
359
    """
358
360
    >>> q = test_environ()
359
 
    
360
 
    Progress bars output to stderr, but doctest does not capture that.
361
 
 
362
 
    >>> old_stderr = sys.stderr
363
 
    >>> sys.stderr = sys.stdout
364
 
 
365
361
    >>> result_path = os.path.join(q, "result")
366
362
    >>> commit_test_revisions()
367
363
    >>> version = pybaz.Version("test@example.com/test--test--0.1")
368
 
    >>> old_ui = bzrlib.ui.ui_factory
369
 
    >>> bzrlib.ui.ui_factory = bzrlib.ui.text.TextUIFactory(
370
 
    ...     bar_type=bzrlib.progress.DotsProgressBar)
371
 
 
372
 
    >>> import_version('/', version, dry_run=True)
 
364
    >>> def printer(message): print message
 
365
    >>> import_version('/', version, printer, fancy=False, dry_run=True)
373
366
    Traceback (most recent call last):
374
367
    NotPreviousImport: / is not the location of a previous import.
375
 
    >>> import_version(result_path, version, dry_run=True)
 
368
    >>> import_version(result_path, version, printer, fancy=False, dry_run=True)
376
369
    Traceback (most recent call last):
377
370
    UserError: The version test@example.com/test--test--0.1 does not exist.
378
371
    >>> version = pybaz.Version("test@example.com/test--test--0")
379
 
    >>> import_version(result_path, version, dry_run=True) #doctest: +ELLIPSIS
380
 
    importing test@example.com/test--test--0 into ...
381
 
    ...
382
 
    revisions: ..........................................
 
372
    >>> import_version(result_path, version, printer, fancy=False, dry_run=True)
 
373
    not fancy
 
374
    ....
383
375
    Dry run, not modifying output_dir
384
376
    Cleaning up
385
 
    >>> import_version(result_path, version) #doctest: +ELLIPSIS
386
 
    importing test@example.com/test--test--0 into ...
387
 
    ...
388
 
    revisions: .....................................................................
 
377
    >>> import_version(result_path, version, printer, fancy=False)
 
378
    not fancy
 
379
    ....
389
380
    Cleaning up
390
381
    Import complete.
391
 
    >>> import_version(result_path, version) #doctest: +ELLIPSIS
 
382
    >>> import_version(result_path, version, printer, fancy=False)
392
383
    Tree is up-to-date with test@example.com/test--test--0--patch-2
393
384
    >>> commit_more_test_revisions()
394
 
    >>> import_version(result_path, version) #doctest: +ELLIPSIS
395
 
    importing test@example.com/test--test--0 into ...
396
 
    revisions: ....................................................
 
385
    >>> import_version(result_path, version, printer, fancy=False)
 
386
    not fancy
 
387
    ..
397
388
    Cleaning up
398
389
    Import complete.
399
 
    >>> bzrlib.ui.ui_factory = old_ui
400
 
    >>> sys.stderr = old_stderr
401
390
    >>> teardown_environ(q)
402
391
    """
 
392
    try:
 
393
        ancestors, old_revno = get_remaining_revisions(output_dir, version,
 
394
                                                       reuse_history_from)
 
395
    except NotBranchError, e:
 
396
        raise NotPreviousImport(e.path)
 
397
    if old_revno is None and len(ancestors) == 0:
 
398
        print 'Version %s has no revisions.' % version
 
399
        return
 
400
    if len(ancestors) == 0:
 
401
        last_revision = get_last_revision(Branch.open(output_dir))
 
402
        print 'Tree is up-to-date with %s' % last_revision
 
403
        return
 
404
 
403
405
    progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
404
 
    try:
 
406
    tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
 
407
                               dir=os.path.dirname(output_dir))
 
408
    try:
 
409
        wt = WorkingTree.open(output_dir)
 
410
    except (NotBranchError, NoWorkingTree):
 
411
        wt = None
 
412
    if wt is None:
 
413
        old_basis = EmptyTree()
 
414
    else:
 
415
        old_basis = wt.basis_tree()
 
416
    try:
 
417
        if not fancy:
 
418
            print "not fancy"
405
419
        try:
406
 
            ancestors, old_revno = get_remaining_revisions(output_dir, version,
407
 
                                                           reuse_history_from)
408
 
        except NotBranchError, e:
409
 
            raise NotPreviousImport(e.path)
410
 
        if old_revno is None and len(ancestors) == 0:
411
 
            progress_bar.note('Version %s has no revisions.' % version)
412
 
            return
413
 
        if len(ancestors) == 0:
414
 
            last_revision = get_last_revision(Branch.open(output_dir))
415
 
            progress_bar.note('Tree is up-to-date with %s' % last_revision)
416
 
            return
417
 
 
418
 
        progress_bar.note("importing %s into %s" % (version, output_dir))
419
 
    
420
 
        tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
421
 
                                   dir=os.path.dirname(output_dir))
 
420
            for result in iter_import_version(output_dir, ancestors, tempdir,
 
421
                    progress_bar, fast=fast, verbose=verbose, dry_run=dry_run,
 
422
                    max_count=max_count, standalone=standalone):
 
423
                if fancy:
 
424
                    show_progress(progress_bar, result)
 
425
                else:
 
426
                    sys.stdout.write('.')
 
427
        finally:
 
428
            if fancy:
 
429
                progress_bar.finished()
 
430
            else:
 
431
                sys.stdout.write('\n')
 
432
 
 
433
        if dry_run:
 
434
            print 'Dry run, not modifying output_dir'
 
435
            return
 
436
 
 
437
        # Update the working tree of the branch
422
438
        try:
423
439
            wt = WorkingTree.open(output_dir)
424
 
        except (NotBranchError, NoWorkingTree):
 
440
        except NoWorkingTree:
425
441
            wt = None
426
 
        if wt is None:
427
 
            old_basis = EmptyTree()
428
 
        else:
429
 
            old_basis = wt.basis_tree()
430
 
        try:
431
 
            for result in iter_import_version(output_dir, ancestors, tempdir,
432
 
                    pb=progress_bar,
433
 
                    fast=fast, verbose=verbose, dry_run=dry_run,
434
 
                    max_count=max_count, standalone=standalone):
435
 
                show_progress(progress_bar, result)
436
 
            if dry_run:
437
 
                progress_bar.note('Dry run, not modifying output_dir')
438
 
                return
439
 
    
440
 
            # Update the working tree of the branch
441
 
            try:
442
 
                wt = WorkingTree.open(output_dir)
443
 
            except NoWorkingTree:
444
 
                wt = None
445
 
            if wt is not None:
446
 
                wt.set_last_revision(wt.branch.last_revision())
447
 
                merge_inner(wt.branch, wt.basis_tree(), old_basis, 
448
 
                            ignore_zero=True, this_tree=wt)
449
 
                wt.revert([])
450
 
    
451
 
        finally:
452
 
            
453
 
            progress_bar.note('Cleaning up')
454
 
            shutil.rmtree(tempdir)
455
 
        progress_bar.note("Import complete.")
 
442
        if wt is not None:
 
443
            wt.set_last_revision(wt.branch.last_revision())
 
444
            merge_inner(wt.branch, wt.basis_tree(), old_basis, 
 
445
                        ignore_zero=True, this_tree=wt)
 
446
            wt.revert([])
 
447
 
456
448
    finally:
457
 
        progress_bar.finished()
 
449
        printer('Cleaning up')
 
450
        shutil.rmtree(tempdir)
 
451
    printer("Import complete.")
458
452
            
459
453
class UserError(BzrCommandError):
460
454
    def __init__(self, message):
579
573
        if verbose:
580
574
            version = str(revision.version)
581
575
            if version != previous_version:
582
 
                pb.note('On version: %s' % version)
 
576
                clear_progress_bar()
 
577
                print '\rOn version: %s' % version
583
578
            yield Progress(str(revision.patchlevel), i, len(ancestors))
584
579
            previous_version = version
585
580
        else:
597
592
                    raise
598
593
                missing_ancestor = revision
599
594
                revdir = None
600
 
                pb.note("unable to access ancestor %s, making into a merge."
 
595
                print ("unable to access ancestor %s, making into a merge."
601
596
                       % missing_ancestor)
602
597
                continue
603
598
            target_tree = create_checkout_metadata(target_branch, revdir)
636
631
            for merged_rev in direct_merges:
637
632
                target_tree.add_pending_merge(revision_id(merged_rev))
638
633
            target_tree.set_inventory(baz_inv)
639
 
            commitobj = Commit(reporter=ImportCommitReporter())
 
634
            commitobj = Commit(reporter=ImportCommitReporter(pb))
640
635
            commitobj.commit(working_tree=target_tree,
641
636
                             message=log_message.decode('ascii', 'replace'), 
642
637
                             verbose=False, committer=log_creator,
733
728
    takes_args = ['to_location', 'from_branch?', 'reuse_history*']
734
729
    takes_options = ['verbose', 'max-count']
735
730
 
 
731
    def printer(self, name):
 
732
        print name
 
733
 
736
734
    def run(self, to_location, from_branch=None, fast=False, max_count=None,
737
735
            verbose=False, dry_run=False, reuse_history_list=[]):
738
736
        to_location = os.path.realpath(str(to_location))
744
742
                return 1
745
743
        if reuse_history_list is None:
746
744
            reuse_history_list = []
747
 
        import_version(to_location, from_branch, 
 
745
        import_version(to_location, from_branch, self.printer, 
748
746
                       max_count=max_count, 
749
747
                       reuse_history_from=reuse_history_list)
750
748
 
756
754
 
757
755
 
758
756
class cmd_baz_import(Command):
759
 
    """Import an Arch or Baz archive into a bzr repository.  <BZRTOOLS>
 
757
    """Import an Arch or Baz archive into bzr branches.  <BZRTOOLS>
760
758
 
761
759
    This command should be used on local archives (or mirrors) only.  It is
762
760
    quite slow on remote archives.
777
775
    takes_options = ['verbose', Option('prefixes', type=str,
778
776
                     help="Prefixes of branches to import, colon-separated")]
779
777
 
 
778
    def printer(self, name):
 
779
        print name
 
780
 
780
781
    def run(self, to_root_dir, from_archive, verbose=False,
781
782
            reuse_history_list=[], prefixes=None):
782
783
        if reuse_history_list is None:
786
787
            os.mkdir(to_root)
787
788
        if prefixes is not None:
788
789
            prefixes = prefixes.split(':')
789
 
        import_archive(to_root, from_archive, verbose,
 
790
        import_archive(to_root, from_archive, verbose, self.printer, 
790
791
                       reuse_history_list, prefixes=prefixes)
791
792
 
792
793
 
793
 
def import_archive(to_root, from_archive, verbose,
 
794
def import_archive(to_root, from_archive, verbose, printer,
794
795
                   reuse_history_from=[], standalone=False,
795
796
                   prefixes=None):
796
797
    def selected(version):
812
813
        except NoRepositoryPresent:
813
814
            raise BzrCommandError("Can't create repository at existing branch.")
814
815
    versions = list(pybaz.Archive(str(from_archive)).iter_versions())
815
 
    progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
 
816
#    progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
816
817
    try:
817
818
        for num, version in enumerate(versions):
818
 
            progress_bar.update("Branch", num, len(versions))
 
819
#            progress_bar.update("Branch", num, len(versions))
819
820
            if not selected(version):
820
821
                print "Skipping %s" % version
821
822
                continue
822
823
            target = os.path.join(to_root, map_namespace(version))
 
824
            printer("importing %s into %s" % (version, target))
823
825
            if not os.path.exists(os.path.dirname(target)):
824
826
                os.makedirs(os.path.dirname(target))
825
827
            try:
826
 
                import_version(target, version,
 
828
                import_version(target, version, printer,
827
829
                               reuse_history_from=reuse_history_from, 
828
830
                               standalone=standalone)
829
831
            except pybaz.errors.ExecProblem,e:
830
832
                if str(e).find('The requested revision cannot be built.') != -1:
831
 
                    progress_bar.note(
832
 
                        "Skipping version %s as it cannot be built due"
833
 
                        " to a missing parent archive." % version)
 
833
                    printer("Skipping version %s as it cannot be built due"
 
834
                            " to a missing parent archive." % version)
834
835
                else:
835
836
                    raise
836
837
            except UserError, e:
837
838
                if str(e).find('already exists, and the last revision ') != -1:
838
 
                    progress_bar.note(
839
 
                        "Skipping version %s as it has had commits made"
840
 
                        " since it was converted to bzr." % version)
 
839
                    printer("Skipping version %s as it has had commits made"
 
840
                            " since it was converted to bzr." % version)
841
841
                else:
842
842
                    raise
843
843
    finally:
844
 
        progress_bar.finished()
845
 
 
 
844
        pass
 
845
#        progress_bar.finished()
846
846
 
847
847
def map_namespace(a_version):
848
848
    a_version = pybaz.Version("%s" % a_version)
856
856
        return "%s/%s" % (category, branch)
857
857
    return "%s/%s/%s" % (category, version, branch)
858
858
 
859
 
 
860
859
def map_file_id(file_id):
861
860
    """Convert a baz file id to a bzr one."""
862
861
    return file_id.replace('%', '%25').replace('/', '%2f')