Skip to content

Commit 6fec557

Browse files
authored
Refine get_purldb_entries to compare on plain PURL #307 (#308)
* Refine get_purldb_entries to compare on plain PURL #307 Including the qualifiers and subpaths in the comparison is too restrictive. Signed-off-by: tdruez <[email protected]> * Add changelog entry #307 Signed-off-by: tdruez <[email protected]> --------- Signed-off-by: tdruez <[email protected]>
1 parent 925d404 commit 6fec557

File tree

5 files changed

+41
-8
lines changed

5 files changed

+41
-8
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ Release notes
153153
This tab displays related packages grouped by their normalized ("plain") Package URL.
154154
https://github.com/aboutcode-org/dejacode/issues/276
155155

156+
- Refine get_purldb_entries to compare on plain PackageURL.
157+
Including the qualifiers and subpaths in the comparison was too restrictive.
158+
https://github.com/aboutcode-org/dejacode/issues/307
159+
156160
### Version 5.2.1
157161

158162
- Fix the models documentation navigation.

component_catalog/models.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
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
7879
from dje.utils import is_purl_str
7980
from dje.utils import merge_common_non_empty_values
8081
from dje.utils import set_fields_from_object
@@ -2560,9 +2561,14 @@ def get_purldb_entries(self, user, max_request_call=0, timeout=10):
25602561
return []
25612562

25622563
# Cleanup the PurlDB entries:
2563-
# - Packages with different PURL are excluded.
2564+
# Packages with different "plain" PURL are excluded. The qualifiers and
2565+
# subpaths are not involved in this comparison.
25642566
if package_url:
2565-
purldb_entries = [entry for entry in purldb_entries if entry.get("purl") == package_url]
2567+
purldb_entries = [
2568+
entry
2569+
for entry in purldb_entries
2570+
if get_plain_purl(entry.get("purl", "")) == package_url
2571+
]
25662572

25672573
return purldb_entries
25682574

component_catalog/tests/test_models.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,27 +2558,35 @@ def test_package_model_inferred_url_property(self):
25582558

25592559
@mock.patch("dejacode_toolkit.purldb.PurlDB.find_packages")
25602560
def test_package_model_get_purldb_entries(self, mock_find_packages):
2561-
purl = "pkg:pypi/[email protected]"
2562-
package1 = make_package(self.dataspace, package_url=purl)
2561+
purl1 = "pkg:pypi/[email protected]"
2562+
purl2 = "pkg:pypi/[email protected]?file_name=Django-3.0.tar.gz"
2563+
purl3 = "pkg:pypi/django"
2564+
package1 = make_package(self.dataspace, package_url=purl1)
25632565
purldb_entry1 = {
2564-
"purl": purl,
2566+
"purl": purl1,
25652567
"type": "pypi",
25662568
"name": "django",
25672569
"version": "3.0",
25682570
}
25692571
purldb_entry2 = {
2570-
"purl": "pkg:pypi/django",
2572+
"purl": purl2,
2573+
"type": "pypi",
2574+
"name": "django",
2575+
"version": "3.0",
2576+
}
2577+
purldb_entry3 = {
2578+
"purl": purl3,
25712579
"type": "pypi",
25722580
"name": "django",
25732581
}
25742582

25752583
mock_find_packages.return_value = None
25762584
purldb_entries = package1.get_purldb_entries(user=self.user)
25772585

2578-
mock_find_packages.return_value = [purldb_entry1, purldb_entry2]
2586+
mock_find_packages.return_value = [purldb_entry1, purldb_entry2, purldb_entry3]
25792587
purldb_entries = package1.get_purldb_entries(user=self.user)
25802588
# The purldb_entry2 is excluded as the PURL differs
2581-
self.assertEqual([purldb_entry1], purldb_entries)
2589+
self.assertEqual([purldb_entry1, purldb_entry2], purldb_entries)
25822590

25832591
@mock.patch("component_catalog.models.Package.get_purldb_entries")
25842592
def test_package_model_update_from_purldb(self, mock_get_purldb_entries):

dje/tests/test_utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from dje.utils import get_instance_from_referer
3232
from dje.utils import get_instance_from_resolver
3333
from dje.utils import get_object_compare_diff
34+
from dje.utils import get_plain_purl
3435
from dje.utils import get_referer_resolver
3536
from dje.utils import get_zipfile
3637
from dje.utils import group_by_name_version
@@ -526,6 +527,15 @@ def test_utils_is_purl_fragment(self):
526527
for fragment in invalid_fragments:
527528
self.assertFalse(is_purl_fragment(fragment), msg=fragment)
528529

530+
def test_utils_get_plain_purl(self):
531+
self.assertEqual("", get_plain_purl(""))
532+
self.assertEqual("not:a/purl", get_plain_purl("not:a/purl"))
533+
self.assertEqual("not:a/purl", get_plain_purl("not:a/purl"))
534+
self.assertEqual("pkg:npm/[email protected]", get_plain_purl("pkg:npm/[email protected]"))
535+
self.assertEqual(
536+
"pkg:npm/[email protected]", get_plain_purl("pkg:npm/[email protected]?qualifier=1#frament")
537+
)
538+
529539
def test_utils_localized_datetime(self):
530540
self.assertIsNone(localized_datetime(None))
531541

dje/utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,11 @@ def is_purl_fragment(string):
656656
return any(connector in string for connector in purl_connectors)
657657

658658

659+
def get_plain_purl(purl_str):
660+
"""Remove the qualifiers and subpath from the `purl_str```."""
661+
return purl_str.split("?")[0]
662+
663+
659664
def remove_empty_values(input_dict):
660665
"""
661666
Return a new dict not including empty value entries from `input_dict`.

0 commit comments

Comments
 (0)