[Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
The proposal to merge ~pappacena/launchpad:delete-oci-project into launchpad:master has been updated. Status: Approved => Merged For more details, see: https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 -- Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
[Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
The proposal to merge ~pappacena/launchpad:delete-oci-project into launchpad:master has been updated. Status: Needs review => Approved For more details, see: https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 -- Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
Re: [Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Added the requested change. It should be good to go now. Diff comments: > diff --git a/lib/lp/registry/model/ociproject.py > b/lib/lp/registry/model/ociproject.py > index 3cf675f..15f552c 100644 > --- a/lib/lp/registry/model/ociproject.py > +++ b/lib/lp/registry/model/ociproject.py > @@ -299,6 +300,36 @@ class OCIProject(BugTargetBase, StormBase): > return [] > return BRANCH_POLICY_ALLOWED_TYPES[self.pillar.branch_sharing_policy] > > +def destroySelf(self): > +"""See `IOCIProject`.""" > +from lp.bugs.model.bugtask import BugTask > +from lp.code.model.gitrepository import GitRepository > +from lp.oci.model.ocirecipe import OCIRecipe > + > +# Cannot delete this OCI project if it has recipes associated if it. > +exists_recipes = not IStore(OCIRecipe).find( > +OCIRecipe, > +OCIRecipe.oci_project == self).is_empty() > +if exists_recipes: > +raise CannotDeleteOCIProject("This OCI project contains > recipes.") > + > +# Cannot delete this OCI project if it has bugs associated with it. > +exists_bugs = not IStore(BugTask).find( > +BugTask, BugTask.ociproject == self).is_empty() It makes sense. Adding and XXX with guidelines for when we map the BugTask.ociprojectseries field. > +if exists_bugs: > +raise CannotDeleteOCIProject("This OCI project contains bugs.") > + > +git_repos = IStore(GitRepository).find( > +GitRepository, GitRepository.oci_project == self) > +if not git_repos.is_empty(): > +repos = ", ".join(repo.display_name for repo in git_repos) > +raise CannotDeleteOCIProject( > +"There are git repositories associated with this OCI > project: " > ++ repos) > +for series in self.series: > +series.destroySelf() > +IStore(self).remove(self) > + > > @implementer(IOCIProjectSet) > class OCIProjectSet: -- https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
Re: [Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Diff comments: > diff --git a/lib/lp/registry/model/ociproject.py > b/lib/lp/registry/model/ociproject.py > index 3cf675f..15f552c 100644 > --- a/lib/lp/registry/model/ociproject.py > +++ b/lib/lp/registry/model/ociproject.py > @@ -299,6 +300,36 @@ class OCIProject(BugTargetBase, StormBase): > return [] > return BRANCH_POLICY_ALLOWED_TYPES[self.pillar.branch_sharing_policy] > > +def destroySelf(self): > +"""See `IOCIProject`.""" > +from lp.bugs.model.bugtask import BugTask > +from lp.code.model.gitrepository import GitRepository > +from lp.oci.model.ocirecipe import OCIRecipe > + > +# Cannot delete this OCI project if it has recipes associated if it. > +exists_recipes = not IStore(OCIRecipe).find( > +OCIRecipe, > +OCIRecipe.oci_project == self).is_empty() > +if exists_recipes: > +raise CannotDeleteOCIProject("This OCI project contains > recipes.") > + > +# Cannot delete this OCI project if it has bugs associated with it. > +exists_bugs = not IStore(BugTask).find( > +BugTask, BugTask.ociproject == self).is_empty() True. I guess I'm mostly concerned about it being a speedbump for future developers. Maybe at least an XXX comment? > +if exists_bugs: > +raise CannotDeleteOCIProject("This OCI project contains bugs.") > + > +git_repos = IStore(GitRepository).find( > +GitRepository, GitRepository.oci_project == self) > +if not git_repos.is_empty(): > +repos = ", ".join(repo.display_name for repo in git_repos) > +raise CannotDeleteOCIProject( > +"There are git repositories associated with this OCI > project: " > ++ repos) > +for series in self.series: > +series.destroySelf() > +IStore(self).remove(self) > + > > @implementer(IOCIProjectSet) > class OCIProjectSet: -- https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
Re: [Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Diff comments: > diff --git a/lib/lp/registry/model/ociproject.py > b/lib/lp/registry/model/ociproject.py > index 3cf675f..15f552c 100644 > --- a/lib/lp/registry/model/ociproject.py > +++ b/lib/lp/registry/model/ociproject.py > @@ -299,6 +300,36 @@ class OCIProject(BugTargetBase, StormBase): > return [] > return BRANCH_POLICY_ALLOWED_TYPES[self.pillar.branch_sharing_policy] > > +def destroySelf(self): > +"""See `IOCIProject`.""" > +from lp.bugs.model.bugtask import BugTask > +from lp.code.model.gitrepository import GitRepository > +from lp.oci.model.ocirecipe import OCIRecipe > + > +# Cannot delete this OCI project if it has recipes associated if it. > +exists_recipes = not IStore(OCIRecipe).find( > +OCIRecipe, > +OCIRecipe.oci_project == self).is_empty() > +if exists_recipes: > +raise CannotDeleteOCIProject("This OCI project contains > recipes.") > + > +# Cannot delete this OCI project if it has bugs associated with it. > +exists_bugs = not IStore(BugTask).find( > +BugTask, BugTask.ociproject == self).is_empty() Although we already have it prepared at database level, we are not currently supporting bugs for OCIProjectSeries (the database column is not even mapped at the BugTask model, since we don't have a UI to manage that today). > +if exists_bugs: > +raise CannotDeleteOCIProject("This OCI project contains bugs.") > + > +git_repos = IStore(GitRepository).find( > +GitRepository, GitRepository.oci_project == self) > +if not git_repos.is_empty(): > +repos = ", ".join(repo.display_name for repo in git_repos) > +raise CannotDeleteOCIProject( > +"There are git repositories associated with this OCI > project: " > ++ repos) I agree. And we have a reasonable way of listing those git repositories in the UI already. I'll remove this. > +for series in self.series: > +series.destroySelf() > +IStore(self).remove(self) > + > > @implementer(IOCIProjectSet) > class OCIProjectSet: -- https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
Re: [Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Review: Approve Diff comments: > diff --git a/lib/lp/registry/model/ociproject.py > b/lib/lp/registry/model/ociproject.py > index 3cf675f..15f552c 100644 > --- a/lib/lp/registry/model/ociproject.py > +++ b/lib/lp/registry/model/ociproject.py > @@ -299,6 +300,36 @@ class OCIProject(BugTargetBase, StormBase): > return [] > return BRANCH_POLICY_ALLOWED_TYPES[self.pillar.branch_sharing_policy] > > +def destroySelf(self): > +"""See `IOCIProject`.""" > +from lp.bugs.model.bugtask import BugTask > +from lp.code.model.gitrepository import GitRepository > +from lp.oci.model.ocirecipe import OCIRecipe > + > +# Cannot delete this OCI project if it has recipes associated if it. > +exists_recipes = not IStore(OCIRecipe).find( > +OCIRecipe, > +OCIRecipe.oci_project == self).is_empty() > +if exists_recipes: > +raise CannotDeleteOCIProject("This OCI project contains > recipes.") > + > +# Cannot delete this OCI project if it has bugs associated with it. > +exists_bugs = not IStore(BugTask).find( > +BugTask, BugTask.ociproject == self).is_empty() Or possibly also BugTask.ociprojectseries, since that and BugTask.ociproject are mutually-exclusive? > +if exists_bugs: > +raise CannotDeleteOCIProject("This OCI project contains bugs.") > + > +git_repos = IStore(GitRepository).find( > +GitRepository, GitRepository.oci_project == self) > +if not git_repos.is_empty(): > +repos = ", ".join(repo.display_name for repo in git_repos) > +raise CannotDeleteOCIProject( > +"There are git repositories associated with this OCI > project: " > ++ repos) Hm, maybe. I think I might be wary of listing all the repositories in the exception message, since that could potentially get quite long. > +for series in self.series: > +series.destroySelf() > +IStore(self).remove(self) > + > > @implementer(IOCIProjectSet) > class OCIProjectSet: -- https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
Re: [Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Added the check to prevent deletion when there are bugs associated with the OCI project. It should be good for another review round now. Diff comments: > diff --git a/lib/lp/registry/model/ociproject.py > b/lib/lp/registry/model/ociproject.py > index e98b3ea..da0bb98 100644 > --- a/lib/lp/registry/model/ociproject.py > +++ b/lib/lp/registry/model/ociproject.py > @@ -297,6 +298,28 @@ class OCIProject(BugTargetBase, StormBase): > namespace = getUtility(IGitNamespaceSet).get(person, > oci_project=self) > return namespace.name > > +def destroySelf(self): > +"""See `IOCIProject`.""" > +from lp.oci.model.ocirecipe import OCIRecipe > +from lp.code.model.gitrepository import GitRepository > + > +exists_recipes = not IStore(OCIRecipe).find( > +OCIRecipe, > +OCIRecipe.oci_project == self).is_empty() > +if exists_recipes: > +raise CannotDeleteOCIProject("This OCI recipe contains recipes.") Absolutely! Fixing it. > + > +git_repos = IStore(GitRepository).find( > +GitRepository, GitRepository.oci_project == self) > +if not git_repos.is_empty(): > +repos = ", ".join(repo.display_name for repo in git_repos) > +raise CannotDeleteOCIProject( > +"There are git repositories associated with this OCI > project: " > ++ repos) > +for series in self.series: > +series.destroySelf() > +IStore(self).remove(self) > + > > @implementer(IOCIProjectSet) > class OCIProjectSet: -- https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
Re: [Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Review: Needs Information What about bugs? Now that those are landing, I guess this will need to handle those too (maybe just refusing if the OCI project has any bug tasks). Diff comments: > diff --git a/lib/lp/registry/model/ociproject.py > b/lib/lp/registry/model/ociproject.py > index e98b3ea..da0bb98 100644 > --- a/lib/lp/registry/model/ociproject.py > +++ b/lib/lp/registry/model/ociproject.py > @@ -297,6 +298,28 @@ class OCIProject(BugTargetBase, StormBase): > namespace = getUtility(IGitNamespaceSet).get(person, > oci_project=self) > return namespace.name > > +def destroySelf(self): > +"""See `IOCIProject`.""" > +from lp.oci.model.ocirecipe import OCIRecipe > +from lp.code.model.gitrepository import GitRepository > + > +exists_recipes = not IStore(OCIRecipe).find( > +OCIRecipe, > +OCIRecipe.oci_project == self).is_empty() > +if exists_recipes: > +raise CannotDeleteOCIProject("This OCI recipe contains recipes.") Maybe "This OCI project contains recipes."? > + > +git_repos = IStore(GitRepository).find( > +GitRepository, GitRepository.oci_project == self) > +if not git_repos.is_empty(): > +repos = ", ".join(repo.display_name for repo in git_repos) > +raise CannotDeleteOCIProject( > +"There are git repositories associated with this OCI > project: " > ++ repos) > +for series in self.series: > +series.destroySelf() > +IStore(self).remove(self) > + > > @implementer(IOCIProjectSet) > class OCIProjectSet: -- https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 Your team Launchpad code reviewers is subscribed to branch ~pappacena/launchpad:delete-oci-project. ___ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp
[Launchpad-reviewers] [Merge] ~pappacena/launchpad:delete-oci-project into launchpad:master
Thiago F. Pappacena has proposed merging ~pappacena/launchpad:delete-oci-project into launchpad:master. Commit message: Adding API to delete OCI projects Requested reviews: Launchpad code reviewers (launchpad-reviewers) Related bugs: Bug #1925079 in Launchpad itself: "Add possibility to delete a OCI project" https://bugs.launchpad.net/launchpad/+bug/1925079 For more details, see: https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/401424 -- Your team Launchpad code reviewers is requested to review the proposed merge of ~pappacena/launchpad:delete-oci-project into launchpad:master. diff --git a/lib/lp/registry/interfaces/ociproject.py b/lib/lp/registry/interfaces/ociproject.py index bb0a785..b1ea1a2 100644 --- a/lib/lp/registry/interfaces/ociproject.py +++ b/lib/lp/registry/interfaces/ociproject.py @@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ +'CannotDeleteOCIProject', 'IOCIProject', 'IOCIProjectSet', 'OCI_PROJECT_ALLOW_CREATE', @@ -16,6 +17,7 @@ __all__ = [ from lazr.restful.declarations import ( call_with, error_status, +export_destructor_operation, export_factory_operation, exported, exported_as_webservice_entry, @@ -60,6 +62,11 @@ from lp.services.fields import ( OCI_PROJECT_ALLOW_CREATE = 'oci.project.create.enabled' +@error_status(http_client.BAD_REQUEST) +class CannotDeleteOCIProject(Exception): +"""The OCIProject cannnot be deleted.""" + + class IOCIProjectView(IHasGitRepositories, Interface): """IOCIProject attributes that require launchpad.View permission.""" @@ -160,6 +167,16 @@ class IOCIProjectEdit(Interface): def setOfficialRecipeStatus(recipe, status): """Change whether an OCI Recipe is official or not for this project.""" +@export_destructor_operation() +@operation_for_version('devel') +def destroySelf(): +"""Delete this OCI project. + +Any OCI recipe and git repository related to this OCI project should +be deleted beforehand. OCIProjectSeries objects are automatically +deleted. +""" + class IOCIProjectLegitimate(Interface): """IOCIProject methods that require launchpad.AnyLegitimatePerson diff --git a/lib/lp/registry/interfaces/ociprojectseries.py b/lib/lp/registry/interfaces/ociprojectseries.py index d51eebd..ee20e4b 100644 --- a/lib/lp/registry/interfaces/ociprojectseries.py +++ b/lib/lp/registry/interfaces/ociprojectseries.py @@ -1,4 +1,4 @@ -# Copyright 2019-2020 Canonical Ltd. This software is licensed under the +# Copyright 2019-2021 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Interfaces to allow bug filing on multiple versions of an OCI Project.""" @@ -77,6 +77,9 @@ class IOCIProjectSeriesEditableAttributes(Interface): class IOCIProjectSeriesEdit(Interface): """IOCIProjectSeries attributes that require launchpad.Edit permission.""" +def destroySelf(): +"""Delete this OCI project series.""" + @exported_as_webservice_entry( publish_web_link=True, as_of="devel", singular_name="oci_project_series") diff --git a/lib/lp/registry/model/ociproject.py b/lib/lp/registry/model/ociproject.py index e98b3ea..da0bb98 100644 --- a/lib/lp/registry/model/ociproject.py +++ b/lib/lp/registry/model/ociproject.py @@ -46,6 +46,7 @@ from lp.code.model.branchnamespace import ( from lp.oci.interfaces.ocirecipe import IOCIRecipeSet from lp.registry.interfaces.distribution import IDistribution from lp.registry.interfaces.ociproject import ( +CannotDeleteOCIProject, IOCIProject, IOCIProjectSet, ) @@ -297,6 +298,28 @@ class OCIProject(BugTargetBase, StormBase): namespace = getUtility(IGitNamespaceSet).get(person, oci_project=self) return namespace.name +def destroySelf(self): +"""See `IOCIProject`.""" +from lp.oci.model.ocirecipe import OCIRecipe +from lp.code.model.gitrepository import GitRepository + +exists_recipes = not IStore(OCIRecipe).find( +OCIRecipe, +OCIRecipe.oci_project == self).is_empty() +if exists_recipes: +raise CannotDeleteOCIProject("This OCI recipe contains recipes.") + +git_repos = IStore(GitRepository).find( +GitRepository, GitRepository.oci_project == self) +if not git_repos.is_empty(): +repos = ", ".join(repo.display_name for repo in git_repos) +raise CannotDeleteOCIProject( +"There are git repositories associated with this OCI project: " ++ repos) +for series in self.series: +series.destroySelf() +IStore(self).remove(self) + @implementer(IOCIProjectSet) class OCIProjectSet: diff --git a/lib/lp/registry/model/ociprojectseries.py b/lib/lp/registry/model/ociprojectseries.py index 31ccac3..5d935d6