← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:snap-core22 into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:snap-core22 into launchpad:master.

Commit message:
Allow selecting the core22 channel for snap/charm builds

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/407089
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:snap-core22 into launchpad:master.
diff --git a/lib/lp/charms/browser/tests/test_charmrecipe.py b/lib/lp/charms/browser/tests/test_charmrecipe.py
index 4e72f78..617cdf0 100644
--- a/lib/lp/charms/browser/tests/test_charmrecipe.py
+++ b/lib/lp/charms/browser/tests/test_charmrecipe.py
@@ -1040,6 +1040,7 @@ class TestCharmRecipeRequestBuildsView(BaseTestCharmRecipeView):
             core
             core18
             core20
+            core22
             The channels to use for build tools when building the charm
             recipe.
             or
diff --git a/lib/lp/charms/browser/widgets/charmrecipebuildchannels.py b/lib/lp/charms/browser/widgets/charmrecipebuildchannels.py
index f5b2861..616293e 100644
--- a/lib/lp/charms/browser/widgets/charmrecipebuildchannels.py
+++ b/lib/lp/charms/browser/widgets/charmrecipebuildchannels.py
@@ -32,7 +32,7 @@ class CharmRecipeBuildChannelsWidget(BrowserWidget, InputWidget):
 
     template = ViewPageTemplateFile("templates/charmrecipebuildchannels.pt")
     hint = False
-    snap_names = ["charmcraft", "core", "core18", "core20"]
+    snap_names = ["charmcraft", "core", "core18", "core20", "core22"]
     _widgets_set_up = False
 
     def __init__(self, context, request):
diff --git a/lib/lp/charms/browser/widgets/templates/charmrecipebuildchannels.pt b/lib/lp/charms/browser/widgets/templates/charmrecipebuildchannels.pt
index 0430f4a..3b68f80 100644
--- a/lib/lp/charms/browser/widgets/templates/charmrecipebuildchannels.pt
+++ b/lib/lp/charms/browser/widgets/templates/charmrecipebuildchannels.pt
@@ -19,6 +19,10 @@
     <td>core20</td>
     <td><div tal:content="structure view/core20_widget" /></td>
   </tr>
+  <tr>
+    <td>core22</td>
+    <td><div tal:content="structure view/core22_widget" /></td>
+  </tr>
 </table>
 
 </tal:root>
diff --git a/lib/lp/charms/browser/widgets/tests/test_charmrecipebuildchannelswidget.py b/lib/lp/charms/browser/widgets/tests/test_charmrecipebuildchannelswidget.py
index b20d944..ed1653c 100644
--- a/lib/lp/charms/browser/widgets/tests/test_charmrecipebuildchannelswidget.py
+++ b/lib/lp/charms/browser/widgets/tests/test_charmrecipebuildchannelswidget.py
@@ -64,6 +64,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNotNone(getattr(self.widget, "core_widget", None))
         self.assertIsNotNone(getattr(self.widget, "core18_widget", None))
         self.assertIsNotNone(getattr(self.widget, "core20_widget", None))
+        self.assertIsNotNone(getattr(self.widget, "core22_widget", None))
 
     def test_setUpSubWidgets_second_call(self):
         # The setUpSubWidgets method exits early if a flag is set to
@@ -74,6 +75,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(getattr(self.widget, "core_widget", None))
         self.assertIsNone(getattr(self.widget, "core18_widget", None))
         self.assertIsNone(getattr(self.widget, "core20_widget", None))
+        self.assertIsNone(getattr(self.widget, "core22_widget", None))
 
     def test_setRenderedValue_None(self):
         self.widget.setRenderedValue(None)
@@ -81,6 +83,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(self.widget.core_widget._getCurrentValue())
         self.assertIsNone(self.widget.core18_widget._getCurrentValue())
         self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core22_widget._getCurrentValue())
 
     def test_setRenderedValue_empty(self):
         self.widget.setRenderedValue({})
