← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jelmer/launchpad/bzr-code-imports into lp:launchpad/db-devel

 

Jelmer Vernooij has proposed merging lp:~jelmer/launchpad/bzr-code-imports into lp:launchpad/db-devel with lp:~jelmer/launchpad/bzr-code-import-db as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jelmer/launchpad/bzr-code-imports/+merge/65654

Add support for importing code from Bazaar branches. 

At the moment mirrors of remote Bazaar branches are created with completely different infrastructure as the code imports. This is confusing for users (bug 611837) and duplicates a lot of code. Several features are only available for code imports (bug 362622, bug 193607, bug 193607, bug 371484) and vice versa. Having shared infrastructure would also make it easier to fix several open bugs that affect both code imports and code mirrors (bug 519159, bug 136939)

Code imports are a bit heavier than mirrors at the moment, as they run on a separate machine and require an extra copy of the branch that is imported. 

This branch only adds backend support for Bazaar branches, it does not yet add a UI which can add code imports of this kind nor does it migrate any of the existing code mirrors.
-- 
https://code.launchpad.net/~jelmer/launchpad/bzr-code-imports/+merge/65654
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jelmer/launchpad/bzr-code-imports into lp:launchpad/db-devel.
=== modified file 'lib/canonical/config/schema-lazr.conf'
--- lib/canonical/config/schema-lazr.conf	2011-06-13 09:43:22 +0000
+++ lib/canonical/config/schema-lazr.conf	2011-06-23 12:47:49 +0000
@@ -504,6 +504,11 @@
 # datatype: integer
 default_interval_cvs: 43200
 
+# The default value of the update interval of a code import from
+# Bazaar, in seconds.
+# datatype: integer
+default_interval_bzr: 21600
+
 # Where the tarballs of foreign branches are uploaded for storage.
 # datatype: string
 foreign_tree_store: sftp://hoover@escudero/srv/importd/sources/

