Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions strictdoc/commands/manage_autouid_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ def execute(
trace_info_
) in traceability_index.get_file_traceability_index().trace_infos:
ManageAutoUIDCommand._rewrite_source_file(
trace_info_, project_config
trace_info_,
project_config,
traceability_index=traceability_index,
)

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

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

if (sdoc_node_ := source_node_.sdoc_node) is not None:
sdoc_node_.set_field_value(
field_name="MID",
form_field_index=0,
value=hash_spdx_id_str,
traceability_index.update_node_mid(
sdoc_node_, hash_spdx_id_str
)
node_rewrites[field_remapped_mid] = hash_spdx_id

Expand Down
73 changes: 72 additions & 1 deletion strictdoc/core/traceability_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

import datetime
from copy import deepcopy
from copy import copy, deepcopy
from typing import Any, Dict, Generator, List, Optional, Tuple, Union

from strictdoc.backend.sdoc.document_reference import DocumentReference
Expand All @@ -13,6 +13,10 @@
from strictdoc.backend.sdoc.models.grammar_element import GrammarElement
from strictdoc.backend.sdoc.models.inline_link import InlineLink
from strictdoc.backend.sdoc.models.node import SDocNode
from strictdoc.backend.sdoc.models.reference import (
ChildReqReference,
ParentReqReference,
)
from strictdoc.backend.sdoc_source_code.models.source_file_info import (
RelationMarkerType,
SourceFileTraceabilityInfo,
Expand Down Expand Up @@ -537,6 +541,73 @@ def parent_cycle_traverse_(node_id: str) -> List[Any]:
datetime.datetime.today(),
)

def update_node_mid(self, node: SDocNode, new_mid: str) -> None:
"""
Update a node’s MID identifier and update all parent and child node
relations to reference this new MID.

The graph database contains relations between nodes. Since these
relations remain unchanged, the job of this function is only to update
each node's original .relations, so that they point to the new MID.
"""

old_mid = node.reserved_mid

#
# Update all child nodes.
#
child_nodes: OrderedSet[SDocNode] = self.graph_database.get_link_values(
link_type=GraphLinkType.NODE_TO_CHILD_NODES,
lhs_node=node,
edge=ALL_EDGES,
)
for child_node_ in child_nodes:
child_node_document = child_node_.get_document()
assert child_node_document is not None

if child_node_document.config.relation_field != "MID":
continue

for relation_ in copy(child_node_.relations):
if (
isinstance(relation_, ParentReqReference)
and relation_.ref_uid == old_mid
):
relation_.ref_uid = new_mid

#
# Update all parent nodes.
#
parent_nodes: OrderedSet[SDocNode] = (
self.graph_database.get_link_values(
link_type=GraphLinkType.NODE_TO_PARENT_NODES,
lhs_node=node,
edge=ALL_EDGES,
)
)
for parent_node_ in parent_nodes:
parent_node_document = parent_node_.get_document()
assert parent_node_document is not None

if parent_node_document.config.relation_field != "MID":
continue

for relation_ in copy(parent_node_.relations):
if (
isinstance(relation_, ChildReqReference)
and relation_.ref_uid == old_mid
):
relation_.ref_uid = new_mid

#
# Update the node itself.
#
node.set_field_value(
field_name="MID",
form_field_index=0,
value=new_mid,
)

def update_requirement_child_uid(
self, requirement: SDocNode, child_uid: str, role: Optional[str]
) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ CHECK-DIFF-NEXT: ---
CHECK-DIFF-NEXT: > MID: {{[a-f0-9]{64}}}
CHECK-DIFF-NEXT: > HASH: dee51cd1dc666a6d1b2678c27c2b6dfc85376107e403963a8afc83acb62ff944

#
# The output requirements file only contains the change in two fields with
# nothing else affected.
# The regular expression is used to verify that the field is indeed SHA256.
#
RUN: %expect_exit 1 %diff %S/tests.sdoc %T/tests.sdoc | filecheck %s --check-prefix CHECK-DIFF-TESTS
CHECK-DIFF-TESTS: < VALUE: TBD
CHECK-DIFF-TESTS-NEXT: ---
CHECK-DIFF-TESTS-NEXT: > VALUE: {{[a-f0-9]{64}}}

#
# Source file with SPDX fields gets a stable hash generated.
#
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
[DOCUMENT]
MID: 11111122222233333344444455555566
TITLE: SPDX tests
OPTIONS:
ENABLE_MID: True
RELATION_FIELD: MID
MARKUP: Text

[GRAMMAR]
ELEMENTS:
- TAG: TEXT
FIELDS:
- TITLE: MID
TYPE: String
REQUIRED: False
- TITLE: STATEMENT
TYPE: String
REQUIRED: True
- TAG: SECTION
PROPERTIES:
IS_COMPOSITE: True
FIELDS:
- TITLE: MID
TYPE: String
REQUIRED: False
- TITLE: UID
TYPE: String
REQUIRED: False
- TITLE: TITLE
TYPE: String
REQUIRED: True
- TAG: TEST
PROPERTIES:
VIEW_STYLE: Narrative
FIELDS:
- TITLE: MID
HUMAN_TITLE: SPDX-Req-ID
TYPE: String
REQUIRED: False
- TITLE: HASH
HUMAN_TITLE: SPDX-Req-HKey
TYPE: String
REQUIRED: False
- TITLE: UID
TYPE: String
REQUIRED: False
- TITLE: FOO
TYPE: String
REQUIRED: False
- TITLE: BAR
TYPE: String
REQUIRED: False
- TITLE: TITLE
TYPE: String
REQUIRED: False
- TITLE: STATEMENT
HUMAN_TITLE: SPDX-Req-Text
TYPE: String
REQUIRED: False
RELATIONS:
- TYPE: Parent
- TYPE: File

[TEST]
MID: TBD-TEST
HASH: TBD
FOO: FOO text from sdoc
BAR: BAR text from sdoc
TITLE: TITLE from sdoc
RELATIONS:
- TYPE: Parent
VALUE: TBD