From 955a3ba9a080a869c4d431cbe18b5637672885a5 Mon Sep 17 00:00:00 2001 From: AbanoubAziz Date: Sat, 22 Mar 2025 18:07:45 +0200 Subject: [PATCH 1/5] feat: Adding ancestors method to the CodebaseResource Model with testing Signed-off-by: AbanoubAziz Signed-off-by: abanoubfarhan --- scanpipe/models.py | 19 +++++++++++++++++++ scanpipe/tests/test_models.py | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/scanpipe/models.py b/scanpipe/models.py index 49914b406..b079828bf 100644 --- a/scanpipe/models.py +++ b/scanpipe/models.py @@ -27,6 +27,7 @@ import shutil import uuid from collections import Counter +from collections import deque from collections import defaultdict from contextlib import suppress from itertools import groupby @@ -2875,6 +2876,24 @@ def descendants(self): """ return self.project.codebaseresources.filter(path__startswith=f"{self.path}/") + def ancestors(self): + """ + Return a QuerySet of ancestors CodebaseResource objects using a database query + on the current CodebaseResource `path`. The current CodebaseResource is not included + """ + + if not self.has_parent(): + return [] + anscesotrs = deque() + current = self.parent() + anscesotrs_appendleft = anscesotrs.appendleft + + while current: + anscesotrs_appendleft(current) + current = current.parent() + + return list(anscesotrs) + def children(self, codebase=None): """ Return a QuerySet of direct children CodebaseResource objects using a diff --git a/scanpipe/tests/test_models.py b/scanpipe/tests/test_models.py index a7adcd5fd..87b0101cf 100644 --- a/scanpipe/tests/test_models.py +++ b/scanpipe/tests/test_models.py @@ -1905,6 +1905,18 @@ def test_scanpipe_codebase_resource_descendants(self): "asgiref-3.3.0-py3-none-any.whl-extract/asgiref/wsgi.py", ] self.assertEqual(expected, sorted([resource.path for resource in descendants])) + + def test_scanpipe_codebase_resource_ancestors(self): + path = "asgiref-3.3.0-py3-none-any.whl-extract/asgiref/__init__.py" + resource = self.project_asgiref.codebaseresources.get(path=path) + ancestors = list(resource.ancestors()) + self.assertEqual(2, len(ancestors)) + self.assertNotIn(resource.path, ancestors) + expected = [ + "asgiref-3.3.0-py3-none-any.whl-extract", + "asgiref-3.3.0-py3-none-any.whl-extract/asgiref", + ] + self.assertEqual(expected, [resource.path for resource in ancestors]) def test_scanpipe_codebase_resource_children(self): path = "asgiref-3.3.0-py3-none-any.whl-extract" From 471f7a634fe2d60d1230b73c0b9314d70ed6f0b9 Mon Sep 17 00:00:00 2001 From: AbanoubAziz Date: Sat, 22 Mar 2025 18:16:37 +0200 Subject: [PATCH 2/5] fix: validating the code using ruff Signed-off-by: AbanoubAziz Signed-off-by: abanoubfarhan --- scanpipe/models.py | 34 +++++++++++++++++----------------- scanpipe/tests/test_models.py | 22 +++++++++++----------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/scanpipe/models.py b/scanpipe/models.py index b079828bf..7ad2b45bd 100644 --- a/scanpipe/models.py +++ b/scanpipe/models.py @@ -27,8 +27,8 @@ import shutil import uuid from collections import Counter -from collections import deque from collections import defaultdict +from collections import deque from contextlib import suppress from itertools import groupby from operator import itemgetter @@ -2876,22 +2876,22 @@ def descendants(self): """ return self.project.codebaseresources.filter(path__startswith=f"{self.path}/") - def ancestors(self): - """ - Return a QuerySet of ancestors CodebaseResource objects using a database query - on the current CodebaseResource `path`. The current CodebaseResource is not included - """ - - if not self.has_parent(): - return [] - anscesotrs = deque() - current = self.parent() - anscesotrs_appendleft = anscesotrs.appendleft - - while current: - anscesotrs_appendleft(current) - current = current.parent() - + def ancestors(self): + """ + Return a QuerySet of ancestors CodebaseResource objects using a database query + on the current CodebaseResource `path`. The current CodebaseResource is not + included + """ + if not self.has_parent(): + return [] + anscesotrs = deque() + current = self.parent() + anscesotrs_appendleft = anscesotrs.appendleft + + while current: + anscesotrs_appendleft(current) + current = current.parent() + return list(anscesotrs) def children(self, codebase=None): diff --git a/scanpipe/tests/test_models.py b/scanpipe/tests/test_models.py index 87b0101cf..6c0ff73f1 100644 --- a/scanpipe/tests/test_models.py +++ b/scanpipe/tests/test_models.py @@ -1905,17 +1905,17 @@ def test_scanpipe_codebase_resource_descendants(self): "asgiref-3.3.0-py3-none-any.whl-extract/asgiref/wsgi.py", ] self.assertEqual(expected, sorted([resource.path for resource in descendants])) - - def test_scanpipe_codebase_resource_ancestors(self): - path = "asgiref-3.3.0-py3-none-any.whl-extract/asgiref/__init__.py" - resource = self.project_asgiref.codebaseresources.get(path=path) - ancestors = list(resource.ancestors()) - self.assertEqual(2, len(ancestors)) - self.assertNotIn(resource.path, ancestors) - expected = [ - "asgiref-3.3.0-py3-none-any.whl-extract", - "asgiref-3.3.0-py3-none-any.whl-extract/asgiref", - ] + + def test_scanpipe_codebase_resource_ancestors(self): + path = "asgiref-3.3.0-py3-none-any.whl-extract/asgiref/__init__.py" + resource = self.project_asgiref.codebaseresources.get(path=path) + ancestors = list(resource.ancestors()) + self.assertEqual(2, len(ancestors)) + self.assertNotIn(resource.path, ancestors) + expected = [ + "asgiref-3.3.0-py3-none-any.whl-extract", + "asgiref-3.3.0-py3-none-any.whl-extract/asgiref", + ] self.assertEqual(expected, [resource.path for resource in ancestors]) def test_scanpipe_codebase_resource_children(self): From fc85c21ed2f5d83c94e3a193b417030fa2d63a1f Mon Sep 17 00:00:00 2001 From: abanoubfarhan Date: Mon, 24 Mar 2025 20:18:52 +0200 Subject: [PATCH 3/5] feat: Added serialize method to CodebaseResource class Signed-off-by: abanoubfarhan --- scanpipe/models.py | 14 +++++++++++++- scanpipe/tests/test_models.py | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/scanpipe/models.py b/scanpipe/models.py index 7ad2b45bd..4b54d94a2 100644 --- a/scanpipe/models.py +++ b/scanpipe/models.py @@ -2855,7 +2855,7 @@ def parent(self, codebase=None): """ parent_path = self.parent_path() return parent_path and self.project.codebaseresources.get(path=parent_path) - + def siblings(self, codebase=None): """ Return a sequence of sibling Resource objects for this Resource @@ -3078,6 +3078,18 @@ def as_spdx(self): types=self.get_spdx_types(), ) + def serialize(self): + """ + Return a mapping of represting this CodebaseResource and it's data in a form + that can be serialized to JSON, YAML, etc. it can be used to reconstruct + the resource + """ + serializable = defaultdict(dict) + serializable["name"] = self.name + serializable["type"] = self.type.value + if self.location: + serializable["location"] = self.location + return dict(serializable) class CodebaseRelation( UUIDPKModel, diff --git a/scanpipe/tests/test_models.py b/scanpipe/tests/test_models.py index 6c0ff73f1..5a7c31663 100644 --- a/scanpipe/tests/test_models.py +++ b/scanpipe/tests/test_models.py @@ -1917,6 +1917,24 @@ def test_scanpipe_codebase_resource_ancestors(self): "asgiref-3.3.0-py3-none-any.whl-extract/asgiref", ] self.assertEqual(expected, [resource.path for resource in ancestors]) + + def test_scanpipe_codebase_resource_serialize(self): + resource1 = make_resource_file(self.project1, path="pathtoresource/resource1") + expected = { + "location": resource1.location, + "type": "file", + "name": "resource1", + } + self.assertEqual(expected, resource1.serialize()) + + resource2 = make_resource_directory(self.project1, path="pathtodir/resource2") + expected = { + "location": resource2.location, + "type": "directory", + "name": "resource2", + } + self.assertEqual(expected, resource2.serialize()) + def test_scanpipe_codebase_resource_children(self): path = "asgiref-3.3.0-py3-none-any.whl-extract" From 40f240142560fea924ff0488fad5a7754625c6a9 Mon Sep 17 00:00:00 2001 From: abanoubfarhan Date: Mon, 24 Mar 2025 20:33:34 +0200 Subject: [PATCH 4/5] fix: validating the code using ruff Signed-off-by: abanoubfarhan --- scanpipe/models.py | 5 +++-- scanpipe/tests/test_models.py | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scanpipe/models.py b/scanpipe/models.py index 4b54d94a2..4a105b6ee 100644 --- a/scanpipe/models.py +++ b/scanpipe/models.py @@ -2855,7 +2855,7 @@ def parent(self, codebase=None): """ parent_path = self.parent_path() return parent_path and self.project.codebaseresources.get(path=parent_path) - + def siblings(self, codebase=None): """ Return a sequence of sibling Resource objects for this Resource @@ -3081,7 +3081,7 @@ def as_spdx(self): def serialize(self): """ Return a mapping of represting this CodebaseResource and it's data in a form - that can be serialized to JSON, YAML, etc. it can be used to reconstruct + that can be serialized to JSON, YAML, etc. it can be used to reconstruct the resource """ serializable = defaultdict(dict) @@ -3091,6 +3091,7 @@ def serialize(self): serializable["location"] = self.location return dict(serializable) + class CodebaseRelation( UUIDPKModel, ProjectRelatedModel, diff --git a/scanpipe/tests/test_models.py b/scanpipe/tests/test_models.py index 5a7c31663..d2e3e70d8 100644 --- a/scanpipe/tests/test_models.py +++ b/scanpipe/tests/test_models.py @@ -1917,7 +1917,7 @@ def test_scanpipe_codebase_resource_ancestors(self): "asgiref-3.3.0-py3-none-any.whl-extract/asgiref", ] self.assertEqual(expected, [resource.path for resource in ancestors]) - + def test_scanpipe_codebase_resource_serialize(self): resource1 = make_resource_file(self.project1, path="pathtoresource/resource1") expected = { @@ -1935,7 +1935,6 @@ def test_scanpipe_codebase_resource_serialize(self): } self.assertEqual(expected, resource2.serialize()) - def test_scanpipe_codebase_resource_children(self): path = "asgiref-3.3.0-py3-none-any.whl-extract" resource = self.project_asgiref.codebaseresources.get(path=path) From 9e1148c09ca78de55fc7da6fa7df9419ab043913 Mon Sep 17 00:00:00 2001 From: Abanoub Aziz Date: Sat, 26 Apr 2025 02:29:52 +0300 Subject: [PATCH 5/5] fix: small typo and removed unnessary function of serializing Signed-off-by: Abanoub Aziz --- scanpipe/models.py | 21 ++++----------------- scanpipe/tests/test_models.py | 17 ----------------- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/scanpipe/models.py b/scanpipe/models.py index 4a105b6ee..eb9b40213 100644 --- a/scanpipe/models.py +++ b/scanpipe/models.py @@ -2884,15 +2884,15 @@ def ancestors(self): """ if not self.has_parent(): return [] - anscesotrs = deque() + ancestors = deque() current = self.parent() - anscesotrs_appendleft = anscesotrs.appendleft + ancestors_appendleft = ancestors.appendleft while current: - anscesotrs_appendleft(current) + ancestors_appendleft(current) current = current.parent() - return list(anscesotrs) + return list(ancestors) def children(self, codebase=None): """ @@ -3078,19 +3078,6 @@ def as_spdx(self): types=self.get_spdx_types(), ) - def serialize(self): - """ - Return a mapping of represting this CodebaseResource and it's data in a form - that can be serialized to JSON, YAML, etc. it can be used to reconstruct - the resource - """ - serializable = defaultdict(dict) - serializable["name"] = self.name - serializable["type"] = self.type.value - if self.location: - serializable["location"] = self.location - return dict(serializable) - class CodebaseRelation( UUIDPKModel, diff --git a/scanpipe/tests/test_models.py b/scanpipe/tests/test_models.py index d2e3e70d8..6c0ff73f1 100644 --- a/scanpipe/tests/test_models.py +++ b/scanpipe/tests/test_models.py @@ -1918,23 +1918,6 @@ def test_scanpipe_codebase_resource_ancestors(self): ] self.assertEqual(expected, [resource.path for resource in ancestors]) - def test_scanpipe_codebase_resource_serialize(self): - resource1 = make_resource_file(self.project1, path="pathtoresource/resource1") - expected = { - "location": resource1.location, - "type": "file", - "name": "resource1", - } - self.assertEqual(expected, resource1.serialize()) - - resource2 = make_resource_directory(self.project1, path="pathtodir/resource2") - expected = { - "location": resource2.location, - "type": "directory", - "name": "resource2", - } - self.assertEqual(expected, resource2.serialize()) - def test_scanpipe_codebase_resource_children(self): path = "asgiref-3.3.0-py3-none-any.whl-extract" resource = self.project_asgiref.codebaseresources.get(path=path)