From 4dad0e1a8c6af7484a309a3e826a33f8df89c0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armin=20T=C3=A4nzer?= Date: Fri, 14 Jul 2023 09:56:04 +0200 Subject: [PATCH 1/3] remove unused CircleCI workflow and directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Armin Tänzer --- .circleci/config.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 7bca2704d..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Empty Circle CI configuration file to make pipeline pass - -version: 2.1 - -jobs: - empty-job: - docker: - - image: python:3.11 - steps: - - run: echo "Empty Job to make CircleCI green, we switched to https://github.com/spdx/tools-python/actions" - -workflows: - simple-workflow: - jobs: - - empty-job From 2402596f1b7f12791e8516dd7b3634c6aa830f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armin=20T=C3=A4nzer?= Date: Wed, 19 Jul 2023 10:49:02 +0200 Subject: [PATCH 2/3] make "Package CONTAINS Package" valid even when files_analyzed == False MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Armin Tänzer --- src/spdx_tools/spdx/spdx_element_utils.py | 15 ++++++++++++- .../spdx/validation/package_validator.py | 16 ++++++++++++-- .../spdx/validation/test_package_validator.py | 21 +++++++++++++++++-- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/spdx_tools/spdx/spdx_element_utils.py b/src/spdx_tools/spdx/spdx_element_utils.py index c3cb3f7fa..0d6bd8946 100644 --- a/src/spdx_tools/spdx/spdx_element_utils.py +++ b/src/spdx_tools/spdx/spdx_element_utils.py @@ -3,10 +3,11 @@ # SPDX-License-Identifier: Apache-2.0 import hashlib -from beartype.typing import List, Union +from beartype.typing import List, Optional, Type, Union from spdx_tools.spdx.model import ( ChecksumAlgorithm, + Document, ExternalDocumentRef, File, Package, @@ -15,6 +16,18 @@ ) +def get_element_type_from_spdx_id( + spdx_id: str, document: Document +) -> Optional[Union[Type[Package], Type[File], Type[Snippet]]]: + if spdx_id in [package.spdx_id for package in document.packages]: + return Package + if spdx_id in [file.spdx_id for file in document.files]: + return File + if spdx_id in [snippet.spdx_id for snippet in document.snippets]: + return Snippet + return None + + def get_full_element_spdx_id( element: Union[Package, File, Snippet], document_namespace: str, diff --git a/src/spdx_tools/spdx/validation/package_validator.py b/src/spdx_tools/spdx/validation/package_validator.py index 4307fc8ef..25cd6147f 100644 --- a/src/spdx_tools/spdx/validation/package_validator.py +++ b/src/spdx_tools/spdx/validation/package_validator.py @@ -4,8 +4,9 @@ from beartype.typing import List, Optional -from spdx_tools.spdx.model import Document, Package, Relationship, RelationshipType +from spdx_tools.spdx.model import Document, File, Package, Relationship, RelationshipType from spdx_tools.spdx.model.relationship_filters import filter_by_type_and_origin, filter_by_type_and_target +from spdx_tools.spdx.spdx_element_utils import get_element_type_from_spdx_id from spdx_tools.spdx.validation.checksum_validator import validate_checksums from spdx_tools.spdx.validation.external_package_ref_validator import validate_external_package_refs from spdx_tools.spdx.validation.license_expression_validator import ( @@ -50,12 +51,23 @@ def validate_package_within_document( package_contains_relationships = filter_by_type_and_origin( document.relationships, RelationshipType.CONTAINS, package.spdx_id ) + package_contains_file_relationships = [ + relationship + for relationship in package_contains_relationships + if get_element_type_from_spdx_id(relationship.related_spdx_element_id, document) == File + ] + contained_in_package_relationships = filter_by_type_and_target( document.relationships, RelationshipType.CONTAINED_BY, package.spdx_id ) + file_contained_in_package_relationships = [ + relationship + for relationship in contained_in_package_relationships + if get_element_type_from_spdx_id(relationship.spdx_element_id, document) == File + ] combined_relationships: List[Relationship] = ( - package_contains_relationships + contained_in_package_relationships + package_contains_file_relationships + file_contained_in_package_relationships ) if combined_relationships: diff --git a/tests/spdx/validation/test_package_validator.py b/tests/spdx/validation/test_package_validator.py index c2b6640d2..a6ef976ef 100644 --- a/tests/spdx/validation/test_package_validator.py +++ b/tests/spdx/validation/test_package_validator.py @@ -74,10 +74,27 @@ def test_invalid_package(package_input, expected_message): @pytest.mark.parametrize( "relationships", [ - [Relationship("SPDXRef-Package", RelationshipType.CONTAINS, "SPDXRef-File1")], [Relationship("SPDXRef-Package", RelationshipType.CONTAINS, "DocumentRef-external:SPDXRef-File")], - [Relationship("SPDXRef-File2", RelationshipType.CONTAINED_BY, "SPDXRef-Package")], [Relationship("DocumentRef-external:SPDXRef-File", RelationshipType.CONTAINED_BY, "SPDXRef-Package")], + ], +) +def test_valid_package_with_contains(relationships): + document = document_fixture( + relationships=relationships, + files=[file_fixture(spdx_id="SPDXRef-File1"), file_fixture(spdx_id="SPDXRef-File2")], + ) + package = package_fixture(files_analyzed=False, verification_code=None, license_info_from_files=[]) + + validation_messages: List[ValidationMessage] = validate_package_within_document(package, "SPDX-2.3", document) + + assert validation_messages == [] + + +@pytest.mark.parametrize( + "relationships", + [ + [Relationship("SPDXRef-Package", RelationshipType.CONTAINS, "SPDXRef-File1")], + [Relationship("SPDXRef-File2", RelationshipType.CONTAINED_BY, "SPDXRef-Package")], [ Relationship("SPDXRef-Package", RelationshipType.CONTAINS, "SPDXRef-File2"), Relationship("SPDXRef-File1", RelationshipType.CONTAINED_BY, "SPDXRef-Package"), From 8ef0cef2f53a98139ce6c25767762bd152dbbd62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armin=20T=C3=A4nzer?= Date: Wed, 19 Jul 2023 15:32:16 +0200 Subject: [PATCH 3/3] set validate=True as default value in the rdf writer to be consistent with the writers of the other formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Armin Tänzer --- src/spdx_tools/spdx/writer/rdf/rdf_writer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/spdx_tools/spdx/writer/rdf/rdf_writer.py b/src/spdx_tools/spdx/writer/rdf/rdf_writer.py index 7756e56c6..206494def 100644 --- a/src/spdx_tools/spdx/writer/rdf/rdf_writer.py +++ b/src/spdx_tools/spdx/writer/rdf/rdf_writer.py @@ -17,7 +17,9 @@ from spdx_tools.spdx.writer.write_utils import validate_and_deduplicate -def write_document_to_stream(document: Document, stream: IO[bytes], validate: bool, drop_duplicates: bool = True): +def write_document_to_stream( + document: Document, stream: IO[bytes], validate: bool = True, drop_duplicates: bool = True +): document = validate_and_deduplicate(document, validate, drop_duplicates) graph = Graph() doc_namespace = document.creation_info.document_namespace @@ -51,6 +53,6 @@ def write_document_to_stream(document: Document, stream: IO[bytes], validate: bo graph.serialize(stream, "pretty-xml", encoding="UTF-8", max_depth=100) -def write_document_to_file(document: Document, file_name: str, validate: bool, drop_duplicates: bool = True): +def write_document_to_file(document: Document, file_name: str, validate: bool = True, drop_duplicates: bool = True): with open(file_name, "wb") as out: write_document_to_stream(document, out, validate, drop_duplicates)