diff --git a/src/spdx/parser/rdf/package_parser.py b/src/spdx/parser/rdf/package_parser.py index ff0b020c8..b95866023 100644 --- a/src/spdx/parser/rdf/package_parser.py +++ b/src/spdx/parser/rdf/package_parser.py @@ -9,8 +9,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Optional - -from rdflib import URIRef, Graph, RDFS, DOAP +from rdflib import URIRef, Graph, RDFS, DOAP, Literal from spdx.datetime_conversions import datetime_from_str from spdx.model.package import Package, PackagePurpose, ExternalPackageRef, PackageVerificationCode, \ @@ -47,7 +46,7 @@ def parse_package(package_node: URIRef, graph: Graph, doc_namespace: str) -> Pac external_package_refs = [] for (_, _, external_package_ref_node) in graph.triples((package_node, SPDX_NAMESPACE.externalRef, None)): - external_package_refs.append(parse_external_package_ref(external_package_ref_node, graph)) + external_package_refs.append(parse_external_package_ref(external_package_ref_node, graph, doc_namespace)) files_analyzed = bool(graph.value(package_node, SPDX_NAMESPACE.filesAnalyzed, default=True)) license_concluded = parse_literal_or_no_assertion_or_none( logger, graph, package_node, SPDX_NAMESPACE.licenseConcluded, @@ -121,14 +120,14 @@ def parse_package_verification_code(package_verification_code_node: URIRef, grap return package_verification_code -def parse_external_package_ref(external_package_ref_node: URIRef, graph: Graph) -> ExternalPackageRef: +def parse_external_package_ref(external_package_ref_node: URIRef, graph: Graph, doc_namespace) -> ExternalPackageRef: logger = Logger() ref_locator = parse_literal(logger, graph, external_package_ref_node, SPDX_NAMESPACE.referenceLocator) ref_category = parse_literal( logger, graph, external_package_ref_node, SPDX_NAMESPACE.referenceCategory, parsing_method=lambda x: parse_enum_value(x, ExternalPackageRefCategory, SPDX_NAMESPACE.referenceCategory_, )) ref_type = parse_literal(logger, graph, external_package_ref_node, SPDX_NAMESPACE.referenceType, - parsing_method=lambda x: remove_prefix(x, REFERENCE_NAMESPACE)) + parsing_method=lambda x: parse_external_package_ref_type(x, doc_namespace)) comment = parse_literal(logger, graph, external_package_ref_node, RDFS.comment) raise_parsing_error_if_logger_has_messages(logger) @@ -136,3 +135,10 @@ def parse_external_package_ref(external_package_ref_node: URIRef, graph: Graph) dict(category=ref_category, reference_type=ref_type, locator=ref_locator, comment=comment)) return external_package_ref + +def parse_external_package_ref_type(external_package_ref_type_literal: Literal, doc_namespace: str) -> str: + if external_package_ref_type_literal.startswith(doc_namespace): + return external_package_ref_type_literal[len(doc_namespace)+1:] + if external_package_ref_type_literal.startswith(REFERENCE_NAMESPACE): + return external_package_ref_type_literal[len(REFERENCE_NAMESPACE):] + return external_package_ref_type_literal.toPython() diff --git a/tests/spdx/parser/rdf/data/file_to_test_rdf_parser.rdf.xml b/tests/spdx/parser/rdf/data/file_to_test_rdf_parser.rdf.xml index f832f8f09..89b7da146 100644 --- a/tests/spdx/parser/rdf/data/file_to_test_rdf_parser.rdf.xml +++ b/tests/spdx/parser/rdf/data/file_to_test_rdf_parser.rdf.xml @@ -1,186 +1,242 @@ - - - - - - - - - - - org.apache.tomcat:tomcat:9.0.0.M4 - - - externalPackageRefComment - - - - - - - - - https://homepage.com - Person: supplierName (some@mail.com) - packageSummary - true - 2022-12-03T00:00:00Z - packageAttributionText - packageDescription - packageComment - - - ./exclude.py - 85ed0817af83a24ad8da68c2b5094de69833983c - - - packageLicenseComment - packageName - 2022-12-01T00:00:00Z - 12.2 - Person: originatorName (some@mail.com) - - - packageCopyrightText - 2022-12-02T00:00:00Z - - - 71c4025dd9897b364f3ebbb42c484ff43d00791c - - - - ./packageFileName - sourceInfo - https://download.com - - - snippetComment - - - - - - - - - - - - - - - fileComment - - copyrightText - fileContributor - - - annotationComment - Person: annotatorName (some@mail.com) - 2022-12-01T00:00:00Z - - - - licenseComment + + SPDX-2.3 + + + https://see.also + extractedText + LicenseRef-1 + licenseComment + licenseName + + + documentComment + documentName + + + + + + fileNotice + + + annotationComment + Person: annotatorName (some@mail.com) + 2022-12-01T00:00:00Z + + + + fileAttributionText + + + + + + + + + fileContributor + + copyrightText + + + + 71c4025dd9897b364f3ebbb42c484ff43d00791c + + + fileComment + ./fileName.py + licenseComment + + + + + + + + creatorComment + Person: creatorName (some@mail.com) + 3.19 + 2022-12-01T00:00:00Z + + + + - - - 71c4025dd9897b364f3ebbb42c484ff43d00791c - + + + 71c4025dd9897b364f3ebbb42c484ff43d00791c + - ./fileName.py - - - fileNotice - fileAttributionText - - - 3 - - - - - - 4 - - - - - - - - - - 2 - - - - - 1 - - - - - - snippetAttributionText - - snippetLicenseComment - licenseCopyrightText - snippetName - - - - - - - - - - SPDX-2.3 - documentComment - - - + + + + + + + + + + + + 12.2 + ./packageFileName + Person: supplierName (some@mail.com) + https://download.com + + + Person: originatorName (some@mail.com) + + + + + + + 2022-12-03T00:00:00Z + true + packageDescription + + sourceInfo + packageLicenseComment + + + ./exclude.py + 85ed0817af83a24ad8da68c2b5094de69833983c + + + + 2022-12-02T00:00:00Z + packageComment + packageAttributionText + https://homepage.com + 2022-12-01T00:00:00Z + packageName + packageSummary - - 71c4025dd9897b364f3ebbb42c484ff43d00791c - - + + 71c4025dd9897b364f3ebbb42c484ff43d00791c + + - - - documentName - - - extractedText - https://see.also - LicenseRef-1 - licenseComment - licenseName - - - - - - - relationshipComment - - - - - 2022-12-01T00:00:00Z - creatorComment - 3.19 - Person: creatorName (some@mail.com) - - - + packageCopyrightText + + + org.apache.tomcat:tomcat:9.0.0.M4 + + + externalPackageRefComment + + + + + packageName + 2022-12-01T00:00:00Z + Person: supplierName (some@mail.com) + + + + 71c4025dd9897b364f3ebbb42c484ff43d00791c + + + 12.2 + + + 2022-12-03T00:00:00Z + https://homepage.com + true + ./packageFileName + + + + + + + + + ./exclude.py + 85ed0817af83a24ad8da68c2b5094de69833983c + + + + packageCopyrightText + http://differentdownload.com + sourceInfo + packageSummary + packageAttributionText + packageDescription + + + + + + + Person: originatorName (some@mail.com) + + + + + This is the external ref for Acme + acmecorp/acmenator/4.1.3-alpha + + + + packageComment + 2022-12-02T00:00:00Z + packageLicenseComment + + + + + + + + 3 + + + + + + 4 + + + + + + + + + 1 + + + + + + + 2 + + + + + + + + snippetAttributionText + snippetName + snippetLicenseComment + snippetComment + licenseCopyrightText + + + + + + + diff --git a/tests/spdx/parser/rdf/test_package_parser.py b/tests/spdx/parser/rdf/test_package_parser.py index f1e9615af..5999e2ed8 100644 --- a/tests/spdx/parser/rdf/test_package_parser.py +++ b/tests/spdx/parser/rdf/test_package_parser.py @@ -11,8 +11,9 @@ import os from unittest import TestCase +import pytest from license_expression import get_spdx_licensing -from rdflib import RDF, Graph +from rdflib import RDF, Graph, Literal from spdx.model.actor import Actor, ActorType from spdx.model.checksum import ChecksumAlgorithm, Checksum @@ -55,14 +56,22 @@ def test_package_parser(): assert package.originator == Actor(ActorType.PERSON, "originatorName", "some@mail.com") -def test_external_package_ref_parser(): +@pytest.mark.parametrize("download_location,category,locator,type,comment", + [("https://download.com", ExternalPackageRefCategory.PACKAGE_MANAGER, + "org.apache.tomcat:tomcat:9.0.0.M4", "maven-central", "externalPackageRefComment"), + ("http://differentdownload.com", ExternalPackageRefCategory.OTHER, + "acmecorp/acmenator/4.1.3-alpha", "LocationRef-acmeforge","This is the external ref for Acme")]) +def test_external_package_ref_parser(download_location, category, locator, type, comment): graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/file_to_test_rdf_parser.rdf.xml")) - package_node = graph.value(predicate=RDF.type, object=SPDX_NAMESPACE.Package) + doc_namespace = "https://some.namespace" + # we use the download location to identify the package node + # in the test file we have two different external package refs depending on the package + package_node = graph.value(predicate=SPDX_NAMESPACE.downloadLocation, object=Literal(download_location)) external_package_ref_node = graph.value(package_node, SPDX_NAMESPACE.externalRef) - external_package_ref = parse_external_package_ref(external_package_ref_node, graph) + external_package_ref = parse_external_package_ref(external_package_ref_node, graph, doc_namespace) - assert external_package_ref.category == ExternalPackageRefCategory.PACKAGE_MANAGER - assert external_package_ref.locator == "org.apache.tomcat:tomcat:9.0.0.M4" - assert external_package_ref.reference_type == "maven-central" - assert external_package_ref.comment == "externalPackageRefComment" + assert external_package_ref.category == category + assert external_package_ref.locator == locator + assert external_package_ref.reference_type == type + assert external_package_ref.comment == comment