Skip to content

Commit

Permalink
Provide feedback on the "Improve" action through the import system #45
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <tdruez@nexb.com>
  • Loading branch information
tdruez committed Sep 2, 2024
1 parent 8f02c13 commit 578d706
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 14 deletions.
2 changes: 1 addition & 1 deletion component_catalog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2529,7 +2529,7 @@ def update_from_purldb(self, user):
when available.
"""
purldb_entries = self.get_purldb_entries(user)
if not purldb_entries or len(purldb_entries) != 1:
if not purldb_entries:
return

package_data = purldb_entries[0]
Expand Down
28 changes: 24 additions & 4 deletions dje/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ def improve_packages_from_purldb(product_uuid, user_uuid):
DejacodeUser = apps.get_model("dje", "DejacodeUser")
History = apps.get_model("dje", "History")
Product = apps.get_model("product_portfolio", "product")
ScanCodeProject = apps.get_model("product_portfolio", "scancodeproject")

try:
user = DejacodeUser.objects.get(uuid=user_uuid)
Expand All @@ -262,16 +263,35 @@ def improve_packages_from_purldb(product_uuid, user_uuid):
logger.error("[improve_packages_from_purldb]: Permission denied.")
return

updated_packages = product.improve_packages_from_purldb(user)
logger.info(f"[improve_packages_from_purldb]: {len(updated_packages)} updated from PurlDB.")
scancode_project = ScanCodeProject.objects.create(
product=product,
dataspace=product.dataspace,
type=ScanCodeProject.ProjectType.IMPROVE_FROM_PURLDB,
status=ScanCodeProject.Status.IMPORT_STARTED,
created_by=user,
)

try:
updated_packages = product.improve_packages_from_purldb(user)
except Exception as e:
scancode_project.update(
status=ScanCodeProject.Status.FAILURE,
import_log=str(e),
)

verb = "Improved packages from PurlDB"
logger.info(f"[improve_packages_from_purldb]: {len(updated_packages)} updated from PurlDB.")
verb = "Improved packages from PurlDB:"
if updated_packages:
description = ", ".join([str(package) for package in updated_packages])
History.log_change(user, product, message=f"{verb}: {description}")
History.log_change(user, product, message=f"{verb} {description}")
else:
description = "No packages updated from PurlDB data."

scancode_project.update(
status=ScanCodeProject.Status.SUCCESS,
import_log=[verb, description],
)

notify.send(
sender=user,
verb=verb,
Expand Down
18 changes: 18 additions & 0 deletions product_portfolio/migrations/0007_alter_scancodeproject_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2024-09-02 15:24

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('product_portfolio', '0006_productdependency'),
]

operations = [
migrations.AlterField(
model_name='scancodeproject',
name='type',
field=models.CharField(choices=[('IMPORT_FROM_MANIFEST', 'Import from Manifest'), ('LOAD_SBOMS', 'Load SBOMs'), ('PULL_FROM_SCANCODEIO', 'Pull from ScanCode.io'), ('IMPROVE_FROM_PURLDB', 'Improve from PurlDB')], db_index=True, help_text='The type of import, for the ProjectType choices.', max_length=50),
),
]
12 changes: 12 additions & 0 deletions product_portfolio/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1216,13 +1216,23 @@ def generate_input_file_path(instance, filename):
return f"{dataspace}/scancode_project/{instance.uuid}/{filename}"


class ScanCodeProjectQuerySet(ProductSecuredQuerySet):
def in_progress(self):
in_progress_statuses = [
ScanCodeProject.Status.SUBMITTED,
ScanCodeProject.Status.IMPORT_STARTED,
]
return self.filter(status__in=in_progress_statuses)


class ScanCodeProject(HistoryFieldsMixin, DataspacedModel):
"""Wrap a ScanCode.io Project."""

class ProjectType(models.TextChoices):
IMPORT_FROM_MANIFEST = "IMPORT_FROM_MANIFEST", _("Import from Manifest")
LOAD_SBOMS = "LOAD_SBOMS", _("Load SBOMs")
PULL_FROM_SCANCODEIO = "PULL_FROM_SCANCODEIO", _("Pull from ScanCode.io")
IMPROVE_FROM_PURLDB = "IMPROVE_FROM_PURLDB", _("Improve from PurlDB")

class Status(models.TextChoices):
SUBMITTED = "submitted"
Expand Down Expand Up @@ -1278,6 +1288,8 @@ class Status(models.TextChoices):
default=dict,
)

objects = DataspacedManager.from_queryset(ScanCodeProjectQuerySet)()

class Meta:
unique_together = ("dataspace", "uuid")
ordering = ["-created_date"]
Expand Down
20 changes: 18 additions & 2 deletions product_portfolio/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def test_product_portfolio_detail_view_tab_inventory_and_hierarchy_availability(
ProductComponent.objects.create(
product=self.product1, component=self.component1, dataspace=self.dataspace
)
with self.assertNumQueries(29):
with self.assertNumQueries(30):
response = self.client.get(url)
self.assertContains(response, expected1)
self.assertContains(response, expected2)
Expand All @@ -161,7 +161,7 @@ def test_product_portfolio_detail_view_tab_inventory_availability(self):
ProductPackage.objects.create(
product=self.product1, package=self.package1, dataspace=self.dataspace
)
with self.assertNumQueries(26):
with self.assertNumQueries(27):
response = self.client.get(url)
self.assertContains(response, expected)

Expand Down Expand Up @@ -3142,6 +3142,16 @@ def test_product_portfolio_improve_packages_from_purldb_view(self, mock_is_confi
self.assertEqual(200, response.status_code)
self.assertContains(response, "Improve Packages from PurlDB in progress...")

ScanCodeProject.objects.create(
product=self.product1,
dataspace=self.product1.dataspace,
type=ScanCodeProject.ProjectType.IMPROVE_FROM_PURLDB,
status=ScanCodeProject.Status.IMPORT_STARTED,
)
response = self.client.get(url, follow=True)
self.assertEqual(200, response.status_code)
self.assertContains(response, "Improve Packages already in progress...")

@mock.patch("product_portfolio.models.Product.improve_packages_from_purldb")
def test_product_portfolio_improve_packages_from_purldb_task(self, mock_improve):
mock_improve.return_value = ["pkg1", "pkg2"]
Expand Down Expand Up @@ -3176,3 +3186,9 @@ def test_product_portfolio_improve_packages_from_purldb_task(self, mock_improve)
"INFO:dje.tasks:[improve_packages_from_purldb]: 2 updated from PurlDB.",
]
self.assertEqual(expected, cm.output)

import_project = self.product1.scancodeprojects.get()
self.assertEqual(import_project.type, ScanCodeProject.ProjectType.IMPROVE_FROM_PURLDB)
self.assertEqual(import_project.status, ScanCodeProject.Status.SUCCESS)
expected = ["Improved packages from PurlDB:", "pkg1, pkg2"]
self.assertEqual(expected, import_project.import_log)
21 changes: 14 additions & 7 deletions product_portfolio/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2401,11 +2401,18 @@ def improve_packages_from_purldb_view(request, dataspace, name, version=""):
if not product.packages.count():
raise Http404("No packages available for this product.")

transaction.on_commit(
lambda: tasks.improve_packages_from_purldb(
product_uuid=product.uuid,
user_uuid=user.uuid,
)
improve_in_progress = product.scancodeprojects.in_progress().filter(
type=ScanCodeProject.ProjectType.IMPROVE_FROM_PURLDB,
)
messages.success(request, "Improve Packages from PurlDB in progress...")
return redirect(f"{product.get_absolute_url()}#history")

if improve_in_progress.exists():
messages.error(request, "Improve Packages already in progress...")
else:
transaction.on_commit(
lambda: tasks.improve_packages_from_purldb(
product_uuid=product.uuid,
user_uuid=user.uuid,
)
)
messages.success(request, "Improve Packages from PurlDB in progress...")
return redirect(f"{product.get_absolute_url()}#imports")

0 comments on commit 578d706

Please sign in to comment.