From 5a53ab68b5f24d9b8ee6d4c21f93297dfb91a799 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rg=20Behrmann?= Date: Tue, 26 Mar 2024 11:36:31 +0100 Subject: [PATCH] config: capitalise inner keys in JSON dump --- mkosi/config.py | 49 ++++++++++++++++++++++--------------------- tests/test_json.py | 52 +++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/mkosi/config.py b/mkosi/config.py index 60e84eb4d..93bd2b08e 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -1186,6 +1186,15 @@ class PagerHelpAction(argparse._HelpAction): parser.exit() +def dict_with_capitalised_keys_factory(pairs: Any) -> dict[str, Any]: + def key_transformer(k: str) -> str: + if (s := SETTINGS_LOOKUP_BY_DEST.get(k)) is not None: + return s.name + return "".join(p.capitalize() for p in k.split("_")) + + return {key_transformer(k): v for k, v in dict(pairs).items()} + + @dataclasses.dataclass(frozen=True) class Args: verb: Verb @@ -1222,10 +1231,7 @@ class Args: }) def to_dict(self) -> dict[str, Any]: - def key_transformer(k: str) -> str: - return "".join(p.capitalize() for p in k.split("_")) - - return {key_transformer(k): v for k, v in dataclasses.asdict(self).items()} + return dataclasses.asdict(self, dict_factory=dict_with_capitalised_keys_factory) def to_json(self, *, indent: Optional[int] = 4, sort_keys: bool = True) -> str: """Dump MkosiArgs as JSON string.""" @@ -1536,12 +1542,7 @@ class Config: } def to_dict(self) -> dict[str, Any]: - def key_transformer(k: str) -> str: - if (s := SETTINGS_LOOKUP_BY_DEST.get(k)) is not None: - return s.name - return "".join(p.capitalize() for p in k.split("_")) - - return {key_transformer(k): v for k, v in dataclasses.asdict(self).items()} + return dataclasses.asdict(self, dict_factory=dict_with_capitalised_keys_factory) def to_json(self, *, indent: Optional[int] = 4, sort_keys: bool = True) -> str: """Dump MkosiConfig as JSON string.""" @@ -3887,12 +3888,12 @@ def json_type_transformer(refcls: Union[type[Args], type[Config]]) -> Callable[[ # TODO: exchange for TypeGuard and list comprehension once on 3.10 ret = [] for d in trees: - assert "source" in d - assert "target" in d + assert "Source" in d + assert "Target" in d ret.append( ConfigTree( - source=Path(d["source"]), - target=Path(d["target"]) if d["target"] is not None else None, + source=Path(d["Source"]), + target=Path(d["Target"]) if d["Target"] is not None else None, ) ) return ret @@ -3914,16 +3915,16 @@ def json_type_transformer(refcls: Union[type[Args], type[Config]]) -> Callable[[ # TODO: exchange for TypeGuard and list comprehension once on 3.10 ret = [] for d in drives: - assert "id" in d - assert "size" in d - assert "directory" in d - assert "options" in d + assert "Id" in d + assert "Size" in d + assert "Directory" in d + assert "Options" in d ret.append( QemuDrive( - id=d["id"], - size=int(d["size"]), - directory=Path(d["directory"]) if d["directory"] else None, - options=d["options"], + id=d["Id"], + size=int(d["Size"]), + directory=Path(d["Directory"]) if d["Directory"] else None, + options=d["Options"], ) ) return ret @@ -3935,8 +3936,8 @@ def json_type_transformer(refcls: Union[type[Args], type[Config]]) -> Callable[[ return GenericVersion(version) if version is not None else None def key_source_transformer(keysource: dict[str, Any], fieldtype: type[KeySource]) -> KeySource: - assert "type" in keysource - return KeySource(type=KeySource.Type(keysource["type"]), source=keysource.get("source", "")) + assert "Type" in keysource + return KeySource(type=KeySource.Type(keysource["Type"]), source=keysource.get("Source", "")) transformers = { Path: path_transformer, diff --git a/tests/test_json.py b/tests/test_json.py index 4d8eaba22..1701f646c 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -103,8 +103,8 @@ def test_config() -> None: ], "BuildSources": [ { - "source": "/qux", - "target": "/frob" + "Source": "/qux", + "Target": "/frob" } ], "BuildSourcesEphemeral": true, @@ -194,8 +194,8 @@ def test_config() -> None: "PackageDirectories": [], "PackageManagerTrees": [ { - "source": "/foo/bar", - "target": null + "Source": "/foo/bar", + "Target": null } ], "Packages": [], @@ -215,16 +215,16 @@ def test_config() -> None: "QemuCdrom": false, "QemuDrives": [ { - "directory": "/foo/bar", - "id": "abc", - "options": "abc,qed", - "size": 200 + "Directory": "/foo/bar", + "Id": "abc", + "Options": "abc,qed", + "Size": 200 }, { - "directory": null, - "id": "abc", - "options": "", - "size": 200 + "Directory": null, + "Id": "abc", + "Options": "", + "Size": 200 } ], "QemuFirmware": "linux", @@ -256,12 +256,12 @@ def test_config() -> None: "RuntimeSize": 8589934592, "RuntimeTrees": [ { - "source": "/foo/bar", - "target": "/baz" + "Source": "/foo/bar", + "Target": "/baz" }, { - "source": "/bar/baz", - "target": "/qux" + "Source": "/bar/baz", + "Target": "/qux" } ], "SELinuxRelabel": "disabled", @@ -271,8 +271,8 @@ def test_config() -> None: "SecureBootCertificate": null, "SecureBootKey": "/path/to/keyfile", "SecureBootKeySource": { - "source": "", - "type": "file" + "Source": "", + "Type": "file" }, "SecureBootSignTool": "pesign", "Seed": "7496d7d8-7f08-4a2b-96c6-ec8c43791b60", @@ -281,12 +281,12 @@ def test_config() -> None: "SignExpectedPcr": "disabled", "SkeletonTrees": [ { - "source": "/foo/bar", - "target": "/" + "Source": "/foo/bar", + "Target": "/" }, { - "source": "/bar/baz", - "target": "/qux" + "Source": "/bar/baz", + "Target": "/qux" } ], "SourceDateEpoch": 12345, @@ -303,8 +303,8 @@ def test_config() -> None: "ToolsTreeMirror": null, "ToolsTreePackageManagerTrees": [ { - "source": "/a/b/c", - "target": "/" + "Source": "/a/b/c", + "Target": "/" } ], "ToolsTreePackages": [], @@ -317,8 +317,8 @@ def test_config() -> None: "VerityCertificate": "/path/to/cert", "VerityKey": null, "VerityKeySource": { - "source": "", - "type": "file" + "Source": "", + "Type": "file" }, "VirtualMachineMonitor": "qemu", "WithDocs": true, -- 2.47.2