Skip to content

Commit 79f9cd3

Browse files
authored
Merge pull request #1868 from aboutcode-org/optimize-export
Optimize export management command
2 parents 584b077 + 2ff0b11 commit 79f9cd3

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

vulnerabilities/management/commands/export.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9+
import itertools
910
import logging
1011
from itertools import groupby
1112
from pathlib import Path
13+
from timeit import default_timer as timer
14+
from traceback import format_exc as traceback_format_exc
1215

1316
import saneyaml
17+
from aboutcode.pipeline import LoopProgress
18+
from aboutcode.pipeline import humanize_time
1419
from django.core.management.base import BaseCommand
1520
from django.core.management.base import CommandError
1621
from packageurl import PackageURL
@@ -26,7 +31,7 @@ def serialize_severity(sev):
2631
"score": sev.value,
2732
"scoring_system": sev.scoring_system,
2833
"scoring_elements": sev.scoring_elements,
29-
"published_at": sev.published_at,
34+
"published_at": str(sev.published_at),
3035
"url": sev.url,
3136
}
3237

@@ -88,8 +93,22 @@ def export_data(self, base_path: Path):
8893
"""
8994
i = 0
9095
seen_vcid = set()
96+
export_start_time = timer()
9197

92-
for i, (purl_without_version, package_versions) in enumerate(packages_by_type_ns_name(), 1):
98+
distinct_packages_count = (
99+
Package.objects.values("type", "namespace", "name")
100+
.distinct("type", "namespace", "name")
101+
.count()
102+
)
103+
104+
progress = LoopProgress(
105+
total_iterations=distinct_packages_count,
106+
progress_step=1,
107+
logger=self.stdout.write,
108+
)
109+
for i, (purl_without_version, package_versions) in enumerate(
110+
progress.iter(packages_by_type_ns_name()), 1
111+
):
93112
pkg_version = None
94113
try:
95114
package_urls = []
@@ -108,7 +127,11 @@ def export_data(self, base_path: Path):
108127
}
109128
package_vulnerabilities.append(package_data)
110129

111-
for vuln in pkg_version.vulnerabilities:
130+
vulnerabilities = itertools.chain(
131+
pkg_version.affected_by_vulnerabilities.all(),
132+
pkg_version.fixing_vulnerabilities.all(),
133+
)
134+
for vuln in vulnerabilities:
112135
vcid = vuln.vulnerability_id
113136
# do not write twice the same file
114137
if vcid in seen_vcid:
@@ -131,9 +154,15 @@ def export_data(self, base_path: Path):
131154
self.stdout.write(f"Processed {i} package. Last PURL: {purl_without_version}")
132155

133156
except Exception as e:
134-
raise Exception(f"Failed to process Package: {pkg_version}") from e
157+
self.stdout.write(
158+
self.style.ERROR(
159+
f"Failed to process Package {pkg_version}: {e!r} \n {traceback_format_exc()}"
160+
)
161+
)
135162

136163
self.stdout.write(f"Exported data for: {i} package and {len(seen_vcid)} vulnerabilities.")
164+
export_run_time = timer() - export_start_time
165+
self.stdout.write(f"Export completed in {humanize_time(export_run_time)}")
137166

138167

139168
def by_purl_type_ns_name(package):
@@ -159,7 +188,7 @@ def packages_by_type_ns_name():
159188
"fixing_vulnerabilities__weaknesses",
160189
"fixing_vulnerabilities__severities",
161190
)
162-
.paginated()
191+
.iterator()
163192
)
164193

165194
for tp_ns_name, packages in groupby(qs, key=by_purl_type_ns_name):

vulnerabilities/models.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -994,10 +994,6 @@ def next_non_vulnerable_version(self):
994994
next_non_vulnerable, _ = self.get_non_vulnerable_versions()
995995
return next_non_vulnerable.version if next_non_vulnerable else None
996996

997-
@property
998-
def vulnerabilities(self):
999-
return self.affected_by_vulnerabilities.all() | self.fixing_vulnerabilities.all()
1000-
1001997
@property
1002998
def latest_non_vulnerable_version(self):
1003999
"""

vulnerabilities/tests/test_data/export_command/aboutcode-vulnerabilities/ps/VCID-pst6-b358-aaap.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ severities:
66
- score: '7.0'
77
scoring_system: cvssv3_vector
88
scoring_elements: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
9-
published_at:
9+
published_at: None
1010
url: https://..
1111
weaknesses:
1212
- CWE-15

vulnerabilities/tests/test_models.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,7 @@ def test_affecting_vulnerabilities_vulnerabilityqueryset_method(self):
428428
searched_for_package = self.package_pypi_redis_4_1_1
429429

430430
# Return a queryset of Vulnerabilities that affect this Package.
431-
this_package_vulnerabilities = (
432-
searched_for_package.vulnerabilities.affecting_vulnerabilities()
433-
)
431+
this_package_vulnerabilities = searched_for_package.affected_by
434432

435433
assert this_package_vulnerabilities[0] == self.vuln_VCID_g2fu_45jw_aaan
436434
assert this_package_vulnerabilities[1] == self.vuln_VCID_rqe1_dkmg_aaad

0 commit comments

Comments
 (0)