@@ -88,6 +91,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(self.widget.core_widget._getCurrentValue())
         self.assertIsNone(self.widget.core18_widget._getCurrentValue())
         self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core22_widget._getCurrentValue())
 
     def test_setRenderedValue_one_channel(self):
         self.widget.setRenderedValue({"charmcraft": "stable"})
@@ -96,17 +100,20 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(self.widget.core_widget._getCurrentValue())
         self.assertIsNone(self.widget.core18_widget._getCurrentValue())
         self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core22_widget._getCurrentValue())
 
     def test_setRenderedValue_all_channels(self):
         self.widget.setRenderedValue(
             {"charmcraft": "stable", "core": "candidate", "core18": "beta",
-             "core20": "edge"})
+             "core20": "edge", "core22": "edge/feature"})
         self.assertEqual(
             "stable", self.widget.charmcraft_widget._getCurrentValue())
         self.assertEqual(
             "candidate", self.widget.core_widget._getCurrentValue())
         self.assertEqual("beta", self.widget.core18_widget._getCurrentValue())
         self.assertEqual("edge", self.widget.core20_widget._getCurrentValue())
+        self.assertEqual(
+            "edge/feature", self.widget.core22_widget._getCurrentValue())
 
     def test_hasInput_false(self):
         # hasInput is false when there are no channels in the form data.
@@ -128,6 +135,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
             "field.auto_build_channels.core": "",
             "field.auto_build_channels.core18": "beta",
             "field.auto_build_channels.core20": "edge",
+            "field.auto_build_channels.core22": "edge/feature",
             }
         self.widget.request = LaunchpadTestRequest(form=form)
         self.assertTrue(self.widget.hasValidInput())
@@ -138,10 +146,12 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
             "field.auto_build_channels.core": "",
             "field.auto_build_channels.core18": "beta",
             "field.auto_build_channels.core20": "edge",
+            "field.auto_build_channels.core22": "edge/feature",
             }
         self.widget.request = LaunchpadTestRequest(form=form)
         self.assertEqual(
-            {"charmcraft": "stable", "core18": "beta", "core20": "edge"},
+            {"charmcraft": "stable", "core18": "beta", "core20": "edge",
+             "core22": "edge/feature"},
             self.widget.getInputValue())
 
     def test_call(self):
@@ -151,6 +161,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNotNone(self.widget.core_widget)
         self.assertIsNotNone(self.widget.core18_widget)
         self.assertIsNotNone(self.widget.core20_widget)
+        self.assertIsNotNone(self.widget.core22_widget)
         soup = BeautifulSoup(markup)
         fields = soup.find_all(["input"], {"id": re.compile(".*")})
         expected_ids = [
@@ -158,6 +169,7 @@ class TestCharmRecipeBuildChannelsWidget(TestCaseWithFactory):
             "field.auto_build_channels.core",
             "field.auto_build_channels.core18",
             "field.auto_build_channels.core20",
+            "field.auto_build_channels.core22",
             ]
         ids = [field["id"] for field in fields]
         self.assertContentEqual(expected_ids, ids)