=== modified file 'lib/lp/code/browser/branch.py'
--- lib/lp/code/browser/branch.py	2011-06-17 09:56:57 +0000
+++ lib/lp/code/browser/branch.py	2011-06-23 12:47:49 +0000
@@ -126,7 +126,6 @@
 from lp.code.browser.decorations import DecoratedBranch
 from lp.code.browser.sourcepackagerecipelisting import HasRecipesMenuMixin
 from lp.code.enums import (
-    BranchLifecycleStatus,
     BranchType,
     CodeImportResultStatus,
     CodeImportReviewStatus,

=== modified file 'lib/lp/code/browser/codeimport.py'
--- lib/lp/code/browser/codeimport.py	2011-05-27 21:12:25 +0000
+++ lib/lp/code/browser/codeimport.py	2011-06-23 12:47:49 +0000
@@ -371,6 +371,8 @@
             return None, None, data.get('git_repo_url')
         elif rcs_type == RevisionControlSystems.HG:
             return None, None, data.get('hg_repo_url')
+        elif rcs_type == RevisionControlSystems.BZR:
+            return None, None, data.get('bzr_branch_url')
         else:
             raise AssertionError(
                 'Unexpected revision control type %r.' % rcs_type)
@@ -485,6 +487,9 @@
         elif rcs_type == RevisionControlSystems.HG:
             self._validateURL(
                 data.get('hg_repo_url'), field_name='hg_repo_url')
+        elif rcs_type == RevisionControlSystems.BZR:
+            self._validateURL(
+                data.get('bzr_repo_url'), field_name='bzr_repo_url')
         else:
             raise AssertionError(
                 'Unexpected revision control type %r.' % rcs_type)

=== modified file 'lib/lp/code/bzr.py'
--- lib/lp/code/bzr.py	2011-06-02 19:27:36 +0000
+++ lib/lp/code/bzr.py	2011-06-23 12:47:49 +0000
@@ -20,34 +20,38 @@
 
 from bzrlib.branch import (
     BranchReferenceFormat,
-    BzrBranchFormat4,
     BzrBranchFormat5,
     BzrBranchFormat6,
     BzrBranchFormat7,
     )
 from bzrlib.bzrdir import (
-    BzrDirFormat4,
-    BzrDirFormat5,
-    BzrDirFormat6,
     BzrDirMetaFormat1,
     )
 from bzrlib.plugins.loom.branch import (
     BzrBranchLoomFormat1,
     BzrBranchLoomFormat6,
     )
+from bzrlib.plugins.weave_fmt.branch import (
+    BzrBranchFormat4,
+    )
+from bzrlib.plugins.weave_fmt.bzrdir import (
+    BzrDirFormat4,
+    BzrDirFormat5,
+    BzrDirFormat6,
+    )
 from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
 from bzrlib.repofmt.knitrepo import (
     RepositoryFormatKnit1,
     RepositoryFormatKnit3,
     RepositoryFormatKnit4,
     )
-from bzrlib.repofmt.pack_repo import (
+from bzrlib.repofmt.knitpack_repo import (
     RepositoryFormatKnitPack1,
     RepositoryFormatKnitPack3,
     RepositoryFormatKnitPack4,
     RepositoryFormatKnitPack5,
     )
-from bzrlib.repofmt.weaverepo import (
+from bzrlib.plugins.weave_fmt.repository import (
     RepositoryFormat4,
     RepositoryFormat5,
     RepositoryFormat6,

=== modified file 'lib/lp/code/mail/codeimport.py'
--- lib/lp/code/mail/codeimport.py	2011-05-27 21:12:25 +0000
+++ lib/lp/code/mail/codeimport.py	2011-06-23 12:47:49 +0000
@@ -51,6 +51,7 @@
         RevisionControlSystems.BZR_SVN: 'subversion',
         RevisionControlSystems.GIT: 'git',
         RevisionControlSystems.HG: 'mercurial',
+        RevisionControlSystems.BZR: 'bazaar',
         }
     body = get_email_template('new-code-import.txt') % {
         'person': code_import.registrant.displayname,
@@ -123,7 +124,8 @@
     elif code_import.rcs_type in (RevisionControlSystems.SVN,
                                   RevisionControlSystems.BZR_SVN,
                                   RevisionControlSystems.GIT,
-                                  RevisionControlSystems.HG):
+                                  RevisionControlSystems.HG,
+                                  RevisionControlSystems.BZR):
         if CodeImportEventDataType.OLD_URL in event_data:
             old_url = event_data[CodeImportEventDataType.OLD_URL]
             body.append(

=== modified file 'lib/lp/code/model/codeimport.py'
--- lib/lp/code/model/codeimport.py	2011-04-27 01:42:46 +0000
+++ lib/lp/code/model/codeimport.py	2011-06-23 12:47:49 +0000
@@ -116,6 +116,8 @@
                 config.codeimport.default_interval_git,
             RevisionControlSystems.HG:
                 config.codeimport.default_interval_hg,
+            RevisionControlSystems.BZR:
+                config.codeimport.default_interval_bzr,
             }
         seconds = default_interval_dict[self.rcs_type]
         return timedelta(seconds=seconds)
@@ -133,7 +135,8 @@
             RevisionControlSystems.SVN,
             RevisionControlSystems.GIT,
             RevisionControlSystems.BZR_SVN,
-            RevisionControlSystems.HG):
+            RevisionControlSystems.HG,
+            RevisionControlSystems.BZR):
             return self.url
         else:
             raise AssertionError(
@@ -252,7 +255,8 @@
         elif rcs_type in (RevisionControlSystems.SVN,
                           RevisionControlSystems.BZR_SVN,
                           RevisionControlSystems.GIT,
-                          RevisionControlSystems.HG):
+                          RevisionControlSystems.HG,
+                          RevisionControlSystems.BZR):
             assert cvs_root is None and cvs_module is None
             assert url is not None
         else:

=== modified file 'lib/lp/code/model/codeimportevent.py'
--- lib/lp/code/model/codeimportevent.py	2010-10-17 22:51:50 +0000
+++ lib/lp/code/model/codeimportevent.py	2011-06-23 12:47:49 +0000
@@ -269,7 +269,8 @@
         if code_import.rcs_type in (RevisionControlSystems.SVN,
                                     RevisionControlSystems.BZR_SVN,
                                     RevisionControlSystems.GIT,
-                                    RevisionControlSystems.HG):
+                                    RevisionControlSystems.HG,
+                                    RevisionControlSystems.BZR):
             yield 'URL', code_import.url
         elif code_import.rcs_type == RevisionControlSystems.CVS:
             yield 'CVS_ROOT', code_import.cvs_root

