Skip to content

Commit d42af8a

Browse files
committed
minor improvements to config file obj
1 parent cf912e2 commit d42af8a

File tree

1 file changed

+57
-17
lines changed

1 file changed

+57
-17
lines changed

idom/client/build_config.py

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import ast
3+
from functools import wraps
34
from contextlib import contextmanager
45
from hashlib import sha256
56
from pathlib import Path
@@ -12,49 +13,88 @@
1213
from idom.cli import console
1314

1415

16+
_Method = TypeVar("_Method")
17+
18+
19+
def _requires_open_transaction(method: _Method) -> _Method:
20+
@wraps(method)
21+
def wrapper(self: BuildConfigFile, *args: Any, **kwargs: Any) -> Any:
22+
if not self._transaction_open:
23+
raise RuntimeError("Cannot modify BuildConfigFile without transaction.")
24+
return method(self, *args, **kwargs)
25+
26+
return wrapper
27+
28+
1529
class BuildConfigFile:
1630

17-
__slots__ = "configs", "_path"
18-
_filename = ".idom-build-configs.json"
31+
__slots__ = "_configs", "_path", "_transaction_open"
32+
_filename = "idom-build-config.json"
1933

2034
def __init__(self, path: Path) -> None:
2135
self._path = path / self._filename
22-
self.configs = self._load_configs()
36+
self._config_items = self._load_config_items()
37+
self._transaction_open = False
2338

2439
@contextmanager
2540
def transaction(self) -> Iterator[None]:
26-
old_configs = self.configs
27-
self.configs = old_configs.copy()
41+
"""Open a transaction to modify the config file state"""
42+
self._transaction_open = True
43+
old_configs = self._config_items
44+
self._config_items = old_configs.copy()
2845
try:
2946
yield
3047
except Exception:
31-
self.configs = old_configs
48+
self._config_items = old_configs
3249
raise
3350
else:
3451
self.save()
52+
finally:
53+
self._transaction_open = False
3554

36-
def add(self, build_configs: Iterable[Any], ignore_existing: bool = False) -> None:
37-
for config in map(BuildConfigItem.cast, build_configs):
38-
source_name = config.source_name
39-
if not ignore_existing and source_name in self.configs:
40-
raise ValueError(f"A build config for {source_name!r} already exists")
41-
self.configs[source_name] = config
42-
return None
55+
@property
56+
def configs(self) -> Dict[str, "BuildConfigItem"]:
57+
"""A dictionary of config items"""
58+
return self._config_items.copy()
4359

4460
def save(self) -> None:
61+
"""Save config state to file"""
4562
with self._path.open("w") as f:
46-
json.dump({name: conf._asdict() for name, conf in self.configs.items()}, f)
63+
json.dump(
64+
{name: conf._asdict() for name, conf in self._config_items.items()}, f
65+
)
4766

4867
def show(self, indent: int = 2) -> str:
68+
"""Return string repr of config state"""
4969
return json.dumps(
50-
{name: conf._asdict() for name, conf in self.configs.items()},
70+
{name: conf._asdict() for name, conf in self._config_items.items()},
5171
indent=indent,
5272
)
5373

74+
@_requires_open_transaction
75+
def add(self, build_configs: Iterable[Any], ignore_existing: bool = False) -> None:
76+
"""Add a config item"""
77+
for config in map(BuildConfigItem.cast, build_configs):
78+
source_name = config.source_name
79+
if not ignore_existing and source_name in self._config_items:
80+
raise ValueError(f"A build config for {source_name!r} already exists")
81+
self._config_items[source_name] = config
82+
return None
83+
84+
@_requires_open_transaction
85+
def remove(self, source_name: str, ignore_missing: bool = False) -> None:
86+
"""Remove a config item"""
87+
if ignore_missing:
88+
self._config_items.pop(source_name, None)
89+
else:
90+
del self._config_items[source_name]
91+
92+
@_requires_open_transaction
5493
def clear(self) -> None:
55-
self.configs = {}
94+
"""Clear all config items"""
95+
self._config_items = {}
5696

57-
def _load_configs(self) -> Dict[str, "BuildConfigItem"]:
97+
def _load_config_items(self) -> Dict[str, "BuildConfigItem"]:
5898
if not self._path.exists():
5999
return {}
60100
with self._path.open() as f:

0 commit comments

Comments
 (0)