spdx_tools.spdx.writer.tagvalue.tagvalue_writer_helper_functions

  1# SPDX-License-Identifier: Apache-2.0
  2#  Copyright (c) 2022 spdx contributors
  3#  Licensed under the Apache License, Version 2.0 (the "License");
  4#  you may not use this file except in compliance with the License.
  5#  You may obtain a copy of the License at
  6#    http://www.apache.org/licenses/LICENSE-2.0
  7#  Unless required by applicable law or agreed to in writing, software
  8#  distributed under the License is distributed on an "AS IS" BASIS,
  9#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 10#  See the License for the specific language governing permissions and
 11#  limitations under the License.
 12from beartype.typing import Any, Callable, Dict, List, Optional, TextIO, Tuple, Union
 13from license_expression import LicenseExpression
 14
 15from spdx_tools.spdx.model import (
 16    Actor,
 17    File,
 18    Package,
 19    Relationship,
 20    RelationshipType,
 21    Snippet,
 22    SpdxNoAssertion,
 23    SpdxNone,
 24)
 25
 26
 27def write_separator(out: TextIO):
 28    out.write("\n")
 29
 30
 31def write_value(
 32    tag: str, value: Optional[Union[bool, str, SpdxNone, SpdxNoAssertion, LicenseExpression]], out: TextIO
 33):
 34    if value is not None:
 35        out.write(f"{tag}: {value}\n")
 36
 37
 38def write_range(tag: str, value: Optional[Tuple[int, int]], out: TextIO):
 39    if value:
 40        out.write(f"{tag}: {value[0]}:{value[1]}\n")
 41
 42
 43def write_text_value(tag: str, value: Optional[Union[str, SpdxNone, SpdxNoAssertion]], out: TextIO):
 44    if isinstance(value, str) and "\n" in value:
 45        out.write(f"{tag}: <text>{value}</text>\n")
 46    else:
 47        write_value(tag, value, out)
 48
 49
 50def transform_enum_name_to_tv(enum_str: str) -> str:
 51    return enum_str.replace("_", "-")
 52
 53
 54def write_optional_heading(optional_field: Any, heading: str, text_output: TextIO):
 55    if optional_field:
 56        text_output.write(heading)
 57
 58
 59def write_list_of_elements(
 60    list_of_elements: List[Any],
 61    write_method: Callable[[Any, TextIO], None],
 62    text_output: TextIO,
 63    with_separator: bool = False,
 64):
 65    for element in list_of_elements:
 66        write_method(element, text_output)
 67        if with_separator:
 68            write_separator(text_output)
 69
 70
 71def write_actor(tag: str, element_to_write: Optional[Union[Actor, SpdxNoAssertion]], text_output: TextIO):
 72    if isinstance(element_to_write, Actor):
 73        write_value(tag, element_to_write.to_serialized_string(), text_output)
 74    else:
 75        write_value(tag, element_to_write, text_output)
 76
 77
 78def scan_relationships(
 79    relationships: List[Relationship], packages: List[Package], files: List[File]
 80) -> Tuple[List, Dict]:
 81    contained_files_by_package_id = dict()
 82    relationships_to_write = []
 83    files_by_spdx_id = {file.spdx_id: file for file in files}
 84    packages_spdx_ids = [package.spdx_id for package in packages]
 85    for relationship in relationships:
 86        if relationship.related_spdx_element_id in [SpdxNoAssertion(), SpdxNone()]:
 87            relationships_to_write.append(relationship)
 88        elif (
 89            relationship.relationship_type == RelationshipType.CONTAINS
 90            and relationship.spdx_element_id in packages_spdx_ids
 91            and relationship.related_spdx_element_id in files_by_spdx_id.keys()
 92        ):
 93            contained_files_by_package_id.setdefault(relationship.spdx_element_id, []).append(
 94                files_by_spdx_id[relationship.related_spdx_element_id]
 95            )
 96            if relationship.comment:
 97                relationships_to_write.append(relationship)
 98        elif (
 99            relationship.relationship_type == RelationshipType.CONTAINED_BY
100            and relationship.related_spdx_element_id in packages_spdx_ids
101            and relationship.spdx_element_id in files_by_spdx_id
102        ):
103            contained_files_by_package_id.setdefault(relationship.related_spdx_element_id, []).append(
104                files_by_spdx_id[relationship.spdx_element_id]
105            )
106            if relationship.comment:
107                relationships_to_write.append(relationship)
108        else:
109            relationships_to_write.append(relationship)
110
111    return relationships_to_write, contained_files_by_package_id
112
113
114def get_file_ids_with_contained_snippets(snippets: List[Snippet], files: List[File]) -> Dict:
115    file_ids_with_contained_snippets = dict()
116    file_spdx_ids: List[str] = [file.spdx_id for file in files]
117    for snippet in snippets:
118        if snippet.file_spdx_id in file_spdx_ids:
119            file_ids_with_contained_snippets.setdefault(snippet.file_spdx_id, []).append(snippet)
120
121    return file_ids_with_contained_snippets
def write_separator(out: <class 'TextIO'>):
28def write_separator(out: TextIO):
29    out.write("\n")
def write_value( tag: str, value: Union[bool, str, spdx_tools.spdx.model.spdx_none.SpdxNone, spdx_tools.spdx.model.spdx_no_assertion.SpdxNoAssertion, boolean.boolean.Expression, NoneType], out: <class 'TextIO'>):
32def write_value(
33    tag: str, value: Optional[Union[bool, str, SpdxNone, SpdxNoAssertion, LicenseExpression]], out: TextIO
34):
35    if value is not None:
36        out.write(f"{tag}: {value}\n")
def write_range(tag: str, value: Optional[tuple[int, int]], out: <class 'TextIO'>):
39def write_range(tag: str, value: Optional[Tuple[int, int]], out: TextIO):
40    if value:
41        out.write(f"{tag}: {value[0]}:{value[1]}\n")
def write_text_value( tag: str, value: Union[str, spdx_tools.spdx.model.spdx_none.SpdxNone, spdx_tools.spdx.model.spdx_no_assertion.SpdxNoAssertion, NoneType], out: <class 'TextIO'>):
44def write_text_value(tag: str, value: Optional[Union[str, SpdxNone, SpdxNoAssertion]], out: TextIO):
45    if isinstance(value, str) and "\n" in value:
46        out.write(f"{tag}: <text>{value}</text>\n")
47    else:
48        write_value(tag, value, out)
def transform_enum_name_to_tv(enum_str: str) -> str:
51def transform_enum_name_to_tv(enum_str: str) -> str:
52    return enum_str.replace("_", "-")
def write_optional_heading(optional_field: Any, heading: str, text_output: <class 'TextIO'>):
55def write_optional_heading(optional_field: Any, heading: str, text_output: TextIO):
56    if optional_field:
57        text_output.write(heading)
def write_list_of_elements( list_of_elements: list[typing.Any], write_method: collections.abc.Callable[[typing.Any, typing.TextIO], None], text_output: <class 'TextIO'>, with_separator: bool = False):
60def write_list_of_elements(
61    list_of_elements: List[Any],
62    write_method: Callable[[Any, TextIO], None],
63    text_output: TextIO,
64    with_separator: bool = False,
65):
66    for element in list_of_elements:
67        write_method(element, text_output)
68        if with_separator:
69            write_separator(text_output)
def write_actor( tag: str, element_to_write: Union[spdx_tools.spdx.model.actor.Actor, spdx_tools.spdx.model.spdx_no_assertion.SpdxNoAssertion, NoneType], text_output: <class 'TextIO'>):
72def write_actor(tag: str, element_to_write: Optional[Union[Actor, SpdxNoAssertion]], text_output: TextIO):
73    if isinstance(element_to_write, Actor):
74        write_value(tag, element_to_write.to_serialized_string(), text_output)
75    else:
76        write_value(tag, element_to_write, text_output)
def scan_relationships( relationships: list[spdx_tools.spdx.model.relationship.Relationship], packages: list[spdx_tools.spdx.model.package.Package], files: list[spdx_tools.spdx.model.file.File]) -> tuple[list, dict]:
 79def scan_relationships(
 80    relationships: List[Relationship], packages: List[Package], files: List[File]
 81) -> Tuple[List, Dict]:
 82    contained_files_by_package_id = dict()
 83    relationships_to_write = []
 84    files_by_spdx_id = {file.spdx_id: file for file in files}
 85    packages_spdx_ids = [package.spdx_id for package in packages]
 86    for relationship in relationships:
 87        if relationship.related_spdx_element_id in [SpdxNoAssertion(), SpdxNone()]:
 88            relationships_to_write.append(relationship)
 89        elif (
 90            relationship.relationship_type == RelationshipType.CONTAINS
 91            and relationship.spdx_element_id in packages_spdx_ids
 92            and relationship.related_spdx_element_id in files_by_spdx_id.keys()
 93        ):
 94            contained_files_by_package_id.setdefault(relationship.spdx_element_id, []).append(
 95                files_by_spdx_id[relationship.related_spdx_element_id]
 96            )
 97            if relationship.comment:
 98                relationships_to_write.append(relationship)
 99        elif (
100            relationship.relationship_type == RelationshipType.CONTAINED_BY
101            and relationship.related_spdx_element_id in packages_spdx_ids
102            and relationship.spdx_element_id in files_by_spdx_id
103        ):
104            contained_files_by_package_id.setdefault(relationship.related_spdx_element_id, []).append(
105                files_by_spdx_id[relationship.spdx_element_id]
106            )
107            if relationship.comment:
108                relationships_to_write.append(relationship)
109        else:
110            relationships_to_write.append(relationship)
111
112    return relationships_to_write, contained_files_by_package_id
def get_file_ids_with_contained_snippets( snippets: list[spdx_tools.spdx.model.snippet.Snippet], files: list[spdx_tools.spdx.model.file.File]) -> dict:
115def get_file_ids_with_contained_snippets(snippets: List[Snippet], files: List[File]) -> Dict:
116    file_ids_with_contained_snippets = dict()
117    file_spdx_ids: List[str] = [file.spdx_id for file in files]
118    for snippet in snippets:
119        if snippet.file_spdx_id in file_spdx_ids:
120            file_ids_with_contained_snippets.setdefault(snippet.file_spdx_id, []).append(snippet)
121
122    return file_ids_with_contained_snippets