Skip to content

Fix license detections page error and improve UI #1751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2025
Merged
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
4 changes: 4 additions & 0 deletions scanpipe/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,8 @@ class LicenseFilterSet(FilterSetUtilsMixin, django_filters.FilterSet):
"compliance_alert",
"license_expression",
"license_expression_spdx",
"is_license_clue",
"needs_review",
]

search = DiscoveredLicenseSearchFilter(
Expand All @@ -853,6 +855,8 @@ class LicenseFilterSet(FilterSetUtilsMixin, django_filters.FilterSet):
"license_expression",
"license_expression_spdx",
"compliance_alert",
"is_license_clue",
"needs_review",
],
)
license_expression = django_filters.AllValuesFilter()
Expand Down
1 change: 0 additions & 1 deletion scanpipe/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2537,7 +2537,6 @@ class Meta:
"""

license_expression_field = None
license_expression_spdx_field = None

class Compliance(models.TextChoices):
OK = "ok"
Expand Down
16 changes: 8 additions & 8 deletions scanpipe/templates/scanpipe/license_detection_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
<a href="{% url 'license_detail' project.slug license_detection.identifier %}">{{ license_detection.identifier }}</a>
{% if license_detection.needs_review %}
<a href="{% url 'license_detail' project.slug license_detection.identifier %}#detection">
<i class="fa-solid fa-magnifying-glass fa-sm has-text-danger" title="License Detection Issues"></i>
<i class="fa-solid fa-magnifying-glass fa-sm has-text-danger" title="License detection issue: needs review"></i>
</a>
{% endif %}
{% if license_detection.has_compliance_alert %}
<a href="{% url 'license_detail' project.slug license_detection.identifier %}#detection">
<i class="fa-solid fa-scale-balanced fa-sm has-text-danger" title="License Compliance Alerts"></i>
<i class="fa-solid fa-scale-balanced fa-sm has-text-danger" title="License Compliance Alert"></i>
</a>
{% endif %}
</td>
Expand All @@ -50,13 +50,13 @@
<td>
{{ license_detection.needs_review }}
</td>
{% if display_compliance_alert %}
<td>
<a href="?compliance_alert={{ license_detection.compliance_alert }}" class="is-black-link">
{{ license_detection.compliance_alert }}
</a>
</td>
<td>
{% if display_compliance_alert %}
<a href="?compliance_alert={{ license_detection.compliance_alert }}" class="is-black-link">
{{ license_detection.compliance_alert }}
</a>
{% endif %}
</td>
</tr>
{% empty %}
<tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<article id="license-clarity-panel" class="panel is-dark">
<article id="license-clarity-panel" class="panel is-info">
<div class="panel-heading is-flex is-justify-content-space-between">
License clarity
{% include "scanpipe/dropdowns/help_dropdown_tooltip.html" with content="License clarity is a set of metrics that indicate how clearly, comprehensively and accurately a software project has defined and communicated the licensing that applies to the software." only %}
Expand Down
38 changes: 28 additions & 10 deletions scanpipe/templates/scanpipe/panels/license_detections_summary.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
{% load humanize %}
{% if license_detection_summary %}
<div class="column is-half">
<div class="column is-half">
<article id="license-detection-summary-panel" class="panel is-info">
<div class="panel-heading is-flex is-justify-content-space-between">
Unique license detections
{% include "scanpipe/dropdowns/help_dropdown_tooltip.html" with content="All unique license detections in the codebase identified by matched license text and other license match characteristics. Also contains other license clues." only %}
</div>
<div class="panel is-info">
<nav class="panel is-info">
<p class="panel-heading py-2 is-size-6">
Unique license detections
</p>
{% for license_expression, count in license_detection_summary.items %}
<a class="panel-block is-align-items-flex-start break-word is-flex is-align-items-center" href="{{ project_licenses_url }}?license_expression={{ license_expression|default:'_EMPTY_' }}" target="_blank">
<a class="panel-block is-align-items-flex-start break-word is-flex is-align-items-center" href="{{ project_licenses_url }}?license_expression={{ license_expression|default:'_EMPTY_' }}" target="_blank">
{{ license_expression|default:'<i>No licenses</i>' }}
<span class="tag is-rounded ml-1">{{ count|intcomma }}</span>
{% if license_expression in issue_count_by_expression %}
<span class="has-text-danger is-size-6 ml-2 is-flex is-flex-direction-row" title="License detection issue: needs review">
<span class="ml-1"><i class="fa-solid fa-magnifying-glass"></i></span>
{% for expression, count in issue_count_by_expression.items %}
{% if license_expression is expression %}
<span class="ml-1">{{ count|intcomma }}</span>
{% endif %}
{% endfor %}
</span>
{% endif %}
{% if license_expression in expressions_with_compliance_alert %}
&nbsp; <span class="fa-solid fa-scale-balanced has-text-danger" title="License Compliance Alerts"></span>
<span class="has-text-danger is-size-6 is-flex is-flex-direction-row" title="License Compliance Alert">
<span class="ml-1"><i class="fa-solid fa-scale-balanced"></i></span>
<span class="ml-1">{{ count|intcomma }}</span>
</span>
{% endif %}
</a>
{% endfor %}
Expand All @@ -19,13 +35,13 @@
See all license detections
<span class="tag is-rounded ml-1">{{ total_counts.all|intcomma }}</span>
{% if total_counts.needs_review %}
<span class="has-text-danger is-size-6 ml-2">
<span class="has-text-danger is-size-6 ml-2" title="License detection issue: needs review">
<i class="fa-solid fa-magnifying-glass"></i>
{{ total_counts.needs_review|intcomma }}
</span>
{% endif %}
{% if total_counts.with_compliance_error %}
<span class="has-text-danger is-size-6 ml-2">
<span class="has-text-danger is-size-6 ml-2" title="License Compliance Alert">
<i class="fa-solid fa-scale-balanced fa-sm"></i>
{{ total_counts.with_compliance_error|intcomma }}
</span>
Expand All @@ -37,13 +53,13 @@
See all license clues
<span class="tag is-rounded ml-1">{{ clue_counts.all|intcomma }}</span>
{% if clue_counts.needs_review %}
<span class="has-text-danger is-size-6 ml-2">
<span class="has-text-danger is-size-6 ml-2" title="License detection issue: needs review">
<i class="fa-solid fa-magnifying-glass"></i>
{{ clue_counts.needs_review|intcomma }}
</span>
{% endif %}
{% if clue_counts.with_compliance_error %}
<span class="has-text-danger is-size-6 ml-2">
<span class="has-text-danger is-size-6 ml-2" title="License Compliance Alert">
<i class="fa-solid fa-scale-balanced fa-sm"></i>
{{ clue_counts.with_compliance_error|intcomma }}
</span>
Expand All @@ -52,4 +68,6 @@
{% endif %}
</nav>
</div>
</article>
</div>
{% endif %}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% load humanize %}
{% if resource_status_summary %}
<div class="column is-half">
<nav class="panel is-dark">
<nav class="panel is-info">
<p class="panel-heading">
Resources status
</p>
Expand Down
4 changes: 2 additions & 2 deletions scanpipe/templates/scanpipe/panels/scan_summary_panel.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% load intcomma from humanize %}
<article id="scan-summary-panel" class="panel is-dark">
<div class="panel-heading is-flex is-justify-content-space-between">
<article id="scan-summary-panel" class="panel is-info">
<div class="panel-heading py-2 is-size-6 is-flex is-justify-content-space-between">
Scan summary
{% include "scanpipe/dropdowns/help_dropdown_tooltip.html" with content="A top-level summary of the collected scanned data such as licenses, holders, and languages." only %}
</div>
Expand Down
19 changes: 14 additions & 5 deletions scanpipe/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1129,14 +1129,19 @@ def get_license_detection_summary(project, limit=10):

# Also get count for detections with
expressions_with_compliance_alert = []
issue_count_by_expression = {}
for license_expression in top_licenses.keys():
detections_for_expression = proper_license_detections.filter(
license_expression=license_expression
)
has_compliance_alert = (
proper_license_detections.filter(license_expression=license_expression)
.has_compliance_alert()
.exists()
detections_for_expression.has_compliance_alert().exists()
)
issue_count = detections_for_expression.needs_review().count()
if has_compliance_alert:
expressions_with_compliance_alert.append(license_expression)
if issue_count > 0:
issue_count_by_expression[license_expression] = issue_count

total_counts = {
"with_compliance_error": (
Expand All @@ -1160,18 +1165,20 @@ def get_license_detection_summary(project, limit=10):
return (
top_licenses,
expressions_with_compliance_alert,
issue_count_by_expression,
total_counts,
license_clues,
clue_counts,
)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
summary, expressions, counts, clues, clue_counts = (
summary, expressions, issues, counts, clues, clue_counts = (
self.get_license_detection_summary(project=self.object)
)
context["license_detection_summary"] = summary
context["expressions_with_compliance_alert"] = expressions
context["issue_count_by_expression"] = issues
context["total_counts"] = counts
context["license_clues"] = clues
context["clue_counts"] = clue_counts
Expand Down Expand Up @@ -1896,7 +1903,9 @@ def get_queryset(self):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["display_compliance_alert"] = self.get_project().policies_enabled
context["display_compliance_alert"] = (
self.get_project().license_policies_enabled
)
return context


Expand Down