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
1=== modified file 'lib/lp/code/configure.zcml'
2--- lib/lp/code/configure.zcml 2010-07-25 12:55:56 +0000
3+++ lib/lp/code/configure.zcml 2010-08-10 22:53:44 +0000
4@@ -606,6 +606,11 @@
5 for="lp.registry.interfaces.sourcepackage.ISourcePackage"
6 provides="lp.code.interfaces.branchtarget.IBranchTarget"
7 factory="lp.code.model.branchtarget.PackageBranchTarget"/>
8+ <adapter
9+ for="lp.registry.interfaces.distributionsourcepackage.IDistributionSourcePackage"
10+ provides="lp.code.interfaces.branchtarget.IBranchTarget"
11+ factory="lp.code.model.branchtarget.distribution_sourcepackage_to_branch_target"/>
12+
13 <class class="lp.code.model.branchtarget.PersonBranchTarget">
14 <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>
15 </class>
16@@ -613,6 +618,7 @@
17 for="lp.registry.interfaces.person.IPerson"
18 provides="lp.code.interfaces.branchtarget.IBranchTarget"
19 factory="lp.code.model.branchtarget.PersonBranchTarget"/>
20+
21 <class class="lp.code.model.branchtarget.ProductBranchTarget">
22 <allow interface="lp.code.interfaces.branchtarget.IBranchTarget"/>
23 </class>
24@@ -621,6 +627,10 @@
25 provides="lp.code.interfaces.branchtarget.IBranchTarget"
26 factory="lp.code.model.branchtarget.ProductBranchTarget"/>
27 <adapter
28+ for="lp.registry.interfaces.productseries.IProductSeries"
29+ provides="lp.code.interfaces.branchtarget.IBranchTarget"
30+ factory="lp.code.model.branchtarget.product_series_to_branch_target"/>
31+ <adapter
32 for="lp.code.interfaces.branchtarget.IBranchTarget"
33 provides="canonical.launchpad.webapp.interfaces.ICanonicalUrlData"
34 factory="lp.code.model.branchtarget.get_canonical_url_data_for_target"/>
35
36=== modified file 'lib/lp/code/interfaces/branchtarget.py'
37--- lib/lp/code/interfaces/branchtarget.py 2010-04-23 04:11:12 +0000
38+++ lib/lp/code/interfaces/branchtarget.py 2010-08-10 22:53:44 +0000
39@@ -60,13 +60,15 @@
40 target = Attribute("The branch target, as an `IBranchTarget`.")
41
42
43-class IBranchTarget(IPrimaryContext):
44+class IBranchTarget(Interface):
45 """A target of branches.
46
47 A product contains branches, a source package on a distroseries contains
48 branches, and a person contains 'junk' branches.
49 """
50
51+ context = Attribute('The primary context.')
52+
53 name = Attribute("The name of the target.")
54
55 components = Attribute(
56
57=== modified file 'lib/lp/code/model/branchtarget.py'
58--- lib/lp/code/model/branchtarget.py 2010-04-14 17:44:00 +0000
59+++ lib/lp/code/model/branchtarget.py 2010-08-10 22:53:44 +0000
60@@ -340,3 +340,17 @@
61 def get_canonical_url_data_for_target(branch_target):
62 """Return the `ICanonicalUrlData` for an `IBranchTarget`."""
63 return ICanonicalUrlData(branch_target.context)
64+
65+
66+def product_series_to_branch_target(product_series):
67+ """The Product itself is the branch target given a ProductSeries."""
68+ return ProductBranchTarget(product_series.product)
69+
70+def distribution_sourcepackage_to_branch_target(distro_sourcepackage):
71+ """The development version of the distro sourcepackage is the target."""
72+ dev_version = distro_sourcepackage.development_version
73+ # It is possible for distributions to not have any series, and if that is
74+ # the case, the dev_version is None.
75+ if dev_version is None:
76+ return None
77+ return PackageBranchTarget(dev_version)
78
79=== modified file 'lib/lp/code/model/tests/test_branchtarget.py'
80--- lib/lp/code/model/tests/test_branchtarget.py 2010-07-28 04:18:53 +0000
81+++ lib/lp/code/model/tests/test_branchtarget.py 2010-08-10 22:53:44 +0000
82@@ -26,8 +26,8 @@
83
84 class BaseBranchTargetTests:
85
86- def test_provides_IPrimaryContext(self):
87- self.assertProvides(self.target, IPrimaryContext)
88+ def test_provides_IBranchTarget(self):
89+ self.assertProvides(self.target, IBranchTarget)
90
91 def test_context(self):
92 # IBranchTarget.context is the original object.
93@@ -93,6 +93,21 @@
94 target = IBranchTarget(self.original)
95 self.assertIsInstance(target, PackageBranchTarget)
96
97+ def test_distrosourcepackage_adapter(self):
98+ # Adapting a distrosourcepackage will make a branch target with the
99+ # current series of the distro as the distroseries.
100+ distro = self.original.distribution
101+ distro_sourcepackage = distro.getSourcePackage(
102+ self.original.sourcepackagename)
103+ target = IBranchTarget(distro_sourcepackage)
104+ self.assertIsInstance(target, PackageBranchTarget)
105+ self.assertEqual(
106+ [distro, distro.currentseries],
107+ target.components[:2])
108+ self.assertEqual(
109+ self.original.sourcepackagename,
110+ target.components[2].sourcepackagename)
111+
112 def test_components(self):
113 target = IBranchTarget(self.original)
114 self.assertEqual(
115@@ -320,6 +335,14 @@
116 target = IBranchTarget(self.original)
117 self.assertIsInstance(target, ProductBranchTarget)
118
119+ def test_productseries_adapter(self):
120+ # Adapting a product series will make a product branch target.
121+ product = self.factory.makeProduct()
122+ series = self.factory.makeProductSeries(product)
123+ target = IBranchTarget(series)
124+ self.assertIsInstance(target, ProductBranchTarget)
125+ self.assertEqual([product], target.components)
126+
127 def test_components(self):
128 target = IBranchTarget(self.original)
129 self.assertEqual([self.original], list(target.components))