Merge lp:~sinzui/launchpad/non-existent-packages-bug-204119 into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Approved by: Brad Crittenden
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~sinzui/launchpad/non-existent-packages-bug-204119
Merge into: lp:launchpad
Diff against target: 326 lines (+105/-46)
10 files modified
lib/lp/bugs/stories/guided-filebug/xx-project-guided-filebug.txt (+12/-0)
lib/lp/registry/browser/packaging.py (+9/-0)
lib/lp/registry/browser/productseries.py (+27/-3)
lib/lp/registry/browser/tests/packaging-views.txt (+37/-2)
lib/lp/registry/stories/product/xx-product-package-pages.txt (+9/-8)
lib/lp/registry/stories/productseries/xx-productseries-index.txt (+1/-4)
lib/lp/registry/templates/product-packages.pt (+2/-2)
lib/lp/registry/templates/productseries-portlet-packages.pt (+0/-3)
lib/lp/registry/templates/productseries-ubuntupkg.pt (+6/-23)
lib/lp/testing/factory.py (+2/-1)
To merge this branch: bzr merge lp:~sinzui/launchpad/non-existent-packages-bug-204119
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+17176@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (3.5 KiB)

This is my branch to prevent packaging links to unpublished Ubuntu packages.

    lp:~sinzui/launchpad/non-existent-packages-bug-204119
    Diff size: 305
    Launchpad bug: https://bugs.launchpad.net/bugs/204119
    Test command: ./bin/test -vv \
        -t packaging-views.txt \
        -t xx-product-package-pages.txt \
        -t xx-productseries-index.txt
    Pre-implementation: beuno, bigjools, flacoste
    Target release: 10.01

= Prevent packaging links to unpublished Ubuntu packages =

Launchpad allows users to create links to non-existent packages such as
https://edge.launchpad.net/ubuntu/breezy/+source/warzone2100.

The base view does not verify the that the package was published because
it is designed to accommodate any distro. But this feature is intended for
Ubuntu and it would not have been added if it Ubuntu did not want it, so
the rules must favour Ubuntu.

The work in this branch was started months ago. It was stalled by a debate
regarding the motivations for upstream projects linking to Ubuntu, and the
feature's design to accommodate all distros.

It was decided that the feature will never work well for other distros, and
that is why there are less then 100 links after 4 years. The feature must
favour Ubuntu. There is a problem with the Ubuntu-only form; some users
want to select the non-current series, and we should accommodate that before
we remove the generic form.

== Rules ==

    * Update the base view to verify the package was published in the series if
      the series is full functionality (Ubuntu)
    * Update the ubuntu view to show all the Ubuntu series, but retain the
      rule to use the current series as the default.
    * Update all the project and series pages to use +ubuntupkg instead of
      +addpackage.
    * ADDENDUM: I improved the instructions to use the ubuntu form.

There will be follow up branches to remove the +addpackage view and a query
to remove the packaging links to the non-existent series package.

== QA ==

On staging (or edge if you are willing to clean up)
    * https://edge.launchpad.net/gdp/+packages
    * Verify the action is `(+) Link to Ubuntu package`
    * Follow the link
    * Verify the form lists all Ubuntu series
    * Verify the default series is Lucid
    * Enter gedit-developer-plugins into the source package name field
      and submit
    * Verify that the error message is:
      The source package is not published in Lucid

== Lint ==

Linting changed files:
  lib/lp/registry/browser/packaging.py
  lib/lp/registry/browser/productseries.py
  lib/lp/registry/browser/tests/packaging-views.txt
  lib/lp/registry/stories/product/xx-product-package-pages.txt
  lib/lp/registry/stories/productseries/xx-productseries-index.txt
  lib/lp/registry/templates/product-packages.pt
  lib/lp/registry/templates/productseries-portlet-packages.pt
  lib/lp/registry/templates/productseries-ubuntupkg.pt
  lib/lp/testing/factory.py

