From 990eb0223589460c15b1034213698200d24b9440 Mon Sep 17 00:00:00 2001 From: Trong Nhan Mai Date: Mon, 23 Sep 2024 12:00:27 +1000 Subject: [PATCH] chore: allow multiple artifact paths for a purl type --- src/macaron/artifact/local_artifact.py | 42 ++++++++++++++------ src/macaron/slsa_analyzer/analyze_context.py | 5 +-- tests/artifact/test_local_artifact.py | 25 +++++++----- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/macaron/artifact/local_artifact.py b/src/macaron/artifact/local_artifact.py index eb862e477..67b70c318 100644 --- a/src/macaron/artifact/local_artifact.py +++ b/src/macaron/artifact/local_artifact.py @@ -25,17 +25,17 @@ def get_local_artifact_repo_mapper() -> Mapping[str, str]: return local_artifact_mapper -def construct_local_artifact_path_from_purl( +def construct_local_artifact_paths_from_purl( build_purl_type: str, component_purl: PackageURL, local_artifact_repo_mapper: Mapping[str, str], -) -> str | None: +) -> list[str] | None: """Get B.""" local_artifact_repo = local_artifact_repo_mapper.get(build_purl_type) if local_artifact_repo is None: return None - artifact_path = None + artifact_path = [] match build_purl_type: case "maven": group = component_purl.namespace @@ -45,10 +45,12 @@ def construct_local_artifact_path_from_purl( if group is None or version is None: return None - artifact_path = os.path.join( - local_artifact_repo, - "repository", - construct_maven_repository_path(group, artifact, version), + artifact_path.append( + os.path.join( + local_artifact_repo, + "repository", + construct_maven_repository_path(group, artifact, version), + ) ) case "pypi": # TODO: implement this. @@ -59,22 +61,36 @@ def construct_local_artifact_path_from_purl( return artifact_path +# key: purl type +# value: list of paths +# If a key doesn't exist -> cannot construct the artifact paths for that purl type +# (no local artifact repo found or not enough information from PURL string or simply +# the PURL string is not applicable for that purl type). +# If a value is an empty list -> Can construct the local artifact paths but no paths exist in the local artifact repository. def get_local_artifact_paths( purl: PackageURL, build_tool_purl_types: list[str], local_artifact_repo_mapper: Mapping[str, str], -) -> dict[str, str]: +) -> dict[str, list[str]]: """Get C.""" - result = {} + local_artifact_paths_purl_mapping = {} for build_purl_type in build_tool_purl_types: - local_artfiact_path = construct_local_artifact_path_from_purl( + local_artfiact_paths = construct_local_artifact_paths_from_purl( build_purl_type=build_purl_type, component_purl=purl, local_artifact_repo_mapper=local_artifact_repo_mapper, ) - if local_artfiact_path and os.path.isdir(local_artfiact_path): - result[build_purl_type] = local_artfiact_path + if not local_artfiact_paths: + continue - return result + resolved_local_artifact_paths = [] + + for local_artifact_path in local_artfiact_paths: + if os.path.isdir(local_artifact_path): + resolved_local_artifact_paths.append(local_artifact_path) + + local_artifact_paths_purl_mapping[build_purl_type] = resolved_local_artifact_paths + + return local_artifact_paths_purl_mapping diff --git a/src/macaron/slsa_analyzer/analyze_context.py b/src/macaron/slsa_analyzer/analyze_context.py index 88ef09d7e..998e1ec29 100644 --- a/src/macaron/slsa_analyzer/analyze_context.py +++ b/src/macaron/slsa_analyzer/analyze_context.py @@ -52,9 +52,8 @@ class ChecksOutputs(TypedDict): """The commit digest extracted from provenance, if applicable.""" provenance_verified: bool """True if the provenance exists and has been verified against a signed companion provenance.""" - local_artifact_paths: dict[str, str] - # TODO this doc string for this variable need more informatino, to be revise later. - """The mapping between build tool types and the directory that contains the corresponding artifacts.""" + local_artifact_paths: dict[str, list[str]] + """The mapping between purl types and the local artifact absolute paths.""" class AnalyzeContext: diff --git a/tests/artifact/test_local_artifact.py b/tests/artifact/test_local_artifact.py index 3e44bdcb6..50157ac5e 100644 --- a/tests/artifact/test_local_artifact.py +++ b/tests/artifact/test_local_artifact.py @@ -9,7 +9,7 @@ import pytest from packageurl import PackageURL -from macaron.artifact.local_artifact import construct_local_artifact_path_from_purl, get_local_artifact_paths +from macaron.artifact.local_artifact import construct_local_artifact_paths_from_purl, get_local_artifact_paths @pytest.mark.parametrize( @@ -19,7 +19,7 @@ "maven", "pkg:maven/com.google.guava/guava@33.2.1-jre", {"maven": "/home/foo/.m2"}, - "/home/foo/.m2/repository/com/google/guava/guava/33.2.1-jre", + ["/home/foo/.m2/repository/com/google/guava/guava/33.2.1-jre"], id="A maven type PURL with available local maven repo", ), pytest.param( @@ -63,12 +63,12 @@ def test_construct_local_artifact_path_from_purl( build_purl_type: str, purl_str: str, local_artifact_repo_mapper: Mapping[str, str], - expectation: str, + expectation: list[str], ) -> None: """Test constructing a local artifact path from a given purl.""" component_purl = PackageURL.from_string(purl_str) assert ( - construct_local_artifact_path_from_purl( + construct_local_artifact_paths_from_purl( build_purl_type=build_purl_type, component_purl=component_purl, local_artifact_repo_mapper=local_artifact_repo_mapper, @@ -78,18 +78,20 @@ def test_construct_local_artifact_path_from_purl( @pytest.mark.parametrize( - ("purl_str", "build_tool_purl_types"), + ("purl_str", "build_tool_purl_types", "expectation"), [ pytest.param( "pkg:maven/com.google.guava/guava@33.2.1-jre", ["maven", "pypi"], - id="A maven type PURL where multiple build tool types are discovered", + {"maven": []}, + id="A maven type PURL where multiple build tool types are discovered. But no artifact path is available.", ), ], ) def test_get_local_artifact_paths_non_existing( purl_str: str, build_tool_purl_types: list[str], + expectation: dict[str, list[str]], ) -> None: """Test getting local artifact paths of non existing artifacts. @@ -101,8 +103,11 @@ def test_get_local_artifact_paths_non_existing( "maven": temp_dir, "pypi": temp_dir, } - assert not get_local_artifact_paths( - purl=purl, - build_tool_purl_types=build_tool_purl_types, - local_artifact_repo_mapper=local_artifact_repo_mapper, + assert ( + get_local_artifact_paths( + purl=purl, + build_tool_purl_types=build_tool_purl_types, + local_artifact_repo_mapper=local_artifact_repo_mapper, + ) + == expectation )