forked from madebr/python-cmake-file-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.py
More file actions
93 lines (75 loc) · 3.65 KB
/
api.py
File metadata and controls
93 lines (75 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from pathlib import Path
from typing import Any, Optional
from cmake_file_api.errors import CMakeException
from cmake_file_api.kinds.api import CMakeApiType, OBJECT_KINDS_API
from cmake_file_api.reply.index.api import INDEX_API
from cmake_file_api.kinds.kind import ObjectKind
from cmake_file_api.reply.index.v1 import CMakeReplyFileV1
class CMakeFileApiV1:
__slots__ = ("_build_path", )
def __init__(self, build_path: Path):
self._build_path = build_path
def _create_query_path(self) -> Path:
result = self._build_path / ".cmake" / "api" / "v1" / "query"
result.mkdir(parents=True, exist_ok=True)
if not result.is_dir():
raise NotADirectoryError(f"Query path '{result}' is not a directory")
return result
def _create_reply_path(self) -> Path:
result = self._build_path / ".cmake" / "api" / "v1" / "reply"
result.mkdir(parents=True, exist_ok=True)
if not result.is_dir():
raise NotADirectoryError(f"Reply path '{result}' is not a directory")
return result
@staticmethod
def _instrument_query_path(query_path: Path, kind: ObjectKind, kind_version: int) -> None:
(query_path / f"{kind.value}-v{kind_version}").touch()
@staticmethod
def _find_index_path(reply_path: Path) -> Optional[Path]:
try:
return next(reply_path.glob("index-*.json"))
except StopIteration:
return None
def find_index_path(self) -> Optional[Path]:
reply_path = self._create_reply_path()
return self._find_index_path(reply_path)
def instrument(self, kind: ObjectKind, kind_version: int) -> None:
query_path = self._create_query_path()
self._instrument_query_path(query_path, kind, kind_version)
def instrument_all(self) -> None:
query_path = self._create_query_path()
for kind, kind_api in OBJECT_KINDS_API.items():
for kind_version in kind_api.keys():
self._instrument_query_path(query_path, kind, kind_version)
def _index(self, reply_path: Path) -> CMakeReplyFileV1:
index_path = self._find_index_path(reply_path)
if index_path is None:
raise CMakeException("CMake did not generate index file. Maybe your cmake version is too old?")
index_api = INDEX_API.get(1)
if not index_api:
raise CMakeException("Unknown api version")
return index_api.from_path(index_path)
def index(self) -> CMakeReplyFileV1:
reply_path = self._create_reply_path()
return self._index(reply_path)
def inspect(self, kind: ObjectKind, kind_version: int) -> Optional[CMakeApiType]:
reply_path = self._create_reply_path()
index = self._index(reply_path)
data_path = index.reply.stateless.get((kind, kind_version), None)
if data_path is None:
return None
api: Optional[type[CMakeApiType]] = OBJECT_KINDS_API.get(kind, {}).get(kind_version, None)
if api is None:
return None
return api.from_path(reply_path / str(data_path.jsonFile), reply_path)
def inspect_all(self) -> dict[ObjectKind, dict[int, object]]:
reply_path = self._create_reply_path()
index = self._index(reply_path)
result: dict[ObjectKind, dict[int, Any]] = {}
for (kind, kind_version), reply_file_ref in index.reply.stateless.items():
api = OBJECT_KINDS_API.get(kind, {}).get(kind_version, None)
if api is None:
continue
kind_data = api.from_path(reply_path / str(reply_file_ref.jsonFile), reply_path)
result.setdefault(kind, {})[kind_version] = kind_data
return result