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

Proposed by Tim Penhey
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 11334
Proposed branch: lp:~thumper/launchpad/branch-target-adapters
Merge into: lp:launchpad
Diff against target: 129 lines (+52/-3)
4 files modified
lib/lp/code/configure.zcml (+10/-0)
lib/lp/code/interfaces/branchtarget.py (+3/-1)
lib/lp/code/model/branchtarget.py (+14/-0)
lib/lp/code/model/tests/test_branchtarget.py (+25/-2)
To merge this branch: bzr merge lp:~thumper/launchpad/branch-target-adapters
Reviewer Review Type Date Requested Status
Michael Hudson-Doyle Approve
Review via email: mp+31698@code.launchpad.net

Commit message

Add a few more adapters to IBranchTarget.

Description of the change

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

To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote :

On Tue, Aug 3, 2010 at 10:33 PM, Tim Penhey <email address hidden> wrote:
> Tim Penhey has proposed merging lp:~thumper/launchpad/branch-target-adapters into lp:launchpad/devel.
...
> 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.

I'm curious. This wasn't a part of the work we did at the Epic... why
is this needed?

jml

Revision history for this message
Tim Penhey (thumper) wrote :

On Wed, 04 Aug 2010 09:41:13 you wrote:
> On Tue, Aug 3, 2010 at 10:33 PM, Tim Penhey <email address hidden>
wrote:
> > Tim Penhey has proposed merging
> > lp:~thumper/launchpad/branch-target-adapters into lp:launchpad/devel.
>
> ...
>
> > 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.
>
> I'm curious. This wasn't a part of the work we did at the Epic... why
> is this needed?
>
> jml

It is part of that "minor" bit that was left :-)

It makes the code that allows the branch creation to work when given a short
name, and the ability to set the linked branch.

We use the ILinkedBranchTraverser to get one of:
  Product, ProductSeries, SourcePackage, DistributionSourcePackage

We then adapt that to an IBranchTarget. We then use the target to get the
IBranchNamespace for the requester. Then we can check branch names to make
sure there isn't a conflict.

The the guts of the reason is to go from something that can have a linked
branch to a branch namespace we go through a branch target.