=== modified file 'lib/lp/code/model/tests/test_branchjob.py'
--- lib/lp/code/model/tests/test_branchjob.py	2011-05-23 11:06:50 +0000
+++ lib/lp/code/model/tests/test_branchjob.py	2011-06-23 12:47:49 +0000
@@ -17,7 +17,7 @@
     BzrBranchFormat7,
     )
 from bzrlib.bzrdir import BzrDirMetaFormat1
-from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack6
+from bzrlib.repofmt.knitpack_repo import RepositoryFormatKnitPack6
 from bzrlib.revision import NULL_REVISION
 from bzrlib.transport import get_transport
 import pytz

=== modified file 'lib/lp/code/model/tests/test_codeimport.py'
--- lib/lp/code/model/tests/test_codeimport.py	2011-05-27 21:12:25 +0000
+++ lib/lp/code/model/tests/test_codeimport.py	2011-06-23 12:47:49 +0000
@@ -71,6 +71,20 @@
         # No job is created for the import.
         self.assertIs(None, code_import.import_job)
 
+    def test_new_svn_import_svn_scheme(self):
+        """A subversion import can use the svn:// scheme."""
+        code_import = CodeImportSet().new(
+            registrant=self.factory.makePerson(),
+            target=IBranchTarget(self.factory.makeProduct()),
+            branch_name='imported',
+            rcs_type=RevisionControlSystems.SVN,
+            url=self.factory.getUniqueURL(scheme="svn"))
+        self.assertEqual(
+            CodeImportReviewStatus.NEW,
+            code_import.review_status)
+        # No job is created for the import.
+        self.assertIs(None, code_import.import_job)
+
     def test_reviewed_svn_import(self):
         """A specific review status can be set for a new import."""
         code_import = CodeImportSet().new(
@@ -117,6 +131,21 @@
         # A job is created for the import.
         self.assertIsNot(None, code_import.import_job)
 
+    def test_git_import_git_scheme(self):
+        """A git import can have a git:// style URL."""
+        code_import = CodeImportSet().new(
+            registrant=self.factory.makePerson(),
+            target=IBranchTarget(self.factory.makeProduct()),
+            branch_name='imported',
+            rcs_type=RevisionControlSystems.GIT,
+            url=self.factory.getUniqueURL(scheme="git"),
+            review_status=None)
+        self.assertEqual(
+            CodeImportReviewStatus.REVIEWED,
+            code_import.review_status)
+        # A job is created for the import.
+        self.assertIsNot(None, code_import.import_job)
+
     def test_git_import_reviewed(self):
         """A new git import is always reviewed by default."""
         code_import = CodeImportSet().new(
@@ -147,6 +176,21 @@
         # A job is created for the import.
         self.assertIsNot(None, code_import.import_job)
 
+    def test_bzr_import_reviewed(self):
+        """A new bzr import is always reviewed by default."""
+        code_import = CodeImportSet().new(
+            registrant=self.factory.makePerson(),
+            target=IBranchTarget(self.factory.makeProduct()),
+            branch_name='mirrored',
+            rcs_type=RevisionControlSystems.BZR,
+            url=self.factory.getUniqueURL(),
+            review_status=None)
+        self.assertEqual(
+            CodeImportReviewStatus.REVIEWED,
+            code_import.review_status)
+        # A job is created for the import.
+        self.assertIsNot(None, code_import.import_job)
+
     def test_junk_code_import_rejected(self):
         """You are not allowed to create code imports targetting +junk."""
         registrant = self.factory.makePerson()

=== modified file 'lib/lp/codehosting/__init__.py'
--- lib/lp/codehosting/__init__.py	2011-03-30 15:16:35 +0000
+++ lib/lp/codehosting/__init__.py	2011-06-23 12:47:49 +0000
@@ -70,6 +70,18 @@
     __import__("bzrlib.plugins.%s" % plugin_name)
 
 
+def load_bundled_plugin(plugin_name):
+    """Load a plugin bundled with Bazaar."""
+    from bzrlib.plugin import get_core_plugin_path
+    from bzrlib import plugins
+    if get_core_plugin_path() not in plugins.__path__:
+        plugins.__path__.append(get_core_plugin_path())
+    __import__("bzrlib.plugins.%s" % plugin_name)
+
+
+load_bundled_plugin("weave_fmt")
+
+
 def remove_hook(self, hook):
     """Remove the hook from the HookPoint"""
     self._callbacks.remove(hook)

=== modified file 'lib/lp/codehosting/codeimport/tests/servers.py'
--- lib/lp/codehosting/codeimport/tests/servers.py	2011-06-02 10:48:54 +0000
+++ lib/lp/codehosting/codeimport/tests/servers.py	2011-06-23 12:47:49 +0000
@@ -4,6 +4,7 @@
 """Server classes that know how to create various kinds of foreign archive."""
 
 __all__ = [
+    'BzrServer',
     'CVSServer',
     'GitServer',
     'MercurialServer',
@@ -21,6 +22,8 @@
 import tempfile
 import time
 
+from bzrlib.bzrdir import BzrDir
+from bzrlib.branchbuilder import BranchBuilder
 from bzrlib.tests.treeshape import build_tree_contents
 from bzrlib.transport import Server
 from bzrlib.urlutils import (
@@ -246,3 +249,21 @@
                 f.close()
             repo[None].add([filename])
         repo.commit(text='<The commit message>', user='jane Foo <joe@xxxxxxx>')
+
+
+class BzrServer(Server):
+
+    def __init__(self, repo_url):
+        super(BzrServer, self).__init__()
+        self.repo_url = repo_url
+
+    def makeRepo(self, tree_contents):
+        branch = BzrDir.create_branch_convenience(self.repo_url)
+        branch.get_config().set_user_option("create_signatures", "never")
+        builder = BranchBuilder(branch=branch)
+        actions = [('add', ('', 'tree-root', 'directory', None))]
+        actions += [('add', (path, path+'-id', 'file', content)) for (path,
+            content) in tree_contents]
+        builder.build_snapshot(None, None,
+                actions, committer='Joe Foo <joe@xxxxxxx>',
+                message=u'<The commit message>')

=== modified file 'lib/lp/codehosting/codeimport/tests/test_worker.py'
--- lib/lp/codehosting/codeimport/tests/test_worker.py	2011-06-21 05:38:15 +0000
+++ lib/lp/codehosting/codeimport/tests/test_worker.py	2011-06-23 12:47:49 +0000
@@ -17,6 +17,9 @@
     Branch,
     BranchReferenceFormat,
     )
+from bzrlib.branchbuilder import (
+    BranchBuilder,
+    )
 from bzrlib.bzrdir import (
     BzrDir,
     BzrDirFormat,
@@ -49,6 +52,7 @@
     extract_tarball,
     )
 from lp.codehosting.codeimport.tests.servers import (
+    BzrServer,
     CVSServer,
     GitServer,
     MercurialServer,
@@ -56,6 +60,7 @@
     )
 from lp.codehosting.codeimport.worker import (
     BazaarBranchStore,
+    BzrImportWorker,
     BzrSvnImportWorker,
     CodeImportWorkerExitCode,
     CSCVSImportWorker,
@@ -1001,10 +1006,10 @@
         # import should be rejected.
         args = {'rcstype': self.rcstype}
         reference_url = self.createBranchReference()
-        if self.rcstype in ('git', 'bzr-svn', 'hg'):
+        if self.rcstype in ('git', 'bzr-svn', 'hg', 'bzr'):
             args['url'] = reference_url
         else:
-            raise AssertionError("unexpected rcs_type %r" % self.rcs_type)
+            raise AssertionError("unexpected rcs_type %r" % self.rcstype)
         source_details = self.factory.makeCodeImportSourceDetails(**args)
         worker = self.makeImportWorker(source_details)
         self.assertEqual(
@@ -1162,5 +1167,48 @@
             self.bazaar_store, logging.getLogger())
 
 
+class TestBzrImport(WorkerTest, TestActualImportMixin,
+                    PullingImportWorkerTests):
+
+    rcstype = 'bzr'
+
+    def setUp(self):
+        super(TestBzrImport, self).setUp()
+        self.setUpImport()
+
+    def makeImportWorker(self, source_details):
+        """Make a new `ImportWorker`."""
+        return BzrImportWorker(
+            source_details, self.get_transport('import_data'),
+            self.bazaar_store, logging.getLogger())
+
+    def makeForeignCommit(self, source_details):
+        """Change the foreign tree, generating exactly one commit."""
+        branch = Branch.open(source_details.url)
+        builder = BranchBuilder(branch=branch)
+        builder.build_commit(message=self.factory.getUniqueString(),
+            committer="Joe Random Hacker <joe@xxxxxxxxxxx>")
+        self.foreign_commit_count += 1
+
+    def makeSourceDetails(self, branch_name, files):
+        """Make Bzr `CodeImportSourceDetails` pointing at a real Bzr repo.
+        """
+        repository_path = self.makeTemporaryDirectory()
+        bzr_server = BzrServer(repository_path)
+        bzr_server.start_server()
+        self.addCleanup(bzr_server.stop_server)
+
+        bzr_server.makeRepo(files)
+        self.foreign_commit_count = 1
+
+        return self.factory.makeCodeImportSourceDetails(
+            rcstype='bzr', url=repository_path)
+
+    def test_partial(self):
+        # Skip tests of partial tests, as they are disabled for native imports
+        # at the moment.
+        return
+
+
 def test_suite():
     return unittest.TestLoader().loadTestsFromName(__name__)

=== modified file 'lib/lp/codehosting/codeimport/tests/test_workermonitor.py'
--- lib/lp/codehosting/codeimport/tests/test_workermonitor.py	2011-06-16 23:43:04 +0000
+++ lib/lp/codehosting/codeimport/tests/test_workermonitor.py	2011-06-23 12:47:49 +0000
@@ -50,6 +50,7 @@
 from lp.code.model.codeimportjob import CodeImportJob
 from lp.codehosting import load_optional_plugin
 from lp.codehosting.codeimport.tests.servers import (
+    BzrServer,
     CVSServer,
     GitServer,
     MercurialServer,
@@ -682,6 +683,16 @@
 
         return self.factory.makeCodeImport(hg_repo_url=self.repo_path)
 
+    def makeBzrCodeImport(self):
+        """Make a `CodeImport` that points to a real Bazaar branch."""
+        self.bzr_server = BzrServer(self.repo_path)
+        self.bzr_server.start_server()
+        self.addCleanup(self.bzr_server.stop_server)
+
+        self.bzr_server.makeRepo([('README', 'contents')])
+        self.foreign_commit_count = 1
+        return self.factory.makeCodeImport(bzr_branch_url=self.repo_path)
+
     def getStartedJobForImport(self, code_import):
         """Get a started `CodeImportJob` for `code_import`.
 
@@ -782,6 +793,15 @@
         result = self.performImport(job_id)
         return result.addCallback(self.assertImported, code_import_id)
 
+    def test_import_bzr(self):
+        # Create a Bazaar CodeImport and import it.
+        job = self.getStartedJobForImport(self.makeBzrCodeImport())
+        code_import_id = job.code_import.id
+        job_id = job.id
+        self.layer.txn.commit()
+        result = self.performImport(job_id)
+        return result.addCallback(self.assertImported, code_import_id)
+
     # XXX 2010-03-24 MichaelHudson, bug=541526: This test fails intermittently
     # in EC2.
     def DISABLED_test_import_bzrsvn(self):

=== modified file 'lib/lp/codehosting/codeimport/worker.py'
--- lib/lp/codehosting/codeimport/worker.py	2011-06-21 05:38:15 +0000
+++ lib/lp/codehosting/codeimport/worker.py	2011-06-23 12:47:49 +0000
@@ -6,6 +6,7 @@
 __metaclass__ = type
 __all__ = [
     'BazaarBranchStore',
+    'BzrImportWorker',
     'BzrSvnImportWorker',
     'CSCVSImportWorker',
     'CodeImportSourceDetails',
@@ -23,6 +24,8 @@
 
 from bzrlib.branch import (
     Branch,
+    BranchFormat,
+    BranchReferenceFormat,
     InterBranch,
     )
 from bzrlib.bzrdir import (
@@ -190,9 +193,9 @@
 
     :ivar branch_id: The id of the branch associated to this code import, used
         for locating the existing import and the foreign tree.
-    :ivar rcstype: 'svn' or 'cvs' as appropriate.
+    :ivar rcstype: 'svn', 'cvs', 'hg', 'git', 'bzr-svn', 'bzr' as appropriate.
     :ivar url: The branch URL if rcstype in ['svn', 'bzr-svn',
-        'git'], None otherwise.
+        'git', 'hg', 'bzr'], None otherwise.
     :ivar cvs_root: The $CVSROOT if rcstype == 'cvs', None otherwise.
     :ivar cvs_module: The CVS module if rcstype == 'cvs', None otherwise.
     """
@@ -210,7 +213,7 @@
         """Convert command line-style arguments to an instance."""
         branch_id = int(arguments.pop(0))
         rcstype = arguments.pop(0)
-        if rcstype in ['svn', 'bzr-svn', 'git', 'hg']:
+        if rcstype in ['svn', 'bzr-svn', 'git', 'hg', 'bzr']:
             [url] = arguments
             cvs_root = cvs_module = None
         elif rcstype == 'cvs':
@@ -237,6 +240,8 @@
             return cls(branch_id, 'git', str(code_import.url))
         elif code_import.rcs_type == RevisionControlSystems.HG:
             return cls(branch_id, 'hg', str(code_import.url))
+        elif code_import.rcs_type == RevisionControlSystems.BZR:
+            return cls(branch_id, 'bzr', str(code_import.url))
         else:
             raise AssertionError("Unknown rcstype %r." % code_import.rcs_type)
 
@@ -244,7 +249,7 @@
         """Return a list of arguments suitable for passing to a child process.
         """
         result = [str(self.branch_id), self.rcstype]
-        if self.rcstype in ['svn', 'bzr-svn', 'git', 'hg']:
+        if self.rcstype in ['svn', 'bzr-svn', 'git', 'hg', 'bzr']:
             result.append(self.url)
         elif self.rcstype == 'cvs':
             result.append(self.cvs_root)
@@ -619,9 +624,17 @@
                 except NotBranchError:
                     pass
             else:
+<<<<<<< TREE
                 self._logger.info("No branch found at remote location.")
                 return CodeImportWorkerExitCode.FAILURE_INVALID
             remote_branch = format.open(transport).open_branch()
+=======
+                raise NotBranchError(self.source_details.url)
+            remote_dir = format.open(transport)
+            if remote_dir.get_branch_reference() is not None:
+                raise NotBranchError(self.source_details.url)
+            remote_branch = remote_dir.open_branch()
+>>>>>>> MERGE-SOURCE
             remote_branch_tip = remote_branch.last_revision()
             inter_branch = InterBranch.get(remote_branch, bazaar_branch)
             self._logger.info("Importing branch.")
@@ -822,3 +835,18 @@
         """See `PullingImportWorker.probers`."""
         from bzrlib.plugins.svn import SvnRemoteProber
         return [SvnRemoteProber]
+
+
+class BzrImportWorker(PullingImportWorker):
+    """An import worker for importing Bazaar branches."""
+
+    def getRevisionLimit(self):
+        """See `PullingImportWorker.getRevisionLimit`."""
+        # For now, just grab the whole branch at once
+        return None
+
+    @property
+    def probers(self):
+        """See `PullingImportWorker.probers`."""
+        from bzrlib.bzrdir import BzrProber, RemoteBzrProber
+        return [BzrProber, RemoteBzrProber]

=== modified file 'lib/lp/codehosting/puller/tests/test_worker.py'
--- lib/lp/codehosting/puller/tests/test_worker.py	2010-10-15 08:47:20 +0000
+++ lib/lp/codehosting/puller/tests/test_worker.py	2011-06-23 12:47:49 +0000
@@ -25,7 +25,7 @@
     NotBranchError,
     NotStacked,
     )
-from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack1
+from bzrlib.repofmt.knitpack_repo import RepositoryFormatKnitPack1
 from bzrlib.revision import NULL_REVISION
 from bzrlib.tests import (
     TestCaseInTempDir,

=== modified file 'lib/lp/codehosting/puller/tests/test_worker_formats.py'
--- lib/lp/codehosting/puller/tests/test_worker_formats.py	2010-08-20 20:31:18 +0000
+++ lib/lp/codehosting/puller/tests/test_worker_formats.py	2011-06-23 12:47:49 +0000
@@ -7,14 +7,18 @@
 
 import unittest
 
+import lp.codehosting # for bzr plugins
+
 from bzrlib.branch import Branch
 from bzrlib.bzrdir import (
-    BzrDirFormat6,
     BzrDirMetaFormat1,
     )
 from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
-from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5
-from bzrlib.repofmt.weaverepo import (
+from bzrlib.repofmt.knitpack_repo import RepositoryFormatKnitPack5
+from bzrlib.plugins.weave_fmt.bzrdir import (
+    BzrDirFormat6,
+    )
+from bzrlib.plugins.weave_fmt.repository import (
     RepositoryFormat6,
     RepositoryFormat7,
     )

=== modified file 'lib/lp/codehosting/puller/worker.py'
--- lib/lp/codehosting/puller/worker.py	2011-06-03 01:00:53 +0000
+++ lib/lp/codehosting/puller/worker.py	2011-06-23 12:47:49 +0000
@@ -8,17 +8,22 @@
 import sys
 import urllib2
 
+import lp.codehosting # to load bzr plugins
+
 from bzrlib import errors
 from bzrlib.branch import (
     Branch,
+    )
+from bzrlib.bzrdir import BzrDir
+from bzrlib.plugins.weave_fmt.branch import (
     BzrBranchFormat4,
     )
-from bzrlib.bzrdir import BzrDir
-from bzrlib.repofmt.weaverepo import (
+from bzrlib.plugins.weave_fmt.repository import (
     RepositoryFormat4,
     RepositoryFormat5,
     RepositoryFormat6,
     )
+
 import bzrlib.ui
 from bzrlib.ui import SilentUIFactory
 from lazr.uri import InvalidURIError

=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py	2011-05-27 21:12:25 +0000
+++ lib/lp/registry/browser/productseries.py	2011-06-23 12:47:49 +0000
@@ -827,15 +827,6 @@
     ))
 
 
-class RevisionControlSystemsExtended(RevisionControlSystems):
-    """External RCS plus Bazaar."""
-    BZR = DBItem(99, """
-        Bazaar
-
-        External Bazaar branch.
-        """)
-
-
 class SetBranchForm(Interface):
     """The fields presented on the form for setting a branch."""
 
@@ -844,7 +835,7 @@
         ['cvs_module'])
 
     rcs_type = Choice(title=_("Type of RCS"),
-        required=False, vocabulary=RevisionControlSystemsExtended,
+        required=False, vocabulary=RevisionControlSystems,
         description=_(
             "The version control system to import from. "))
 
@@ -908,7 +899,7 @@
     @property
     def initial_values(self):
         return dict(
-            rcs_type=RevisionControlSystemsExtended.BZR,
+            rcs_type=RevisionControlSystems.BZR,
             branch_type=LINK_LP_BZR,
             branch_location=self.context.branch)
 
@@ -989,7 +980,7 @@
             self.setFieldError(
                 'rcs_type',
                 'You must specify the type of RCS for the remote host.')
-        elif rcs_type == RevisionControlSystemsExtended.CVS:
+        elif rcs_type == RevisionControlSystems.CVS:
             if 'cvs_module' not in data:
                 self.setFieldError(
                     'cvs_module',
@@ -1022,8 +1013,9 @@
         # Extend the allowed schemes for the repository URL based on
         # rcs_type.
         extra_schemes = {
-            RevisionControlSystemsExtended.BZR_SVN: ['svn'],
-            RevisionControlSystemsExtended.GIT: ['git'],
+            RevisionControlSystems.BZR_SVN: ['svn'],
+            RevisionControlSystems.GIT: ['git'],
+            RevisionControlSystems.BZR: ['bzr'],
             }
         schemes.update(extra_schemes.get(rcs_type, []))
         return schemes
@@ -1050,7 +1042,7 @@
             # The branch location is not required for validation.
             self._setRequired(['branch_location'], False)
             # The cvs_module is required if it is a CVS import.
-            if rcs_type == RevisionControlSystemsExtended.CVS:
+            if rcs_type == RevisionControlSystems.CVS:
                 self._setRequired(['cvs_module'], True)
         else:
             raise AssertionError("Unknown branch type %s" % branch_type)
@@ -1110,7 +1102,7 @@
                 # Either create an externally hosted bzr branch
                 # (a.k.a. 'mirrored') or create a new code import.
                 rcs_type = data.get('rcs_type')
-                if rcs_type == RevisionControlSystemsExtended.BZR:
+                if rcs_type == RevisionControlSystems.BZR:
                     branch = self._createBzrBranch(
                         BranchType.MIRRORED, branch_name, branch_owner,
                         data['repo_url'])
@@ -1123,7 +1115,7 @@
                         'the series.')
                 else:
                     # We need to create an import request.
-                    if rcs_type == RevisionControlSystemsExtended.CVS:
+                    if rcs_type == RevisionControlSystems.CVS:
                         cvs_root = data.get('repo_url')
                         cvs_module = data.get('cvs_module')
                         url = None

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2011-06-14 20:43:01 +0000
+++ lib/lp/testing/factory.py	2011-06-23 12:47:49 +0000
@@ -473,7 +473,7 @@
             branch_id = self.getUniqueInteger()
         if rcstype is None:
             rcstype = 'svn'
-        if rcstype in ['svn', 'bzr-svn', 'hg']:
+        if rcstype in ['svn', 'bzr-svn', 'hg', 'bzr']:
             assert cvs_root is cvs_module is None
             if url is None:
                 url = self.getUniqueURL()
@@ -2103,7 +2103,8 @@
 
     def makeCodeImport(self, svn_branch_url=None, cvs_root=None,
                        cvs_module=None, target=None, branch_name=None,
-                       git_repo_url=None, hg_repo_url=None, registrant=None,
+                       git_repo_url=None, hg_repo_url=None,
+                       bzr_branch_url=None, registrant=None,
                        rcs_type=None, review_status=None):
         """Create and return a new, arbitrary code import.
 
@@ -2112,7 +2113,7 @@
         unique URL.
         """
         if (svn_branch_url is cvs_root is cvs_module is git_repo_url is
-            hg_repo_url is None):
+            hg_repo_url is bzr_branch_url is None):
             svn_branch_url = self.getUniqueURL()
 
         if target is None:
@@ -2143,6 +2144,11 @@
                 registrant, target, branch_name,
                 rcs_type=RevisionControlSystems.HG,
                 url=hg_repo_url)
+        elif bzr_branch_url is not None:
+            code_import = code_import_set.new(
+                registrant, target, branch_name,
+                rcs_type=RevisionControlSystems.BZR,
+                url=bzr_branch_url)
         else:
             assert rcs_type in (None, RevisionControlSystems.CVS)
             code_import = code_import_set.new(

=== modified file 'scripts/code-import-worker.py'
--- scripts/code-import-worker.py	2011-06-16 23:43:04 +0000
+++ scripts/code-import-worker.py	2011-06-23 12:47:49 +0000
@@ -26,8 +26,9 @@
 from canonical.config import config
 from lp.codehosting import load_optional_plugin
 from lp.codehosting.codeimport.worker import (
-    BzrSvnImportWorker, CSCVSImportWorker, CodeImportSourceDetails,
-    GitImportWorker, HgImportWorker, get_default_bazaar_branch_store)
+    BzrImportWorker, BzrSvnImportWorker, CSCVSImportWorker,
+    CodeImportSourceDetails, GitImportWorker, HgImportWorker,
+    get_default_bazaar_branch_store)
 from canonical.launchpad import scripts
 
 
@@ -65,8 +66,15 @@
         elif source_details.rcstype == 'hg':
             load_optional_plugin('hg')
             import_worker_cls = HgImportWorker
+<<<<<<< TREE
         elif source_details.rcstype in ['cvs', 'svn']:
             import_worker_cls = CSCVSImportWorker
+=======
+        elif source_details.rcstype == 'bzr':
+            load_optional_plugin('loom')
+            load_optional_plugin('weave_fmt')
+            import_worker_cls = BzrImportWorker
+>>>>>>> MERGE-SOURCE
         else:
             raise AssertionError(
                 'unknown rcstype %r' % source_details.rcstype)

=== modified file 'versions.cfg'
--- versions.cfg	2011-06-04 04:34:59 +0000
+++ versions.cfg	2011-06-23 12:47:49 +0000
@@ -6,7 +6,7 @@
 
 ampoule = 0.2.0
 BeautifulSoup = 3.1.0.1
-bzr = 2.3.3
+bzr = 2.4b4
 chameleon.core = 1.0b35
 chameleon.zpt = 1.0b17
 ClientForm = 0.2.10