launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #24020
[Merge] ~twom/launchpad:oci-recipe-name into launchpad:master
Tom Wardill has proposed merging ~twom/launchpad:oci-recipe-name into launchpad:master.
Commit message:
Add OCIRecipeName in preparation for OCIRecipeTarget
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~twom/launchpad/+git/launchpad/+merge/373740
Names are their own object to allow multiple recipes to have different targets, but the same name.
Add the model, interface, factory method, zcml and security.cfg declarations.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~twom/launchpad:oci-recipe-name into launchpad:master.
diff --git a/database/schema/security.cfg b/database/schema/security.cfg
index 1e9ca05..2a760b5 100644
--- a/database/schema/security.cfg
+++ b/database/schema/security.cfg
@@ -1238,6 +1238,7 @@ public.logintoken = SELECT, INSERT, UPDATE
public.message = SELECT, INSERT, UPDATE
public.milestone = SELECT, INSERT, UPDATE
public.openididentifier = SELECT
+public.ocirecipename = SELECT, INSERT, UPDATE
public.packageupload = SELECT, INSERT, UPDATE
public.packageuploadbuild = SELECT, INSERT, UPDATE
public.packageuploadcustom = SELECT, INSERT, UPDATE
@@ -1413,6 +1414,7 @@ public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
public.milestonetag = SELECT
+public.ocirecipename = SELECT
public.openididentifier = SELECT
public.packagecopyjob = SELECT, INSERT
public.packagediff = SELECT, INSERT, UPDATE, DELETE
@@ -1529,6 +1531,7 @@ public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
public.milestonetag = SELECT
+public.ocirecipename = SELECT
public.openididentifier = SELECT
public.packagecopyjob = SELECT, INSERT, UPDATE
public.packagediff = SELECT, UPDATE
@@ -1631,6 +1634,7 @@ public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
public.milestonetag = SELECT
+public.ocirecipename = SELECT
public.person = SELECT
public.personlanguage = SELECT
public.personsettings = SELECT
@@ -1832,6 +1836,7 @@ public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
public.milestonetag = SELECT, INSERT, DELETE
+public.ocirecipename = SELECT
public.openididentifier = SELECT
public.packageset = SELECT
public.packagesetgroup = SELECT
@@ -1951,6 +1956,7 @@ public.libraryfilealias = SELECT, INSERT
public.libraryfilecontent = SELECT, INSERT
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
+public.ocirecipename = SELECT
public.openididentifier = SELECT
public.person = SELECT
public.product = SELECT
@@ -2008,6 +2014,7 @@ public.libraryfilecontent = SELECT, INSERT
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.ocirecipename = SELECT
public.person = SELECT
public.personsettings = SELECT
public.previewdiff = SELECT, INSERT
@@ -2144,6 +2151,7 @@ public.job = SELECT, INSERT, UPDATE
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestonetag = SELECT
+public.ocirecipename = SELECT
public.person = SELECT, INSERT
public.personsettings = SELECT, INSERT
public.product = SELECT, INSERT, UPDATE
@@ -2260,6 +2268,7 @@ public.milestonetag = SELECT, INSERT, UPDATE, DELETE
public.nameblacklist = SELECT, UPDATE
public.oauthaccesstoken = SELECT, UPDATE
public.oauthrequesttoken = SELECT, UPDATE
+public.ocirecipename = SELECT
public.officialbugtag = SELECT
public.openididentifier = SELECT, UPDATE
public.packagecopyrequest = SELECT, UPDATE
@@ -2377,6 +2386,7 @@ public.livefsfile = SELECT, DELETE
public.logintoken = SELECT, DELETE
public.mailinglistsubscription = SELECT, DELETE
public.milestonetag = SELECT
+public.ocirecipename = SELECT
public.openidconsumerassociation = SELECT, DELETE
public.openidconsumernonce = SELECT, DELETE
public.person = SELECT, DELETE
@@ -2529,6 +2539,7 @@ public.distroseries = SELECT
public.emailaddress = SELECT
public.gitrepository = SELECT
public.job = SELECT, INSERT, UPDATE
+public.ocirecipename = SELECT
public.person = SELECT
public.packaging = SELECT
public.product = SELECT, UPDATE
@@ -2551,6 +2562,7 @@ public.bugtask = SELECT
public.bugtaskflat = SELECT
public.distribution = SELECT
public.distroseries = SELECT
+public.ocirecipename = SELECT
public.product = SELECT
public.productseries = SELECT
public.sourcepackagename = SELECT
@@ -2562,6 +2574,7 @@ public.branch = SELECT
public.distribution = SELECT
public.gitrepository = SELECT
public.job = SELECT, UPDATE
+public.ocirecipename = SELECT
public.person = SELECT
public.product = SELECT
public.snap = SELECT
diff --git a/lib/lp/registry/configure.zcml b/lib/lp/registry/configure.zcml
index 7a74bad..047a31b 100644
--- a/lib/lp/registry/configure.zcml
+++ b/lib/lp/registry/configure.zcml
@@ -714,6 +714,26 @@
interface="lp.registry.interfaces.pillar.IPillarPersonFactory"/>
</securedutility>
+ <!-- OCIRecipeName -->
+ <class
+ class="lp.registry.model.ocirecipename.OCIRecipeName">
+ <allow
+ interface="lp.registry.interfaces.ocirecipename.IOCIRecipeName"/>
+ </class>
+
+ <!-- OCIRecipeNameSet -->
+ <securedutility
+ class="lp.registry.model.ocirecipename.OCIRecipeNameSet"
+ provides="lp.registry.interfaces.ocirecipename.IOCIRecipeNameSet">
+ <allow
+ interface="lp.registry.interfaces.ocirecipename.IOCIRecipeNameSet"/>
+ </securedutility>
+ <class
+ class="lp.registry.model.ocirecipename.OCIRecipeNameSet">
+ <allow
+ interface="lp.registry.interfaces.ocirecipename.IOCIRecipeNameSet"/>
+ </class>
+
<!-- SourcePackageName -->
<class
diff --git a/lib/lp/registry/errors.py b/lib/lp/registry/errors.py
index 7564299..e8a99e1 100644
--- a/lib/lp/registry/errors.py
+++ b/lib/lp/registry/errors.py
@@ -23,6 +23,7 @@ __all__ = [
'NoSuchAccount',
'NoSuchDistroSeries',
'NoSuchSourcePackageName',
+ 'NoSuchRecipeName',
'NotPlaceholderAccount',
'InclusiveTeamLinkageError',
'PPACreationError',
@@ -109,6 +110,10 @@ class NoSuchSourcePackageName(NameLookupFailed):
"""Raised when we can't find a particular sourcepackagename."""
_message_prefix = "No such source package"
+class NoSuchRecipeName(NameLookupFailed):
+ """Raised when we can't find a particular ocirecipename."""
+ _message_prefix = "No such OCI recipe"
+
@error_status(httplib.BAD_REQUEST)
class CannotTransitionToCountryMirror(Exception):
diff --git a/lib/lp/registry/interfaces/ocirecipename.py b/lib/lp/registry/interfaces/ocirecipename.py
new file mode 100644
index 0000000..b6226e1
--- /dev/null
+++ b/lib/lp/registry/interfaces/ocirecipename.py
@@ -0,0 +1,38 @@
+from zope.interface import (
+ Interface
+)
+from zope.schema import (
+ Int,
+ Text,
+ )
+
+from lp import _
+
+
+class IOCIRecipeName(Interface):
+
+ id = Int(title=_("OCI Recipe Name ID"),
+ required=True,
+ readonly=True
+ )
+
+ name = Text(title=_("Name of recipe"))
+
+
+class IOCIRecipeNameSet(Interface):
+
+ def __getitem__(name):
+ """Retrieve a ocirecipename by name."""
+
+ def getByName(name):
+ """Return a ocirecipename by its name.
+
+ If the ocirecipename can't be found a NoSuchRecipeName will be
+ raised.
+ """
+
+ def getAll():
+ """return an iselectresults representing all package names"""
+
+ def new(name):
+ """Create a new oci recipe name."""
diff --git a/lib/lp/registry/model/ocirecipename.py b/lib/lp/registry/model/ocirecipename.py
new file mode 100644
index 0000000..88d3a65
--- /dev/null
+++ b/lib/lp/registry/model/ocirecipename.py
@@ -0,0 +1,66 @@
+from storm.properties import Unicode
+from storm.locals import (
+ Desc,
+ Int,
+ )
+from zope.interface import implementer
+
+from lp.app.validators.name import valid_name
+from lp.services.database.interfaces import (
+ IMasterStore,
+ IStore,
+ )
+from lp.services.database.stormbase import StormBase
+from lp.registry.errors import (
+ InvalidName,
+ NoSuchRecipeName,
+ )
+from lp.registry.interfaces.ocirecipename import (
+ IOCIRecipeName,
+ IOCIRecipeNameSet,
+ )
+from lp.services.helpers import ensure_unicode
+
+
+@implementer(IOCIRecipeName)
+class OCIRecipeName(StormBase):
+
+ __storm_table__ = "OCIRecipeName"
+
+ id = Int(primary=True)
+ name = Unicode(name="name", allow_none=False)
+
+ def __init__(self, name):
+ super(OCIRecipeName, self).__init__()
+ self.name = name
+
+
+@implementer(IOCIRecipeNameSet)
+class OCIRecipeNameSet:
+
+ def __getitem__(self, name):
+ """See `IOCIRecipeNameSet`."""
+ return self.getByName
+
+ def getByName(self, name):
+ """See `IOCIRecipeNameSet`."""
+ recipe_name = IStore(OCIRecipeName).find(
+ OCIRecipeName, OCIRecipeName.name == name).one()
+ if recipe_name is None:
+ raise NoSuchRecipeName(name)
+ return recipe_name
+
+ def getAll(self):
+ """See `IOCIRecipeNameSet`."""
+ return IStore(OCIRecipeName).find(OCIRecipeName).order_by(
+ Desc(OCIRecipeName.name))
+
+ def new(self, name):
+ """See `IOCIRecipeNameSet`."""
+ if not valid_name(name):
+ raise InvalidName(
+ "%s is not a valid name for an OCI recipe." % name)
+ store = IMasterStore(OCIRecipeName)
+ recipe_name = OCIRecipeName(name=name)
+ store.add(recipe_name)
+ return recipe_name
diff --git a/lib/lp/registry/tests/test_ocirecipename.py b/lib/lp/registry/tests/test_ocirecipename.py
new file mode 100644
index 0000000..0a576cb
--- /dev/null
+++ b/lib/lp/registry/tests/test_ocirecipename.py
@@ -0,0 +1,47 @@
+import transaction
+from testtools.testcase import ExpectedException
+
+from lp.registry.errors import (
+ InvalidName,
+ NoSuchRecipeName,
+ )
+from lp.registry.model.ocirecipename import (
+ OCIRecipeName,
+ OCIRecipeNameSet,
+ )
+from lp.services.database.interfaces import IStore
+from lp.testing import TestCaseWithFactory
+from lp.testing.layers import DatabaseFunctionalLayer
+
+
+class OCIRecipeNameTest(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ def test_create(self):
+ name = self.factory.makeOCIRecipeName()
+ self.assertTrue(name.name.startswith('oci-base-name'))
+
+ def test_invalid_name(self):
+ with ExpectedException(
+ InvalidName,
+ 'invalid%20name is not a valid name for an OCI recipe.'):
+ OCIRecipeNameSet().new('invalid%20name')
+
+ def test_get_missing(self):
+ with ExpectedException(
+ NoSuchRecipeName,
+ "No such OCI recipe: 'invalid'"):
+ OCIRecipeNameSet().getByName(u'invalid')
+
+ def test_get(self):
+ created = self.factory.makeOCIRecipeName()
+ IStore(OCIRecipeName).flush()
+ fetched = OCIRecipeNameSet().getByName(created.name)
+ self.assertEqual(fetched, created)
+
+ def test_get_all(self):
+ for i in range(5):
+ self.factory.makeOCIRecipeName()
+ all_recipes = OCIRecipeNameSet().getAll()
+ self.assertEqual(all_recipes.count(), 5)
diff --git a/lib/lp/registry/tests/test_ocirecipetarget.py b/lib/lp/registry/tests/test_ocirecipetarget.py
new file mode 100644
index 0000000..5333cf6
--- /dev/null
+++ b/lib/lp/registry/tests/test_ocirecipetarget.py
@@ -0,0 +1,24 @@
+# Copyright 2019 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+from __future__ import absolute_import, print_function, unicode_literals
+
+__metaclass__ = type
+
+from lp.registry.model.ocirecipename import OCIRecipeName
+from lp.registry.model.ocirecipetarget import OCIRecipeTarget
+from lp.testing import TestCaseWithFactory
+from lp.testing.layers import DatabaseFunctionalLayer
+
+
+class OCIRecipeTargetTest(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ def test_create(self):
+ name = OCIRecipeName(name="Test OCI Recipe Name")
+ registrant = self.factory.makePerson()
+ project = self.factory.makeProduct()
+ distribution = self.factory.makeDistribution()
+ target = OCIRecipeTarget(registrant, project, distribution, name)
+ print(target.date_created)
+ self.assertTrue(target)
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index 568ddab..1d421fe 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -200,6 +200,8 @@ from lp.registry.interfaces.mailinglist import (
from lp.registry.interfaces.mailinglistsubscription import (
MailingListAutoSubscribePolicy,
)
+from lp.registry.interfaces.ocirecipename import IOCIRecipeNameSet
+from lp.registry.interfaces.ocirecipetarget import IOCIRecipeTarget
from lp.registry.interfaces.packaging import (
IPackagingUtil,
PackagingType,
@@ -4896,6 +4898,11 @@ class BareLaunchpadObjectFactory(ObjectFactory):
registrant, name, display_name, distro_series, build_channels,
date_created=date_created)
+ def makeOCIRecipeName(self, name=None):
+ if name is None:
+ name = self.getUniqueString(u"oci-base-name")
+ return getUtility(IOCIRecipeNameSet).new(name)
+
# Some factory methods return simple Python types. We don't add
# security wrappers for them, as well as for objects created by