== Test ==

    * lib/lp/registry/browser/tests/packaging-views.txt
    * lib/lp/registry/stories/product/xx-product-package-pages.txt
    * lib/lp/registry/stories/productseries/xx-productseries-index.txt

== Implementation ==

    * lib/lp/registry/browser/pack...

Read more...

Revision history for this message
Brad Crittenden (bac) wrote :
Download full text (5.1 KiB)

Hi Curtis,

Thanks for the branch. It looks good save for a few small items below.

> === modified file 'lib/lp/registry/browser/productseries.py'
> --- lib/lp/registry/browser/productseries.py 2009-12-05 18:37:28 +0000
> +++ lib/lp/registry/browser/productseries.py 2010-01-11 23:10:26 +0000
> @@ -33,6 +33,9 @@
>
> from zope.component import getUtility
> from zope.app.form.browser import TextAreaWidget, TextWidget
> +from zope.formlib import form
> +from zope.schema import Choice
> +from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
>
> from z3c.ptcompat import ViewPageTemplateFile
>
> @@ -366,7 +369,7 @@
>
> class ProductSeriesUbuntuPackagingView(PackagingAddView):
>
> - field_names = ['sourcepackagename']
> + field_names = ['sourcepackagename', 'distroseries']
> page_title = 'Ubuntu source packaging'
> label = page_title
>
> @@ -374,8 +377,8 @@
> """Set the static packaging information for this series."""
> super(ProductSeriesUbuntuPackagingView, self).__init__(
> context, request)
> - ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
> - self._ubuntu_series = ubuntu.currentseries
> + self._ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
> + self._ubuntu_series = self._ubuntu.currentseries
> try:
> package = self.context.getPackage(self._ubuntu_series)
> self.default_sourcepackagename = package.sourcepackagename
> @@ -383,6 +386,28 @@
> # The package has never been set.
> self.default_sourcepackagename = None
>
> + def setUpFields(self):
> + """See `LaunchpadFormView`.
> +
> + The packaging is restricted to ubuntu series and the default value
> + is the current development series.
> + """
> + super(PackagingAddView, self).setUpFields()

As we discussed on IRC the class name is wrong.

