Changeset 2c46d2d in rtems-central
- Timestamp:
- 07/28/22 08:51:22 (17 months ago)
- Branches:
- master
- Children:
- bb633e2
- Parents:
- e0980df
- git-author:
- Sebastian Huber <sebastian.huber@…> (07/28/22 08:51:22)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (07/28/22 09:26:30)
- Location:
- rtemsspec
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
rtemsspec/items.py
re0980df r2c46d2d 2 2 """ This module provides specification items and an item cache. """ 3 3 4 # Copyright (C) 2019, 202 1embedded brains GmbH (http://www.embedded-brains.de)4 # Copyright (C) 2019, 2022 embedded brains GmbH (http://www.embedded-brains.de) 5 5 # 6 6 # Redistribution and use in source and binary forms, with or without … … 32 32 import stat 33 33 from typing import Any, Callable, Dict, Iterable, Iterator, List, NamedTuple, \ 34 Optional, Set, Tuple, Union 34 Optional, Set, TextIO, Tuple, Union 35 import json 35 36 import yaml 36 37 … … 417 418 def save(self): 418 419 """ Saves the item to the corresponding file. """ 419 with open(self.file, "w") as dst: 420 data = {} 421 for key, value in self._data.items(): 422 if not key.startswith("_"): 423 data[key] = value 424 dst.write( 425 yaml.dump(data, default_flow_style=False, allow_unicode=True)) 420 self._cache.save_data(self.file, self._data) 426 421 427 422 def load(self): 428 423 """ Loads the item from the corresponding file. """ 429 filename = self.file 430 with open(filename, "r") as src: 431 self._data = yaml.safe_load(src.read()) 432 self._data["_file"] = filename 424 self._data = self._cache.load_data(self.file, self._uid) 433 425 434 426 … … 620 612 621 613 622 def _load_ item(path: str, uid: str) -> Any:614 def _load_yaml_data(path: str, uid: str) -> Any: 623 615 with open(path, "r") as src: 624 616 try: … … 633 625 634 626 627 def _load_json_data(path: str, uid: str) -> Any: 628 with open(path, "r") as src: 629 try: 630 data = json.load(src) 631 except json.JSONDecodeError as err: 632 msg = ("JSON error while loading specification item file " 633 f"'{path}': {str(err)}") 634 raise IOError(msg) from err 635 data["_file"] = os.path.abspath(path) 636 data["_uid"] = uid 637 return data 638 639 635 640 class ItemCache: 636 641 """ This class provides a cache of specification items. """ … … 642 647 self._types = set() # type: Set[str] 643 648 self._updates = 0 644 cache_dir = os.path.abspath(config["cache-directory"]) 645 for index, path in enumerate(config["paths"]): 646 self._load_items_recursive(str(index), path, path, cache_dir) 649 self._load_items(config) 647 650 if post_process_load: 648 651 post_process_load(self._items) … … 696 699 The item is not added to the persistent cache storage. 697 700 """ 698 return self.add_volatile_item(uid, _load_item(path, uid))701 return self.add_volatile_item(uid, self.load_data(path, uid)) 699 702 700 703 def _add_item(self, uid: str, data: Any) -> Item: … … 713 716 uid = "/" + os.path.relpath(path2, base).replace( 714 717 ".yml", "") 715 data_by_uid[uid] = _load_ item(path2, uid)718 data_by_uid[uid] = _load_yaml_data(path2, uid) 716 719 os.makedirs(os.path.dirname(cache_file), exist_ok=True) 717 720 with open(cache_file, "wb") as out: … … 745 748 self._load_items_in_dir(base, path, cache_file, update_cache) 746 749 750 def _load_items(self, config: Any): 751 cache_dir = os.path.abspath(config["cache-directory"]) 752 for index, path in enumerate(config["paths"]): 753 self._load_items_recursive(str(index), path, path, cache_dir) 754 755 def load_data(self, path: str, uid: str) -> Any: 756 """ Loads the item data from the file specified by path. """ 757 # pylint: disable=no-self-use 758 return _load_yaml_data(path, uid) 759 760 def _save_data(self, file: TextIO, data: Any) -> None: 761 # pylint: disable=no-self-use 762 file.write( 763 yaml.dump(data, default_flow_style=False, allow_unicode=True)) 764 765 def save_data(self, path: str, data: Any) -> None: 766 """ Saves the item data to the file specified by path. """ 767 print('save-data', path, data) 768 with open(path, "w") as file: 769 data2 = {} 770 for key, value in data.items(): 771 if not key.startswith("_"): 772 data2[key] = value 773 self._save_data(file, data2) 774 747 775 def _init_parents(self) -> None: 748 776 for item in self._items.values(): … … 776 804 777 805 806 class JSONItemCache(ItemCache): 807 """ This class provides a cache of specification items using JSON. """ 808 def _load_json_items(self, base: str, path: str) -> None: 809 for name in os.listdir(path): 810 path2 = os.path.join(path, name) 811 if name.endswith(".json") and not name.startswith("."): 812 uid = "/" + os.path.relpath(path2, base).replace(".json", "") 813 self._add_item(uid, _load_json_data(path2, uid)) 814 else: 815 if stat.S_ISDIR(os.lstat(path2).st_mode): 816 self._load_json_items(base, path2) 817 818 def _load_items(self, config: Any): 819 for path in config["paths"]: 820 self._load_json_items(path, path) 821 822 def load_data(self, path: str, uid: str) -> Any: 823 # pylint: disable=no-self-use 824 return _load_json_data(path, uid) 825 826 def _save_data(self, file: TextIO, data: Any) -> None: 827 # pylint: disable=no-self-use 828 json.dump(data, file, sort_keys=True, indent=2) 829 830 778 831 class EmptyItem(Item): 779 832 """ Objects of this class represent empty items. """ -
rtemsspec/tests/test_items_item.py
re0980df r2c46d2d 28 28 import pytest 29 29 30 from rtemsspec.items import EmptyItemCache, Item, Item Cache, \31 ItemGetValueContext, Link30 from rtemsspec.items import EmptyItemCache, Item, ItemGetValueContext, \ 31 JSONItemCache, Link 32 32 33 33 … … 267 267 268 268 269 def test_save_and_load_json(tmpdir): 270 spec_dir = os.path.join(os.path.dirname(__file__), "spec-json") 271 config = {"paths": [spec_dir], "spec-type-root-uid": None} 272 item_cache = JSONItemCache(config) 273 item = item_cache["/d/b"].parent("b") 274 file = os.path.join(tmpdir, "file") 275 item.file = file 276 assert item["enabled-by"] 277 item["enabled-by"] = False 278 item.save() 279 with open(file, "r") as src: 280 assert src.read() == """{ 281 "SPDX-License-Identifier": "CC-BY-SA-4.0 OR BSD-2-Clause", 282 "copyrights": [ 283 "Copyright (C) 2022 embedded brains GmbH (http://www.embedded-brains.de)" 284 ], 285 "enabled-by": false, 286 "links": [], 287 "type": "a" 288 }""" 289 item.load() 290 with open(file, "w") as dst: 291 dst.write("invalid") 292 with pytest.raises(IOError): 293 item.load() 294 295 269 296 def test_item_get_value_arg(): 270 297 item = Item(EmptyItemCache(), "i", {})
Note: See TracChangeset
for help on using the changeset viewer.