[Patchew-devel] [PATCH 06/10] mods: refactor extraction of configuration into a dictionary

Paolo Bonzini posted 10 patches 6 years ago
There is a newer version of this series
[Patchew-devel] [PATCH 06/10] mods: refactor extraction of configuration into a dictionary
Posted by Paolo Bonzini 6 years ago
Both the email and testing modules have code to extract the
configuration from project properties into a dictionary.
Generalize that code, using the project_config_schema to
drive the conversion, and use it in the git plugin as well

This matches the way configuration will be stored in the database
when we move away from project properties.  In fact, all
this nice visitor code will disappear very soon...
---
 mod.py          | 37 ++++++++++++++++++++++++++++++++++++-
 mods/email.py   | 14 +-------------
 mods/git.py     | 28 ++++++++++++++++------------
 mods/testing.py | 25 ++++---------------------
 4 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/mod.py b/mod.py
index 319d4d3..d24e924 100644
--- a/mod.py
+++ b/mod.py
@@ -53,7 +53,7 @@ class PatchewModule(object):
         prefix = prefix + scm.name + "."
         def _build_map_items():
             r = {}
-            for p, v in project.get_properties().items():
+            for p in project.get_properties().keys():
                 if not p.startswith(prefix):
                     continue
                 name = p[len(prefix):]
@@ -152,6 +152,41 @@ class PatchewModule(object):
         tmpl += self._render_template(request, project, TMPL_END)
         return tmpl
 
+    def _get_map_scm(self, project, prop_name, scm):
+        prefix = prop_name + "."
+        result = {}
+        for p in project.get_properties().keys():
+            if not p.startswith(prefix):
+                continue
+            name = p[len(prefix):]
+            name = name[:name.rfind(".")]
+            if name in result:
+                continue
+            assert scm.item.name == '{name}'
+            value = self._get_one(project, prefix + name, scm.item)
+            result[name] = value
+        return result
+
+    def _get_array_scm(self, project, prop_name, scm):
+        prefix = prop_name + "."
+        result = {}
+        for i in scm.members:
+            assert i.name != '{name}'
+            result[i.name] = self._get_one(project, prefix + i.name, i)
+        return result
+
+    def _get_one(self, project, prop_name, scm):
+        if type(scm) == MapSchema:
+            return self._get_map_scm(project, prop_name, scm)
+        elif type(scm) == ArraySchema:
+            return self._get_array_scm(project, prop_name, scm)
+        else:
+            return project.get_property(prop_name)
+
+    def get_project_config(self, project):
+        scm = self.project_config_schema
+        return self._get_one(project, scm.name, scm)
+
 _loaded_modules = {}
 
 def _module_init_config(cls):
diff --git a/mods/email.py b/mods/email.py
index 14553f0..58dac57 100644
--- a/mods/email.py
+++ b/mods/email.py
@@ -191,19 +191,7 @@ Email information is configured in "INI" style:
         return "<%s@patchew.org>" % uuid.uuid1()
 
     def get_notifications(self, project):
-        ret = {}
-        for k, v in project.get_properties().items():
-            if not k.startswith("email.notifications."):
-                continue
-            tn = k[len("email.notifications."):]
-            if "." not in tn:
-                continue
-            an = tn[tn.find(".") + 1:]
-            tn = tn[:tn.find(".")]
-            ret.setdefault(tn, {})
-            ret[tn][an] = v
-            ret[tn]["name"] = tn
-        return ret
+        return self.get_project_config(project).get("notifications", {})
 
     def on_event(self, event, **params):
         class EmailCancelled(Exception):
diff --git a/mods/git.py b/mods/git.py
index 110f261..d459a0b 100644
--- a/mods/git.py
+++ b/mods/git.py
@@ -98,9 +98,6 @@ class GitModule(PatchewModule):
         if series.is_complete:
             self.mark_as_pending_apply(series)
 
