specitems 1.4.2__tar.gz → 1.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {specitems-1.4.2 → specitems-1.4.4}/PKG-INFO +1 -1
- {specitems-1.4.2 → specitems-1.4.4}/pyproject.toml +2 -2
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/__init__.py +10 -2
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/cliutil.py +67 -1
- specitems-1.4.4/src/specitems/contentcommonmark.py +119 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/specverify.py +26 -90
- {specitems-1.4.2 → specitems-1.4.4}/README.md +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/cite.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/clihash.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/clipickle.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/clispecdoc.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/cliyamlquery.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/content.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/contentmarkdown.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/contentsphinx.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/contenttext.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/getvaluesubprocess.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/glossary.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/hashutil.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/itemmapper.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/items.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/py.typed +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/spec.pickle +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/specdoc.py +0 -0
- {specitems-1.4.2 → specitems-1.4.4}/src/specitems/subprocessaction.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specitems
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.4
|
|
4
4
|
Summary: Provides interfaces to work with specification items.
|
|
5
5
|
Keywords: certification,documentation,markdown,qualification,requirements-management,traceability
|
|
6
6
|
Author: The specitems Authors
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specitems"
|
|
7
|
-
version = "1.4.
|
|
7
|
+
version = "1.4.4"
|
|
8
8
|
description = "Provides interfaces to work with specification items."
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "The specitems Authors", email = "specthings@embedded-brains.de"}
|
|
@@ -56,7 +56,7 @@ spechash = "specitems.clihash:clihash"
|
|
|
56
56
|
specyamlquery = "specitems.cliyamlquery:cliyamlquery"
|
|
57
57
|
|
|
58
58
|
[build-system]
|
|
59
|
-
requires = ["uv_build>=0.10.0
|
|
59
|
+
requires = ["uv_build>=0.10.0"]
|
|
60
60
|
build-backend = "uv_build"
|
|
61
61
|
|
|
62
62
|
[dependency-groups]
|
|
@@ -26,11 +26,13 @@
|
|
|
26
26
|
|
|
27
27
|
from .cite import BibTeXCitationProvider
|
|
28
28
|
from .cliutil import (
|
|
29
|
+
LoggingStatus,
|
|
29
30
|
create_config,
|
|
30
31
|
get_arguments,
|
|
31
32
|
get_item_cache_arguments,
|
|
32
33
|
init_logging,
|
|
33
34
|
load_config,
|
|
35
|
+
monitor_logging,
|
|
34
36
|
)
|
|
35
37
|
from .content import (
|
|
36
38
|
Content,
|
|
@@ -56,6 +58,10 @@ from .contenttext import (
|
|
|
56
58
|
latex_escape,
|
|
57
59
|
make_label,
|
|
58
60
|
)
|
|
61
|
+
from .contentcommonmark import (
|
|
62
|
+
CommonMarkContent,
|
|
63
|
+
CommonMarkMapper,
|
|
64
|
+
)
|
|
59
65
|
from .contentmarkdown import (
|
|
60
66
|
MarkdownContent,
|
|
61
67
|
MarkdownMapper,
|
|
@@ -129,7 +135,6 @@ from .specdoc import (SpecDocumentConfig, add_specification_documentation,
|
|
|
129
135
|
generate_specification_documentation)
|
|
130
136
|
from .specverify import (
|
|
131
137
|
SpecVerifier,
|
|
132
|
-
VerifyStatus,
|
|
133
138
|
verify_specification_format,
|
|
134
139
|
)
|
|
135
140
|
from .subprocessaction import (
|
|
@@ -140,6 +145,8 @@ from .subprocessaction import (
|
|
|
140
145
|
__all__ = [
|
|
141
146
|
"BibTeXCitationProvider",
|
|
142
147
|
"COL_SPAN",
|
|
148
|
+
"CommonMarkContent",
|
|
149
|
+
"CommonMarkMapper",
|
|
143
150
|
"Content",
|
|
144
151
|
"ContentAddContext",
|
|
145
152
|
"Copyright",
|
|
@@ -170,6 +177,7 @@ __all__ = [
|
|
|
170
177
|
"ItemViewGetMissing",
|
|
171
178
|
"JSONItemCache",
|
|
172
179
|
"Link",
|
|
180
|
+
"LoggingStatus",
|
|
173
181
|
"MARKDOWN_ROLES",
|
|
174
182
|
"MarkdownContent",
|
|
175
183
|
"MarkdownMapper",
|
|
@@ -181,7 +189,6 @@ __all__ = [
|
|
|
181
189
|
"SphinxMapper",
|
|
182
190
|
"TextContent",
|
|
183
191
|
"TextMapper",
|
|
184
|
-
"VerifyStatus",
|
|
185
192
|
"add_specification_documentation",
|
|
186
193
|
"augment_glossary_terms",
|
|
187
194
|
"base64_to_hex",
|
|
@@ -219,6 +226,7 @@ __all__ = [
|
|
|
219
226
|
"make_lines",
|
|
220
227
|
"make_subprocess_environment",
|
|
221
228
|
"make_text",
|
|
229
|
+
"monitor_logging",
|
|
222
230
|
"pickle_load_data_by_uid",
|
|
223
231
|
"run_subprocess_action",
|
|
224
232
|
"save_data",
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
26
|
|
|
27
27
|
import argparse
|
|
28
|
+
import contextlib
|
|
28
29
|
import itertools
|
|
29
30
|
import logging
|
|
30
31
|
import os
|
|
31
|
-
from typing import Any, Callable, Iterable,
|
|
32
|
+
from typing import (Any, Callable, Iterable, Iterator, NamedTuple, Optional,
|
|
33
|
+
Type, TypeVar)
|
|
32
34
|
|
|
33
35
|
import yaml
|
|
34
36
|
|
|
@@ -142,6 +144,70 @@ def init_logging(args: argparse.Namespace) -> None:
|
|
|
142
144
|
handlers=handlers)
|
|
143
145
|
|
|
144
146
|
|
|
147
|
+
class LoggingStatus(NamedTuple):
|
|
148
|
+
"""Counts of log messages grouped by severity.
|
|
149
|
+
|
|
150
|
+
Attributes:
|
|
151
|
+
critical: Number of CRITICAL messages.
|
|
152
|
+
error: Number of ERROR messages.
|
|
153
|
+
warning: Number of WARNING messages.
|
|
154
|
+
info: Number of INFO messages.
|
|
155
|
+
debug: Number of DEBUG messages.
|
|
156
|
+
"""
|
|
157
|
+
critical: int
|
|
158
|
+
error: int
|
|
159
|
+
warning: int
|
|
160
|
+
info: int
|
|
161
|
+
debug: int
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class LogMonitor(logging.Filter):
|
|
165
|
+
""" Monitors log messages grouped by severity. """
|
|
166
|
+
|
|
167
|
+
def __init__(self) -> None:
|
|
168
|
+
super().__init__()
|
|
169
|
+
self._counts: dict[int, int] = {}
|
|
170
|
+
|
|
171
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
|
172
|
+
"""Count the given logging record and allow propagation.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
record: The logging record to count.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
True so the log record is processed by the logging system.
|
|
179
|
+
"""
|
|
180
|
+
count = self._counts.get(record.levelno, 0)
|
|
181
|
+
self._counts[record.levelno] = count + 1
|
|
182
|
+
return True
|
|
183
|
+
|
|
184
|
+
def get_status(self) -> LoggingStatus:
|
|
185
|
+
"""Return a LoggingStatus summarizing collected log counts.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Aggregated counts for each standard logging level.
|
|
189
|
+
"""
|
|
190
|
+
return LoggingStatus(self._counts.get(logging.CRITICAL, 0),
|
|
191
|
+
self._counts.get(logging.ERROR, 0),
|
|
192
|
+
self._counts.get(logging.WARNING, 0),
|
|
193
|
+
self._counts.get(logging.INFO, 0),
|
|
194
|
+
self._counts.get(logging.DEBUG, 0))
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@contextlib.contextmanager
|
|
198
|
+
def monitor_logging() -> Iterator[LogMonitor]:
|
|
199
|
+
"""
|
|
200
|
+
Monitors the logging and counts the log records grouped by severity.
|
|
201
|
+
"""
|
|
202
|
+
logger = logging.getLogger()
|
|
203
|
+
monitor = LogMonitor()
|
|
204
|
+
logger.addFilter(monitor)
|
|
205
|
+
try:
|
|
206
|
+
yield monitor
|
|
207
|
+
finally:
|
|
208
|
+
logger.removeFilter(monitor)
|
|
209
|
+
|
|
210
|
+
|
|
145
211
|
def load_config(config_filename: str) -> Any:
|
|
146
212
|
""" Loads the configuration file with recursive includes. """
|
|
147
213
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
""" Provides interfaces for CommonMark content generation. """
|
|
3
|
+
|
|
4
|
+
# Copyright (C) 2025, 2026 embedded brains GmbH & Co. KG
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions
|
|
8
|
+
# are met:
|
|
9
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
18
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
19
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
20
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
21
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
22
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
23
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
24
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
25
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
from typing import Iterable, Optional, Sequence
|
|
28
|
+
|
|
29
|
+
from .content import GenericContent, make_lines
|
|
30
|
+
from .contentmarkdown import MarkdownContent
|
|
31
|
+
from .contenttext import COL_SPAN, ROW_SPAN, TextContent, TextMapper
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _make_simple(cell: str | int) -> str:
|
|
35
|
+
if isinstance(cell, str):
|
|
36
|
+
return cell
|
|
37
|
+
if cell == COL_SPAN | ROW_SPAN:
|
|
38
|
+
return "↖"
|
|
39
|
+
if cell == ROW_SPAN:
|
|
40
|
+
return "←"
|
|
41
|
+
return "↑"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CommonMarkContent(MarkdownContent):
|
|
45
|
+
""" This class builds CommonMark content. """
|
|
46
|
+
|
|
47
|
+
def reference(self, label: str, name: Optional[str] = None) -> str:
|
|
48
|
+
if not name:
|
|
49
|
+
name = label
|
|
50
|
+
return self.link(name, f"#{label}")
|
|
51
|
+
|
|
52
|
+
def term(self, text: str, term: str | None = None) -> str:
|
|
53
|
+
return text
|
|
54
|
+
|
|
55
|
+
def cite(self, identifier: str) -> str:
|
|
56
|
+
return ""
|
|
57
|
+
|
|
58
|
+
def add_label(self, label: str) -> None:
|
|
59
|
+
self.add(f"<a id=\"{label.strip()}\"></a>")
|
|
60
|
+
|
|
61
|
+
def add_rubric(self, name: str) -> None:
|
|
62
|
+
self.add([self.strong(name), ""])
|
|
63
|
+
|
|
64
|
+
def add_image(self, base: str, width: Optional[str] = None) -> None:
|
|
65
|
+
self.add(f"")
|
|
66
|
+
|
|
67
|
+
def add_index_entries(self, entries: list[str]) -> None:
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
def open_directive(self,
|
|
71
|
+
name: str,
|
|
72
|
+
value: Optional[str] = None,
|
|
73
|
+
options: Optional[list[str]] = None) -> None:
|
|
74
|
+
self.add(f"```{name.strip()}")
|
|
75
|
+
self.gap = False
|
|
76
|
+
|
|
77
|
+
def add_simple_table(self,
|
|
78
|
+
rows: Sequence[Iterable[str]],
|
|
79
|
+
widths: Optional[list[int]] = None,
|
|
80
|
+
font_size: Optional[str | int] = None) -> None:
|
|
81
|
+
super().add_simple_table(rows)
|
|
82
|
+
|
|
83
|
+
def add_grid_table(self,
|
|
84
|
+
rows: Sequence[Iterable[str | int]],
|
|
85
|
+
widths: Optional[list[int]] = None,
|
|
86
|
+
header_rows: int = 1,
|
|
87
|
+
font_size: Optional[str | int] = None) -> None:
|
|
88
|
+
if not rows:
|
|
89
|
+
return
|
|
90
|
+
simple_rows = [
|
|
91
|
+
tuple(_make_simple(cell) for cell in row) for row in rows
|
|
92
|
+
]
|
|
93
|
+
self.add_simple_table(simple_rows)
|
|
94
|
+
|
|
95
|
+
def add_definition_item(self, name: GenericContent,
|
|
96
|
+
definition: GenericContent) -> None:
|
|
97
|
+
self.add(f"{self.strong(', '.join(make_lines(name)))}:")
|
|
98
|
+
self.append(definition)
|
|
99
|
+
|
|
100
|
+
def add_glossary_term(self, term: str, definition: str) -> None:
|
|
101
|
+
self.add_definition_item(term, definition)
|
|
102
|
+
|
|
103
|
+
def add_code_block(self,
|
|
104
|
+
code: list[str],
|
|
105
|
+
language: str = "none",
|
|
106
|
+
font_size: str | int = "footnotesize",
|
|
107
|
+
line_number_start: int = 1) -> None:
|
|
108
|
+
with self.directive(language):
|
|
109
|
+
self.append(code)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class CommonMarkMapper(TextMapper):
|
|
113
|
+
""" Provides an item mapper for CommonMark formatted text production. """
|
|
114
|
+
|
|
115
|
+
def create_content(
|
|
116
|
+
self,
|
|
117
|
+
section_level: int = 0,
|
|
118
|
+
the_license: str | set[str] | None = None) -> TextContent:
|
|
119
|
+
return CommonMarkContent(section_level, the_license)
|
|
@@ -6,7 +6,7 @@ verify that a set of specification items is in line with a specification item
|
|
|
6
6
|
format specification. The format specification is defined by specification
|
|
7
7
|
items. Logging is used for informational messages and for reporting errors
|
|
8
8
|
found during verification. The result of the format verification is
|
|
9
|
-
represented by a :py:class:`
|
|
9
|
+
represented by a :py:class:`LoggingStatus` object.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
# Copyright (C) 2020, 2026 embedded brains GmbH & Co. KG
|
|
@@ -32,65 +32,16 @@ represented by a :py:class:`VerifyStatus` object.
|
|
|
32
32
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
33
33
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
34
34
|
|
|
35
|
-
from contextlib import contextmanager
|
|
36
35
|
import logging
|
|
37
36
|
import re
|
|
38
|
-
from typing import Any,
|
|
37
|
+
from typing import Any, NamedTuple
|
|
39
38
|
|
|
39
|
+
from .cliutil import LoggingStatus, monitor_logging
|
|
40
40
|
from .items import Item, ItemCache
|
|
41
41
|
|
|
42
42
|
_VerifierMap = dict[str, "_Verifier"]
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
class VerifyStatus(NamedTuple):
|
|
46
|
-
"""Counts of log messages produced by a verification run.
|
|
47
|
-
|
|
48
|
-
Attributes:
|
|
49
|
-
critical: Number of CRITICAL messages.
|
|
50
|
-
error: Number of ERROR messages.
|
|
51
|
-
warning: Number of WARNING messages.
|
|
52
|
-
info: Number of INFO messages.
|
|
53
|
-
debug: Number of DEBUG messages.
|
|
54
|
-
"""
|
|
55
|
-
critical: int
|
|
56
|
-
error: int
|
|
57
|
-
warning: int
|
|
58
|
-
info: int
|
|
59
|
-
debug: int
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class _Filter(logging.Filter):
|
|
63
|
-
|
|
64
|
-
def __init__(self) -> None:
|
|
65
|
-
super().__init__()
|
|
66
|
-
self._counts: dict[int, int] = {}
|
|
67
|
-
|
|
68
|
-
def filter(self, record: logging.LogRecord) -> bool:
|
|
69
|
-
"""Count the given logging record and allow propagation.
|
|
70
|
-
|
|
71
|
-
Args:
|
|
72
|
-
record: The logging record to count.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
True so the log record is processed by the logging system.
|
|
76
|
-
"""
|
|
77
|
-
count = self._counts.get(record.levelno, 0)
|
|
78
|
-
self._counts[record.levelno] = count + 1
|
|
79
|
-
return True
|
|
80
|
-
|
|
81
|
-
def get_verify_info(self) -> VerifyStatus:
|
|
82
|
-
"""Return a VerifyStatus summarizing collected log counts.
|
|
83
|
-
|
|
84
|
-
Returns:
|
|
85
|
-
Aggregated counts for each standard logging level.
|
|
86
|
-
"""
|
|
87
|
-
return VerifyStatus(self._counts.get(logging.CRITICAL, 0),
|
|
88
|
-
self._counts.get(logging.ERROR, 0),
|
|
89
|
-
self._counts.get(logging.WARNING, 0),
|
|
90
|
-
self._counts.get(logging.INFO, 0),
|
|
91
|
-
self._counts.get(logging.DEBUG, 0))
|
|
92
|
-
|
|
93
|
-
|
|
94
45
|
def _type_name(value: Any):
|
|
95
46
|
type_name = type(value).__name__
|
|
96
47
|
if type_name == "NoneType":
|
|
@@ -680,15 +631,6 @@ def _gather_item_verifiers(item: Item, verifier_map: _VerifierMap) -> None:
|
|
|
680
631
|
_create_verifier(link.item, verifier_map)
|
|
681
632
|
|
|
682
633
|
|
|
683
|
-
@contextmanager
|
|
684
|
-
def _add_filter() -> Iterator[_Filter]:
|
|
685
|
-
logger = logging.getLogger()
|
|
686
|
-
log_filter = _Filter()
|
|
687
|
-
logger.addFilter(log_filter)
|
|
688
|
-
yield log_filter
|
|
689
|
-
logger.removeFilter(log_filter)
|
|
690
|
-
|
|
691
|
-
|
|
692
634
|
class SpecVerifier:
|
|
693
635
|
"""Orchestrates construction of verifiers from spec items and running
|
|
694
636
|
verification.
|
|
@@ -732,31 +674,23 @@ class SpecVerifier:
|
|
|
732
674
|
logging.info("type: %s", name)
|
|
733
675
|
verifier_map[name].resolve_type_refinements()
|
|
734
676
|
|
|
735
|
-
def verify_all(self, item_cache: ItemCache) ->
|
|
677
|
+
def verify_all(self, item_cache: ItemCache) -> None:
|
|
736
678
|
"""Verify all items in the provided item cache.
|
|
737
679
|
|
|
738
|
-
The method installs a logging filter to collect counts, iterates all
|
|
739
|
-
items in the cache and invokes the root verifier on each item's data.
|
|
740
|
-
|
|
741
680
|
Args:
|
|
742
681
|
item_cache: The cache containing items to verify.
|
|
743
|
-
|
|
744
|
-
Returns:
|
|
745
|
-
Status with counts of messages emitted during verification.
|
|
746
682
|
"""
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
def verify(self, item: Item) -> VerifyStatus:
|
|
683
|
+
if self._root_verifier is None:
|
|
684
|
+
logging.error("root type item does not exist in item cache")
|
|
685
|
+
else:
|
|
686
|
+
logging.info("start specification item verification")
|
|
687
|
+
for key in sorted(item_cache):
|
|
688
|
+
item = item_cache[key]
|
|
689
|
+
self._root_verifier.verify(_Path(item, f"{item.uid}:"),
|
|
690
|
+
item.data)
|
|
691
|
+
logging.info("finished specification item verification")
|
|
692
|
+
|
|
693
|
+
def verify(self, item: Item) -> LoggingStatus:
|
|
760
694
|
"""Verify the item format.
|
|
761
695
|
|
|
762
696
|
Args:
|
|
@@ -765,16 +699,16 @@ class SpecVerifier:
|
|
|
765
699
|
Returns:
|
|
766
700
|
Status with counts of messages emitted during verification.
|
|
767
701
|
"""
|
|
768
|
-
with
|
|
702
|
+
with monitor_logging() as monitor:
|
|
769
703
|
if self._root_verifier is None:
|
|
770
704
|
logging.error("root type item does not exist in item cache")
|
|
771
705
|
else:
|
|
772
706
|
self._root_verifier.verify(_Path(item, f"{item.uid}:"),
|
|
773
707
|
item.data)
|
|
774
|
-
|
|
708
|
+
return monitor.get_status()
|
|
775
709
|
|
|
776
710
|
|
|
777
|
-
def verify_specification_format(item_cache: ItemCache) ->
|
|
711
|
+
def verify_specification_format(item_cache: ItemCache) -> LoggingStatus:
|
|
778
712
|
"""Verify all items using the specification root type from the item cache.
|
|
779
713
|
|
|
780
714
|
Emits an error if the item cache has no specification root type.
|
|
@@ -785,9 +719,11 @@ def verify_specification_format(item_cache: ItemCache) -> VerifyStatus:
|
|
|
785
719
|
Returns:
|
|
786
720
|
The status summarizing the verification run.
|
|
787
721
|
"""
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
722
|
+
with monitor_logging() as monitor:
|
|
723
|
+
root_type_uid = item_cache.type_provider.root_type_uid
|
|
724
|
+
if root_type_uid is None:
|
|
725
|
+
logging.error("item cache has no root type")
|
|
726
|
+
else:
|
|
727
|
+
verifier = SpecVerifier(item_cache, root_type_uid)
|
|
728
|
+
verifier.verify_all(item_cache)
|
|
729
|
+
return monitor.get_status()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|