> As we discussed on IRC "PPA that must be removed" should be "PPA that must be
> deleted" since that is the link the user must use.
>
> has_ppa_with_published_packages() will allow users to merge active ppas
> without packages. I think these ppas will show up in searches. Can you talk to
> someone on the soyuz team
Hi Curtis,
Thanks for the review.
I have changed the condition to not allow merges on a person or team with a PPA in the ACTIVE or DELETING status whether or not it has published packages, so that links to merged persons don't show up in https://launchpad.net/~PERSON/+archivesubscriptions
Incremental Diff:
=== modified file 'lib/lp/registry/browser/peoplemerge.py'
--- lib/lp/registry/browser/peoplemerge.py 2010-12-15 20:17:39 +0000
+++ lib/lp/registry/browser/peoplemerge.py 2010-12-17 04:08:34 +0000
@@ -134,11 +134,12 @@ mapping=dict(name=dupe_person.name)))
# We cannot merge the teams if there is a PPA with published
# packages on the duplicate person, unless that PPA is removed.
- if dupe_person.has_ppa_with_published_packages:
+ if dupe_person.has_existing_ppa: self.addError(_(
- "${name} has a PPA that must be removed before it "
- "can be merged.", mapping=dict(name=dupe_person.name)))
-
+ "${name} has a PPA that must be deleted before it "
+ "can be merged. It may take ten minutes to remove the "
+ "deleted PPA's files.",
+ mapping=dict(name=dupe_person.name)))
def render(self):
# Subclasses may define other actions that they will render manually
- def test_cannot_merge_team_with_ppa_containing_published_packages(self):
- # A team with a published PPA cannot be merged.
+ def test_cannot_merge_team_with_ppa(self):
+ # A team with a PPA cannot be merged. login_celebrity('admin') self.dupe_team.subscriptionpolicy = TeamSubscriptionPolicy.MODERATED
archive = self.dupe_team.createPPA()
- self.factory.makeSourcePackagePublishingHistory(archive=archive) login_celebrity('registry_experts')
view = self.getView() self.assertEqual(
- [u'dupe-team has a PPA that must be removed before '
- 'it can be merged.'],
+ [u"dupe-team has a PPA that must be deleted before it can be "
+ "merged. It may take ten minutes to remove the deleted PPA's "
+ "files."], view.errors)
- def test_cannot_merge_person_with_ppa_containing_published_packages(self):
- # The PPA must be removed before the person can be merged.
+ def test_cannot_merge_person_with_ppa(self):
+ # A person with a PPA cannot be merged. login_celebrity('admin')
archive = self.dupe_person.createPPA()
- self.factory.makeSourcePackagePublishingHistory(archive=archive)
view = self.getView() self.assertEqual(
- [u'dupe-person has a PPA that must be removed before '
- 'it can be merged.'],
+ [u"dupe-person has a PPA that must be deleted before it can be "
+ "merged. It may take ten minutes to remove the deleted PPA's "
+ "files."], view.errors)
=== modified file 'lib/lp/registry/doc/person-merge.txt'
--- lib/lp/registry/doc/person-merge.txt 2010-12-15 20:17:39 +0000
+++ lib/lp/registry/doc/person-merge.txt 2010-12-17 04:07:56 +0000
@@ -446,7 +446,6 @@
>>> person_with_ppa = factory.makePerson()
>>> other_person = factory.makePerson()
>>> archive = person_with_ppa.createPPA()
- >>> ignore = factory.makeSourcePackagePublishingHistory(archive=archive)
>>> email = IMasterObject(person_with_ppa.preferredemail)
>>> email.status = EmailAddressStatus.VALIDATED
>>> email.destroySelf()
@@ -454,4 +453,4 @@
>>> personset.merge(person_with_ppa, other_person)
Traceback (most recent call last):
...
- AssertionError: from_person still has ppas with published packages.
+ AssertionError: from_person has a ppa in ACTIVE or DELETING status
+ has_existing_ppa = Bool(
+ title=_("Does this person have a ppa that is active or not fully "
+ "deleted?"),
+ readonly=True, required=False)
+
has_ppa_with_published_packages = Bool( title=_("Does this person have a ppa with published packages?"), readonly=True, required=False)
@property
+ def has_existing_ppa(self):
+ """See `IPerson`."""
+ result = Store.of(self).find(
+ Archive,
+ Archive.owner == self.id,
+ Archive.purpose == ArchivePurpose.PPA,
+ Archive.status.is_in(
+ [ArchiveStatus.ACTIVE, ArchiveStatus.DELETING]))
+ return not result.is_empty()
+
+ @property
def has_ppa_with_published_packages(self):
+ """See `IPerson`."""
result = Store.of(self).find( Archive, SourcePackagePublishingHistory.archive == Archive.id,
@@ -3862,9 +3874,9 @@
if getUtility(IEmailAddressSet).getByPerson(from_person).count() > 0:
raise AssertionError('from_person still has email addresses.')
- if from_person.has_ppa_with_published_packages:
+ if from_person.has_existing_ppa:
raise AssertionError(
- 'from_person still has ppas with published packages.')
+ 'from_person has a ppa in ACTIVE or DELETING status')
if from_person.is_team and from_person.allmembers.count() > 0:
raise AssertionError(
> As we discussed on IRC "PPA that must be removed" should be "PPA that must be with_published_ packages( ) will allow users to merge active ppas
> deleted" since that is the link the user must use.
>
> has_ppa_
> without packages. I think these ppas will show up in searches. Can you talk to
> someone on the soyuz team
Hi Curtis,
Thanks for the review.
I have changed the condition to not allow merges on a person or team with a PPA in the ACTIVE or DELETING status whether or not it has published packages, so that links to merged persons don't show up in https:/ /launchpad. net/~PERSON/ +archivesubscri ptions
Incremental Diff:
=== modified file 'lib/lp/ registry/ browser/ peoplemerge. py' registry/ browser/ peoplemerge. py 2010-12-15 20:17:39 +0000 registry/ browser/ peoplemerge. py 2010-12-17 04:08:34 +0000
mapping= dict(name= dupe_person. name))) has_ppa_ with_published_ packages: has_existing_ ppa:
self. addError( _( dict(name= dupe_person. name))) dict(name= dupe_person. name)))
--- lib/lp/
+++ lib/lp/
@@ -134,11 +134,12 @@
# We cannot merge the teams if there is a PPA with published
# packages on the duplicate person, unless that PPA is removed.
- if dupe_person.
+ if dupe_person.
- "${name} has a PPA that must be removed before it "
- "can be merged.", mapping=
-
+ "${name} has a PPA that must be deleted before it "
+ "can be merged. It may take ten minutes to remove the "
+ "deleted PPA's files.",
+ mapping=
def render(self):
# Subclasses may define other actions that they will render manually
=== modified file 'lib/lp/ registry/ browser/ tests/test_ peoplemerge. py' registry/ browser/ tests/test_ peoplemerge. py 2010-12-15 20:17:39 +0000 registry/ browser/ tests/test_ peoplemerge. py 2010-12-17 04:07:09 +0000
self. assertEqual( [], view.errors)
self. assertEqual( self.target_ team, self.dupe_ team.merged)
--- lib/lp/
+++ lib/lp/
@@ -156,17 +156,17 @@
- def test_cannot_ merge_team_ with_ppa_ containing_ published_ packages( self): merge_team_ with_ppa( self):
login_ celebrity( 'admin' )
self. dupe_team. subscriptionpol icy = TeamSubscriptio nPolicy. MODERATED team.createPPA( ) makeSourcePacka gePublishingHis tory(archive= archive)
login_ celebrity( 'registry_ experts' )
self. assertEqual(
view. errors)
- # A team with a published PPA cannot be merged.
+ def test_cannot_
+ # A team with a PPA cannot be merged.
archive = self.dupe_
- self.factory.
view = self.getView()
- [u'dupe-team has a PPA that must be removed before '
- 'it can be merged.'],
+ [u"dupe-team has a PPA that must be deleted before it can be "
+ "merged. It may take ten minutes to remove the deleted PPA's "
+ "files."],
def test_registry_ delete_ team_with_ super_teams( self): initialized_ view(
self. person_ set, '+adminpeopleme rge', form=form)
@@ -205,13 +205,13 @@
return create_
- def test_cannot_ merge_person_ with_ppa_ containing_ published_ packages( self): merge_person_ with_ppa( self):
login_ celebrity( 'admin' ) person. createPPA( ) makeSourcePacka gePublishingHis tory(archive= archive)
self. assertEqual(
view. errors)
- # The PPA must be removed before the person can be merged.
+ def test_cannot_
+ # A person with a PPA cannot be merged.
archive = self.dupe_
- self.factory.
view = self.getView()
- [u'dupe-person has a PPA that must be removed before '
- 'it can be merged.'],
+ [u"dupe-person has a PPA that must be deleted before it can be "
+ "merged. It may take ten minutes to remove the deleted PPA's "
+ "files."],
=== modified file 'lib/lp/ registry/ doc/person- merge.txt' registry/ doc/person- merge.txt 2010-12-15 20:17:39 +0000 registry/ doc/person- merge.txt 2010-12-17 04:07:56 +0000 makePerson( ) makePerson( ) with_ppa. createPPA( ) makeSourcePacka gePublishingHis tory(archive= archive) person_ with_ppa. preferredemail) tus.VALIDATED merge(person_ with_ppa, other_person)
--- lib/lp/
+++ lib/lp/
@@ -446,7 +446,6 @@
>>> person_with_ppa = factory.
>>> other_person = factory.
>>> archive = person_
- >>> ignore = factory.
>>> email = IMasterObject(
>>> email.status = EmailAddressSta
>>> email.destroySelf()
@@ -454,4 +453,4 @@
>>> personset.
Traceback (most recent call last):
...
- AssertionError: from_person still has ppas with published packages.
+ AssertionError: from_person has a ppa in ACTIVE or DELETING status
=== modified file 'lib/lp/ registry/ interfaces/ person. py' registry/ interfaces/ person. py 2010-12-15 20:07:54 +0000 registry/ interfaces/ person. py 2010-12-17 01:05:21 +0000
value_ type=Reference( schema= Interface) ))
--- lib/lp/
+++ lib/lp/
@@ -862,6 +862,11 @@
# Really IArchive, see archive.py
+ has_existing_ppa = Bool( ppa_with_ published_ packages = Bool(
title= _("Does this person have a ppa with published packages?"),
readonly= True, required=False)
+ title=_("Does this person have a ppa that is active or not fully "
+ "deleted?"),
+ readonly=True, required=False)
+
has_
=== modified file 'lib/lp/ registry/ model/person. py' registry/ model/person. py 2010-12-15 20:07:54 +0000 registry/ model/person. py 2010-12-17 04:09:17 +0000
owner= self, purpose= ArchivePurpose. PPA, orderBy='name')
--- lib/lp/
+++ lib/lp/
@@ -2752,7 +2752,19 @@
@property ppa(self) : self).find( status. is_in( ACTIVE, ArchiveStatus. DELETING] )) with_published_ packages( self): self).find(
Archive,
SourcePac kagePublishingH istory. archive == Archive.id, IEmailAddressSe t).getByPerson( from_person) .count( ) > 0: 'from_person still has email addresses.')
+ def has_existing_
+ """See `IPerson`."""
+ result = Store.of(
+ Archive,
+ Archive.owner == self.id,
+ Archive.purpose == ArchivePurpose.PPA,
+ Archive.
+ [ArchiveStatus.
+ return not result.is_empty()
+
+ @property
def has_ppa_
+ """See `IPerson`."""
result = Store.of(
@@ -3862,9 +3874,9 @@
if getUtility(
raise AssertionError(
- if from_person. has_ppa_ with_published_ packages: has_existing_ ppa:
+ if from_person.
raise AssertionError(
- 'from_person still has ppas with published packages.')
+ 'from_person has a ppa in ACTIVE or DELETING status')
if from_person.is_team and from_person. allmembers. count() > 0:
raise AssertionError(