← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~thumper/launchpad/branch-target-adapters into lp:launchpad/devel

 

Tim Penhey has proposed merging lp:~thumper/launchpad/branch-target-adapters into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)


As part of the on-going work to make the smart server understand the short lp: style urls for private branches, I need some extra branch target adapters.  This branch adds the adapters for IProductSeries -> IBranchTarget, and IDistributionSourcePackage -> IBranchTarget.

tests:
  test_.*_adapter

-- 
https://code.launchpad.net/~thumper/launchpad/branch-target-adapters/+merge/31698
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~thumper/launchpad/branch-target-adapters into lp:launchpad/devel.
=== modified file 'lib/canonical/launchpad/browser/launchpad.py'
--- lib/canonical/launchpad/browser/launchpad.py	2010-08-02 01:37:09 +0000
+++ lib/canonical/launchpad/browser/launchpad.py	2010-08-03 21:32:54 +0000
@@ -80,12 +80,11 @@
 from lp.bugs.interfaces.bug import IBugSet
 from lp.bugs.interfaces.malone import IMaloneApplication
 from lp.buildmaster.interfaces.builder import IBuilderSet
+from lp.code.errors import (
+    CannotHaveLinkedBranch, InvalidNamespace, NoLinkedBranch)
 from lp.code.interfaces.branch import IBranchSet
 from lp.code.interfaces.branchlookup import IBranchLookup
-from lp.code.interfaces.branchnamespace import InvalidNamespace
 from lp.code.interfaces.codeimport import ICodeImportSet
-from lp.code.interfaces.linkedbranch import (
-    CannotHaveLinkedBranch, NoLinkedBranch)
 from lp.hardwaredb.interfaces.hwdb import IHWDBApplication
 from lp.registry.interfaces.codeofconduct import ICodeOfConductSet
 from lp.registry.interfaces.distribution import IDistributionSet

=== modified file 'lib/lp/code/configure.zcml'
--- lib/lp/code/configure.zcml	2010-07-25 12:55:56 +0000
+++ lib/lp/code/configure.zcml	2010-08-03 21:32:54 +0000
@@ -606,6 +606,11 @@
       for="lp.registry.interfaces.sourcepackage.ISourcePackage"
       provides="lp.code.interfaces.branchtarget.IBranchTarget"
       factory="lp.code.model.branchtarget.PackageBranchTarget"/>
+  <adapter
+      for="lp.registry.interfaces.distributionsourcepackage.IDistributionSourcePackage"
+      provides="lp.code.interfaces.branchtarget.IBranchTarget"
+      factory="lp.code.model.branchtarget.distribution_sourcepackage_to_branch_target"/>
+
   <class class="lp.code.model.branchtarget.PersonBranchTarget">
     <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>
   </class>
@@ -613,6 +618,7 @@
       for="lp.registry.interfaces.person.IPerson"
       provides="lp.code.interfaces.branchtarget.IBranchTarget"
       factory="lp.code.model.branchtarget.PersonBranchTarget"/>
+
   <class class="lp.code.model.branchtarget.ProductBranchTarget">
     <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>
   </class>
@@ -621,6 +627,10 @@
       provides="lp.code.interfaces.branchtarget.IBranchTarget"
       factory="lp.code.model.branchtarget.ProductBranchTarget"/>
   <adapter
+      for="lp.registry.interfaces.productseries.IProductSeries"
+      provides="lp.code.interfaces.branchtarget.IBranchTarget"
+      factory="lp.code.model.branchtarget.product_series_to_branch_target"/>
+  <adapter
       for="lp.code.interfaces.branchtarget.IBranchTarget"
       provides="canonical.launchpad.webapp.interfaces.ICanonicalUrlData"
       factory="lp.code.model.branchtarget.get_canonical_url_data_for_target"/>

=== modified file 'lib/lp/code/errors.py'
--- lib/lp/code/errors.py	2010-08-02 02:51:42 +0000
+++ lib/lp/code/errors.py	2010-08-03 21:32:54 +0000
@@ -20,12 +20,15 @@
     'BuildNotAllowedForDistro',
     'BranchMergeProposalExists',
     'CannotDeleteBranch',
+    'CannotHaveLinkedBranch',
     'CodeImportAlreadyRequested',
     'CodeImportAlreadyRunning',
     'CodeImportNotInReviewedState',
     'ClaimReviewFailed',
     'ForbiddenInstruction',
     'InvalidBranchMergeProposal',
+    'InvalidNamespace',
+    'NoLinkedBranch',
     'NoSuchBranch',
     'PrivateBranchRecipe',
     'ReviewNotPending',
@@ -131,10 +134,13 @@
     """The branch cannot be made private."""
 
 
-class NoSuchBranch(NameLookupFailed):
-    """Raised when we try to load a branch that does not exist."""
+class CannotHaveLinkedBranch(Exception):
+    """Raised when we try to get the linked branch for a thing that can't."""
 
-    _message_prefix = "No such branch"
+    def __init__(self, component):
+        self.component = component
+        Exception.__init__(
+            self, "%r cannot have linked branches." % (component,))
 
 
 class ClaimReviewFailed(Exception):
@@ -154,6 +160,33 @@
     webservice_error(400) #Bad request.
 
 
+class InvalidNamespace(Exception):
+    """Raised when someone tries to lookup a namespace with a bad name.
+
+    By 'bad', we mean that the name is unparseable. It might be too short, too
+    long or malformed in some other way.
+    """
+
+    def __init__(self, name):
+        self.name = name
+        Exception.__init__(
+            self, "Cannot understand namespace name: '%s'" % (name,))
+
+
+class NoLinkedBranch(Exception):
+    """Raised when there's no linked branch for a thing."""
+
+    def __init__(self, component):
+        self.component = component
+        Exception.__init__(self, "%r has no linked branch." % (component,))
+
+
+class NoSuchBranch(NameLookupFailed):
+    """Raised when we try to load a branch that does not exist."""
+
+    _message_prefix = "No such branch"
+
+
 class PrivateBranchRecipe(Exception):
 
     def __init__(self, branch):

=== modified file 'lib/lp/code/interfaces/branchnamespace.py'
--- lib/lp/code/interfaces/branchnamespace.py	2009-08-13 15:12:16 +0000
+++ lib/lp/code/interfaces/branchnamespace.py	2010-08-03 21:32:54 +0000
@@ -11,7 +11,6 @@
     'IBranchNamespace',
     'IBranchNamespacePolicy',
     'IBranchNamespaceSet',
-    'InvalidNamespace',
     'lookup_branch_namespace',
     'split_unique_name',
     ]
@@ -281,19 +280,6 @@
         """
 
 
-class InvalidNamespace(Exception):
-    """Raised when someone tries to lookup a namespace with a bad name.
-
-    By 'bad', we mean that the name is unparseable. It might be too short, too
-    long or malformed in some other way.
-    """
-
-    def __init__(self, name):
-        self.name = name
-        Exception.__init__(
-            self, "Cannot understand namespace name: '%s'" % (name,))
-
-
 def get_branch_namespace(person, product=None, distroseries=None,
                          sourcepackagename=None):
     return getUtility(IBranchNamespaceSet).get(

=== modified file 'lib/lp/code/interfaces/linkedbranch.py'
--- lib/lp/code/interfaces/linkedbranch.py	2010-04-07 20:43:03 +0000
+++ lib/lp/code/interfaces/linkedbranch.py	2010-08-03 21:32:54 +0000
@@ -12,15 +12,15 @@
 
 __metaclass__ = type
 __all__ = [
-    'CannotHaveLinkedBranch',
     'get_linked_branch',
     'ICanHasLinkedBranch',
-    'NoLinkedBranch',
     ]
 
 from zope.interface import Attribute, Interface
 from zope.security.proxy import isinstance as zope_isinstance
 
+from lp.code.errors import CannotHaveLinkedBranch, NoLinkedBranch
+
 
 class ICanHasLinkedBranch(Interface):
     """Something that has a linked branch."""
@@ -41,23 +41,6 @@
         """
 
 
