This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new 6e8371d  Only show the most recent check of each type
6e8371d is described below

commit 6e8371d85e37bc34ca39eb772bca2acc60d2d054
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Mar 25 16:22:47 2025 +0200

    Only show the most recent check of each type
---
 atr/routes/files.py            | 50 ++++++++++++++++++++++++++----------------
 atr/templates/files-check.html | 14 ++++++------
 atr/templates/files-list.html  | 37 ++++++++++++++++++++++++++-----
 3 files changed, 70 insertions(+), 31 deletions(-)

diff --git a/atr/routes/files.py b/atr/routes/files.py
index d515634..63afced 100644
--- a/atr/routes/files.py
+++ b/atr/routes/files.py
@@ -332,6 +332,27 @@ async def root_files_add_project(
     )
 
 
+async def _get_recent_tasks_by_type(
+    data: db.Session, release_name: str, file_path: str, modified: int
+) -> dict[str, models.Task]:
+    """Get the most recent task for each task type for a specific file."""
+    tasks = await data.task(
+        release_name=release_name,
+        path=str(file_path),
+        modified=modified,
+    ).all()
+
+    # Group by task_type and keep the most recent one
+    # We use the highest id to determine the most recent task
+    recent_tasks: dict[str, models.Task] = {}
+    for task in tasks:
+        # If we haven't seen this task type before or if this task is newer
+        if (task.task_type not in recent_tasks) or (task.id > 
recent_tasks[task.task_type].id):
+            recent_tasks[task.task_type] = task
+
+    return recent_tasks
+
+
 @committer_route("/files/list/<project_name>/<version_name>")
 async def root_files_list(session: CommitterSession, project_name: str, 
version_name: str) -> str:
     """Show all the files in the rsync upload directory for a release."""
