Skip to content

Commit a9410f8

Browse files
committed
Add is_root property to CodebaseResource #180
* Update docstrings * Update expected test results Signed-off-by: Jono Yang <jyang@nexb.com>
1 parent 06acd33 commit a9410f8

File tree

10 files changed

+325
-185
lines changed

10 files changed

+325
-185
lines changed

scanpipe/models.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@
7474
scanpipe_app = apps.get_app_config("scanpipe")
7575

7676

77+
ROOT_SYMBOL = "."
78+
79+
7780
class RunInProgressError(Exception):
7881
"""Run are in progress or queued on this project."""
7982

@@ -1551,6 +1554,16 @@ def is_symlink(self):
15511554
"""
15521555
return self.type == self.Type.SYMLINK
15531556

1557+
@property
1558+
def is_root(self):
1559+
"""
1560+
Returns True, if the resource is the root of the codebase.
1561+
1562+
We consider the root resource of the codebase to be the resource whose
1563+
path is equal to ROOT_SYMBOL.
1564+
"""
1565+
return self.path == ROOT_SYMBOL
1566+
15541567
def compute_compliance_alert(self):
15551568
"""
15561569
Computes and returns the compliance_alert value from the `licenses` policies.
@@ -1591,9 +1604,17 @@ def descendants(self):
15911604
Returns a QuerySet of descendant CodebaseResource objects using a
15921605
database query on the current CodebaseResource `path`.
15931606
The current CodebaseResource is not included.
1607+
1608+
In the case where we are at the root CodebaseResource of a codebase, we
1609+
return all CodebaseResources, excluding the root CodebaseResource, whose
1610+
path is equal to ROOT_SYMBOL.
15941611
"""
1595-
if self.path == ".":
1596-
return self.project.codebaseresources.exclude(path=".")
1612+
if self.is_root:
1613+
# We use a different query in the case we are at the root
1614+
# CodebaseResource because its path is equal to ROOT_SYMBOL, and no
1615+
# other CodebaseResource start with ROOT_SYMBOL. Using the other query
1616+
# would result in no CodebaseResources being returned.
1617+
return self.project.codebaseresources.exclude(path=ROOT_SYMBOL)
15971618
else:
15981619
return self.project.codebaseresources.filter(
15991620
path__startswith=f"{self.path}/"
@@ -1611,7 +1632,11 @@ def children(self, codebase=None):
16111632
`codebase` is not used in this context but required for compatibility
16121633
with the commoncode.resource.Codebase class API.
16131634
"""
1614-
if self.path == ".":
1635+
if self.is_root:
1636+
# The root CodebaseResource has a path of ROOT_SYMBOL, and no other
1637+
# CodebaseResource paths starts with ROOT_SYMBOL. Because of this,
1638+
# we cannot use the path value of the root as part of the query, as
1639+
# no other CodebaseResources would be found.
16151640
unnested_file_or_directory = "^[^/]+$"
16161641
children_regex = rf"{unnested_file_or_directory}"
16171642
else:

scanpipe/pipes/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@
2929

3030
from django.db.models import Count
3131

32-
from packageurl import normalize_qualifiers
33-
3432
from scanpipe.models import CodebaseResource
3533
from scanpipe.models import DiscoveredPackage
34+
from scanpipe.models import ROOT_SYMBOL
3635
from scanpipe.pipes import scancode
3736

3837
logger = logging.getLogger("scanpipe.pipes")
@@ -64,10 +63,11 @@ def make_codebase_resource(project, location, rootfs_path=None):
6463

6564
if location_path == project.codebase_path:
6665
# If we are making a CodebaseResource for the project codebase/
67-
# directory, `relative_path` will be ".". However, when we scan
66+
# directory, `relative_path` will be ROOT_SYMBOL. However, when we scan
6867
# `location`, the `name` field will be "codebase". We have to overwrite
69-
# the `name` field with "." to be consistant with `relative_path`
70-
resource_data["name"] = "."
68+
# the `name` field with ROOT_SYMBOL to be consistant with
69+
# `relative_path`
70+
resource_data["name"] = ROOT_SYMBOL
7171

7272
if rootfs_path:
7373
resource_data["rootfs_path"] = rootfs_path

scanpipe/pipes/codebase.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from django.core.exceptions import ObjectDoesNotExist
2424

2525
from scanpipe.models import Project
26+
from scanpipe.models import ROOT_SYMBOL
2627

2728

2829
def sort_by_lower_name(resource):
@@ -70,7 +71,7 @@ def __init__(self, project):
7071
@property
7172
def root(self):
7273
try:
73-
return self.project.codebaseresources.get(path=".")
74+
return self.project.codebaseresources.get(path=ROOT_SYMBOL)
7475
except ObjectDoesNotExist:
7576
raise AttributeError("Codebase root cannot be determined.")
7677

0 commit comments

Comments
 (0)