diff --git a/lib/lp/charms/interfaces/charmrecipe.py b/lib/lp/charms/interfaces/charmrecipe.py
index 57d5ce8..c6dac7d 100644
--- a/lib/lp/charms/interfaces/charmrecipe.py
+++ b/lib/lp/charms/interfaces/charmrecipe.py
@@ -471,7 +471,7 @@ class ICharmRecipeEditableAttributes(Interface):
         description=_(
             "A dictionary mapping snap names to channels to use when building "
             "this charm recipe.  Currently only 'charmcraft', 'core', "
-            "'core18', and 'core20' keys are supported."))
+            "'core18', 'core20', and 'core22' keys are supported."))
 
     is_stale = Bool(
         title=_("Charm recipe is stale and is due to be rebuilt."),
diff --git a/lib/lp/charms/interfaces/charmrecipebuild.py b/lib/lp/charms/interfaces/charmrecipebuild.py
index 8b678bb..45b57a4 100644
--- a/lib/lp/charms/interfaces/charmrecipebuild.py
+++ b/lib/lp/charms/interfaces/charmrecipebuild.py
@@ -63,8 +63,8 @@ class ICharmRecipeBuildView(IPackageBuild):
         title=_("Source snap channels to use for this build."),
         description=_(
             "A dictionary mapping snap names to channels to use for this "
-            "build.  Currently only 'charmcraft', 'core', 'core18', and "
-            "'core20' keys are supported."),
+            "build.  Currently only 'charmcraft', 'core', 'core18', 'core20', "
+            "and 'core22' keys are supported."),
         key_type=TextLine())
 
     virtualized = Bool(
diff --git a/lib/lp/charms/interfaces/charmrecipejob.py b/lib/lp/charms/interfaces/charmrecipejob.py
index 08eedc5..554b231 100644
--- a/lib/lp/charms/interfaces/charmrecipejob.py
+++ b/lib/lp/charms/interfaces/charmrecipejob.py
@@ -62,8 +62,8 @@ class ICharmRecipeRequestBuildsJob(IRunnableJob):
         title=_("Source snap channels to use for these builds."),
         description=_(
             "A dictionary mapping snap names to channels to use for these "
-            "builds.  Currently only 'charmcraft', 'core', 'core18', and "
-            "'core20' keys are supported."),
+            "builds.  Currently only 'charmcraft', 'core', 'core18', "
+            "'core20', and 'core22' keys are supported."),
         key_type=TextLine(), required=False, readonly=True)
 
     architectures = Set(
diff --git a/lib/lp/snappy/browser/tests/test_snap.py b/lib/lp/snappy/browser/tests/test_snap.py
index 762783d..9525518 100644
--- a/lib/lp/snappy/browser/tests/test_snap.py
+++ b/lib/lp/snappy/browser/tests/test_snap.py
@@ -2133,6 +2133,7 @@ class TestSnapRequestBuildsView(BaseTestSnapView):
             core
             core18
             core20
+            core22
             snapcraft
             The channels to use for build tools when building the snap
             package.
diff --git a/lib/lp/snappy/browser/widgets/snapbuildchannels.py b/lib/lp/snappy/browser/widgets/snapbuildchannels.py
index f7e3eb5..7d08edb 100644
--- a/lib/lp/snappy/browser/widgets/snapbuildchannels.py
+++ b/lib/lp/snappy/browser/widgets/snapbuildchannels.py
@@ -34,7 +34,7 @@ class SnapBuildChannelsWidget(BrowserWidget, InputWidget):
 
     template = ViewPageTemplateFile("templates/snapbuildchannels.pt")
     hint = False
-    snap_names = ["core", "core18", "core20", "snapcraft"]
+    snap_names = ["core", "core18", "core20", "core22", "snapcraft"]
     _widgets_set_up = False
 
     def __init__(self, context, request):
diff --git a/lib/lp/snappy/browser/widgets/templates/snapbuildchannels.pt b/lib/lp/snappy/browser/widgets/templates/snapbuildchannels.pt
index 28700a3..5a92fdf 100644
--- a/lib/lp/snappy/browser/widgets/templates/snapbuildchannels.pt
+++ b/lib/lp/snappy/browser/widgets/templates/snapbuildchannels.pt
@@ -16,6 +16,10 @@
     <td><div tal:content="structure view/core20_widget" /></td>
   </tr>
   <tr>
+    <td>core22</td>
+    <td><div tal:content="structure view/core22_widget" /></td>
+  </tr>
+  <tr>
     <td>snapcraft</td>
     <td><div tal:content="structure view/snapcraft_widget" /></td>
   </tr>
diff --git a/lib/lp/snappy/browser/widgets/tests/test_snapbuildchannelswidget.py b/lib/lp/snappy/browser/widgets/tests/test_snapbuildchannelswidget.py
index 4a4861c..08a4527 100644
--- a/lib/lp/snappy/browser/widgets/tests/test_snapbuildchannelswidget.py
+++ b/lib/lp/snappy/browser/widgets/tests/test_snapbuildchannelswidget.py
@@ -89,6 +89,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNotNone(getattr(self.widget, "core_widget", None))
         self.assertIsNotNone(getattr(self.widget, "core18_widget", None))
         self.assertIsNotNone(getattr(self.widget, "core20_widget", None))
+        self.assertIsNotNone(getattr(self.widget, "core22_widget", None))
         self.assertIsNotNone(getattr(self.widget, "snapcraft_widget", None))
 
     def test_setUpSubWidgets_second_call(self):
@@ -99,6 +100,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(getattr(self.widget, "core_widget", None))
         self.assertIsNone(getattr(self.widget, "core18_widget", None))
         self.assertIsNone(getattr(self.widget, "core20_widget", None))
+        self.assertIsNone(getattr(self.widget, "core22_widget", None))
         self.assertIsNone(getattr(self.widget, "snapcraft_widget", None))
 
     def test_setRenderedValue_None(self):
@@ -106,6 +108,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(self.widget.core_widget._getCurrentValue())
         self.assertIsNone(self.widget.core18_widget._getCurrentValue())
         self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core22_widget._getCurrentValue())
         self.assertIsNone(self.widget.snapcraft_widget._getCurrentValue())
 
     def test_setRenderedValue_empty(self):
