1010
1111from django .contrib .contenttypes .models import ContentType
1212from django .contrib .humanize .templatetags .humanize import intcomma
13- from django .core .management .base import CommandError
1413from django .urls import reverse
1514from django .utils import timezone
1615
@@ -188,24 +187,11 @@ def process_vc_entry(
188187 verbosity = 1 ,
189188):
190189 """
191- Process a single VulnerableCode purl entry: find the matching packages in ``queryset``,
192- create or update each linked vulnerability , and apply the API-provided risk score.
190+ Process a single VulnerableCode purl entry: find matching packages, create or update
191+ linked vulnerabilities , and apply the API-provided risk score.
193192
194- ``vulnerability_cache`` is a dict mapping advisory_uid to Vulnerability instances,
195- pre-fetched by the caller in a single batch query. Newly created vulnerabilities are
196- added to the cache so subsequent entries in the same batch reuse them without a DB hit.
197-
198- M2M links between packages and vulnerabilities are created in batch via
199- ``batch_add_affected`` (1 SELECT + 1 bulk INSERT) instead of one ``get_or_create``
200- per pair.
201-
202- Risk score is applied in a single UPDATE query, bypassing ``Package.save()`` and the
203- ``handle_assigned_licenses`` overhead it carries. The API-provided purl-level
204- ``risk_score`` is used directly when present; otherwise the MAX of the linked
205- vulnerability risk scores is computed in the same query.
206-
207- Returns the affected packages as a list (already evaluated), or an empty list if the
208- entry has no vulnerabilities. The ``results`` dict is updated in-place.
193+ Returns the affected packages as a list, or an empty list if the entry has no
194+ vulnerabilities. The ``results`` dict is updated in-place.
209195 """
210196 affected_by_vulnerabilities = vc_entry .get ("affected_by_vulnerabilities" )
211197 if not affected_by_vulnerabilities :
@@ -222,7 +208,9 @@ def process_vc_entry(
222208 )
223209 affected_packages = list (packages_qs )
224210 if not affected_packages :
225- raise CommandError ("Could not find packages!" )
211+ if log_func :
212+ log_func (f" Warning: no packages found for { purl } , skipping." )
213+ return []
226214
227215 if log_func and verbosity >= 2 :
228216 advisory_count = len (affected_by_vulnerabilities )
@@ -237,8 +225,8 @@ def process_vc_entry(
237225 dataspace ,
238226 update ,
239227 results ,
228+ created_advisory_uids ,
240229 vulnerability = vulnerability_cache .get (advisory_uid ),
241- created_advisory_uids = created_advisory_uids ,
242230 )
243231 vulnerability_cache [advisory_uid ] = vulnerability
244232 vulnerabilities .append (vulnerability )
@@ -254,29 +242,18 @@ def process_vc_entry(
254242
255243
256244def create_or_update_vulnerability (
257- vulnerability_data , dataspace , update , results , vulnerability = None , created_advisory_uids = None
245+ vulnerability_data , dataspace , update , results , created_advisory_uids , vulnerability = None
258246):
259- """
260- Create or update a Vulnerability from ``vulnerability_data``.
261-
262- ``vulnerability`` is the already-resolved instance (looked up from the caller's
263- ``vulnerability_cache``), or ``None`` if not yet created. M2M linking is handled
264- by the caller via ``batch_add_affected``.
265-
266- ``created_advisory_uids`` is a run-wide set of advisory_uids created during this fetch.
267- Vulnerabilities in this set are skipped for updates to avoid spurious re-updates when the
268- same advisory appears in multiple packages across different batches.
269- """
247+ """Create or update a Vulnerability from ``vulnerability_data``."""
270248 advisory_uid = vulnerability_data ["advisory_uid" ]
271249 if not vulnerability :
272250 vulnerability = Vulnerability .create_from_data (
273251 dataspace = dataspace ,
274252 data = vulnerability_data ,
275253 )
276254 results ["created" ] += 1
277- if created_advisory_uids is not None :
278- created_advisory_uids .add (advisory_uid )
279- elif update and advisory_uid not in (created_advisory_uids or ()):
255+ created_advisory_uids .add (advisory_uid )
256+ elif update and advisory_uid not in created_advisory_uids :
280257 updated_fields = vulnerability .update_from_data (
281258 user = None ,
282259 data = vulnerability_data ,
0 commit comments