Merge lp:~edwin-grubbs/launchpad/bug-272343-packaging-views into lp:launchpad

Proposed by Edwin Grubbs
Status: Merged
Approved by: Curtis Hovey
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~edwin-grubbs/launchpad/bug-272343-packaging-views
Merge into: lp:launchpad
Diff against target: 552 lines (+104/-215)
7 files modified
lib/canonical/launchpad/pagetests/basics/notfound-traversals.txt (+0/-1)
lib/canonical/launchpad/webapp/menu.py (+6/-1)
lib/lp/registry/browser/configure.zcml (+0/-7)
lib/lp/registry/browser/packaging.py (+1/-76)
lib/lp/registry/browser/productseries.py (+61/-15)
lib/lp/registry/browser/tests/packaging-views.txt (+36/-72)
lib/lp/registry/templates/productseries-packaging.pt (+0/-43)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-272343-packaging-views
Reviewer Review Type Date Requested Status
Curtis Hovey (community) Approve
Review via email: mp+17859@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

Summary
-------

Remove PackagingAddView and productseries-packaging.pt.

Implementation details
----------------------

Removed PackagingAddView and moved the next_url, cancel_url,
and validate() code from PackagingAddView to ProductSeriesUbuntuPackagingView,
which used to subclass from it.
    lib/lp/registry/browser/configure.zcml
    lib/lp/registry/browser/packaging.py
    lib/lp/registry/browser/productseries.py

Removed file:
    lib/lp/registry/templates/productseries-packaging.pt

Converted tests for +addpackage to test +ubuntupkg unless the
test is obsolete.
    lib/lp/registry/browser/tests/packaging-views.txt

Make the error clearer when a menu item's method is removed
but is still referenced in the menu.links attribute.
    lib/canonical/launchpad/webapp/menu.py

Tests
-----

./bin/test -vv -t 'packaging-views.txt'

Demo and Q/A
------------

* Open a project series.
  * Click on "Link to Ubuntu package".
  * There should be no change in behavior.

Revision history for this message
Curtis Hovey (sinzui) wrote :

Hi Edwin.

I really appreciate your refactoring to remove the obsolete view. There is a conflict with DistroSeriesStatus that you need to fix. Adi renamed it SeriesStatus yesterday.

I have some hesitation about the assert in the doctest. There was a bad test in the past that wrote the assert wrongly and we did not discover it until after users reported errors. There is nothing wrong with your use, but printing the expected items would make it clear what you expected to be in the vocabulary tokens.

review: Approve
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

> Hi Edwin.
>
> I really appreciate your refactoring to remove the obsolete view. There is a
> conflict with DistroSeriesStatus that you need to fix. Adi renamed it
> SeriesStatus yesterday.
>
> I have some hesitation about the assert in the doctest. There was a bad test
> in the past that wrote the assert wrongly and we did not discover it until
> after users reported errors. There is nothing wrong with your use, but
> printing the expected items would make it clear what you expected to be in the
> vocabulary tokens.

Hi Curtis,

Thanks for the review. Here is the incremental diff:

