@@ -642,7 +642,8 @@ def list(self, request, format=None):
642642 def index_packages (self , request , * args , ** kwargs ):
643643 """
644644 Take a list of `packages` (where each item is a dictionary containing either PURL
645- or versionless PURL along with vers range) and index it.
645+ or versionless PURL along with vers range, optionally with source package PURL)
646+ and index it.
646647
647648 If `reindex` flag is True then existing package will be rescanned, if `reindex_set`
648649 is True then all the package in the same set will be rescanned.
@@ -657,15 +658,18 @@ def index_packages(self, request, *args, **kwargs):
657658 "packages": [
658659 {
659660 "purl": "pkg:npm/[email protected] ", 660- "vers": null
661+ "vers": null,
662+ "source_purl": None
661663 },
662664 {
663665 "purl": "pkg:npm/less",
664- "vers": "vers:npm/>=1.1.0|<=1.1.4"
666+ "vers": "vers:npm/>=1.1.0|<=1.1.4",
667+ "source_purl": None
665668 },
666669 {
667670 "purl": "pkg:npm/foobar",
668- "vers": null
671+ "vers": null,
672+ "source_purl": None
669673 }
670674 ]
671675 "reindex": true,
@@ -703,7 +707,7 @@ def _reindex_package(package, reindexed_packages):
703707 return
704708 package .rescan ()
705709 reindexed_packages .append (package )
706-
710+
707711 serializer = self .serializer_class (data = request .data )
708712
709713 if not serializer .is_valid ():
@@ -721,12 +725,13 @@ def _reindex_package(package, reindexed_packages):
721725 reindexed_packages = []
722726 requeued_packages = []
723727
724- supported_ecosystems = ['maven' , 'npm' ]
728+ supported_ecosystems = ['maven' , 'npm' , 'debian' ]
725729
726- unique_purls , unsupported_packages , unsupported_vers = get_resolved_purls (packages , supported_ecosystems )
730+ unique_packages , unsupported_packages , unsupported_vers = get_resolved_packages (packages , supported_ecosystems )
727731
728732 if reindex :
729- for purl in unique_purls :
733+ for package in unique_packages :
734+ purl = package ['purl' ]
730735 lookups = purl_to_lookups (purl )
731736 packages = Package .objects .filter (** lookups )
732737 if packages .count () > 0 :
@@ -737,12 +742,13 @@ def _reindex_package(package, reindexed_packages):
737742 for p in package_set .packages .all ():
738743 _reindex_package (p , reindexed_packages )
739744 else :
740- nonexistent_packages .append (purl )
745+ nonexistent_packages .append (package )
741746 requeued_packages .extend ([p .package_url for p in reindexed_packages ])
742747
743- elif not reindex or nonexistent_packages :
744- interesting_purls = nonexistent_packages if nonexistent_packages else unique_purls
745- for purl in interesting_purls :
748+ if not reindex or nonexistent_packages :
749+ interesting_packages = nonexistent_packages if nonexistent_packages else unique_packages
750+ for package in interesting_packages :
751+ purl = package ['purl' ]
746752 is_routable_purl = priority_router .is_routable (purl )
747753 if not is_routable_purl :
748754 unsupported_packages .append (purl )
@@ -880,19 +886,19 @@ def list(self, request):
880886 return Response (serializer .data )
881887
882888
883- def get_resolved_purls (packages , supported_ecosystems ):
889+ def get_resolved_packages (packages , supported_ecosystems ):
884890 """
885891 Take a list of dict containing purl or version-less purl along with vers
886- and return a list of resolved purls, a list of unsupported purls, and a
887- list of unsupported vers.
892+ and return a list of package dicsts containing resolved purls, a list of
893+ unsupported purls, and a list of unsupported vers.
888894 """
889- unique_resolved_purls = set ()
895+ resolved_packages_by_purl = {}
890896 unsupported_purls = set ()
891897 unsupported_vers = set ()
892898
893- for items in packages or []:
894- purl = items .get ('purl' )
895- vers = items .get ('vers' )
899+ for package in packages or []:
900+ purl = package .get ('purl' )
901+ vers = package .get ('vers' )
896902
897903 if not purl :
898904 continue
@@ -908,21 +914,26 @@ def get_resolved_purls(packages, supported_ecosystems):
908914 continue
909915
910916 if parsed_purl .version :
911- unique_resolved_purls . add ( purl )
917+ resolved_packages_by_purl [ purl ] = package
912918 continue
913919
914920 # Versionless PURL without any vers-range should give all versions.
915921 if not vers and not parsed_purl .version :
916- if resolved := resolve_all_versions (parsed_purl ):
917- unique_resolved_purls .update (resolved )
922+ if resolved_purls := resolve_all_versions (parsed_purl ):
923+ for res_purl in resolved_purls :
924+ resolved_packages_by_purl [res_purl ] = {'purl' : res_purl }
918925 continue
919926
920- if resolved := resolve_versions (parsed_purl , vers ):
921- unique_resolved_purls .update (resolved )
927+ if resolved_purls := resolve_versions (parsed_purl , vers ):
928+ for res_purl in resolved_purls :
929+ resolved_packages_by_purl [res_purl ] = {'purl' : res_purl }
922930 else :
923931 unsupported_vers .add (vers )
932+
933+ unique_resolved_packages = resolved_packages_by_purl .values ()
934+
935+ return list (unique_resolved_packages ), list (unsupported_purls ), list (unsupported_vers )
924936
925- return list (unique_resolved_purls ), list (unsupported_purls ), list (unsupported_vers )
926937
927938def resolve_all_versions (parsed_purl ):
928939 """
@@ -942,6 +953,7 @@ def resolve_all_versions(parsed_purl):
942953 for version in all_versions
943954 ]
944955
956+
945957def resolve_versions (parsed_purl , vers ):
946958 """
947959 Take version-less purl along with vers range and return
@@ -977,6 +989,7 @@ def resolve_versions(parsed_purl, vers):
977989
978990 return result
979991
992+
980993def get_all_versions_plain (purl : PackageURL ):
981994 """
982995 Return all the versions available for the given purls.
@@ -996,6 +1009,7 @@ def get_all_versions_plain(purl: PackageURL):
9961009 all_versions = versionAPI ().fetch (package_name ) or []
9971010 return [ version .value for version in all_versions ]
9981011
1012+
9991013def get_all_versions (purl ):
10001014 """
10011015 Return all the versions available for the given purls as
0 commit comments