@@ -113,6 +116,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(self.widget.core_widget._getCurrentValue())
         self.assertIsNone(self.widget.core18_widget._getCurrentValue())
         self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core22_widget._getCurrentValue())
         self.assertIsNone(self.widget.snapcraft_widget._getCurrentValue())
 
     def test_setRenderedValue_one_channel(self):
@@ -120,18 +124,22 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNone(self.widget.core_widget._getCurrentValue())
         self.assertIsNone(self.widget.core18_widget._getCurrentValue())
         self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core20_widget._getCurrentValue())
+        self.assertIsNone(self.widget.core22_widget._getCurrentValue())
         self.assertEqual(
             "stable", self.widget.snapcraft_widget._getCurrentValue())
 
     def test_setRenderedValue_all_channels(self):
         self.widget.setRenderedValue(
             {"core": "candidate", "core18": "beta", "core20": "edge",
-             "snapcraft": "stable"})
+             "core22": "edge/feature", "snapcraft": "stable"})
         self.assertEqual(
             "candidate", self.widget.core_widget._getCurrentValue())
         self.assertEqual("beta", self.widget.core18_widget._getCurrentValue())
         self.assertEqual("edge", self.widget.core20_widget._getCurrentValue())
         self.assertEqual(
+            "edge/feature", self.widget.core22_widget._getCurrentValue())
+        self.assertEqual(
             "stable", self.widget.snapcraft_widget._getCurrentValue())
 
     def test_hasInput_false(self):
@@ -153,6 +161,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
             "field.auto_build_channels.core": "",
             "field.auto_build_channels.core18": "beta",
             "field.auto_build_channels.core20": "edge",
+            "field.auto_build_channels.core22": "edge/feature",
             "field.auto_build_channels.snapcraft": "stable",
             }
         self.widget.request = LaunchpadTestRequest(form=form)
@@ -163,11 +172,12 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
             "field.auto_build_channels.core": "",
             "field.auto_build_channels.core18": "beta",
             "field.auto_build_channels.core20": "edge",
