Merge lp:~edwin-grubbs/launchpad/bug-553384-deactivated-project-oops into lp:launchpad
| Status: | Merged |
|---|---|
| Approved by: | Gavin Panella on 2010-04-21 |
| Approved revision: | no longer in the source branch. |
| Merged at revision: | not available |
| Proposed branch: | lp:~edwin-grubbs/launchpad/bug-553384-deactivated-project-oops |
| Merge into: | lp:launchpad |
| Diff against target: |
654 lines (+190/-101) 20 files modified
lib/lp/answers/doc/person.txt (+4/-0) lib/lp/blueprints/doc/specification.txt (+12/-8) lib/lp/blueprints/doc/sprint.txt (+12/-8) lib/lp/bugs/browser/bugalsoaffects.py (+0/-20) lib/lp/bugs/browser/tests/bugtask-adding-views.txt (+0/-36) lib/lp/registry/browser/product.py (+18/-4) lib/lp/registry/browser/tests/product-views.txt (+23/-5) lib/lp/registry/doc/milestone.txt (+4/-0) lib/lp/registry/doc/person.txt (+4/-0) lib/lp/registry/doc/pillar.txt (+3/-0) lib/lp/registry/doc/product.txt (+9/-3) lib/lp/registry/doc/project.txt (+9/-1) lib/lp/registry/model/product.py (+12/-1) lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt (+15/-8) lib/lp/registry/stories/product/xx-product-edit.txt (+7/-7) lib/lp/registry/stories/project/xx-project-index.txt (+6/-0) lib/lp/registry/tests/test_product.py (+28/-0) lib/lp/testing/__init__.py (+14/-0) lib/lp/translations/doc/translationimportqueue.txt (+3/-0) lib/lp/translations/stories/translationgroups/30-show-group-translation-targets.txt (+7/-0) |
| To merge this branch: | bzr merge lp:~edwin-grubbs/launchpad/bug-553384-deactivated-project-oops |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Gavin Panella (community) | 2010-04-20 | Approve on 2010-04-21 | |
| Brad Crittenden (community) | code | Approve on 2010-04-21 | |
|
Review via email:
|
|||
Commit Message
Don't let a project linked to source packages be deactivated, since it will cause an oops on the $sourcepackage/
Description of the Change
Summary
-------
Fixed bug 553384 and bug 140526.
The $sourcepackage/
inactive project. To prevent this, it should not be possible to deactivate
a project until all its links to source packages have been removed.
Implementation details
-------
Don't allow deactivation of products linked to source packages in the
model or in the views.
lib/
lib/
lib/
lib/
Removed workaround for bug 140526:
lib/
lib/
Fixed tests:
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
lib/
Tests
-----
./bin/test -vv -t 'test_product|
Demo and Q/A
------------
* Open http://
* Uncheck the "active" input.
* Click "Change"
* The "active" field should have the error message:
"This project cannot be deactivated since it is still linked to
source packages."
* Open http://
* Uncheck the "active" input.
* Click "Change"
* The "active" field should have the error message:
"This project cannot be deactivated since it is still linked to
source packages."
| Brad Crittenden (bac) wrote : | # |
Hi Edwin,
Thanks for making this fix...it sure had lots of tentacles.
> === modified file 'lib/lp/
> --- lib/lp/
+++ lib/lp/
> @@ -351,6 +351,10 @@
> supported projects.
>
> >>> login('<email address hidden>')
> +
> + # A product cannot be deactivated if it is linked to source packages.
I think this comment would be easier to read in context if it were
phrased positively, i.e.
# Unlink the source packages so the firefox project can be deactivated.
I see you've repeated the phrase many, many times in your changes.
I'll leave it up to you to decide whether you want to make the wording
change everywhere as it is only a minor improvement.
> + >>> from lp.testing import unlink_
> + >>> unlink_
> >>> firefox.active = False
> >>> sorted(target.name
> ... for target in no_priv.
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -103,26 +103,6 @@
> bugtask = self.context
> upstream = bugtask.
> if upstream is not None:
> - if not upstream.active:
> - # XXX: Guilherme Salgado 2007-09-18 bug=140526: This is only
> - # possible because of bug 140526, which allows packages to
> - # be linked to inactive products.
> - series = bugtask.
> - assert series is not None, (
> - "This package is linked to a product series so this "
> - "package's distribution must have at least one distro "
> - "series.")
> - sourcepackage = series.
> - bugtask.
> - self.request.
> - structured(
> - _("""
> - This package is linked to an inactive upstream. You
> - can <a href="%
> - to avoid this step in the future."""),
> - package_
> - return
> -
I'm really glad you found and removed these.
> try:
> valid_upstreamt
> except WidgetsError:
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -1444,6 +1444,15 @@
> """See `LaunchpadFormV
> self.validate_
>
> + if data['active'] == False and self.context.active == True:
> + if len(self.
> + self.setFieldEr
> + structured(
> + 'This project cannot be dea...
| Edwin Grubbs (edwin-grubbs) wrote : | # |
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -352,7 +352,7 @@
>>> login('<email address hidden>')
- # A product cannot be deactivated if it is linked to source packages.
+ # Unlink the source packages so the project can be deactivated.
>>> from lp.testing import unlink_
>>> unlink_
>>> firefox.active = False
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -208,7 +208,7 @@
>>> from canonical.
>>> login('<email address hidden>')
- # A product cannot be deactivated if it is linked to source packages.
+ # Unlink the source packages so the project can be deactivated.
>>> from lp.testing import unlink_
>>> unlink_
>>> upstream_
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -156,7 +156,7 @@
>>> firefox = getUtility(
>>> login("<email address hidden>")
- # A product cannot be deactivated if it is linked to source packages.
+ # Unlink the source packages so the project can be deactivated.
>>> from lp.testing import unlink_
>>> unlink_
>>> firefox.active = False
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -1376,7 +1376,7 @@
return self.next_url
-class EditPrivateBugs
+class ProductValidati
def validate_
"""Perform validation for the private bugs setting."""
@@ -1387,8 +1387,20 @@
-
-class ProductAdminVie
+ def validate_
+ """Verify whether a product can be safely deactivated."""
+ if data['active'] == False and self.context.active == True:
+ if len(self.
+ self.setFieldEr
+ structured(
+ 'This project cannot be deactivated since it is '
+ 'linked to one or more '
+ '<a href="%s">source packages</a>.',
+ canonical_
+
+
+class ProductAdminVie
+ """View for $project/+admin"""
label = "Administer project details"
field_names = ["name", "owner", "active", "autoupdate", "private_bugs"]
@@ -1443,15 +1455,7 @@
def validate(self, data):
"""See `La...
| Edwin Grubbs (edwin-grubbs) wrote : | # |
> Hi Edwin,
>
> This is nice, and it's good to see some XXXs go in the process. The
> view code with the Storm validator as a backstop is elegant.
>
> I've got a few questions and comments, so Needs Information for now.
>
> Cheers, Gavin.
>
Hi Gavin and Brad,
Thanks for the reviews. The incremental diff is in the previous comment.
> > === modified file 'lib/lp/
> > --- lib/lp/
> > +++ lib/lp/
> > @@ -1444,6 +1444,15 @@
> > """See `LaunchpadFormV
> > self.validate_
> >
> > + if data['active'] == False and self.context.active == True:
> > + if len(self.
> > + self.setFieldEr
> > + structured(
> > + 'This project cannot be deactivated since it is '
> > + 'linked to '
> > + '<a href="%
> > + canonical_
>
> You could change this to instead pass view_name=
> canonical_url().
Fixed.
> It is worth showing this message before the user tries to deactivate
> the project? Perhaps a message next to the control, and the control
> disabled.
That's a nice idea, however, the validation would still be necessary for
race conditions when the form is displayed before the source package is
linked. Since deactivation will be done much more often by reviewers
than regular users, I don't know if it is worth it. I believe Curtis
still reviews most of the projects, so I'll ask him.
> Also, the text "This project cannot be deactivated since it is linked
> to source packages" doesn't sound quite right. How about "... linked
> to one or more source packages"?
Fixed.
> Perhaps it's worth getting a UI review?
Since I'm already talking to Curtis, and he's a UI reviewer, I'll ask him.
> > +
> > @property
> > def cancel_url(self):
> > """See `LaunchpadFormV
> > @@ -1491,6 +1500,15 @@
> > # supervisor.
> > self.validate_
> >
> > + if data['active'] == False and self.context.active == True:
> > + if len(self.
> > + self.setFieldEr
> > + structured(
> > + 'This project cannot be deactivated since it is '
> > + 'linked to '
> > + '<a href="%
> > + canonical_
>
> Same here, re. view_name.
>
> ProductReviewLi
> in ProductAdminVie
> that both ProductAdminView and ProductReviewLi
Done.
> > +
> >
> > class ProductAddSerie
> > """A form to add new product series"""
> >
> > === modified file 'lib/lp/
> > --- lib/lp/
| Curtis Hovey (sinzui) wrote : | # |
Hello Edwin, et al.
Regarding who and how projects are deactivated...
Users cannot deactivate a project, reviewers and admins can. The rule of not deactivating a linked project seemed obvious 6 months ago and I have always deleted bad packaging links /before/ deactivating a project. It is clear from the oops this was not obvious to everyone so I reported a bug to stop other reviewers from doing the wrong thing.
I do not deactivate projects with legitimate links to Ubuntu. This has frustrated two users who think their desires outweigh the community. We *will not* deactivate any linked project because someone else will just have it reactivated.
This issue relates to series deletion. Users cannot delete a series that is linked to a package. The user can delete the packaing links. In the case of the sugar project, the user recreated links for the correct series.

Hi Edwin,
This is nice, and it's good to see some XXXs go in the process. The
view code with the Storm validator as a backstop is elegant.
I've got a few questions and comments, so Needs Information for now.
Cheers, Gavin.
> === modified file 'lib/lp/ answers/ doc/person. txt' answers/ doc/person. txt 2010-02-05 21:25:23 +0000 answers/ doc/person. txt 2010-04-21 11:03:32 +0000 source_ packages source_ packages( firefox) getDirectAnswer QuestionTargets ()) blueprints/ doc/specificati on.txt' blueprints/ doc/specificati on.txt 2009-08-13 19:03:36 +0000 blueprints/ doc/specificati on.txt 2010-04-21 11:03:32 +0000 database. sqlbase import flush_database_ updates firefox. active = False updates( ) specifications( filter= ['install' ]): installation kubuntu -check ubuntu database. sqlbase import flush_database_ updates source_ packages source_ packages( upstream_ firefox) firefox. active = False updates( ) specifications( filter= ['install' ]): installation kubuntu -check ubuntu blueprints/ doc/sprint. txt' blueprints/ doc/sprint. txt 2010-02-17 11:13:06 +0000 blueprints/ doc/sprint. txt 2010-04-21 11:03:32 +0000 launchpad. interfaces import IProductSet launchpad. ftests import login IProductSet) .getByName( 'firefox' ) updates( ) ons().count( ) launchpad. interfaces import IProductSet launchpad. ftests import login IProductSet) .getByName( 'firefox' ) source_ packages source_ packages( firefox) updates( ) ons().count( )
> --- lib/lp/
> +++ lib/lp/
> @@ -351,6 +351,10 @@
> supported projects.
>
> >>> login('<email address hidden>')
> +
> + # A product cannot be deactivated if it is linked to source packages.
> + >>> from lp.testing import unlink_
> + >>> unlink_
> >>> firefox.active = False
> >>> sorted(target.name
> ... for target in no_priv.
>
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -205,14 +205,18 @@
>
> Specs from inactive products are filtered out.
>
> - >>> from canonical.
> - >>> login('<email address hidden>')
> - >>> upstream_
> - >>> flush_database_
> - >>> for spec in specset.
> - ... print spec.name, spec.target.name
> - cluster-
> - media-integrity
> + >>> from canonical.
> + >>> login('<email address hidden>')
> +
> + # A product cannot be deactivated if it is linked to source packages.
> + >>> from lp.testing import unlink_
> + >>> unlink_
> + >>> upstream_
> + >>> flush_database_
> + >>> for spec in specset.
> + ... print spec.name, spec.target.name
> + cluster-
> + media-integrity
>
>
> Reset firefox so we don't mess up later tests.
>
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -151,14 +151,18 @@
>
> Inactive products are excluded from the listings.
>
> - >>> from canonical.
> - >>> from canonical.
> - >>> firefox = getUtility(
> - >>> login("<email address hidden>")
> - >>> firefox.active = False
> - >>> flush_database_
> - >>> ubz.specificati
> - 0
> + >>> from canonical.
> + >>> from canonical.
> + >>> firefox = getUtility(
> + >>> login("<email address hidden>")
> +
> + # A product cannot be deactivated if it is linked to source packages.
> + >>> from lp.testing import unlink_
> + >>> unlink_
> + >>> firefox.active = False
> + >>> flush_database_
> + >>> ubz.specificati
> + 0
>
> ...