Skip to content

Commit 25594ab

Browse files
authored
Merge pull request #2579 from strictdoc-project/stanislaw/autouid
feat(commands/manage_autouid_command): update relations to point to new auto-generated MID
2 parents 9d27fd8 + 394bec4 commit 25594ab

File tree

4 files changed

+167
-9
lines changed

4 files changed

+167
-9
lines changed

strictdoc/commands/manage_autouid_command.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ def execute(
103103
trace_info_
104104
) in traceability_index.get_file_traceability_index().trace_infos:
105105
ManageAutoUIDCommand._rewrite_source_file(
106-
trace_info_, project_config
106+
trace_info_,
107+
project_config,
108+
traceability_index=traceability_index,
107109
)
108110

109111
for document in traceability_index.document_tree.document_list:
@@ -129,11 +131,16 @@ def execute(
129131
def _rewrite_source_file(
130132
trace_info: SourceFileTraceabilityInfo,
131133
project_config: ProjectConfig,
134+
traceability_index: TraceabilityIndex,
132135
) -> None:
133136
"""
134-
NOTE: This only updates the source code with the new calculated value.
135-
All links in the graph database and links in the search index
136-
ARE NOT! modified for now.
137+
NOTE: This updates:
138+
- The links in graph database.
139+
- The source code with the new calculated value.
140+
This DOES NOT update MID in the search index built for each
141+
document in SDocDocument.build_search_index(). The assumption is
142+
that the search index is not used by the 'manage autouid' command,
143+
so updating of the document search indexes can be skipped.
137144
"""
138145

139146
assert trace_info.source_file is not None
@@ -185,10 +192,8 @@ def _rewrite_source_file(
185192
hash_spdx_id = bytes(hash_spdx_id_str, encoding="utf8")
186193

187194
if (sdoc_node_ := source_node_.sdoc_node) is not None:
188-
sdoc_node_.set_field_value(
189-
field_name="MID",
190-
form_field_index=0,
191-
value=hash_spdx_id_str,
195+
traceability_index.update_node_mid(
196+
sdoc_node_, hash_spdx_id_str
192197
)
193198
node_rewrites[field_remapped_mid] = hash_spdx_id
194199

strictdoc/core/traceability_index.py

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44

55
import datetime
6-
from copy import deepcopy
6+
from copy import copy, deepcopy
77
from typing import Any, Dict, Generator, List, Optional, Tuple, Union
88

99
from strictdoc.backend.sdoc.document_reference import DocumentReference
@@ -13,6 +13,10 @@
1313
from strictdoc.backend.sdoc.models.grammar_element import GrammarElement
1414
from strictdoc.backend.sdoc.models.inline_link import InlineLink
1515
from strictdoc.backend.sdoc.models.node import SDocNode
16+
from strictdoc.backend.sdoc.models.reference import (
17+
ChildReqReference,
18+
ParentReqReference,
19+
)
1620
from strictdoc.backend.sdoc_source_code.models.source_file_info import (
1721
RelationMarkerType,
1822
SourceFileTraceabilityInfo,
@@ -537,6 +541,73 @@ def parent_cycle_traverse_(node_id: str) -> List[Any]:
537541
datetime.datetime.today(),
538542
)
539543

544+
def update_node_mid(self, node: SDocNode, new_mid: str) -> None:
545+
"""
546+
Update a node’s MID identifier and update all parent and child node
547+
relations to reference this new MID.
548+
549+
The graph database contains relations between nodes. Since these
550+
relations remain unchanged, the job of this function is only to update
551+
each node's original .relations, so that they point to the new MID.
552+
"""
553+
554+
old_mid = node.reserved_mid
555+
556+
#
557+
# Update all child nodes.
558+
#
559+
child_nodes: OrderedSet[SDocNode] = self.graph_database.get_link_values(
560+
link_type=GraphLinkType.NODE_TO_CHILD_NODES,
561+
lhs_node=node,
562+
edge=ALL_EDGES,
563+
)
564+
for child_node_ in child_nodes:
565+
child_node_document = child_node_.get_document()
566+
assert child_node_document is not None
567+
568+
if child_node_document.config.relation_field != "MID":
569+
continue
570+
571+
for relation_ in copy(child_node_.relations):
572+
if (
573+
isinstance(relation_, ParentReqReference)
574+
and relation_.ref_uid == old_mid
575+
):
576+
relation_.ref_uid = new_mid
577+
578+
#
579+
# Update all parent nodes.
580+
#
581+
parent_nodes: OrderedSet[SDocNode] = (
582+
self.graph_database.get_link_values(
583+
link_type=GraphLinkType.NODE_TO_PARENT_NODES,
584+
lhs_node=node,
585+
edge=ALL_EDGES,
586+
)
587+
)
588+
for parent_node_ in parent_nodes:
589+
parent_node_document = parent_node_.get_document()
590+
assert parent_node_document is not None
591+
592+
if parent_node_document.config.relation_field != "MID":
593+
continue
594+
595+
for relation_ in copy(parent_node_.relations):
596+
if (
597+
isinstance(relation_, ChildReqReference)
598+
and relation_.ref_uid == old_mid
599+
):
600+
relation_.ref_uid = new_mid
601+
602+
#
603+
# Update the node itself.
604+
#
605+
node.set_field_value(
606+
field_name="MID",
607+
form_field_index=0,
608+
value=new_mid,
609+
)
610+
540611
def update_requirement_child_uid(
541612
self, requirement: SDocNode, child_uid: str, role: Optional[str]
542613
) -> None:

tests/integration/features/source_code_traceability/_source_nodes/_auto_uuid/10_linux_spdx_req_id_autogen/test.itest

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ CHECK-DIFF-NEXT: ---
2020
CHECK-DIFF-NEXT: > MID: {{[a-f0-9]{64}}}
2121
CHECK-DIFF-NEXT: > HASH: dee51cd1dc666a6d1b2678c27c2b6dfc85376107e403963a8afc83acb62ff944
2222

23+
#
24+
# The output requirements file only contains the change in two fields with
25+
# nothing else affected.
26+
# The regular expression is used to verify that the field is indeed SHA256.
27+
#
28+
RUN: %expect_exit 1 %diff %S/tests.sdoc %T/tests.sdoc | filecheck %s --check-prefix CHECK-DIFF-TESTS
29+
CHECK-DIFF-TESTS: < VALUE: TBD
30+
CHECK-DIFF-TESTS-NEXT: ---
31+
CHECK-DIFF-TESTS-NEXT: > VALUE: {{[a-f0-9]{64}}}
32+
2333
#
2434
# Source file with SPDX fields gets a stable hash generated.
2535
#
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
[DOCUMENT]
2+
MID: 11111122222233333344444455555566
3+
TITLE: SPDX tests
4+
OPTIONS:
5+
ENABLE_MID: True
6+
RELATION_FIELD: MID
7+
MARKUP: Text
8+
9+
[GRAMMAR]
10+
ELEMENTS:
11+
- TAG: TEXT
12+
FIELDS:
13+
- TITLE: MID
14+
TYPE: String
15+
REQUIRED: False
16+
- TITLE: STATEMENT
17+
TYPE: String
18+
REQUIRED: True
19+
- TAG: SECTION
20+
PROPERTIES:
21+
IS_COMPOSITE: True
22+
FIELDS:
23+
- TITLE: MID
24+
TYPE: String
25+
REQUIRED: False
26+
- TITLE: UID
27+
TYPE: String
28+
REQUIRED: False
29+
- TITLE: TITLE
30+
TYPE: String
31+
REQUIRED: True
32+
- TAG: TEST
33+
PROPERTIES:
34+
VIEW_STYLE: Narrative
35+
FIELDS:
36+
- TITLE: MID
37+
HUMAN_TITLE: SPDX-Req-ID
38+
TYPE: String
39+
REQUIRED: False
40+
- TITLE: HASH
41+
HUMAN_TITLE: SPDX-Req-HKey
42+
TYPE: String
43+
REQUIRED: False
44+
- TITLE: UID
45+
TYPE: String
46+
REQUIRED: False
47+
- TITLE: FOO
48+
TYPE: String
49+
REQUIRED: False
50+
- TITLE: BAR
51+
TYPE: String
52+
REQUIRED: False
53+
- TITLE: TITLE
54+
TYPE: String
55+
REQUIRED: False
56+
- TITLE: STATEMENT
57+
HUMAN_TITLE: SPDX-Req-Text
58+
TYPE: String
59+
REQUIRED: False
60+
RELATIONS:
61+
- TYPE: Parent
62+
- TYPE: File
63+
64+
[TEST]
65+
MID: TBD-TEST
66+
HASH: TBD
67+
FOO: FOO text from sdoc
68+
BAR: BAR text from sdoc
69+
TITLE: TITLE from sdoc
70+
RELATIONS:
71+
- TYPE: Parent
72+
VALUE: TBD

0 commit comments

Comments
 (0)