Repository: packit-service/packit
Pull request #850 (2020-06-01 13:42:22)

Allow dumping of the package config
This PR enables dumping of the package config, which can be used in the packit-service when passing info into task

packit-as-a-service[bot]: Congratulations! One of the builds has completed. :champagne:

You can install the built RPMs by following these steps:

* `sudo yum install -y dnf-plugins-core` on RHEL 8
* `sudo dnf install -y dnf-plugins-core` on Fedora
* `dnf copr enable packit/packit-service-packit-850`
* And now you can install the packages.

Please note that the RPMs should be used only in a testing environment.
softwarefactory-project-zuul[bot]: Build failed.

- [packit-pre-commit ](https://softwarefactory-project.io/zuul/t/packit-service/build/79ab067f49c243d5850bdef69c68aa5b) : SUCCESS in 2m 46s
- [packit-tests-rpm ](https://softwarefactory-project.io/zuul/t/packit-service/build/5415f06d366c484191c7b81903f55895) : SUCCESS in 7m 39s
- [packit-tests-pip-deps ](https://softwarefactory-project.io/zuul/t/packit-service/build/d20d467fcb234a198c83faac1570d60c) : FAILURE in 7m 52s
- [packit-tests-git-master ](https://softwarefactory-project.io/zuul/t/packit-service/build/f2ea33840c484ec0ab3e8361845fc2cd) : FAILURE in 8m 13s
- [packit-tests-rpm-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/51c843606c6a4b22baadebef47ed9e0c) : SUCCESS in 2m 07s
- [packit-tests-pip-deps-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/e6d5870d8c804fc587309987a15969e3) : SUCCESS in 2m 17s
- [packit-tests-git-master-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/ff11ad6856ff44958f2e570e5b0628c9) : SUCCESS in 2m 59s
- [reverse-dep-packit-service-tests ](https://softwarefactory-project.io/zuul/t/packit-service/build/1846b26771bc40e483e35cee8f247262) : SUCCESS in 3m 51s

softwarefactory-project-zuul[bot]: Build failed.

- [packit-pre-commit ](https://softwarefactory-project.io/zuul/t/packit-service/build/55088d11f3514fe890f52fb241aa7111) : SUCCESS in 2m 18s
- [packit-tests-rpm ](https://softwarefactory-project.io/zuul/t/packit-service/build/e0d898eafbf44f9482a0832f906ee9d3) : SUCCESS in 6m 03s
- [packit-tests-pip-deps ](https://softwarefactory-project.io/zuul/t/packit-service/build/f5dfdd9d791341089329c739268581f8) : FAILURE in 7m 25s
- [packit-tests-git-master ](https://softwarefactory-project.io/zuul/t/packit-service/build/a3bf862305434139ae28df9aad4e0760) : FAILURE in 7m 27s
- [packit-tests-rpm-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/f93d3728eecd465aa90319a3c3fd56f1) : SUCCESS in 1m 51s
- [packit-tests-pip-deps-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/aeecdba5e721416a8f6c6a450f197179) : SUCCESS in 2m 41s
- [packit-tests-git-master-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/b94df98bb1614ca995c70efc491467aa) : SUCCESS in 2m 33s
- [reverse-dep-packit-service-tests ](https://softwarefactory-project.io/zuul/t/packit-service/build/d9d71bf68f6d44098e0362650d14b6f9) : SUCCESS in 4m 04s

softwarefactory-project-zuul[bot]: Build succeeded.

- [packit-pre-commit ](https://softwarefactory-project.io/zuul/t/packit-service/build/5d5cf07209e0440090617677abccdb32) : SUCCESS in 2m 20s
- [packit-tests-rpm ](https://softwarefactory-project.io/zuul/t/packit-service/build/083c8b543eaf4d15bea3e76652f74195) : SUCCESS in 6m 54s
- [packit-tests-pip-deps ](https://softwarefactory-project.io/zuul/t/packit-service/build/ef14767d3e9f4d9eb4f6996d5090fdf9) : SUCCESS in 7m 18s
- [packit-tests-git-master ](https://softwarefactory-project.io/zuul/t/packit-service/build/ca9a094ed91a48b49fe2268b87dfe6c2) : SUCCESS in 8m 37s
- [packit-tests-rpm-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/37d1bd94defb4c2d88c6c8d496bfd72d) : SUCCESS in 1m 48s
- [packit-tests-pip-deps-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/24e3984a272441deb70b2dbb8be428f1) : SUCCESS in 2m 43s
- [packit-tests-git-master-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/b0dbefb9dfef4f15a1155af2b5933564) : SUCCESS in 2m 48s
- [reverse-dep-packit-service-tests ](https://softwarefactory-project.io/zuul/t/packit-service/build/67d255ae0c704549b877857af29e177b) : SUCCESS in 4m 08s

softwarefactory-project-zuul[bot]: Build succeeded.

- [packit-pre-commit ](https://softwarefactory-project.io/zuul/t/packit-service/build/ffb5555442934f44a495c6ae72ea7464) : SUCCESS in 2m 27s
- [packit-tests-rpm ](https://softwarefactory-project.io/zuul/t/packit-service/build/fc174104e37647cea13a6c8d97d5aac0) : SUCCESS in 7m 12s
- [packit-tests-pip-deps ](https://softwarefactory-project.io/zuul/t/packit-service/build/09a23e845d3148bcac554824fbd7e918) : SUCCESS in 7m 39s
- [packit-tests-git-master ](https://softwarefactory-project.io/zuul/t/packit-service/build/63d96d3a4def45758a5539ce17fd3e77) : SUCCESS in 8m 47s
- [packit-tests-rpm-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/bc13f3b1315a4a139908538b578d6de0) : SUCCESS in 2m 13s
- [packit-tests-pip-deps-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/c2513e4b30f1425cb95893ca2125df67) : SUCCESS in 2m 37s
- [packit-tests-git-master-sess-rec ](https://softwarefactory-project.io/zuul/t/packit-service/build/98389b1dad304b90be94146a35c5158c) : SUCCESS in 2m 54s
- [reverse-dep-packit-service-tests ](https://softwarefactory-project.io/zuul/t/packit-service/build/ac59f5c240694f3a871636b881e4d99a) : SUCCESS in 4m 05s

TomasTomecek: I'm going to ask Hunor's favourite question: what is the reason for this PR? Could you please clarify where this is going to be used?

Patch:
diff --git a/packit/schema.py b/packit/schema.py
index f427795b..9527cc51 100644
--- a/packit/schema.py
+++ b/packit/schema.py
@@ -19,17 +19,10 @@
 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
-
 from logging import getLogger
 from typing import Dict, Any, Optional, Mapping
 
-from marshmallow import (
-    Schema,
-    fields,
-    post_load,
-    pre_load,
-    ValidationError,
-)
+from marshmallow import Schema, fields, post_load, pre_load, ValidationError, post_dump
 
 try:
     from marshmallow import __version_info__
@@ -64,7 +57,7 @@ class FilesToSyncField(fields.Field):
     """
 
     def _serialize(self, value: Any, attr: str, obj: Any, **kwargs):
-        raise NotImplementedError
+        return {"src": value.src, "dest": value.dest}
 
     def _deserialize(
         self,
@@ -98,7 +91,7 @@ class ActionField(fields.Field):
     """
 
     def _serialize(self, value: Any, attr: str, obj: Any, **kwargs):
-        raise NotImplementedError
+        return {action_name.value: val for action_name, val in value.items()}
 
     def _deserialize(
         self,
@@ -128,7 +121,7 @@ class ActionField(fields.Field):
 
 class NotProcessedField(fields.Field):
     """
-    Field class to mark fields which wil not be processed, only generates warning.
+    Field class to mark fields which will not be processed, only generates warning.
     Can be passed additional message via additional_message parameter.
 
     :param str additional_message: additional warning message to be displayed
@@ -169,6 +162,17 @@ class MM23Schema(Schema):
             result = super().load(*args, **kwargs).data
         return result
 
+    def dump(self, *args, **kwargs):
+        if MM3:
+            result = super().dump(*args, **kwargs)
+        else:  # v2
+            result = super().dump(*args, **kwargs).data
+        return result
+
+    @post_dump
+    def remove_none_values(self, data, **kwargs):
+        return {key: value for key, value in data.items() if value is not None}
+
 
 # TODO: inherit from MM23Schema
 class SyncFilesConfigSchema(Schema):
@@ -228,6 +232,10 @@ class JobMetadataSchema(Schema):
     def make_instance(self, data, **_):
         return JobMetadataConfig(**data)
 
+    @post_dump
+    def remove_none_values(self, data, **kwargs):
+        return {key: value for key, value in data.items() if value is not None}
+
 
 # TODO: inherit from MM23Schema
 class JobConfigSchema(Schema):
@@ -235,15 +243,14 @@ class JobConfigSchema(Schema):
     Schema for processing JobConfig config data.
     """
 
-    job = EnumField(JobType, required=True)
+    job = EnumField(JobType, required=True, attribute="type")
     trigger = EnumField(JobConfigTriggerType, required=True)
     metadata = fields.Nested(JobMetadataSchema)
     overrides = fields.Dict()
 
     @post_load
     def make_instance(self, data, **_):
-        type = data.pop("job")
-        return JobConfig(type=type, **data)
+        return JobConfig(**data)
 
 
 class PullRequestNotificationsSchema(Schema):
@@ -279,7 +286,8 @@ class PackageConfigSchema(MM23Schema):
     upstream_ref = fields.String()
     upstream_tag_template = fields.String()
     dist_git_url = NotProcessedField(
-        additional_message="it is generated from dist_git_base_url and downstream_package_name"
+        additional_message="it is generated from dist_git_base_url and downstream_package_name",
+        load_only=True,
     )
     dist_git_base_url = fields.String()
     dist_git_namespace = fields.String()


Test patch:
diff --git a/tests/unit/test_package_config.py b/tests/unit/test_package_config.py
index 6b55a75a..673cd08a 100644
--- a/tests/unit/test_package_config.py
+++ b/tests/unit/test_package_config.py
@@ -20,7 +20,7 @@ from packit.config.package_config import (
     PackageConfig,
     get_local_specfile_path,
 )
-from packit.schema import MM3
+from packit.schema import MM3, PackageConfigSchema
 from packit.sync import SyncFilesItem
 from tests.spellbook import UP_OSBUILD, SYNC_FILES
 from tests.unit.test_config import (
@@ -888,3 +888,47 @@ def test_notifications_section():
 def test_get_local_specfile_path():
     assert str(get_local_specfile_path(UP_OSBUILD)) == "osbuild.spec"
     assert not get_local_specfile_path(SYNC_FILES)
+
+
+@pytest.mark.parametrize(
+    "package_config",
+    [
+        PackageConfig(
+            specfile_path="fedora/package.spec",
+            synced_files=SyncFilesConfig(
+                files_to_sync=[
+                    SyncFilesItem(src="fedora/package.spec", dest="fedora/package.spec")
+                ]
+            ),
+            downstream_package_name="package",
+            upstream_package_name="package",
+        ),
+        PackageConfig(
+            specfile_path="fedora/package.spec",
+            synced_files=SyncFilesConfig(
+                files_to_sync=[
+                    SyncFilesItem(src="fedora/package.spec", dest="fedora/package.spec")
+                ]
+            ),
+            jobs=[get_job_config_full()],
+            downstream_package_name="package",
+        ),
+        PackageConfig(
+            specfile_path="fedora/package.spec",
+            actions={
+                ActionName.pre_sync: "some/pre-sync/command --option",
+                ActionName.get_current_version: "get-me-version",
+            },
+            jobs=[],
+            upstream_project_url="https://github.com/asd/qwe",
+            upstream_package_name="qwe",
+            dist_git_base_url="https://something.wicked",
+            downstream_package_name="package",
+        ),
+    ],
+)
+def test_serialize_and_deserialize(package_config):
+    schema = PackageConfigSchema()
+    serialized = schema.dump(package_config)
+    new_package_config = schema.load(serialized)
+    assert package_config == new_package_config