-class CannotHaveLinkedBranch(Exception):
-    """Raised when we try to get the linked branch for a thing that can't."""
-
-    def __init__(self, component):
-        self.component = component
-        Exception.__init__(
-            self, "%r cannot have linked branches." % (component,))
-
-
-class NoLinkedBranch(Exception):
-    """Raised when there's no linked branch for a thing."""
-
-    def __init__(self, component):
-        self.component = component
-        Exception.__init__(self, "%r has no linked branch." % (component,))
-
-
 def get_linked_branch(provided):
     """Get the linked branch for 'provided', whatever that is.
 

=== modified file 'lib/lp/code/model/branchlookup.py'
--- lib/lp/code/model/branchlookup.py	2010-08-02 02:36:32 +0000
+++ lib/lp/code/model/branchlookup.py	2010-08-03 21:32:54 +0000
@@ -21,13 +21,12 @@
 from lp.registry.model.person import Person
 from lp.registry.model.product import Product
 from lp.registry.model.sourcepackagename import SourcePackageName
-from lp.code.errors import NoSuchBranch
+from lp.code.errors import (
+    CannotHaveLinkedBranch, InvalidNamespace, NoLinkedBranch, NoSuchBranch)
 from lp.code.interfaces.branchlookup import (
     IBranchLookup, ILinkedBranchTraversable, ILinkedBranchTraverser)
-from lp.code.interfaces.branchnamespace import (
-    IBranchNamespaceSet, InvalidNamespace)
-from lp.code.interfaces.linkedbranch import (
-    CannotHaveLinkedBranch, get_linked_branch, NoLinkedBranch)
+from lp.code.interfaces.branchnamespace import IBranchNamespaceSet
+from lp.code.interfaces.linkedbranch import get_linked_branch
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distroseries import (
     IDistroSeries, IDistroSeriesSet, NoSuchDistroSeries)

=== modified file 'lib/lp/code/model/branchnamespace.py'
--- lib/lp/code/model/branchnamespace.py	2010-08-02 02:36:32 +0000
+++ lib/lp/code/model/branchnamespace.py	2010-08-03 21:32:54 +0000
@@ -28,11 +28,11 @@
     BranchVisibilityRule, CodeReviewNotificationLevel)
 from lp.code.errors import (
     BranchCreationForbidden, BranchCreatorNotMemberOfOwnerTeam,
-    BranchCreatorNotOwner, BranchExists, NoSuchBranch)
+    BranchCreatorNotOwner, BranchExists, InvalidNamespace, NoSuchBranch)
 from lp.code.interfaces.branch import (
     IBranch, user_has_special_branch_access)
 from lp.code.interfaces.branchnamespace import (
-    IBranchNamespace, IBranchNamespacePolicy, InvalidNamespace)
+    IBranchNamespace, IBranchNamespacePolicy)
 from lp.code.interfaces.branchtarget import IBranchTarget
 from lp.code.model.branch import Branch
 from lp.registry.interfaces.distribution import (

=== modified file 'lib/lp/code/model/branchtarget.py'
--- lib/lp/code/model/branchtarget.py	2010-04-14 17:44:00 +0000
+++ lib/lp/code/model/branchtarget.py	2010-08-03 21:32:54 +0000
@@ -340,3 +340,17 @@
 def get_canonical_url_data_for_target(branch_target):
     """Return the `ICanonicalUrlData` for an `IBranchTarget`."""
     return ICanonicalUrlData(branch_target.context)
+
+
+def product_series_to_branch_target(product_series):
+    """The Product itself is the branch target given a ProductSeries."""
+    return ProductBranchTarget(product_series.product)
+
+def distribution_sourcepackage_to_branch_target(distro_sourcepackage):
+    """The development version of the distro sourcepackage is the target."""
+    dev_version = distro_sourcepackage.development_version
+    # It is possible for distributions to not have any series, and if that is
+    # the case, the dev_version is None.
+    if dev_version is None:
+        return None
+    return PackageBranchTarget(dev_version)

=== modified file 'lib/lp/code/model/tests/test_branchlookup.py'
--- lib/lp/code/model/tests/test_branchlookup.py	2010-08-02 02:36:32 +0000
+++ lib/lp/code/model/tests/test_branchlookup.py	2010-08-03 21:32:54 +0000
@@ -13,13 +13,12 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.config import config
-from lp.code.errors import NoSuchBranch
+from lp.code.errors import (
+    CannotHaveLinkedBranch, InvalidNamespace, NoLinkedBranch, NoSuchBranch)
 from lp.code.interfaces.branchlookup import (
     IBranchLookup, ILinkedBranchTraverser)
-from lp.code.interfaces.branchnamespace import (
-    get_branch_namespace, InvalidNamespace)
-from lp.code.interfaces.linkedbranch import (
-    CannotHaveLinkedBranch, ICanHasLinkedBranch, NoLinkedBranch)
+from lp.code.interfaces.branchnamespace import get_branch_namespace
+from lp.code.interfaces.linkedbranch import ICanHasLinkedBranch
 from lp.registry.interfaces.distroseries import NoSuchDistroSeries
 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
 from lp.registry.interfaces.person import NoSuchPerson

=== modified file 'lib/lp/code/model/tests/test_branchnamespace.py'
--- lib/lp/code/model/tests/test_branchnamespace.py	2010-08-02 02:36:32 +0000
+++ lib/lp/code/model/tests/test_branchnamespace.py	2010-08-03 21:32:54 +0000
@@ -21,10 +21,10 @@
     BranchLifecycleStatus, BranchType, BranchVisibilityRule)
 from lp.code.errors import (
     BranchCreationForbidden, BranchCreatorNotMemberOfOwnerTeam,
-    BranchCreatorNotOwner, BranchExists, NoSuchBranch)
+    BranchCreatorNotOwner, BranchExists, InvalidNamespace, NoSuchBranch)
 from lp.code.interfaces.branchnamespace import (
     get_branch_namespace, IBranchNamespacePolicy, IBranchNamespace,
-    IBranchNamespaceSet, lookup_branch_namespace, InvalidNamespace)
+    IBranchNamespaceSet, lookup_branch_namespace)
 from lp.code.interfaces.branchtarget import IBranchTarget
 from lp.registry.interfaces.distribution import NoSuchDistribution
 from lp.registry.interfaces.distroseries import NoSuchDistroSeries

=== modified file 'lib/lp/code/model/tests/test_branchtarget.py'
--- lib/lp/code/model/tests/test_branchtarget.py	2010-07-28 04:18:53 +0000
+++ lib/lp/code/model/tests/test_branchtarget.py	2010-08-03 21:32:54 +0000
@@ -93,6 +93,19 @@
         target = IBranchTarget(self.original)
         self.assertIsInstance(target, PackageBranchTarget)
 
+    def test_distrosourcepackage_adapter(self):
+        distro = self.original.distribution
+        distro_sourcepackage = distro.getSourcePackage(
+            self.original.sourcepackagename)
+        target = IBranchTarget(distro_sourcepackage)
+        self.assertIsInstance(target, PackageBranchTarget)
+        self.assertEqual(
+            [distro, distro.currentseries],
+            target.components[:2])
+        self.assertEqual(
+            self.original.sourcepackagename,
+            target.components[2].sourcepackagename)
+
     def test_components(self):
         target = IBranchTarget(self.original)
         self.assertEqual(
@@ -320,6 +333,12 @@
         target = IBranchTarget(self.original)
         self.assertIsInstance(target, ProductBranchTarget)
 
+    def test_productseries_adapter(self):
+        series = self.factory.makeProductSeries(product=self.original)
+        target = IBranchTarget(series)
+        self.assertIsInstance(target, ProductBranchTarget)
+        self.assertEqual([self.original], target.components)
+
     def test_components(self):
         target = IBranchTarget(self.original)
         self.assertEqual([self.original], list(target.components))

=== modified file 'lib/lp/code/xmlrpc/branch.py'
--- lib/lp/code/xmlrpc/branch.py	2010-08-02 02:51:42 +0000
+++ lib/lp/code/xmlrpc/branch.py	2010-08-03 21:32:54 +0000
@@ -23,15 +23,13 @@
 from canonical.launchpad.webapp.interfaces import ILaunchBag
 from lp.code.enums import BranchType
 from lp.code.errors import (
-    BranchCreationException, BranchCreationForbidden, NoSuchBranch)
+    BranchCreationException, BranchCreationForbidden, CannotHaveLinkedBranch,
+    InvalidNamespace, NoLinkedBranch, NoSuchBranch)
 from lp.code.interfaces.branch import IBranch
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.product import IProductSet
 from lp.code.interfaces.branchlookup import IBranchLookup
-from lp.code.interfaces.branchnamespace import (
-    get_branch_namespace, InvalidNamespace)
-from lp.code.interfaces.linkedbranch import (
-    CannotHaveLinkedBranch, NoLinkedBranch)
+from lp.code.interfaces.branchnamespace import get_branch_namespace
 from lp.registry.interfaces.distroseries import NoSuchDistroSeries
 from lp.registry.interfaces.person import NoSuchPerson
 from lp.registry.interfaces.product import (

=== modified file 'lib/lp/code/xmlrpc/codehosting.py'
--- lib/lp/code/xmlrpc/codehosting.py	2010-08-02 02:51:42 +0000
+++ lib/lp/code/xmlrpc/codehosting.py	2010-08-03 21:32:54 +0000
@@ -30,13 +30,13 @@
 from canonical.launchpad.xmlrpc.helpers import return_fault
 
 from lp.app.errors import NameLookupFailed, NotFoundError
-from lp.code.errors import UnknownBranchTypeError
 from lp.code.bzr import BranchFormat, ControlFormat, RepositoryFormat
 from lp.code.enums import BranchType
-from lp.code.errors import BranchCreationException
+from lp.code.errors import (
+    BranchCreationException, InvalidNamespace, UnknownBranchTypeError)
 from lp.code.interfaces.branchlookup import IBranchLookup
 from lp.code.interfaces.branchnamespace import (
-    InvalidNamespace, lookup_branch_namespace, split_unique_name)
+    lookup_branch_namespace, split_unique_name)
 from lp.code.interfaces import branchpuller
 from lp.code.interfaces.codehosting import (
     BRANCH_TRANSPORT, CONTROL_TRANSPORT, ICodehostingAPI, LAUNCHPAD_ANONYMOUS,

=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py	2010-08-02 02:13:52 +0000
+++ lib/lp/registry/browser/person.py	2010-08-03 21:32:54 +0000
@@ -171,8 +171,8 @@
     DAYS_BEFORE_EXPIRATION_WARNING_IS_SENT, ITeamMembership,
     ITeamMembershipSet, TeamMembershipStatus)
 from lp.registry.interfaces.wikiname import IWikiNameSet
-from lp.code.interfaces.branchnamespace import (
-    IBranchNamespaceSet, InvalidNamespace)
+from lp.code.errors import InvalidNamespace
+from lp.code.interfaces.branchnamespace import IBranchNamespaceSet
 from lp.bugs.interfaces.bugtask import IBugTaskSet
 from lp.buildmaster.interfaces.buildbase import BuildStatus
 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet


Follow ups