Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions scanpipe/pipes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from itertools import islice
from pathlib import Path

from django.db import IntegrityError
from django.db.models import Count

from scanpipe.models import AbstractTaskFieldsModel
Expand Down Expand Up @@ -139,12 +140,17 @@ def collect_and_create_codebase_resources(project, batch_size=5000):
"""
model_class = CodebaseResource
objs = yield_resources_from_codebase(project)

while True:
batch = list(islice(objs, batch_size))
if not batch:
break
model_class.objects.bulk_create(batch, batch_size)
try:
while True:
batch = list(islice(objs, batch_size))
if not batch:
break
model_class.objects.bulk_create(batch, batch_size)
except IntegrityError as e:
raise IntegrityError(
"Codebase resources already exist for this project. "
"Reset the project before re-running."
) from e


def update_or_create_resource(project, resource_data):
Expand Down
18 changes: 18 additions & 0 deletions scanpipe/tests/pipes/test_pipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pathlib import Path
from unittest import mock

from django.db import IntegrityError
from django.test import TestCase
from django.test import TransactionTestCase

Expand Down Expand Up @@ -448,3 +449,20 @@ def test_scanpipe_pipes_collect_and_create_codebase_resources(self):
self.assertEqual("from", from_resource.tag)
to_resource = p1.codebaseresources.get(path="to/a.txt")
self.assertEqual("to", to_resource.tag)

def test_scanpipe_pipes_collect_and_create_codebase_resources_duplicate_run(self):
p1 = Project.objects.create(name="Analysis")
input_location = self.data / "codebase" / "a.txt"
to_dir = p1.codebase_path / "to"
to_dir.mkdir()
from_dir = p1.codebase_path / "from"
from_dir.mkdir()
copy_input(input_location, to_dir)
copy_input(input_location, from_dir)

pipes.collect_and_create_codebase_resources(p1)
self.assertEqual(4, p1.codebaseresources.count())

with self.assertRaises(IntegrityError) as ctx:
pipes.collect_and_create_codebase_resources(p1)
self.assertIn("Reset", str(ctx.exception))