Skip to content

Commit ab5c584

Browse files
authored
fix: exclude qualifiers and subpath for PURL comparison in get_purldb_entries #453
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent 59d9102 commit ab5c584

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

component_catalog/models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@
7575
from dje.models import ParentChildRelationshipModel
7676
from dje.models import ReferenceNotesMixin
7777
from dje.tasks import logger as tasks_logger
78-
from dje.utils import get_plain_purl
7978
from dje.utils import is_purl_str
8079
from dje.utils import merge_common_non_empty_values
80+
from dje.utils import plain_purls_equal
8181
from dje.utils import set_fields_from_object
8282
from dje.validators import generic_uri_validator
8383
from dje.validators import validate_url_segment
@@ -2618,13 +2618,13 @@ def get_purldb_entries(self, user, max_request_call=0, timeout=10):
26182618
return []
26192619

26202620
# Cleanup the PurlDB entries:
2621-
# Packages with different "plain" PURL are excluded. The qualifiers and
2622-
# subpaths are not involved in this comparison.
2621+
# Packages with different "plain" PURL are excluded.
2622+
# The qualifiers and subpaths are not involved in this comparison.
26232623
if package_url:
26242624
purldb_entries = [
26252625
entry
26262626
for entry in purldb_entries
2627-
if get_plain_purl(entry.get("purl", "")) == package_url
2627+
if plain_purls_equal(entry.get("purl"), package_url)
26282628
]
26292629

26302630
return purldb_entries

component_catalog/tests/test_models.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,12 +2622,27 @@ def test_package_model_get_purldb_entries(self, mock_find_packages):
26222622

26232623
mock_find_packages.return_value = None
26242624
purldb_entries = package1.get_purldb_entries(user=self.user)
2625+
self.assertEqual([], purldb_entries)
26252626

26262627
mock_find_packages.return_value = [purldb_entry1, purldb_entry2, purldb_entry3]
26272628
purldb_entries = package1.get_purldb_entries(user=self.user)
26282629
# The purldb_entry2 is excluded as the PURL differs
26292630
self.assertEqual([purldb_entry1, purldb_entry2], purldb_entries)
26302631

2632+
@mock.patch("dejacode_toolkit.purldb.PurlDB.find_packages")
2633+
def test_package_model_get_purldb_entries_plain_purls_equal(self, mock_find_packages):
2634+
purl1 = "pkg:maven/core/jackson-core@2.18.3?type=jar"
2635+
purl2 = "pkg:maven/core/jackson-core@2.18.3?classifier=sources&type=jar"
2636+
2637+
package1_purl = "pkg:maven/core/jackson-core@2.18.3?some=qualifier"
2638+
package1 = make_package(self.dataspace, package_url=package1_purl)
2639+
purldb_entry1 = {"purl": purl1}
2640+
purldb_entry2 = {"purl": purl2}
2641+
2642+
mock_find_packages.return_value = [purldb_entry1, purldb_entry2]
2643+
purldb_entries = package1.get_purldb_entries(user=self.user)
2644+
self.assertEqual([purldb_entry1, purldb_entry2], purldb_entries)
2645+
26312646
@mock.patch("component_catalog.models.Package.get_purldb_entries")
26322647
def test_package_model_update_from_purldb(self, mock_get_purldb_entries):
26332648
purldb_entry = {

dje/tests/test_utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from dje.utils import merge_common_non_empty_values
4343
from dje.utils import merge_relations
4444
from dje.utils import normalize_newlines_as_CR_plus_LF
45+
from dje.utils import plain_purls_equal
4546
from dje.utils import remove_field_from_query_dict
4647
from dje.utils import str_to_id_list
4748
from dje.views import get_previous_next
@@ -528,6 +529,7 @@ def test_utils_is_purl_fragment(self):
528529
self.assertFalse(is_purl_fragment(fragment), msg=fragment)
529530

530531
def test_utils_get_plain_purl(self):
532+
self.assertEqual("", get_plain_purl(None))
531533
self.assertEqual("", get_plain_purl(""))
532534
self.assertEqual("not:a/purl", get_plain_purl("not:a/purl"))
533535
self.assertEqual("not:a/purl", get_plain_purl("not:a/purl"))
@@ -536,6 +538,23 @@ def test_utils_get_plain_purl(self):
536538
"pkg:npm/is-npm@1.0.0", get_plain_purl("pkg:npm/is-npm@1.0.0?qualifier=1#frament")
537539
)
538540

541+
def test_utils_plain_purls_equal(self):
542+
purl1 = "pkg:npm/is-npm@1.0.0"
543+
purl2 = "pkg:npm/is-npm@1.0.0"
544+
self.assertTrue(plain_purls_equal(purl1, purl2))
545+
546+
purl1 = "pkg:npm/is-npm@1.0.0?qual=1#subpath"
547+
purl2 = "pkg:npm/is-npm@1.0.0"
548+
self.assertTrue(plain_purls_equal(purl1, purl2))
549+
550+
purl1 = "pkg:npm/is-npm@1.0.0?qual=1"
551+
purl2 = "pkg:npm/is-npm@1.0.0?qual=2"
552+
self.assertTrue(plain_purls_equal(purl1, purl2))
553+
554+
purl1 = "pkg:npm/is-npm@1.0.0"
555+
purl2 = "pkg:npm/is-npm@2.0.0"
556+
self.assertFalse(plain_purls_equal(purl1, purl2))
557+
539558
def test_utils_localized_datetime(self):
540559
self.assertIsNone(localized_datetime(None))
541560

dje/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,9 +658,16 @@ def is_purl_fragment(string):
658658

659659
def get_plain_purl(purl_str):
660660
"""Remove the qualifiers and subpath from the `purl_str```."""
661+
if not purl_str:
662+
return ""
661663
return purl_str.split("?")[0]
662664

663665

666+
def plain_purls_equal(purl1, purl2):
667+
"""Check if two PURLs are equal, ignoring qualifiers and subpath."""
668+
return get_plain_purl(purl1) == get_plain_purl(purl2)
669+
670+
664671
def remove_empty_values(input_dict):
665672
"""
666673
Return a new dict not including empty value entries from `input_dict`.

0 commit comments

Comments
 (0)