@@ -355,7 +376,7 @@ async def root_files_list(session: CommitterSession, 
project_name: str, version_
     path_warnings = {}
     path_errors = {}
     path_modified = {}
-    path_tasks: dict[pathlib.Path, int] = {}
+    path_tasks: dict[pathlib.Path, dict[str, models.Task]] = {}
     for path in paths:
         # Get template and substitutions
         elements = {
@@ -389,16 +410,9 @@ async def root_files_list(session: CommitterSession, 
project_name: str, version_
         full_path = str(util.get_candidate_draft_dir() / project_name / 
version_name / path)
         path_modified[path] = int(await aiofiles.os.path.getmtime(full_path))
 
-        # Get tasks
-        tasks = await data.task(
-            release_name=f"{project_name}-{version_name}",
-            path=str(path),
-            modified=path_modified[path],
-        ).all()
-        path_tasks[path] = sum(
-            1
-            for task in tasks
-            if (task.status == models.TaskStatus.COMPLETED) or (task.status == 
models.TaskStatus.FAILED)
+        # Get the most recent task for each type
+        path_tasks[path] = await _get_recent_tasks_by_type(
+            data, f"{project_name}-{version_name}", str(path), 
path_modified[path]
         )
 
     return await quart.render_template(
@@ -417,6 +431,7 @@ async def root_files_list(session: CommitterSession, 
project_name: str, version_
         errors=path_errors,
         modified=path_modified,
         tasks=path_tasks,
+        models=models,
     )
 
 
@@ -442,15 +457,12 @@ async def root_files_checks(session: CommitterSession, 
project_name: str, versio
         modified = int(await aiofiles.os.path.getmtime(full_path))
         file_size = await aiofiles.os.path.getsize(full_path)
 
-        # Get the tasks for this file
-        tasks = await data.task(
-            release_name=f"{project_name}-{version_name}",
-            path=str(file_path),
-            modified=modified,
-        ).all()
+        # Get the most recent task for each task type
+        recent_tasks = await _get_recent_tasks_by_type(data, 
f"{project_name}-{version_name}", file_path, modified)
+
+        # Convert to a list for the template
+        tasks = list(recent_tasks.values())
 
-        # This shows all tasks, including repeated tasks
-        # TODO: Only show the most recent task for each task type
         all_tasks_completed = all(
             task.status in (models.TaskStatus.COMPLETED, 
models.TaskStatus.FAILED) for task in tasks
         )
diff --git a/atr/templates/files-check.html b/atr/templates/files-check.html
index d14cf17..1e3d97c 100644
--- a/atr/templates/files-check.html
+++ b/atr/templates/files-check.html
@@ -37,15 +37,15 @@
       <div class="d-flex flex-wrap gap-3">
         {% with %}
           {% set status_counts = {
-                      'completed': tasks|selectattr("status.value", "equalto", 
"completed")|list|length,
-                      'failed': tasks|selectattr("status.value", "equalto", 
"failed")|list|length,
-                      'active': tasks|selectattr("status.value", "equalto", 
"active")|list|length,
-                      'queued': tasks|selectattr("status.value", "equalto", 
"queued")|list|length
+                      "completed": tasks|selectattr("status.value", "equalto", 
"completed")|list|length,
+                      "failed": tasks|selectattr("status.value", "equalto", 
"failed")|list|length,
+                      "active": tasks|selectattr("status.value", "equalto", 
"active")|list|length,
+                      "queued": tasks|selectattr("status.value", "equalto", 
"queued")|list|length
                     } %}
 
           {% for status, count in status_counts.items() %}
             {% if count > 0 %}
-              <div class="d-flex align-items-center gap-2 px-3 py-2 rounded 
fw-medium {% if status == 'completed' %}bg-success-subtle border 
border-success-subtle {% elif status == 'failed' %}bg-danger-subtle border 
border-danger-subtle {% elif status == 'active' %}bg-info-subtle border 
border-info-subtle {% else %}bg-light border{% endif %}">
+              <div class="d-flex align-items-center gap-2 px-3 py-2 rounded 
fw-medium {% if status == "completed" %}bg-success-subtle border 
border-success-subtle {% elif status == "failed" %}bg-danger-subtle border 
border-danger-subtle {% elif status == "active" %}bg-info-subtle border 
border-info-subtle {% else %}bg-light border{% endif %}">
                 <span class="fs-5">{{ count }}</span>
                 <span>
                   {%- if status == "queued" -%}
@@ -81,7 +81,7 @@
         <div class="border border-2 rounded p-3 mb-3">
           <div class="d-flex justify-content-between align-items-center mb-2">
             <span class="fw-bold">{{ task.task_type.replace('_', ' 
').replace("verify ", "").title() }}</span>
-            <span class="badge rounded-pill {% if task.status.value == 
'queued' %}bg-secondary {% elif task.status.value == 'active' %}bg-info {% elif 
task.status.value == 'completed' %}bg-success {% elif task.status.value == 
'failed' %}bg-danger {% else %}bg-secondary{% endif %}">
+            <span class="badge rounded-pill {% if task.status.value == 
"queued" %}bg-secondary {% elif task.status.value == "active" %}bg-info {% elif 
task.status.value == "completed" %}bg-success {% elif task.status.value == 
"failed" %}bg-danger {% else %}bg-secondary{% endif %}">
               {%- if task.status.value == "queued" -%}
                 Pending
               {%- elif task.status.value == "active" -%}
@@ -106,7 +106,7 @@
                   <summary class="atr-cursor-pointer user-select-none 
p-2">View detailed results</summary>
                 {% endif %}
 
-                {% if task.task_type == 'verify_rat_license' and 
task.result[0] is mapping %}
+                {% if task.task_type == "verify_rat_license" and 
task.result[0] is mapping %}
                   <div class="d-flex gap-3 mb-2">
                     <span class="badge bg-success-subtle text-success-emphasis 
border border-success-subtle px-2 py-1">
                       <strong>{{ task.result[0].approved_licenses }}</strong> 
files with approved licenses
diff --git a/atr/templates/files-list.html b/atr/templates/files-list.html
index fbfb805..548a0c9 100644
--- a/atr/templates/files-list.html
+++ b/atr/templates/files-list.html
@@ -59,7 +59,7 @@
                 <th>Path</th>
                 <th>Warnings</th>
                 <th>Errors</th>
-                <th>Tasks</th>
+                <th>Checks</th>
               </tr>
             </thead>
             <tbody>
@@ -81,11 +81,38 @@
                     {% for error in errors[path] %}<div class="alert 
alert-danger p-0 px-2 mt-2 mb-0">{{ error }}</div>{% endfor %}
                   </td>
                   <td>
-                    {% if path in tasks %}
-                      <a href="{{ url_for('root_files_checks', 
project_name=project_name, version_name=version_name, file_path=path) }}"
-                         class="btn btn-sm btn-outline-primary">View {{ 
tasks[path] }} check(s)</a>
+                    {% if path in tasks and tasks[path]|length > 0 %}
+                      {% set completed_count = namespace(value=0) %}
+                      {% set failed_count = namespace(value=0) %}
+                      {% set active_count = namespace(value=0) %}
+                      {% set queued_count = namespace(value=0) %}
+
+                      {% for task_type, task in tasks[path].items() %}
+                        {% if task.status.value == 'completed' %}
+                          {% set completed_count.value = completed_count.value 
+ 1 %}
+                        {% elif task.status.value == 'failed' %}
+                          {% set failed_count.value = failed_count.value + 1 %}
+                        {% elif task.status.value == 'active' %}
+                          {% set active_count.value = active_count.value + 1 %}
+                        {% elif task.status.value == 'queued' %}
+                          {% set queued_count.value = queued_count.value + 1 %}
+                        {% endif %}
+                      {% endfor %}
+
+                      <div class="d-flex flex-wrap gap-2 mb-2">
+                        {% if completed_count.value > 0 %}<span class="badge 
bg-success">{{ completed_count.value }} Passed</span>{% endif %}
+                        {% if failed_count.value > 0 %}
+                          <span class="badge bg-danger">{{ failed_count.value 
}} {{ "Issue" if failed_count.value == 1 else "Issues" }}</span>
+                        {% endif %}
+                        {% if active_count.value > 0 %}<span class="badge 
bg-info">{{ active_count.value }} Running</span>{% endif %}
+                        {% if queued_count.value > 0 %}<span class="badge 
bg-secondary">{{ queued_count.value }} Pending</span>{% endif %}
+                      </div>
+
+                      <a href="{{ url_for('root_files_checks', 
project_name=project_name, version_name=version_name, file_path=path) }}">
+                        View all check results
+                      </a>
                     {% else %}
-                      No tasks
+                      No check results
                     {% endif %}
                   </td>
                 </tr>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to