Andrey Fedoseev has proposed merging ~andrey-fedoseev/launchpad:snap-base-features into launchpad:master.
Commit message: Add `ISnapBase.features` field Requested reviews: Launchpad code reviewers (launchpad-reviewers) For more details, see: https://code.launchpad.net/~andrey-fedoseev/launchpad/+git/launchpad/+merge/429878 The field is used to designate the features available for a snap base -- Your team Launchpad code reviewers is requested to review the proposed merge of ~andrey-fedoseev/launchpad:snap-base-features into launchpad:master.
diff --git a/lib/lp/snappy/interfaces/snapbase.py b/lib/lp/snappy/interfaces/snapbase.py index 08cfd79..8fdc1f4 100644 --- a/lib/lp/snappy/interfaces/snapbase.py +++ b/lib/lp/snappy/interfaces/snapbase.py @@ -8,6 +8,8 @@ __all__ = [ "ISnapBase", "ISnapBaseSet", "NoSuchSnapBase", + "ALLOW_DUPLICATE_BUILD_ON", + "SNAP_BASE_KNOWN_FEATURES", ] import http.client @@ -74,6 +76,10 @@ class SnapBaseNameField(ContentNameField): return None +ALLOW_DUPLICATE_BUILD_ON = "allow_duplicate_build_on" +SNAP_BASE_KNOWN_FEATURES = {ALLOW_DUPLICATE_BUILD_ON} + + class ISnapBaseView(Interface): """`ISnapBase` attributes that anyone can view.""" @@ -181,6 +187,20 @@ class ISnapBaseEditableAttributes(Interface): ) ) + features = exported( + Dict( + title=_("Features supported by this base"), + key_type=TextLine(), + required=False, + readonly=False, + description=_( + "A dictionary designating the features supported by the base. " + "Key is the name of a feature, value is a boolean indicating " + "whether the feature is supported or not." + ), + ) + ) + class ISnapBaseEdit(Interface): """`ISnapBase` methods that require launchpad.Edit permission.""" @@ -263,7 +283,14 @@ class ISnapBaseSetEdit(Interface): ) ) @export_factory_operation( - ISnapBase, ["name", "display_name", "distro_series", "build_channels"] + ISnapBase, + [ + "name", + "display_name", + "distro_series", + "build_channels", + "features", + ], ) @operation_for_version("devel") def new( @@ -272,6 +299,7 @@ class ISnapBaseSetEdit(Interface): display_name, distro_series, build_channels, + features, processors=None, date_created=None, ): diff --git a/lib/lp/snappy/model/snapbase.py b/lib/lp/snappy/model/snapbase.py index f87a3e6..e92f91a 100644 --- a/lib/lp/snappy/model/snapbase.py +++ b/lib/lp/snappy/model/snapbase.py @@ -7,7 +7,10 @@ __all__ = [ "SnapBase", ] +from typing import Dict, Optional + import pytz +from storm.databases.postgres import JSON as PgJSON from storm.locals import ( JSON, Bool, @@ -29,6 +32,7 @@ from lp.registry.model.person import Person from lp.services.database.constants import DEFAULT from lp.services.database.interfaces import IMasterStore, IStore from lp.snappy.interfaces.snapbase import ( + SNAP_BASE_KNOWN_FEATURES, CannotDeleteSnapBase, ISnapBase, ISnapBaseSet, @@ -69,6 +73,8 @@ class SnapBase(Storm): is_default = Bool(name="is_default", allow_none=False) + _features = PgJSON(name="features", allow_none=False) + def __init__( self, registrant, @@ -76,6 +82,7 @@ class SnapBase(Storm): display_name, distro_series, build_channels, + features, date_created=DEFAULT, ): super().__init__() @@ -85,8 +92,25 @@ class SnapBase(Storm): self.distro_series = distro_series self.build_channels = build_channels self.date_created = date_created + self.features = features self.is_default = False + @property + def features(self) -> Dict[str, bool]: + return { + k: v + for k, v in (self._features or {}).items() + if k in SNAP_BASE_KNOWN_FEATURES + } + + @features.setter + def features(self, value: Optional[Dict[str, bool]]) -> None: + self._features = { + k: v + for k, v in (value or {}).items() + if k in SNAP_BASE_KNOWN_FEATURES + } + def _getProcessors(self): return list( Store.of(self).find( @@ -217,6 +241,7 @@ class SnapBaseSet: display_name, distro_series, build_channels, + features, processors=None, date_created=DEFAULT, ): @@ -228,6 +253,7 @@ class SnapBaseSet: display_name, distro_series, build_channels, + features, date_created=date_created, ) store.add(snap_base) diff --git a/lib/lp/snappy/tests/test_snapbase.py b/lib/lp/snappy/tests/test_snapbase.py index afd71c1..36d046e 100644 --- a/lib/lp/snappy/tests/test_snapbase.py +++ b/lib/lp/snappy/tests/test_snapbase.py @@ -17,6 +17,7 @@ from lp.app.interfaces.security import IAuthorization from lp.registry.interfaces.pocket import PackagePublishingPocket from lp.services.webapp.interfaces import OAuthPermission from lp.snappy.interfaces.snapbase import ( + ALLOW_DUPLICATE_BUILD_ON, CannotDeleteSnapBase, ISnapBase, ISnapBaseSet, @@ -69,6 +70,17 @@ class TestSnapBase(TestCaseWithFactory): getUtility(ISnapBaseSet).setDefault(snap_base) self.assertRaises(CannotDeleteSnapBase, snap_base.destroySelf) + def test_features(self): + snap_base = self.factory.makeSnapBase( + features={ALLOW_DUPLICATE_BUILD_ON: True, "unknown_feature": True} + ) + self.assertEqual( + snap_base.features, + { + ALLOW_DUPLICATE_BUILD_ON: True, + }, + ) + class TestSnapBaseProcessors(TestCaseWithFactory): @@ -102,6 +114,7 @@ class TestSnapBaseProcessors(TestCaseWithFactory): display_name=self.factory.getUniqueUnicode(), distro_series=self.distroseries, build_channels={}, + features={}, ) self.assertContentEqual(self.procs, snap_base.processors) @@ -113,6 +126,7 @@ class TestSnapBaseProcessors(TestCaseWithFactory): display_name=self.factory.getUniqueUnicode(), distro_series=self.distroseries, build_channels={}, + features={}, processors=self.procs[:2], ) self.assertContentEqual(self.procs[:2], snap_base.processors) @@ -211,6 +225,7 @@ class TestSnapBaseWebservice(TestCaseWithFactory): display_name="Dummy", distro_series=distroseries_url, build_channels={"snapcraft": "stable"}, + features={"allow_duplicate_build_on": True}, ) self.assertEqual(201, response.status) snap_base = webservice.get(response.getHeader("Location")).jsonBody() @@ -228,6 +243,7 @@ class TestSnapBaseWebservice(TestCaseWithFactory): webservice.getAbsoluteUrl(distroseries_url) ), "build_channels": Equals({"snapcraft": "stable"}), + "features": Equals({"allow_duplicate_build_on": True}), "is_default": Is(False), } ), diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py index 3fd560c..7cbd238 100644 --- a/lib/lp/testing/factory.py +++ b/lib/lp/testing/factory.py @@ -6372,6 +6372,7 @@ class LaunchpadObjectFactory(ObjectFactory): display_name=None, distro_series=None, build_channels=None, + features=None, processors=None, date_created=DEFAULT, ): @@ -6394,6 +6395,7 @@ class LaunchpadObjectFactory(ObjectFactory): display_name, distro_series, build_channels, + features=features, processors=processors, date_created=date_created, )
_______________________________________________ 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