+            "field.auto_build_channels.core22": "edge/feature",
             "field.auto_build_channels.snapcraft": "stable",
             }
         self.widget.request = LaunchpadTestRequest(form=form)
         self.assertEqual(
-            {"core18": "beta", "core20": "edge",
+            {"core18": "beta", "core20": "edge", "core22": "edge/feature",
              "snapcraft": "stable"},
             self.widget.getInputValue())
 
@@ -177,6 +187,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
         self.assertIsNotNone(self.widget.core_widget)
         self.assertIsNotNone(self.widget.core18_widget)
         self.assertIsNotNone(self.widget.core20_widget)
+        self.assertIsNotNone(self.widget.core22_widget)
         self.assertIsNotNone(self.widget.snapcraft_widget)
         soup = BeautifulSoup(markup)
         fields = soup.find_all(["input"], {"id": re.compile(".*")})
@@ -184,6 +195,7 @@ class TestSnapBuildChannelsWidget(TestCaseWithFactory):
             "field.auto_build_channels.core",
             "field.auto_build_channels.core18",
             "field.auto_build_channels.core20",
+            "field.auto_build_channels.core22",
             "field.auto_build_channels.snapcraft",
             ]
         ids = [field["id"] for field in fields]
diff --git a/lib/lp/snappy/interfaces/snap.py b/lib/lp/snappy/interfaces/snap.py
index 9d46bb3..2445553 100644
--- a/lib/lp/snappy/interfaces/snap.py
+++ b/lib/lp/snappy/interfaces/snap.py
@@ -412,7 +412,7 @@ class ISnapView(Interface):
             title=_("Source snap channels to use for this build."),
             description=_(
                 "A dictionary mapping snap names to channels to use for this "
-                "build.  Currently only 'core', 'core18', 'core20' "
+                "build.  Currently only 'core', 'core18', 'core20', 'core22', "
                 "and 'snapcraft' keys are supported."),
             key_type=TextLine(), required=False))
     # Really ISnapBuild, patched in lp.snappy.interfaces.webservice.
@@ -442,7 +442,7 @@ class ISnapView(Interface):
             title=_("Source snap channels to use for this build."),
             description=_(
                 "A dictionary mapping snap names to channels to use for this "
-                "build.  Currently only 'core', 'core18', 'core20' "
+                "build.  Currently only 'core', 'core18', 'core20', 'core22', "
                 "and 'snapcraft' keys are supported."),
             key_type=TextLine(), required=False))
     @export_factory_operation(ISnapBuildRequest, [])
@@ -823,7 +823,7 @@ class ISnapEditableAttributes(IHasOwner):
         description=_(
             "A dictionary mapping snap names to channels to use when building "
             "this snap package.  Currently only 'core', 'core18', "
-            "'core20' and 'snapcraft' keys are supported.")))
+            "'core20', 'core22', and 'snapcraft' keys are supported.")))
 
     is_stale = exported(Bool(
         title=_("Snap package is stale and is due to be rebuilt."),
diff --git a/lib/lp/snappy/interfaces/snapbuild.py b/lib/lp/snappy/interfaces/snapbuild.py
index 6236234..f58eca5 100644
--- a/lib/lp/snappy/interfaces/snapbuild.py
+++ b/lib/lp/snappy/interfaces/snapbuild.py
@@ -179,7 +179,7 @@ class ISnapBuildView(IPackageBuild, IPrivacy):
         title=_("Source snap channels to use for this build."),
         description=_(
             "A dictionary mapping snap names to channels to use for this "
-            "build.  Currently only 'core', 'core18', 'core20' "
+            "build.  Currently only 'core', 'core18', 'core20', 'core22', "
             "and 'snapcraft' keys are supported."),
         key_type=TextLine()))
 
diff --git a/lib/lp/snappy/interfaces/snapjob.py b/lib/lp/snappy/interfaces/snapjob.py
index 4f557cf..ad892d1 100644
--- a/lib/lp/snappy/interfaces/snapjob.py
+++ b/lib/lp/snappy/interfaces/snapjob.py
@@ -73,7 +73,7 @@ class ISnapRequestBuildsJob(IRunnableJob):
         title=_("Source snap channels to use for these builds."),
         description=_(
             "A dictionary mapping snap names to channels to use for these "
-            "builds.  Currently only 'core', 'core18', 'core20' "
+            "builds.  Currently only 'core', 'core18', 'core20', 'core22', "
             "and 'snapcraft' keys are supported."),
         key_type=TextLine(), required=False, readonly=True)