{{{
=== modified file 'lib/lp/registry/browser/tests/packaging-views.txt'
--- lib/lp/registry/browser/tests/packaging-views.txt 2010-01-22 16:44:39 +0000
+++ lib/lp/registry/browser/tests/packaging-views.txt 2010-01-22 16:51:28 +0000
@@ -27,8 +27,9 @@
     []
     >>> transaction.commit()

-The view has a label and requires a distro series, source package name,
-and a packaging contents.
+The view has a label and requires a distro series and a source package name.
+The distroseries field's vocabulary is the same as the ubuntu.series
+attribute.

     >>> view = create_view(productseries, '+ubuntupkg')
     >>> print view.label
@@ -43,13 +44,19 @@
     >>> print view.cancel_url
     http://launchpad.dev/hot/hotter

- >>> series_names = [series.name for series in ubuntu.series]
+ >>> for series in ubuntu.series:
+ ... print series.name
+ breezy-autotest
+ grumpy
+ hoary
+ warty
     >>> view.setUpFields()
- >>> vocabulary_tokens = [
- ... term.token
- ... for term in view.form_fields['distroseries'].field.vocabulary
- ... ]
- >>> assert vocabulary_tokens == series_names
+ >>> for term in view.form_fields['distroseries'].field.vocabulary:
+ ... print term.token
+ breezy-autotest
+ grumpy
+ hoary
+ warty

     >>> form = {
     ... 'field.distroseries': 'hoary',
}}}

Revision history for this message
Curtis Hovey (sinzui) wrote :

On Fri, 2010-01-22 at 16:53 +0000, Edwin Grubbs wrote:
> > Hi Edwin.
> >
> > I really appreciate your refactoring to remove the obsolete view. There is a
> > conflict with DistroSeriesStatus that you need to fix. Adi renamed it
> > SeriesStatus yesterday.
> >
> > I have some hesitation about the assert in the doctest. There was a bad test
> > in the past that wrote the assert wrongly and we did not discover it until
> > after users reported errors. There is nothing wrong with your use, but
> > printing the expected items would make it clear what you expected to be in the
> > vocabulary tokens.
>
> Hi Curtis,
>
> Thanks for the review. Here is the incremental diff:

These change look good. thank you.

--
__Curtis C. Hovey_________
http://launchpad.net/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/pagetests/basics/notfound-traversals.txt'
--- lib/canonical/launchpad/pagetests/basics/notfound-traversals.txt 2009-12-05 13:36:12 +0000
+++ lib/canonical/launchpad/pagetests/basics/notfound-traversals.txt 2010-01-22 22:32:18 +0000
@@ -114,7 +114,6 @@
114>>> check("/firefox")114>>> check("/firefox")
115>>> check("/firefox/+series")115>>> check("/firefox/+series")
116>>> check("/firefox/1.0")116>>> check("/firefox/1.0")
117>>> check("/firefox/1.0/+addpackage", auth=True)
118>>> check("/firefox/1.0/+ubuntupkg", auth=True)117>>> check("/firefox/1.0/+ubuntupkg", auth=True)
119>>> check("/firefox/1.0/+edit", auth=True)118>>> check("/firefox/1.0/+edit", auth=True)
120>>> check("/firefox/1.0/+specs")119>>> check("/firefox/1.0/+specs")
121120
=== modified file 'lib/canonical/launchpad/webapp/menu.py'
--- lib/canonical/launchpad/webapp/menu.py 2009-08-13 00:51:50 +0000
+++ lib/canonical/launchpad/webapp/menu.py 2010-01-22 22:32:18 +0000
@@ -229,7 +229,12 @@
229 pass229 pass
230230
231 def _buildLink(self, name):231 def _buildLink(self, name):
232 method = getattr(self, name)232 method = getattr(self, name, None)
233 # Since Zope traversals hides the root cause of an AttributeError,
234 # an AssertionError is raised explaining what went wrong.
235 if method is None:
236 raise AssertionError(
237 '%r does not define %r method.' % (self, name))
233 linkdata = method()238 linkdata = method()
234 # The link need only provide ILinkData. We need an ILink so that239 # The link need only provide ILinkData. We need an ILink so that
235 # we can set attributes on it like 'name' and 'url' and 'linked'.240 # we can set attributes on it like 'name' and 'url' and 'linked'.
236241
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml 2010-01-06 13:42:17 +0000
+++ lib/lp/registry/browser/configure.zcml 2010-01-22 22:32:18 +0000
@@ -1594,13 +1594,6 @@
1594 template="../templates/productseries-table-releases.pt"/>1594 template="../templates/productseries-table-releases.pt"/>
1595 </browser:pages>1595 </browser:pages>
1596 <browser:page1596 <browser:page
1597 name="+addpackage"
1598 for="lp.registry.interfaces.productseries.IProductSeries"
1599 class="lp.registry.browser.packaging.PackagingAddView"
1600 facet="overview"
1601 permission="launchpad.View"
1602 template="../templates/productseries-packaging.pt"/>
1603 <browser:page
1604 name="+ubuntupkg"1597 name="+ubuntupkg"
1605 facet="overview"1598 facet="overview"
1606 template="../templates/productseries-ubuntupkg.pt"1599 template="../templates/productseries-ubuntupkg.pt"
16071600
=== modified file 'lib/lp/registry/browser/packaging.py'
--- lib/lp/registry/browser/packaging.py 2010-01-11 16:26:52 +0000
+++ lib/lp/registry/browser/packaging.py 2010-01-22 22:32:18 +0000
@@ -4,7 +4,6 @@
4__metaclass__ = type4__metaclass__ = type
55
6__all__ = [6__all__ = [
7 'PackagingAddView',
8 'PackagingDeleteView',7 'PackagingDeleteView',
9 ]8 ]
109
@@ -14,82 +13,8 @@
14from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary13from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
1514
16from canonical.launchpad import _15from canonical.launchpad import _
17from lp.registry.interfaces.packaging import (16from lp.registry.interfaces.packaging import IPackagingUtil
18 IPackaging, IPackagingUtil)
19from canonical.launchpad.webapp import canonical_url
20from canonical.launchpad.webapp.launchpadform import action, LaunchpadFormView17from canonical.launchpad.webapp.launchpadform import action, LaunchpadFormView
21from canonical.launchpad.webapp.menu import structured
22
23
24class PackagingAddView(LaunchpadFormView):
25 schema = IPackaging
26 field_names = ['distroseries', 'sourcepackagename', 'packaging']
27 default_distroseries = None
28
29 @property
30 def label(self):
31 """See `LaunchpadFormView`."""
32 return 'Packaging of %s in distributions' % self.context.displayname
33
34 page_title = label
35
36 @property
37 def next_url(self):
38 """See `LaunchpadFormView`."""
39 return canonical_url(self.context)
40
41 cancel_url = next_url
42
43 def validate(self, data):
44 productseries = self.context
45 sourcepackagename = data.get('sourcepackagename', None)
46 distroseries = data.get('distroseries', self.default_distroseries)
47 if sourcepackagename is None:
48 message = "You must choose the source package name."
49 self.setFieldError('sourcepackagename', message)
50 # Do not allow users it create links to unpublished Ubuntu packages.
51 elif distroseries.distribution.full_functionality:
52 source_package = distroseries.getSourcePackage(sourcepackagename)
53 if source_package.currentrelease is None:
54 message = ("The source package is not published in %s." %
55 distroseries.displayname)
56 self.setFieldError('sourcepackagename', message)
57 else:
58 pass
59 packaging_util = getUtility(IPackagingUtil)
60 if packaging_util.packagingEntryExists(
61 productseries=productseries,
62 sourcepackagename=sourcepackagename,
63 distroseries=distroseries):
64 # The series packaging conflicts with itself.
65 message = _(
66 "This series is already packaged in %s." %
67 distroseries.displayname)
68 self.setFieldError('sourcepackagename', message)
69 elif packaging_util.packagingEntryExists(
70 sourcepackagename=sourcepackagename,
71 distroseries=distroseries):
72 # The series package conflicts with another series.
73 sourcepackage = distroseries.getSourcePackage(
74 sourcepackagename.name)
75 message = structured(
76 'The <a href="%s">%s</a> package in %s is already linked to '
77 'another series.' %
78 (canonical_url(sourcepackage),
79 sourcepackagename.name,
80 distroseries.displayname))
81 self.setFieldError('sourcepackagename', message)
82 else:
83 # The distroseries and sourcepackagename are not already linked
84 # to this series, or any other series.
85 pass
86
87 @action('Continue', name='continue')
88 def continue_action(self, action, data):
89 productseries = self.context
90 getUtility(IPackagingUtil).createPackaging(
91 productseries, data['sourcepackagename'], data['distroseries'],
92 data['packaging'], owner=self.user)
9318
9419
95class PackagingDeleteView(LaunchpadFormView):20class PackagingDeleteView(LaunchpadFormView):
9621
=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py 2010-01-20 15:41:25 +0000
+++ lib/lp/registry/browser/productseries.py 2010-01-22 22:32:18 +0000
@@ -59,25 +59,27 @@
59from lp.registry.browser.structuralsubscription import (59from lp.registry.browser.structuralsubscription import (
60 StructuralSubscriptionMenuMixin,60 StructuralSubscriptionMenuMixin,
61 StructuralSubscriptionTargetTraversalMixin)61 StructuralSubscriptionTargetTraversalMixin)
62from lp.registry.interfaces.packaging import (
63 IPackaging, IPackagingUtil)
62from lp.translations.interfaces.potemplate import IPOTemplateSet64from lp.translations.interfaces.potemplate import IPOTemplateSet
63from lp.translations.interfaces.productserieslanguage import (65from lp.translations.interfaces.productserieslanguage import (
64 IProductSeriesLanguageSet)66 IProductSeriesLanguageSet)
65from lp.services.worlddata.interfaces.language import ILanguageSet67from lp.services.worlddata.interfaces.language import ILanguageSet
66from canonical.launchpad.webapp import (68from canonical.launchpad.webapp import (
67 action, ApplicationMenu, canonical_url, custom_widget,69 ApplicationMenu, canonical_url, enabled_with_permission, LaunchpadView,
68 enabled_with_permission, LaunchpadEditFormView,70 Link, Navigation, NavigationMenu, StandardLaunchpadFacets, stepthrough,
69 LaunchpadView, Link, Navigation, NavigationMenu, StandardLaunchpadFacets,71 stepto)
70 stepthrough, stepto)
71from canonical.launchpad.webapp.authorization import check_permission72from canonical.launchpad.webapp.authorization import check_permission
72from canonical.launchpad.webapp.batching import BatchNavigator73from canonical.launchpad.webapp.batching import BatchNavigator
73from canonical.launchpad.webapp.breadcrumb import Breadcrumb74from canonical.launchpad.webapp.breadcrumb import Breadcrumb
74from canonical.launchpad.webapp.interfaces import NotFoundError75from canonical.launchpad.webapp.interfaces import NotFoundError
76from canonical.launchpad.webapp.launchpadform import (
77 action, custom_widget, LaunchpadEditFormView, LaunchpadFormView)
75from canonical.launchpad.webapp.menu import structured78from canonical.launchpad.webapp.menu import structured
76from canonical.widgets.textwidgets import StrippedTextWidget79from canonical.widgets.textwidgets import StrippedTextWidget
7780
78from lp.registry.browser import (81from lp.registry.browser import (
79 MilestoneOverlayMixin, RegistryDeleteViewMixin)82 MilestoneOverlayMixin, RegistryDeleteViewMixin)
80from lp.registry.browser.packaging import PackagingAddView
81from lp.registry.interfaces.series import SeriesStatus83from lp.registry.interfaces.series import SeriesStatus
82from lp.registry.interfaces.productseries import IProductSeries84from lp.registry.interfaces.productseries import IProductSeries
8385
@@ -161,8 +163,7 @@
161 facet = 'overview'163 facet = 'overview'
162 links = [164 links = [
163 'edit', 'delete', 'driver', 'link_branch', 'branch_add', 'ubuntupkg',165 'edit', 'delete', 'driver', 'link_branch', 'branch_add', 'ubuntupkg',
164 'add_package', 'create_milestone', 'create_release',166 'create_milestone', 'create_release', 'rdf', 'subscribe',
165 'rdf', 'subscribe',
166 ]167 ]
167168
168 @enabled_with_permission('launchpad.Edit')169 @enabled_with_permission('launchpad.Edit')
@@ -210,12 +211,6 @@
210 text = 'Link to Ubuntu package'211 text = 'Link to Ubuntu package'
211 return Link('+ubuntupkg', text, icon='add')212 return Link('+ubuntupkg', text, icon='add')
212213
213 @enabled_with_permission('launchpad.View')
214 def add_package(self):
215 """Return a link to link this series to a sourcepackage."""
216 text = 'Link package'
217 return Link('+addpackage', text, icon='add')
218
219 @enabled_with_permission('launchpad.Edit')214 @enabled_with_permission('launchpad.Edit')
220 def create_milestone(self):215 def create_milestone(self):
221 """Return a link to create a milestone."""216 """Return a link to create a milestone."""
@@ -367,8 +362,9 @@
367 return None362 return None
368363
369364
370class ProductSeriesUbuntuPackagingView(PackagingAddView):365class ProductSeriesUbuntuPackagingView(LaunchpadFormView):
371366
367 schema = IPackaging
372 field_names = ['sourcepackagename', 'distroseries']368 field_names = ['sourcepackagename', 'distroseries']
373 page_title = 'Ubuntu source packaging'369 page_title = 'Ubuntu source packaging'
374 label = page_title370 label = page_title
@@ -386,6 +382,13 @@
386 # The package has never been set.382 # The package has never been set.
387 self.default_sourcepackagename = None383 self.default_sourcepackagename = None
388384
385 @property
386 def next_url(self):
387 """See `LaunchpadFormView`."""
388 return canonical_url(self.context)
389
390 cancel_url = next_url
391
389 def setUpFields(self):392 def setUpFields(self):
390 """See `LaunchpadFormView`.393 """See `LaunchpadFormView`.
391394
@@ -428,11 +431,54 @@
428 self.default_distroseries.distribution)431 self.default_distroseries.distribution)
429432
430 def validate(self, data):433 def validate(self, data):
434 productseries = self.context
431 sourcepackagename = data.get('sourcepackagename', None)435 sourcepackagename = data.get('sourcepackagename', None)
436 distroseries = data.get('distroseries', self.default_distroseries)
437
432 if sourcepackagename == self.default_sourcepackagename:438 if sourcepackagename == self.default_sourcepackagename:
433 # The data has not changed, so nothing else needs to be done.439 # The data has not changed, so nothing else needs to be done.
434 return440 return
435 super(ProductSeriesUbuntuPackagingView, self).validate(data)441
442 if sourcepackagename is None:
443 message = "You must choose the source package name."
444 self.setFieldError('sourcepackagename', message)
445 # Do not allow users it create links to unpublished Ubuntu packages.
446 elif distroseries.distribution.full_functionality:
447 source_package = distroseries.getSourcePackage(sourcepackagename)
448 if source_package.currentrelease is None:
449 message = ("The source package is not published in %s." %
450 distroseries.displayname)
451 self.setFieldError('sourcepackagename', message)
452 else:
453 pass
454 packaging_util = getUtility(IPackagingUtil)
455 if packaging_util.packagingEntryExists(
456 productseries=productseries,
457 sourcepackagename=sourcepackagename,
458 distroseries=distroseries):
459 # The series packaging conflicts with itself.
460 message = _(
461 "This series is already packaged in %s." %
462 distroseries.displayname)
463 self.setFieldError('sourcepackagename', message)
464 elif packaging_util.packagingEntryExists(
465 sourcepackagename=sourcepackagename,
466 distroseries=distroseries):
467 # The series package conflicts with another series.
468 sourcepackage = distroseries.getSourcePackage(
469 sourcepackagename.name)
470 message = structured(
471 'The <a href="%s">%s</a> package in %s is already linked to '
472 'another series.' %
473 (canonical_url(sourcepackage),
474 sourcepackagename.name,
475 distroseries.displayname))
476 self.setFieldError('sourcepackagename', message)
477 else:
478 # The distroseries and sourcepackagename are not already linked
479 # to this series, or any other series.
480 pass
481
436482
437 @action('Update', name='continue')483 @action('Update', name='continue')
438 def continue_action(self, action, data):484 def continue_action(self, action, data):
439485
=== modified file 'lib/lp/registry/browser/tests/packaging-views.txt'
--- lib/lp/registry/browser/tests/packaging-views.txt 2010-01-20 15:41:25 +0000
+++ lib/lp/registry/browser/tests/packaging-views.txt 2010-01-22 22:32:18 +0000
@@ -8,7 +8,7 @@
8------------------------------8------------------------------
99
10Distro series sourcepackages can be linked to product series using the10Distro series sourcepackages can be linked to product series using the
11+addpackage named view.11+ubuntupkg named view.
1212
13 >>> from canonical.launchpad.interfaces.launchpad import (13 >>> from canonical.launchpad.interfaces.launchpad import (
14 ... ILaunchpadCelebrities)14 ... ILaunchpadCelebrities)
@@ -25,31 +25,47 @@
25 ... product=product, name='hotter')25 ... product=product, name='hotter')
26 >>> productseries.sourcepackages26 >>> productseries.sourcepackages
27 []27 []
2828 >>> transaction.commit()
29The view has a label and requires a distro series, source package name,29
30and a packaging contents.30The view has a label and requires a distro series and a source package name.
3131The distroseries field's vocabulary is the same as the ubuntu.series
32 >>> view = create_view(productseries, '+addpackage')32attribute.
33
34 >>> view = create_view(productseries, '+ubuntupkg')
33 >>> print view.label35 >>> print view.label
34 Packaging of hotter in distributions36 Ubuntu source packaging
3537
36 >>> print view.page_title38 >>> print view.page_title
37 Packaging of hotter in distributions39 Ubuntu source packaging
3840
39 >>> print view.field_names41 >>> print view.field_names
40 ['distroseries', 'sourcepackagename', 'packaging']42 ['sourcepackagename', 'distroseries']
4143
42 >>> print view.cancel_url44 >>> print view.cancel_url
43 http://launchpad.dev/hot/hotter45 http://launchpad.dev/hot/hotter
4446
47 >>> for series in ubuntu.series:
48 ... print series.name
49 breezy-autotest
50 grumpy
51 hoary
52 warty
53 >>> view.setUpFields()
54 >>> for term in view.form_fields['distroseries'].field.vocabulary:
55 ... print term.token
56 breezy-autotest
57 grumpy
58 hoary
59 warty
60
45 >>> form = {61 >>> form = {
46 ... 'field.distroseries': 'ubuntu/hoary',62 ... 'field.distroseries': 'hoary',
47 ... 'field.sourcepackagename': 'hot',63 ... 'field.sourcepackagename': 'hot',
48 ... 'field.packaging': 'Primary Project',64 ... 'field.packaging': 'Primary Project',
49 ... 'field.actions.continue': 'Continue',65 ... 'field.actions.continue': 'Continue',
50 ... }66 ... }
51 >>> view = create_initialized_view(67 >>> view = create_initialized_view(
52 ... productseries, '+addpackage', form=form)68 ... productseries, '+ubuntupkg', form=form)
53 >>> view.errors69 >>> view.errors
54 []70 []
55 >>> for package in productseries.sourcepackages:71 >>> for package in productseries.sourcepackages:
@@ -58,33 +74,19 @@
5874
59 >>> transaction.commit()75 >>> transaction.commit()
6076
61It is an error to link a series to the same package and distro series twice.
62
63 >>> form = {
64 ... 'field.distroseries': 'ubuntu/hoary',
65 ... 'field.sourcepackagename': 'hot',
66 ... 'field.packaging': 'Primary Project',
67 ... 'field.actions.continue': 'Continue',
68 ... }
69 >>> view = create_initialized_view(
70 ... productseries, '+addpackage', form=form)
71 >>> for error in view.errors:
72 ... print error
73 This series is already packaged in Hoary.
74
75Once a distro series sourcepackage is linked to a product series, no other77Once a distro series sourcepackage is linked to a product series, no other
76product series can link to it.78product series can link to it.
7779
78 >>> other_productseries = factory.makeProductSeries(80 >>> other_productseries = factory.makeProductSeries(
79 ... product=product, name='hotest')81 ... product=product, name='hotest')
80 >>> form = {82 >>> form = {
81 ... 'field.distroseries': 'ubuntu/hoary',83 ... 'field.distroseries': 'hoary',
82 ... 'field.sourcepackagename': 'hot',84 ... 'field.sourcepackagename': 'hot',
83 ... 'field.packaging': 'Primary Project',85 ... 'field.packaging': 'Primary Project',
84 ... 'field.actions.continue': 'Continue',86 ... 'field.actions.continue': 'Continue',
85 ... }87 ... }
86 >>> view = create_initialized_view(88 >>> view = create_initialized_view(
87 ... other_productseries, '+addpackage', form=form)89 ... other_productseries, '+ubuntupkg', form=form)
88 >>> for error in view.errors:90 >>> for error in view.errors:
89 ... print error91 ... print error
90 The <a href=".../hoary/+source/hot">hot</a> package in Hoary is already92 The <a href=".../hoary/+source/hot">hot</a> package in Hoary is already
@@ -93,52 +95,42 @@
93A source package name must be provided.95A source package name must be provided.
9496
95 >>> form = {97 >>> form = {
96 ... 'field.distroseries': 'ubuntu/hoary',98 ... 'field.distroseries': 'hoary',
97 ... 'field.sourcepackagename': '',99 ... 'field.sourcepackagename': '',
98 ... 'field.packaging': 'Primary Project',100 ... 'field.packaging': 'Primary Project',
99 ... 'field.actions.continue': 'Continue',101 ... 'field.actions.continue': 'Continue',
100 ... }102 ... }
101 >>> view = create_initialized_view(103 >>> view = create_initialized_view(
102 ... productseries, '+addpackage', form=form)104 ... productseries, '+ubuntupkg', form=form)
103 >>> for error in view.errors:105 >>> for error in view.errors:
104 ... print error106 ... print error
105 ('sourcepackagename', u'Source Package Name', RequiredMissing())107 ('sourcepackagename', u'Source Package Name', RequiredMissing())
106 You must choose the source package name.108 You must choose the source package name.
107109
108In the case of full functionality distributions like Ubuntu, the source110In the case of full functionality distributions like Ubuntu, the source
109package must be published in the distro series. 111package must be published in the distro series.
110112
111 >>> vapor_spn = factory.makeSourcePackageName('vapor')113 >>> vapor_spn = factory.makeSourcePackageName('vapor')
112 >>> form = {114 >>> form = {
113 ... 'field.distroseries': 'ubuntu/hoary',115 ... 'field.distroseries': 'hoary',
114 ... 'field.sourcepackagename': 'vapor',116 ... 'field.sourcepackagename': 'vapor',
115 ... 'field.packaging': 'Primary Project',117 ... 'field.packaging': 'Primary Project',
116 ... 'field.actions.continue': 'Continue',118 ... 'field.actions.continue': 'Continue',
117 ... }119 ... }
118 >>> view = create_initialized_view(120 >>> view = create_initialized_view(
119 ... productseries, '+addpackage', form=form)121 ... productseries, '+ubuntupkg', form=form)
120 >>> for error in view.errors:122 >>> for error in view.errors:
121 ... print error123 ... print error
122 The source package is not published in Hoary.124 The source package is not published in Hoary.
123125
124The +addpackage view provides the default_distroseries property. It is None
125by default, but subclasses may change it.
126
127 >>> print view.default_distroseries
128 None
129
130126
131Productseries linking Ubuntu packages127Productseries linking Ubuntu packages
132-------------------------------------128-------------------------------------
133129
134The +ubuntupkg named view is a subclass of the +addpackage named view. It130The +ubuntupkg named view allows the user to update the current linked
135allows the user to update the current linked Ubuntu package.131Ubuntu package.
136
137 >>> from lp.registry.browser.packaging import PackagingAddView
138132
139 >>> view = create_initialized_view(productseries, '+ubuntupkg')133 >>> view = create_initialized_view(productseries, '+ubuntupkg')
140 >>> isinstance(view, PackagingAddView)
141 True
142134
143 >>> print view.label135 >>> print view.label
144 Ubuntu source packaging136 Ubuntu source packaging
@@ -314,34 +306,10 @@
314sorted by distribution with Ubuntu first and the rest in alphabetic306sorted by distribution with Ubuntu first and the rest in alphabetic
315order.307order.
316308
317 >>> form = {
318 ... 'field.distroseries': 'redhat/7.0',
319 ... 'field.sourcepackagename': 'hot',
320 ... 'field.packaging': 'Primary Project',
321 ... 'field.actions.continue': 'Continue',
322 ... }
323
324 >>> view = create_initialized_view(
325 ... productseries, '+addpackage', form=form)
326 >>> view.errors
327 []
328 >>> form = {
329 ... 'field.distroseries': 'debian/sarge',
330 ... 'field.sourcepackagename': 'hot',
331 ... 'field.packaging': 'Primary Project',
332 ... 'field.actions.continue': 'Continue',
333 ... }
334
335 >>> view = create_initialized_view(
336 ... productseries, '+addpackage', form=form)
337 >>> view.errors
338 []
339 >>> view = create_initialized_view(product, name='+packages')309 >>> view = create_initialized_view(product, name='+packages')
340 >>> for distro_dict in view.distro_packaging:310 >>> for distro_dict in view.distro_packaging:
341 ... print distro_dict['distribution'].name311 ... print distro_dict['distribution'].name
342 ubuntu312 ubuntu
343 debian
344 redhat
345313
346The +packages named view descends from PackagingDeleteView to provide remove314The +packages named view descends from PackagingDeleteView to provide remove
347link actions for the product's linked packages.315link actions for the product's linked packages.
@@ -357,8 +325,6 @@
357 >>> view = create_initialized_view(product, name='+packages')325 >>> view = create_initialized_view(product, name='+packages')
358 >>> for package in view.all_packaging:326 >>> for package in view.all_packaging:
359 ... print package.distroseries.name, package.productseries.name327 ... print package.distroseries.name, package.productseries.name
360 sarge hotter
361 7.0 hotter
362 grumpy hotter328 grumpy hotter
363 hoary hotter329 hoary hotter
364330
@@ -373,8 +339,6 @@
373 []339 []
374 >>> for package in view.all_packaging:340 >>> for package in view.all_packaging:
375 ... print package.distroseries.name, package.productseries.name341 ... print package.distroseries.name, package.productseries.name
376 sarge hotter
377 7.0 hotter
378 grumpy hotter342 grumpy hotter
379343
380344
381345
=== removed file 'lib/lp/registry/templates/productseries-packaging.pt'
--- lib/lp/registry/templates/productseries-packaging.pt 2009-09-12 06:11:08 +0000
+++ lib/lp/registry/templates/productseries-packaging.pt 1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
1<html
2 xmlns="http://www.w3.org/1999/xhtml"
3 xmlns:tal="http://xml.zope.org/namespaces/tal"
4 xmlns:metal="http://xml.zope.org/namespaces/metal"
5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
6 metal:use-macro="view/macro:page/main_only"
7 i18n:domain="launchpad"
8>
9
10<body>
11
12<div metal:fill-slot="main">
13
14 <div metal:use-macro="context/@@launchpad_form/form">
15
16 <div metal:fill-slot="extra_info"
17 tal:define="sourcepackages context/sourcepackages">
18 <p>
19 Tell Launchpad about a package of
20 <tal:name replace="context/displayname" /> in a release of any
21 supported distribution.
22 <tal:existing condition="sourcepackages">
23 This series is packaged in the following places:
24 </tal:existing>
25 </p>
26
27 <ul class="bulleted"
28 tal:condition="sourcepackages">
29 <li tal:repeat="package sourcepackages">
30 <tal:distro replace="package/distroseries/distribution/name" />
31 <tal:series replace="package/distroseries/name" />
32 <a tal:content="package/name"
33 tal:attributes="href package/fmt:url">apache</a>
34 </li>
35 </ul>
36 </div>
37
38 </div>
39
40</div>
41
42</body>
43</html>