From: Joerg Behrmann Date: Wed, 4 Oct 2023 15:41:46 +0000 (+0200) Subject: json: move JSON keys to PascalCase X-Git-Tag: v18~5^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2c5d15df8992ff51cf81b84a0ee03ccbca4ee2a3;p=thirdparty%2Fmkosi.git json: move JSON keys to PascalCase --- diff --git a/mkosi/config.py b/mkosi/config.py index 6150a0db1..577a8b765 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -16,6 +16,7 @@ import math import operator import os.path import platform +import re import shlex import shutil import subprocess @@ -684,7 +685,11 @@ class MkosiArgs: def to_json(self, *, indent: Optional[int] = 4, sort_keys: bool = True) -> str: """Dump MKosiArgs as JSON string.""" - return json.dumps(dataclasses.asdict(self), cls=MkosiJsonEncoder, indent=indent, sort_keys=sort_keys) + def key_transformer(k: str) -> str: + return "".join(p.capitalize() for p in k.split("_")) + + d = {key_transformer(k): v for k, v in dataclasses.asdict(self).items()} + return json.dumps(d, cls=MkosiJsonEncoder, indent=indent, sort_keys=sort_keys) @classmethod def _load_json(cls, s: Union[str, dict[str, Any], SupportsRead[str], SupportsRead[bytes]]) -> dict[str, Any]: @@ -698,8 +703,11 @@ class MkosiArgs: else: raise ValueError(f"{cls.__name__} can only be constructed from JSON from strings, dictionaries and files.") - transformer = json_type_transformer(cls) - return {k: transformer(k, v) for k, v in j.items()} + value_transformer = json_type_transformer(cls) + def key_transformer(k: str) -> str: + return "_".join(part.lower() for part in FALLBACK_NAME_TO_DEST_SPLITTER.split(k)) + + return {(tk := key_transformer(k)): value_transformer(tk, v) for k, v in j.items()} @classmethod def from_json(cls, s: Union[str, dict[str, Any], SupportsRead[str], SupportsRead[bytes]]) -> "MkosiArgs": @@ -936,7 +944,13 @@ class MkosiConfig: def to_json(self, *, indent: Optional[int] = 4, sort_keys: bool = True) -> str: """Dump MKosiConfig as JSON string.""" - return json.dumps(dataclasses.asdict(self), cls=MkosiJsonEncoder, indent=indent, sort_keys=sort_keys) + 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("_")) + + d = {key_transformer(k): v for k, v in dataclasses.asdict(self).items()} + return json.dumps(d, cls=MkosiJsonEncoder, indent=indent, sort_keys=sort_keys) @classmethod def _load_json(cls, s: Union[str, dict[str, Any], SupportsRead[str], SupportsRead[bytes]]) -> dict[str, Any]: @@ -950,8 +964,13 @@ class MkosiConfig: else: raise ValueError(f"{cls.__name__} can only be constructed from JSON from strings, dictionaries and files.") - transformer = json_type_transformer(cls) - return {k: transformer(k, v) for k, v in j.items()} + value_transformer = json_type_transformer(cls) + def key_transformer(k: str) -> str: + if (s := SETTINGS_LOOKUP_BY_NAME.get(k)) is not None: + return s.dest + return "_".join(part.lower() for part in FALLBACK_NAME_TO_DEST_SPLITTER.split(k)) + + return {(tk := key_transformer(k)): value_transformer(tk, v) for k, v in j.items()} @classmethod def from_json(cls, s: Union[str, dict[str, Any], SupportsRead[str], SupportsRead[bytes]]) -> "MkosiConfig": @@ -1879,6 +1898,13 @@ MATCHES = ( MATCH_LOOKUP = {m.name: m for m in MATCHES} +# This regular expression can be used to split "AutoBump" -> ["Auto", "Bump"] +# and "NSpawnSettings" -> ["NSpawn", "Settings"] +# The first part (?<=[a-z]) is a positive look behind for a lower case letter +# and (?=[A-Z]) is a lookahead assertion matching an upper case letter but not +# consuming it +FALLBACK_NAME_TO_DEST_SPLITTER = re.compile("(?<=[a-z])(?=[A-Z])") + def create_argument_parser(action: type[argparse.Action]) -> argparse.ArgumentParser: parser = argparse.ArgumentParser( diff --git a/tests/test_json.py b/tests/test_json.py index cbf5b2008..e137e936c 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -31,20 +31,20 @@ def test_args(path: Optional[Path]) -> None: dump = textwrap.dedent( f"""\ {{ - "auto_bump": false, - "cmdline": [ + "AutoBump": false, + "Cmdline": [ "foo", "bar" ], - "debug": false, - "debug_shell": false, - "directory": {f'"{os.fspath(path)}"' if path is not None else 'null'}, - "doc_format": "auto", - "force": 9001, - "genkey_common_name": "test", - "genkey_valid_days": "100", - "pager": true, - "verb": "build" + "Debug": false, + "DebugShell": false, + "Directory": {f'"{os.fspath(path)}"' if path is not None else 'null'}, + "DocFormat": "auto", + "Force": 9001, + "GenkeyCommonName": "test", + "GenkeyValidDays": "100", + "Pager": true, + "Verb": "build" }} """ ) @@ -71,60 +71,61 @@ def test_config() -> None: dump = textwrap.dedent( """\ { - "acl": true, - "architecture": "ia64", - "autologin": false, - "base_trees": [ + "Acl": true, + "Architecture": "ia64", + "Autologin": false, + "BaseTrees": [ "/hello/world" ], - "bios_bootloader": "none", - "bootable": "disabled", - "bootloader": "grub", - "build_dir": null, - "build_packages": [ + "BiosBootloader": "none", + "Bootable": "disabled", + "Bootloader": "grub", + "BuildDirectory": null, + "BuildPackages": [ "pkg1", "pkg2" ], - "build_scripts": [ + "BuildScripts": [ "/path/to/buildscript" ], - "build_sources": [ + "BuildSources": [ [ "/qux", "/frob" ] ], - "cache_dir": "/is/this/the/cachedir", - "cache_only": true, - "checksum": false, - "clean_package_metadata": "auto", - "compress_output": "bz2", - "credentials": { + "CacheDirectory": "/is/this/the/cachedir", + "CacheOnly": true, + "Checksum": false, + "CleanPackageMetadata": "auto", + "CompressOutput": "bz2", + "Credentials": { "credkey": "credval" }, - "dependencies": [ + "Dependencies": [ "dep1" ], - "distribution": "fedora", - "environment": {}, - "ephemeral": true, - "extra_search_paths": [], - "extra_trees": [], - "finalize_scripts": [], - "hostname": null, - "image_id": "myimage", - "image_version": "5", - "include": [], - "incremental": false, - "initrd_packages": [ + "Distribution": "fedora", + "Environment": {}, + "Ephemeral": true, + "ExtraSearchPaths": [], + "ExtraTrees": [], + "FinalizeScripts": [], + "Format": "uki", + "Hostname": null, + "ImageId": "myimage", + "ImageVersion": "5", + "Include": [], + "Incremental": false, + "InitrdPackages": [ "clevis" ], - "initrds": [ + "Initrds": [ "/efi/initrd1", "/efi/initrd2" ], - "kernel_command_line": [], - "kernel_command_line_extra": [ + "KernelCommandLine": [], + "KernelCommandLineExtra": [ "look", "im", "on", @@ -133,75 +134,74 @@ def test_config() -> None: "command", "line" ], - "kernel_modules_exclude": [ + "KernelModulesExclude": [ "nvidia" ], - "kernel_modules_include": [ + "KernelModulesInclude": [ "loop" ], - "kernel_modules_initrd": true, - "kernel_modules_initrd_exclude": [], - "kernel_modules_initrd_include": [], - "key": null, - "keymap": "wow, so much keymap", - "local_mirror": null, - "locale": "en_C.UTF-8", - "locale_messages": "", - "make_initrd": false, - "manifest_format": [ + "KernelModulesInitrd": true, + "KernelModulesInitrdExclude": [], + "KernelModulesInitrdInclude": [], + "Key": null, + "Keymap": "wow, so much keymap", + "LocalMirror": null, + "Locale": "en_C.UTF-8", + "LocaleMessages": "", + "MakeInitrd": false, + "ManifestFormat": [ "json", "changelog" ], - "mirror": null, - "nspawn_settings": null, - "output": "outfile", - "output_dir": "/your/output/here", - "output_format": "uki", - "overlay": true, - "package_manager_trees": [ + "Mirror": null, + "NSpawnSettings": null, + "Output": "outfile", + "OutputDirectory": "/your/output/here", + "Overlay": true, + "PackageManagerTrees": [ [ "/foo/bar", null ] ], - "packages": [], - "passphrase": null, - "postinst_scripts": [ + "Packages": [], + "Passphrase": null, + "PostInstallationScripts": [ "/bar/qux" ], - "prepare_scripts": [ + "PrepareScripts": [ "/run/foo" ], - "preset": "default", - "presets": [ + "Preset": "default", + "Presets": [ "default", "initrd" ], - "qemu_args": [], - "qemu_cdrom": false, - "qemu_firmware": "linux", - "qemu_gui": true, - "qemu_kernel": null, - "qemu_kvm": "auto", - "qemu_mem": "", - "qemu_smp": "yes", - "qemu_swtpm": "auto", - "qemu_vsock": "enabled", - "release": "53", - "remove_files": [], - "remove_packages": [ + "QemuArgs": [], + "QemuCdrom": false, + "QemuFirmware": "linux", + "QemuGui": true, + "QemuKernel": null, + "QemuKvm": "auto", + "QemuMem": "", + "QemuSmp": "yes", + "QemuSwtpm": "auto", + "QemuVsock": "enabled", + "Release": "53", + "RemoveFiles": [], + "RemovePackages": [ "all" ], - "repart_dirs": [], - "repositories": [], - "repository_key_check": false, - "root_password": [ + "RepartDirectories": [], + "Repositories": [], + "RepositoryKeyCheck": false, + "RootPassword": [ "test1234", false ], - "root_shell": "/bin/tcsh", - "runtime_size": 8589934592, - "runtime_trees": [ + "RootShell": "/bin/tcsh", + "RuntimeSize": 8589934592, + "RuntimeTrees": [ [ "/foo/bar", "/baz" @@ -211,15 +211,15 @@ def test_config() -> None: "/qux" ] ], - "sector_size": null, - "secure_boot": true, - "secure_boot_certificate": null, - "secure_boot_key": "/path/to/keyfile", - "secure_boot_sign_tool": "pesign", - "seed": "7496d7d8-7f08-4a2b-96c6-ec8c43791b60", - "sign": false, - "sign_expected_pcr": "disabled", - "skeleton_trees": [ + "SectorSize": null, + "SecureBoot": true, + "SecureBootCertificate": null, + "SecureBootKey": "/path/to/keyfile", + "SecureBootSignTool": "pesign", + "Seed": "7496d7d8-7f08-4a2b-96c6-ec8c43791b60", + "Sign": false, + "SignExpectedPcr": "disabled", + "SkeletonTrees": [ [ "/foo/bar", null @@ -229,21 +229,21 @@ def test_config() -> None: "/qux" ] ], - "source_date_epoch": 12345, - "split_artifacts": true, - "ssh": false, - "timezone": null, - "tools_tree": null, - "tools_tree_distribution": null, - "tools_tree_packages": [], - "tools_tree_release": null, - "use_subvolumes": "auto", - "verity_certificate": "/path/to/cert", - "verity_key": null, - "with_docs": true, - "with_network": false, - "with_tests": true, - "workspace_dir": "/cwd" + "SourceDateEpoch": 12345, + "SplitArtifacts": true, + "Ssh": false, + "Timezone": null, + "ToolsTree": null, + "ToolsTreeDistribution": null, + "ToolsTreePackages": [], + "ToolsTreeRelease": null, + "UseSubvolumes": "auto", + "VerityCertificate": "/path/to/cert", + "VerityKey": null, + "WithDocs": true, + "WithNetwork": false, + "WithTests": true, + "WorkspaceDirectory": "/cwd" } """ )