Skip to content

Commit 6ece1ad

Browse files
authored
Create walk method for CodebaseResource and ProjectCodebase (#123)
* Create walk method for CodebaseResource * The walk method has been added to CodebaseResource to mimic the walk method on commoncode.resource.Resource class * The walk method implements the `topdown` argument, which allows us to walk a codebase from the top when topdown is True or from the bottom when topdown is False * The walk method has also been added to ProjectCodebase and is reflective of `commoncode.resource.Codebase.walk()` behavior. * Create tests for new walk functions Signed-off-by: Jono Yang <jyang@nexb.com> * Sort paths in CodebaseResource.children() Signed-off-by: Jono Yang <jyang@nexb.com> * Update code formatting Signed-off-by: Jono Yang <jyang@nexb.com> * Use .iterator() when calling self.children() Signed-off-by: Jono Yang <jyang@nexb.com> * Update test expectation Signed-off-by: Jono Yang <jyang@nexb.com> * Save expected path results in tests * We do not want to compare the walk results of the CodebaseResource against the walk results of the VirtualCodebase. We do not need to exactly mimic the behavior of VirtualCodebase.walk() Signed-off-by: Jono Yang <jyang@nexb.com> * Test walk method in it own class * Shorten path strings for asgiref-3.3.0 and create a new fixture for it * These modifications were done to respect the line limit checks Signed-off-by: Jono Yang <jyang@nexb.com>
1 parent 736ef5c commit 6ece1ad

File tree

5 files changed

+1042
-8
lines changed

5 files changed

+1042
-8
lines changed

scanpipe/models.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from django.db.models import Q
3636
from django.db.models import TextField
3737
from django.db.models.functions import Cast
38+
from django.db.models.functions import Lower
3839
from django.forms import model_to_dict
3940
from django.urls import reverse
4041
from django.utils import timezone
@@ -1160,12 +1161,35 @@ def children(self, codebase=None):
11601161
Return a QuerySet of direct children CodebaseResource objects using a
11611162
Database query on this CodebaseResource `path`.
11621163
1164+
Paths are returned in lower-cased sorted path order to reflect the
1165+
behavior of `commoncode.resource.Resource.children()`
1166+
https://github.com/nexB/commoncode/blob/76a03d9c1cd2a582dcec4351c768c3ef646e1b31/src/commoncode/resource.py#L1199
1167+
11631168
`codebase` is not used in this context but required for compatibility
11641169
with the commoncode.resource.VirtualCodebase class API.
11651170
"""
11661171
exactly_one_sub_directory = "[^/]+$"
11671172
children_regex = rf"^{self.path}/{exactly_one_sub_directory}"
1168-
return self.descendants().filter(path__regex=children_regex)
1173+
return (
1174+
self.descendants()
1175+
.filter(path__regex=children_regex)
1176+
.order_by(Lower("path"))
1177+
)
1178+
1179+
def walk(self, topdown=True):
1180+
"""
1181+
Yield all descendant Resources of this Resource. Does not include self.
1182+
1183+
Walk the tree top-down, depth-first if `topdown` is True, otherwise walk
1184+
bottom-up.
1185+
"""
1186+
for child in self.children().iterator():
1187+
if topdown:
1188+
yield child
1189+
for subchild in child.walk(topdown=topdown):
1190+
yield subchild
1191+
if not topdown:
1192+
yield child
11691193

11701194
def get_absolute_url(self):
11711195
return reverse("resource_detail", args=[self.project_id, self.pk])

scanpipe/pipes/codebase.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,14 @@ def root(self):
7676
def resources(self):
7777
return self.project.codebaseresources.all()
7878

79-
def walk(self):
80-
yield from self.resources.iterator()
79+
def walk(self, topdown=True):
80+
root = self.root
81+
if topdown:
82+
yield root
83+
for resource in root.walk(topdown=topdown):
84+
yield resource
85+
if not topdown:
86+
yield root
8187

8288
def get_tree(self):
8389
return get_tree(self.root, fields=["name", "path"])

0 commit comments

Comments
 (0)