Tim

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Looks fine. The tests could use comments. I don't like the use of self.original (a product?) in test_productseries_adapter.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== 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-10 22:53:44 +0000
@@ -606,6 +606,11 @@
606 for="lp.registry.interfaces.sourcepackage.ISourcePackage"606 for="lp.registry.interfaces.sourcepackage.ISourcePackage"
607 provides="lp.code.interfaces.branchtarget.IBranchTarget"607 provides="lp.code.interfaces.branchtarget.IBranchTarget"
608 factory="lp.code.model.branchtarget.PackageBranchTarget"/>608 factory="lp.code.model.branchtarget.PackageBranchTarget"/>
609 <adapter
610 for="lp.registry.interfaces.distributionsourcepackage.IDistributionSourcePackage"
611 provides="lp.code.interfaces.branchtarget.IBranchTarget"
612 factory="lp.code.model.branchtarget.distribution_sourcepackage_to_branch_target"/>
613
609 <class class="lp.code.model.branchtarget.PersonBranchTarget">614 <class class="lp.code.model.branchtarget.PersonBranchTarget">
610 <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>615 <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>
611 </class>616 </class>
@@ -613,6 +618,7 @@
613 for="lp.registry.interfaces.person.IPerson"618 for="lp.registry.interfaces.person.IPerson"
614 provides="lp.code.interfaces.branchtarget.IBranchTarget"619 provides="lp.code.interfaces.branchtarget.IBranchTarget"
615 factory="lp.code.model.branchtarget.PersonBranchTarget"/>620 factory="lp.code.model.branchtarget.PersonBranchTarget"/>
621
616 <class class="lp.code.model.branchtarget.ProductBranchTarget">622 <class class="lp.code.model.branchtarget.ProductBranchTarget">
617 <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>623 <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>
618 </class>624 </class>
@@ -621,6 +627,10 @@
621 provides="lp.code.interfaces.branchtarget.IBranchTarget"627 provides="lp.code.interfaces.branchtarget.IBranchTarget"
622 factory="lp.code.model.branchtarget.ProductBranchTarget"/>628 factory="lp.code.model.branchtarget.ProductBranchTarget"/>
623 <adapter629 <adapter
630 for="lp.registry.interfaces.productseries.IProductSeries"
631 provides="lp.code.interfaces.branchtarget.IBranchTarget"
632 factory="lp.code.model.branchtarget.product_series_to_branch_target"/>
633 <adapter
624 for="lp.code.interfaces.branchtarget.IBranchTarget"634 for="lp.code.interfaces.branchtarget.IBranchTarget"
625 provides="canonical.launchpad.webapp.interfaces.ICanonicalUrlData"635 provides="canonical.launchpad.webapp.interfaces.ICanonicalUrlData"
626 factory="lp.code.model.branchtarget.get_canonical_url_data_for_target"/>636 factory="lp.code.model.branchtarget.get_canonical_url_data_for_target"/>
627637
=== modified file 'lib/lp/code/interfaces/branchtarget.py'
--- lib/lp/code/interfaces/branchtarget.py 2010-04-23 04:11:12 +0000
+++ lib/lp/code/interfaces/branchtarget.py 2010-08-10 22:53:44 +0000
@@ -60,13 +60,15 @@
60 target = Attribute("The branch target, as an `IBranchTarget`.")60 target = Attribute("The branch target, as an `IBranchTarget`.")
6161
6262
63class IBranchTarget(IPrimaryContext):63class IBranchTarget(Interface):
64 """A target of branches.64 """A target of branches.
6565
66 A product contains branches, a source package on a distroseries contains66 A product contains branches, a source package on a distroseries contains
67 branches, and a person contains 'junk' branches.67 branches, and a person contains 'junk' branches.
68 """68 """
6969
70 context = Attribute('The primary context.')
71
70 name = Attribute("The name of the target.")72 name = Attribute("The name of the target.")
7173
72 components = Attribute(74 components = Attribute(
7375
=== 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-10 22:53:44 +0000
@@ -340,3 +340,17 @@
340def get_canonical_url_data_for_target(branch_target):340def get_canonical_url_data_for_target(branch_target):
341 """Return the `ICanonicalUrlData` for an `IBranchTarget`."""341 """Return the `ICanonicalUrlData` for an `IBranchTarget`."""
342 return ICanonicalUrlData(branch_target.context)342 return ICanonicalUrlData(branch_target.context)
343
344
345def product_series_to_branch_target(product_series):
346 """The Product itself is the branch target given a ProductSeries."""
347 return ProductBranchTarget(product_series.product)
348
349def distribution_sourcepackage_to_branch_target(distro_sourcepackage):
350 """The development version of the distro sourcepackage is the target."""
351 dev_version = distro_sourcepackage.development_version
352 # It is possible for distributions to not have any series, and if that is
353 # the case, the dev_version is None.
354 if dev_version is None:
355 return None
356 return PackageBranchTarget(dev_version)
343357
=== 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-10 22:53:44 +0000
@@ -26,8 +26,8 @@
2626
27class BaseBranchTargetTests:27class BaseBranchTargetTests:
2828
29 def test_provides_IPrimaryContext(self):29 def test_provides_IBranchTarget(self):
30 self.assertProvides(self.target, IPrimaryContext)30 self.assertProvides(self.target, IBranchTarget)
3131
32 def test_context(self):32 def test_context(self):
33 # IBranchTarget.context is the original object.33 # IBranchTarget.context is the original object.
@@ -93,6 +93,21 @@
93 target = IBranchTarget(self.original)93 target = IBranchTarget(self.original)
94 self.assertIsInstance(target, PackageBranchTarget)94 self.assertIsInstance(target, PackageBranchTarget)
9595
96 def test_distrosourcepackage_adapter(self):
97 # Adapting a distrosourcepackage will make a branch target with the
98 # current series of the distro as the distroseries.
99 distro = self.original.distribution
100 distro_sourcepackage = distro.getSourcePackage(
101 self.original.sourcepackagename)
102 target = IBranchTarget(distro_sourcepackage)
103 self.assertIsInstance(target, PackageBranchTarget)
104 self.assertEqual(
105 [distro, distro.currentseries],
106 target.components[:2])
107 self.assertEqual(
108 self.original.sourcepackagename,
109 target.components[2].sourcepackagename)
110
96 def test_components(self):111 def test_components(self):
97 target = IBranchTarget(self.original)112 target = IBranchTarget(self.original)
98 self.assertEqual(113 self.assertEqual(
@@ -320,6 +335,14 @@
320 target = IBranchTarget(self.original)335 target = IBranchTarget(self.original)
321 self.assertIsInstance(target, ProductBranchTarget)336 self.assertIsInstance(target, ProductBranchTarget)
322337
338 def test_productseries_adapter(self):
339 # Adapting a product series will make a product branch target.
340 product = self.factory.makeProduct()
341 series = self.factory.makeProductSeries(product)
342 target = IBranchTarget(series)
343 self.assertIsInstance(target, ProductBranchTarget)
344 self.assertEqual([product], target.components)
345
323 def test_components(self):346 def test_components(self):
324 target = IBranchTarget(self.original)347 target = IBranchTarget(self.original)
325 self.assertEqual([self.original], list(target.components))348 self.assertEqual([self.original], list(target.components))