spdx_tools.spdx.validation.file_validator

 1# SPDX-FileCopyrightText: 2022 spdx contributors
 2#
 3# SPDX-License-Identifier: Apache-2.0
 4
 5from beartype.typing import List, Optional
 6
 7from spdx_tools.spdx.model import ChecksumAlgorithm, Document, File
 8from spdx_tools.spdx.validation.checksum_validator import validate_checksums
 9from spdx_tools.spdx.validation.license_expression_validator import (
10    validate_license_expression,
11    validate_license_expressions,
12)
13from spdx_tools.spdx.validation.spdx_id_validators import validate_spdx_id
14from spdx_tools.spdx.validation.validation_message import SpdxElementType, ValidationContext, ValidationMessage
15
16
17def validate_files(
18    files: List[File], spdx_version: str, document: Optional[Document] = None
19) -> List[ValidationMessage]:
20    validation_messages = []
21    if document:
22        for file in files:
23            validation_messages.extend(validate_file_within_document(file, spdx_version, document))
24    else:
25        for file in files:
26            validation_messages.extend(validate_file(file, spdx_version))
27
28    return validation_messages
29
30
31def validate_file_within_document(file: File, spdx_version: str, document: Document) -> List[ValidationMessage]:
32    validation_messages: List[ValidationMessage] = []
33    context = ValidationContext(
34        spdx_id=file.spdx_id,
35        parent_id=document.creation_info.spdx_id,
36        element_type=SpdxElementType.FILE,
37        full_element=file,
38    )
39
40    for message in validate_spdx_id(file.spdx_id, document):
41        validation_messages.append(ValidationMessage(message, context))
42
43    validation_messages.extend(validate_license_expression(file.license_concluded, document, file.spdx_id))
44
45    validation_messages.extend(validate_license_expressions(file.license_info_in_file, document, file.spdx_id))
46
47    validation_messages.extend(validate_file(file, spdx_version, context))
48
49    return validation_messages
50
51
52def validate_file(
53    file: File, spdx_version: str, context: Optional[ValidationContext] = None
54) -> List[ValidationMessage]:
55    validation_messages = []
56    if not context:
57        context = ValidationContext(spdx_id=file.spdx_id, element_type=SpdxElementType.FILE, full_element=file)
58
59    if file.name.startswith("/"):
60        validation_messages.append(
61            ValidationMessage(
62                f'file name must not be an absolute path starting with "/", but is: {file.name}', context
63            )
64        )
65
66    if ChecksumAlgorithm.SHA1 not in [checksum.algorithm for checksum in file.checksums]:
67        validation_messages.append(
68            ValidationMessage(
69                f"checksums must contain a SHA1 algorithm checksum, but only contains: "
70                f"{[checksum.algorithm for checksum in file.checksums]}",
71                context,
72            )
73        )
74
75    validation_messages.extend(validate_checksums(file.checksums, file.spdx_id, spdx_version))
76
77    if spdx_version == "SPDX-2.2":
78        if file.license_concluded is None:
79            validation_messages.append(ValidationMessage("license_concluded is mandatory in SPDX-2.2", context))
80        if not file.license_info_in_file:
81            validation_messages.append(ValidationMessage("license_info_in_file is mandatory in SPDX-2.2", context))
82        if file.copyright_text is None:
83            validation_messages.append(ValidationMessage("copyright_text is mandatory in SPDX-2.2", context))
84
85    return validation_messages
def validate_files( files: list[spdx_tools.spdx.model.file.File], spdx_version: str, document: Optional[spdx_tools.spdx.model.document.Document] = None) -> list[spdx_tools.spdx.validation.validation_message.ValidationMessage]:
18def validate_files(
19    files: List[File], spdx_version: str, document: Optional[Document] = None
20) -> List[ValidationMessage]:
21    validation_messages = []
22    if document:
23        for file in files:
24            validation_messages.extend(validate_file_within_document(file, spdx_version, document))
25    else:
26        for file in files:
27            validation_messages.extend(validate_file(file, spdx_version))
28
29    return validation_messages
def validate_file_within_document( file: spdx_tools.spdx.model.file.File, spdx_version: str, document: spdx_tools.spdx.model.document.Document) -> list[spdx_tools.spdx.validation.validation_message.ValidationMessage]:
32def validate_file_within_document(file: File, spdx_version: str, document: Document) -> List[ValidationMessage]:
33    validation_messages: List[ValidationMessage] = []
34    context = ValidationContext(
35        spdx_id=file.spdx_id,
36        parent_id=document.creation_info.spdx_id,
37        element_type=SpdxElementType.FILE,
38        full_element=file,
39    )
40
41    for message in validate_spdx_id(file.spdx_id, document):
42        validation_messages.append(ValidationMessage(message, context))
43
44    validation_messages.extend(validate_license_expression(file.license_concluded, document, file.spdx_id))
45
46    validation_messages.extend(validate_license_expressions(file.license_info_in_file, document, file.spdx_id))
47
48    validation_messages.extend(validate_file(file, spdx_version, context))
49
50    return validation_messages
53def validate_file(
54    file: File, spdx_version: str, context: Optional[ValidationContext] = None
55) -> List[ValidationMessage]:
56    validation_messages = []
57    if not context:
58        context = ValidationContext(spdx_id=file.spdx_id, element_type=SpdxElementType.FILE, full_element=file)
59
60    if file.name.startswith("/"):
61        validation_messages.append(
62            ValidationMessage(
63                f'file name must not be an absolute path starting with "/", but is: {file.name}', context
64            )
65        )
66
67    if ChecksumAlgorithm.SHA1 not in [checksum.algorithm for checksum in file.checksums]:
68        validation_messages.append(
69            ValidationMessage(
70                f"checksums must contain a SHA1 algorithm checksum, but only contains: "
71                f"{[checksum.algorithm for checksum in file.checksums]}",
72                context,
73            )
74        )
75
76    validation_messages.extend(validate_checksums(file.checksums, file.spdx_id, spdx_version))
77
78    if spdx_version == "SPDX-2.2":
79        if file.license_concluded is None:
80            validation_messages.append(ValidationMessage("license_concluded is mandatory in SPDX-2.2", context))
81        if not file.license_info_in_file:
82            validation_messages.append(ValidationMessage("license_info_in_file is mandatory in SPDX-2.2", context))
83        if file.copyright_text is None:
84            validation_messages.append(ValidationMessage("copyright_text is mandatory in SPDX-2.2", context))
85
86    return validation_messages