-    def get_project_config(self, project, what):
-        return project.get_property("git." + what)
-
     def _is_repo(self, path):
         if not os.path.isdir(path):
             return False
@@ -116,10 +113,14 @@ class GitModule(PatchewModule):
 
     def get_mirror(self, po, request, format):
         response = {}
-        for key, prop in (("head", "git.head"),
-                          ("pushurl", "git.push_to"),
-                          ("url", "git.public_repo")):
-            response[key] = po.get_property(prop) or None
+        config = self.get_project_config(po)
+        if "push_to" in config:
+            response["pushurl"] = config["push_to"]
+        if "public_repo" in config:
+            response["url"] = config["public_repo"]
+        head = po.get_property("git.head")
+        if head:
+            response["head"] = head
         return response
 
     def rest_project_fields_hook(self, request, fields):
@@ -130,7 +131,9 @@ class GitModule(PatchewModule):
 
     def get_projects_prepare_hook(self, project, response):
         response["git.head"] = project.get_property("git.head")
-        response["git.push_to"] = project.get_property("git.push_to")
+        config = self.get_project_config(project)
+        if "push_to" in config:
+            response["git.push_to"] = config["push_to"]
 
     def prepare_message_hook(self, request, message, detailed):
         if not message.is_series_head:
@@ -264,9 +267,9 @@ class ApplierGetView(APILoginRequiredView):
                                                       "properties", "tags"])
 
         po = m.project
-        for prop in ["git.push_to", "git.public_repo", "git.url_template"]:
-            if po.get_property(prop):
-                response[prop] = po.get_property(prop)
+        config = _instance.get_project_config(po)
+        for k, v in config.items():
+            response["git." + k] = v
         base = _instance.get_base(m)
         if base:
             response["git.repo"] = base.data["repo"]
@@ -296,7 +299,8 @@ class ApplierReportView(APILoginRequiredView):
             if url:
                 data['url'] = url
             elif tag:
-                url_template = p.get_property("git.url_template")
+                config = _instance.get_project_config(po)
+                url_template = config.get("url_template")
                 if url_template:
                     data['url'] = url_template.replace("%t", tag)
             if base:
diff --git a/mods/testing.py b/mods/testing.py
index 9df4ccd..9e41307 100644
--- a/mods/testing.py
+++ b/mods/testing.py
@@ -298,18 +298,7 @@ class TestingModule(PatchewModule):
         ret = {}
         if isinstance(obj, Message):
             obj = obj.project
-        for k, v in obj.get_properties().items():
-            if not k.startswith("testing.tests."):
-                continue
-            tn = k[len("testing.tests."):]
-            if "." not in tn:
-                continue
-            an = tn[tn.find(".") + 1:]
-            tn = tn[:tn.find(".")]
-            ret.setdefault(tn, {})
-            ret[tn][an] = v
-            ret[tn]["name"] = tn
-        return ret
+        return self.get_project_config(obj).get("tests", {})
 
     def _build_reset_ops(self, obj):
         if isinstance(obj, Message):
@@ -409,15 +398,8 @@ class TestingModule(PatchewModule):
             project.extra_ops += self._build_reset_ops(project)
 
     def get_capability_probes(self, project):
-        ret = {}
-        for k, v in project.get_properties().items():
-            prefix = "testing.requirements."
-            if not k.startswith(prefix):
-                continue
-            name = k[len(prefix):]
-            name = name[:name.find(".")]
-            ret[name] = v
-        return ret
+        props = self.get_project_config(project).get('requirements', {})
+        return {k: v['script'] for k, v in props.items()}
 
     def get_testing_probes(self, project, request, format):
         return self.get_capability_probes(project)
@@ -494,6 +476,7 @@ class TestingGetView(APILoginRequiredView):
                 if req not in capabilities:
                     break
             else:
+                t["name"] = tn
                 yield r, t
 
     def _find_project_test(self, request, po, tester, capabilities):
-- 
2.21.0


_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel