clan.cli.inventory: init partial write
This commit is contained in:
@@ -119,6 +119,37 @@ def load_inventory_json(
|
|||||||
return inventory
|
return inventory
|
||||||
|
|
||||||
|
|
||||||
|
def patch(d: dict[str, Any], path: str, content: Any) -> None:
|
||||||
|
"""
|
||||||
|
Update the value at a specific dot-separated path in a nested dictionary.
|
||||||
|
|
||||||
|
:param d: The dictionary to update.
|
||||||
|
:param path: The dot-separated path to the key (e.g., 'foo.bar').
|
||||||
|
:param content: The new value to set.
|
||||||
|
"""
|
||||||
|
keys = path.split(".")
|
||||||
|
current = d
|
||||||
|
for key in keys[:-1]:
|
||||||
|
current = current.setdefault(key, {})
|
||||||
|
current[keys[-1]] = content
|
||||||
|
|
||||||
|
|
||||||
|
@API.register
|
||||||
|
def patch_inventory_with(base_dir: Path, section: str, content: dict[str, Any]) -> None:
|
||||||
|
inventory_file = get_path(base_dir)
|
||||||
|
|
||||||
|
curr_inventory = {}
|
||||||
|
with inventory_file.open("r") as f:
|
||||||
|
curr_inventory = json.load(f)
|
||||||
|
|
||||||
|
patch(curr_inventory, section, content)
|
||||||
|
|
||||||
|
with inventory_file.open("w") as f:
|
||||||
|
json.dump(curr_inventory, f, indent=2)
|
||||||
|
|
||||||
|
commit_file(inventory_file, base_dir, commit_message=f"inventory.{section}: Update")
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def set_inventory(
|
def set_inventory(
|
||||||
inventory: Inventory | dict[str, Any], flake_dir: str | Path, message: str
|
inventory: Inventory | dict[str, Any], flake_dir: str | Path, message: str
|
||||||
|
|||||||
36
pkgs/clan-cli/tests/test_patch_inventory.py
Normal file
36
pkgs/clan-cli/tests/test_patch_inventory.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Functions to test
|
||||||
|
from clan_cli.inventory import patch
|
||||||
|
|
||||||
|
|
||||||
|
def test_patch_nested() -> None:
|
||||||
|
orig = {"a": 1, "b": {"a": 2.1, "b": 2.2}, "c": 3}
|
||||||
|
|
||||||
|
patch(orig, "b.b", "foo")
|
||||||
|
|
||||||
|
# Should only update the nested value
|
||||||
|
assert orig == {"a": 1, "b": {"a": 2.1, "b": "foo"}, "c": 3}
|
||||||
|
|
||||||
|
|
||||||
|
def test_patch_nested_dict() -> None:
|
||||||
|
orig = {"a": 1, "b": {"a": 2.1, "b": 2.2}, "c": 3}
|
||||||
|
|
||||||
|
# This should update the whole "b" dict
|
||||||
|
# Which also removes all other keys
|
||||||
|
patch(orig, "b", {"b": "foo"})
|
||||||
|
|
||||||
|
# Should only update the nested value
|
||||||
|
assert orig == {"a": 1, "b": {"b": "foo"}, "c": 3}
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_missing_paths() -> None:
|
||||||
|
orig = {"a": 1}
|
||||||
|
|
||||||
|
patch(orig, "b.c", "foo")
|
||||||
|
|
||||||
|
# Should only update the nested value
|
||||||
|
assert orig == {"a": 1, "b": {"c": "foo"}}
|
||||||
|
|
||||||
|
orig = {}
|
||||||
|
patch(orig, "a.b.c", "foo")
|
||||||
|
|
||||||
|
assert orig == {"a": {"b": {"c": "foo"}}}
|
||||||
Reference in New Issue
Block a user