> + series_vocabulary = SimpleVocabulary(
> + [SimpleTerm(series, series.name, series.named_version)
> + for series in self._ubuntu.series])
> + choice = Choice(__name__='distroseries',
> + title=_('Series'),
> + default=self._ubuntu_series,
> + vocabulary=series_vocabulary,
> + description=_(
> + "Select the Ubuntu series that this package is published "
> + "in. The current series is most important to the Ubuntu "
> + "community."),

I think "series where this package is published" sounds better. What
do you think?

> + required=True)
> + field = form.Fields(choice, render_context=self.render_context)
> + self.form_fields = self.form_fields.omit(choice.__name__) + field
> +
> def setUpWidgets(self):
> """See `LaunchpadFormView`.
>

> === modified file 'lib/lp/registry/browser/tests/packaging-views.txt'
> --- lib/lp/registry/browser/tests/packaging-views.txt 2009-12-10 20:03:11 +0000
> +++ lib/lp/registry/browser/tests/packaging-views.txt 2010-01-11 23:10:26 +0000
> @@ -18,6 +18,8 @@
> >>> sourcepackagename = factory.makeSourcePackageName('hot')
> >>> sourcepackage = factory.make...

Read more...

review: Approve (code)
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (6.8 KiB)

On Tue, 2010-01-12 at 18:45 +0000, Brad Crittenden wrote:
> > === modified file 'lib/lp/registry/browser/productseries.py'
> > --- lib/lp/registry/browser/productseries.py 2009-12-05 18:37:28 +0000
> > +++ lib/lp/registry/browser/productseries.py 2010-01-11 23:10:26 +0000
...

> > @@ -374,8 +377,8 @@
> > """Set the static packaging information for this series."""
> > super(ProductSeriesUbuntuPackagingView, self).__init__(
> > context, request)
> > - ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
> > - self._ubuntu_series = ubuntu.currentseries
> > + self._ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
> > + self._ubuntu_series = self._ubuntu.currentseries
> > try:
> > package = self.context.getPackage(self._ubuntu_series)
> > self.default_sourcepackagename = package.sourcepackagename
> > @@ -383,6 +386,28 @@
> > # The package has never been set.
> > self.default_sourcepackagename = None
> >
> > + def setUpFields(self):
> > + """See `LaunchpadFormView`.
> > +
> > + The packaging is restricted to ubuntu series and the default value
> > + is the current development series.
> > + """
> > + super(PackagingAddView, self).setUpFields()
>
> As we discussed on IRC the class name is wrong.

Fixed

> > + series_vocabulary = SimpleVocabulary(
> > + [SimpleTerm(series, series.name, series.named_version)
> > + for series in self._ubuntu.series])
> > + choice = Choice(__name__='distroseries',
> > + title=_('Series'),
> > + default=self._ubuntu_series,
> > + vocabulary=series_vocabulary,
> > + description=_(
> > + "Select the Ubuntu series that this package is published "
> > + "in. The current series is most important to the Ubuntu "
> > + "community."),
>
> I think "series where this package is published" sounds better. What
> do you think?

Much better. Accepted.

> > === modified file 'lib/lp/registry/browser/tests/packaging-views.txt'
> > --- lib/lp/registry/browser/tests/packaging-views.txt 2009-12-10 20:03:11 +0000
> > +++ lib/lp/registry/browser/tests/packaging-views.txt 2010-01-11 23:10:26 +0000
> > @@ -18,6 +18,8 @@
> > >>> sourcepackagename = factory.makeSourcePackageName('hot')
> > >>> sourcepackage = factory.makeSourcePackage(
> > ... sourcepackagename=sourcepackagename, distroseries=hoary)
> > + >>> spph = factory.makeSourcePackagePublishingHistory(
> > + ... sourcepackagename=sourcepackagename, distroseries=hoary)
> > >>> product = factory.makeProduct(name="hot", displayname='Hot')
> > >>> productseries = factory.makeProductSeries(
> > ... product=product, name='hotter')
> > @@ -103,6 +105,22 @@
> > ('sourcepackagename', u'Source Package Name', RequiredMissing())
> > You must choose the source package name.
> >
> > +In the case of full functionality distributions like Ubuntu, the source
> > +package must be published in the distro series.
> > +
> > + >>> vapour_spn = factory.makeSourcePack...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/stories/guided-filebug/xx-project-guided-filebug.txt'
--- lib/lp/bugs/stories/guided-filebug/xx-project-guided-filebug.txt 2009-10-22 01:39:19 +0000
+++ lib/lp/bugs/stories/guided-filebug/xx-project-guided-filebug.txt 2010-01-13 15:11:15 +0000
@@ -205,6 +205,18 @@
205If we set up an external bug tracker for Testy Product, this will be reflected205If we set up an external bug tracker for Testy Product, this will be reflected
206in the Test Group's filebug page.206in the Test Group's filebug page.
207207
208 >>> from zope.component import getUtility
209 >>> from canonical.launchpad.interfaces.launchpad import (
210 ... ILaunchpadCelebrities)
211
212 >>> login('admin@canonical.com')
213 >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
214 >>> hoary = ubuntu.getSeries('hoary')
215 >>> thunderbird_spn = factory.getOrMakeSourcePackageName('thunderbird')
216 >>> spph = factory.makeSourcePackagePublishingHistory(
217 ... sourcepackagename=thunderbird_spn, distroseries=hoary)
218 >>> logout()
219
208 >>> admin_browser.open('http://launchpad.dev/testy/+edit')220 >>> admin_browser.open('http://launchpad.dev/testy/+edit')
209 >>> admin_browser.getControl(name='field.bugtracker').value = ['external']221 >>> admin_browser.getControl(name='field.bugtracker').value = ['external']
210 >>> admin_browser.getControl(222 >>> admin_browser.getControl(
211223
=== modified file 'lib/lp/registry/browser/packaging.py'
--- lib/lp/registry/browser/packaging.py 2009-10-23 14:23:18 +0000
+++ lib/lp/registry/browser/packaging.py 2010-01-13 15:11:15 +0000
@@ -47,6 +47,15 @@
47 if sourcepackagename is None:47 if sourcepackagename is None:
48 message = "You must choose the source package name."48 message = "You must choose the source package name."
49 self.setFieldError('sourcepackagename', message)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
50 packaging_util = getUtility(IPackagingUtil)59 packaging_util = getUtility(IPackagingUtil)
51 if packaging_util.packagingEntryExists(60 if packaging_util.packagingEntryExists(
52 productseries=productseries,61 productseries=productseries,
5362
=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py 2009-12-05 18:37:28 +0000
+++ lib/lp/registry/browser/productseries.py 2010-01-13 15:11:15 +0000
@@ -33,6 +33,9 @@
3333
34from zope.component import getUtility34from zope.component import getUtility
35from zope.app.form.browser import TextAreaWidget, TextWidget35from zope.app.form.browser import TextAreaWidget, TextWidget
36from zope.formlib import form
37from zope.schema import Choice
38from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
3639
37from z3c.ptcompat import ViewPageTemplateFile40from z3c.ptcompat import ViewPageTemplateFile
3841
@@ -366,7 +369,7 @@
366369
367class ProductSeriesUbuntuPackagingView(PackagingAddView):370class ProductSeriesUbuntuPackagingView(PackagingAddView):
368371
369 field_names = ['sourcepackagename']372 field_names = ['sourcepackagename', 'distroseries']
370 page_title = 'Ubuntu source packaging'373 page_title = 'Ubuntu source packaging'
371 label = page_title374 label = page_title
372375
@@ -374,8 +377,8 @@
374 """Set the static packaging information for this series."""377 """Set the static packaging information for this series."""
375 super(ProductSeriesUbuntuPackagingView, self).__init__(378 super(ProductSeriesUbuntuPackagingView, self).__init__(
376 context, request)379 context, request)
377 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu380 self._ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
378 self._ubuntu_series = ubuntu.currentseries381 self._ubuntu_series = self._ubuntu.currentseries
379 try:382 try:
380 package = self.context.getPackage(self._ubuntu_series)383 package = self.context.getPackage(self._ubuntu_series)
381 self.default_sourcepackagename = package.sourcepackagename384 self.default_sourcepackagename = package.sourcepackagename
@@ -383,6 +386,27 @@
383 # The package has never been set.386 # The package has never been set.
384 self.default_sourcepackagename = None387 self.default_sourcepackagename = None
385388
389 def setUpFields(self):
390 """See `LaunchpadFormView`.
391
392 The packaging is restricted to ubuntu series and the default value
393 is the current development series.
394 """
395 super(ProductSeriesUbuntuPackagingView, self).setUpFields()
396 series_vocabulary = SimpleVocabulary(
397 [SimpleTerm(series, series.name, series.named_version)
398 for series in self._ubuntu.series])
399 choice = Choice(__name__='distroseries',
400 title=_('Series'),
401 default=self._ubuntu_series,
402 vocabulary=series_vocabulary,
403 description=_(
404 "Series where this package is published. The current series "
405 "is most important to the Ubuntu community."),
406 required=True)
407 field = form.Fields(choice, render_context=self.render_context)
408 self.form_fields = self.form_fields.omit(choice.__name__) + field
409
386 def setUpWidgets(self):410 def setUpWidgets(self):
387 """See `LaunchpadFormView`.411 """See `LaunchpadFormView`.
388412
389413
=== modified file 'lib/lp/registry/browser/tests/packaging-views.txt'
--- lib/lp/registry/browser/tests/packaging-views.txt 2009-12-10 20:03:11 +0000
+++ lib/lp/registry/browser/tests/packaging-views.txt 2010-01-13 15:11:15 +0000
@@ -18,6 +18,8 @@
18 >>> sourcepackagename = factory.makeSourcePackageName('hot')18 >>> sourcepackagename = factory.makeSourcePackageName('hot')
19 >>> sourcepackage = factory.makeSourcePackage(19 >>> sourcepackage = factory.makeSourcePackage(
20 ... sourcepackagename=sourcepackagename, distroseries=hoary)20 ... sourcepackagename=sourcepackagename, distroseries=hoary)
21 >>> spph = factory.makeSourcePackagePublishingHistory(
22 ... sourcepackagename=sourcepackagename, distroseries=hoary)
21 >>> product = factory.makeProduct(name="hot", displayname='Hot')23 >>> product = factory.makeProduct(name="hot", displayname='Hot')
22 >>> productseries = factory.makeProductSeries(24 >>> productseries = factory.makeProductSeries(
23 ... product=product, name='hotter')25 ... product=product, name='hotter')
@@ -103,6 +105,22 @@
103 ('sourcepackagename', u'Source Package Name', RequiredMissing())105 ('sourcepackagename', u'Source Package Name', RequiredMissing())
104 You must choose the source package name.106 You must choose the source package name.
105107
108In the case of full functionality distributions like Ubuntu, the source
109package must be published in the distro series.
110
111 >>> vapor_spn = factory.makeSourcePackageName('vapor')
112 >>> form = {
113 ... 'field.distroseries': 'ubuntu/hoary',
114 ... 'field.sourcepackagename': 'vapor',
115 ... 'field.packaging': 'Primary Project',
116 ... 'field.actions.continue': 'Continue',
117 ... }
118 >>> view = create_initialized_view(
119 ... productseries, '+addpackage', form=form)
120 >>> for error in view.errors:
121 ... print error
122 The source package is not published in Hoary.
123
106The +addpackage view provides the default_distroseries property. It is None124The +addpackage view provides the default_distroseries property. It is None
107by default, but subclasses may change it.125by default, but subclasses may change it.
108126
@@ -129,16 +147,27 @@
129 Ubuntu source packaging147 Ubuntu source packaging
130148
131 >>> print view.field_names149 >>> print view.field_names
132 ['sourcepackagename']150 ['sourcepackagename', 'distroseries']
133151
134 >>> print view.cancel_url152 >>> print view.cancel_url
135 http://launchpad.dev/hot/hotter153 http://launchpad.dev/hot/hotter
136154
137The view restricts the packaging to the current Ubuntu series.155The view restricts the packaging to Ubuntu series, and default is the current
156Ubuntu series.
138157
139 >>> print view.default_distroseries.name158 >>> print view.default_distroseries.name
140 hoary159 hoary
141160
161 >>> print view.widgets['distroseries']._getDefault().name
162 hoary
163
164 >>> for term in view.widgets['distroseries'].vocabulary:
165 ... print term.title
166 Breezy Badger Autotest (6.6.6)
167 Grumpy (5.10)
168 Hoary (5.04)
169 Warty (4.10)
170
142The sourcepackagename is None if the package link was never set. The view's171The sourcepackagename is None if the package link was never set. The view's
143packaging history is empty, and the sourcepackagename widget is empty.172packaging history is empty, and the sourcepackagename widget is empty.
144173
@@ -172,6 +201,10 @@
172201
173The package in the current Ubuntu series can be updated.202The package in the current Ubuntu series can be updated.
174203
204 >>> thunderbird_spn = factory.getOrMakeSourcePackageName('thunderbird')
205 >>> spph = factory.makeSourcePackagePublishingHistory(
206 ... sourcepackagename=thunderbird_spn, distroseries=hoary)
207
175 >>> form = {208 >>> form = {
176 ... 'field.sourcepackagename': 'thunderbird',209 ... 'field.sourcepackagename': 'thunderbird',
177 ... 'field.actions.continue': 'Update',210 ... 'field.actions.continue': 'Update',
@@ -211,6 +244,8 @@
211 >>> login('admin@canonical.com')244 >>> login('admin@canonical.com')
212 >>> hoary.status = DistroSeriesStatus.CURRENT245 >>> hoary.status = DistroSeriesStatus.CURRENT
213 >>> grumpy_series = ubuntu.getSeries('grumpy')246 >>> grumpy_series = ubuntu.getSeries('grumpy')
247 >>> spph = factory.makeSourcePackagePublishingHistory(
248 ... sourcepackagename=sourcepackagename, distroseries=grumpy_series)
214 >>> grumpy_series.status = DistroSeriesStatus.FROZEN249 >>> grumpy_series.status = DistroSeriesStatus.FROZEN
215250
216 >>> a_user = factory.makePerson(name="hedgehog")251 >>> a_user = factory.makePerson(name="hedgehog")
217252
=== modified file 'lib/lp/registry/stories/product/xx-product-package-pages.txt'
--- lib/lp/registry/stories/product/xx-product-package-pages.txt 2009-11-12 23:24:53 +0000
+++ lib/lp/registry/stories/product/xx-product-package-pages.txt 2010-01-13 15:11:15 +0000
@@ -35,14 +35,15 @@
3535
36 >>> evo_owner.getLink(url='/ubuntu/hoary/+source/evolution') is not None36 >>> evo_owner.getLink(url='/ubuntu/hoary/+source/evolution') is not None
37 True37 True
38 >>> evo_owner.getLink(url='/evolution/trunk/+addpackage') is not None38
39 True39Any logged in users can still see the links to create a packaging link.
4040
41If you're not the owner or an admin, you still see the packages, but without41 >>> user_browser.open('http://launchpad.dev/evolution/+packages')
42the link to add packages yourself.42 >>> print user_browser.getLink(url='/evolution/trunk/+ubuntupkg').url
4343 http://launchpad.dev/evolution/trunk/+ubuntupkg
44 >>> browser.open('http://launchpad.dev/evolution/+packages')44
45 >>> browser.getLink(url='/evolution/trunk/+addpackage')45 >>> anon_browser.open('http://launchpad.dev/evolution/+packages')
46 >>> anon_browser.getLink(url='/evolution/trunk/+ubuntupkg')
46 Traceback (most recent call last):47 Traceback (most recent call last):
47 ...48 ...
48 LinkNotFoundError49 LinkNotFoundError
4950
=== modified file 'lib/lp/registry/stories/productseries/xx-productseries-index.txt'
--- lib/lp/registry/stories/productseries/xx-productseries-index.txt 2009-10-30 15:40:55 +0000
+++ lib/lp/registry/stories/productseries/xx-productseries-index.txt 2010-01-13 15:11:15 +0000
@@ -130,14 +130,11 @@
130 This series is not packaged in any distribution series.130 This series is not packaged in any distribution series.
131131
132132
133The driver sees two packaging links near the distribution packaging.133The driver sees a packaging link near the distribution packaging.
134134
135 >>> driver_browser.getLink('Link to Ubuntu package')135 >>> driver_browser.getLink('Link to Ubuntu package')
136 <Link ... url='http://launchpad.dev/firefox/trunk/+ubuntupkg'>136 <Link ... url='http://launchpad.dev/firefox/trunk/+ubuntupkg'>
137137
138 >>> driver_browser.getLink('Link package')
139 <Link ... url='http://launchpad.dev/firefox/trunk/+addpackage'>
140
141There is a section that lists related links to this series138There is a section that lists related links to this series
142139
143 >>> anon_browser.getLink('View series for the Mozilla Firefox project')140 >>> anon_browser.getLink('View series for the Mozilla Firefox project')
144141
=== modified file 'lib/lp/registry/templates/product-packages.pt'
--- lib/lp/registry/templates/product-packages.pt 2009-11-12 23:24:53 +0000
+++ lib/lp/registry/templates/product-packages.pt 2010-01-13 15:11:15 +0000
@@ -85,9 +85,9 @@
85 </table>85 </table>
8686
87 <ul class="table-actions"87 <ul class="table-actions"
88 tal:condition="series/menu:overview/add_package/linked">88 tal:condition="series/menu:overview/ubuntupkg/linked">
89 <li>89 <li>
90 <a tal:replace="structure series/menu:overview/add_package/fmt:link" />90 <a tal:replace="structure series/menu:overview/ubuntupkg/fmt:link" />
91 </li>91 </li>
92 </ul>92 </ul>
93 </div>93 </div>
9494
=== modified file 'lib/lp/registry/templates/productseries-portlet-packages.pt'
--- lib/lp/registry/templates/productseries-portlet-packages.pt 2009-10-22 19:16:03 +0000
+++ lib/lp/registry/templates/productseries-portlet-packages.pt 2010-01-13 15:11:15 +0000
@@ -39,8 +39,5 @@
39 <li>39 <li>
40 <a tal:replace="structure context/menu:overview/ubuntupkg/fmt:icon-link" />40 <a tal:replace="structure context/menu:overview/ubuntupkg/fmt:icon-link" />
41 </li>41 </li>
42 <li>
43 <a tal:replace="structure context/menu:overview/add_package/fmt:icon-link" />
44 </li>
45 </ul>42 </ul>
46</div>43</div>
4744
=== modified file 'lib/lp/registry/templates/productseries-ubuntupkg.pt'
--- lib/lp/registry/templates/productseries-ubuntupkg.pt 2009-10-21 21:16:09 +0000
+++ lib/lp/registry/templates/productseries-ubuntupkg.pt 2010-01-13 15:11:15 +0000
@@ -17,31 +17,14 @@
17 translations from Ubuntu to the17 translations from Ubuntu to the
18 <span tal:replace="context/product/displayname">Firefox</span> team.18 <span tal:replace="context/product/displayname">Firefox</span> team.
19 </p>19 </p>
20
21 <p>20 <p>
22 Use21 Verify that the version packaged in the Ubuntu series is based on
23 <a tal:replace="structure context/menu:overview/add_package/fmt:link" />22 the <tal:series replace="context/title" />. Don&rsquo;t link "HEAD",
24 to link this series to packages in other distribution series.23 "MAIN", "MASTER", or "TRUNK" to an Ubuntu package unless you are
24 certain that the package is based on the trunk of development.
25 </p>25 </p>
26 </div>26
2727 <div metal:use-macro="context/@@launchpad_form/form" />
28 <div class="portlet">
29 <div metal:use-macro="context/@@launchpad_form/form">
30 <div metal:fill-slot="extra_info">
31 <h2>
32 Package in
33 <span tal:replace="view/default_distroseries/title" />
34 </h2>
35
36 <p>
37 Ensure both the <tal:series replace="context/title" /> and the
38 Ubuntu package are exactly correct. Don&rsquo;t link "HEAD",
39 "MAIN", or "TRUNK" to an Ubuntu package unless you are
40 absolutely certain that the package is really based on the
41 trunk of development.
42 </p>
43 </div>
44 </div>
45 </div>28 </div>
4629
47 <div class="portlet"30 <div class="portlet"
4831
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-01-11 23:43:59 +0000
+++ lib/lp/testing/factory.py 2010-01-13 15:11:15 +0000
@@ -277,10 +277,11 @@
277 def makeGPGKey(self, owner):277 def makeGPGKey(self, owner):
278 """Give 'owner' a crappy GPG key for the purposes of testing."""278 """Give 'owner' a crappy GPG key for the purposes of testing."""
279 key_id = self.getUniqueHexString(digits=8).upper()279 key_id = self.getUniqueHexString(digits=8).upper()
280 fingerprint = key_id + 'A' * 32
280 return getUtility(IGPGKeySet).new(281 return getUtility(IGPGKeySet).new(
281 owner.id,282 owner.id,
282 keyid=key_id,283 keyid=key_id,
283 fingerprint='A' * 40,284 fingerprint=fingerprint,
284 keysize=self.getUniqueInteger(),285 keysize=self.getUniqueInteger(),
285 algorithm=GPGKeyAlgorithm.R,286 algorithm=GPGKeyAlgorithm.R,
286 active=True,287 active=True,