You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by sb...@apache.org on 2025/04/25 13:55:32 UTC

(tooling-trusted-release) branch main updated: Disallow making a sub-project from another sub-project

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 4577b3a  Disallow making a sub-project from another sub-project
4577b3a is described below

commit 4577b3a3c08001ee58caefeff2d0f884886613d2
Author: Sean B. Palmer <se...@miscoranda.com>
AuthorDate: Fri Apr 25 14:54:50 2025 +0100

    Disallow making a sub-project from another sub-project
---
 atr/db/models.py                   | 5 +++++
 atr/routes/projects.py             | 4 ++++
 atr/templates/index-committer.html | 9 +++++++--
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/atr/db/models.py b/atr/db/models.py
index 10a3ae4..488b9c8 100644
--- a/atr/db/models.py
+++ b/atr/db/models.py
@@ -148,6 +148,7 @@ class Project(sqlmodel.SQLModel, table=True):
     # Then we can use simply "name" for full_name, and make it str rather than str | None
     name: str = sqlmodel.Field(unique=True, primary_key=True)
     # TODO: Ideally full_name would be unique for str only, but that's complex
+    # We always include "Apache" in the full_name
     full_name: str | None = sqlmodel.Field(default=None)
 
     # True if this a podling project
@@ -155,6 +156,10 @@ class Project(sqlmodel.SQLModel, table=True):
     is_podling: bool = sqlmodel.Field(default=False)
     is_retired: bool = sqlmodel.Field(default=False)
 
+    super_project_name: str | None = sqlmodel.Field(default=None, foreign_key="project.name")
+    # NOTE: Neither "Project" | None nor "Project | None" works
+    super_project: Optional["Project"] = sqlmodel.Relationship()
+
     description: str | None = sqlmodel.Field(default=None)
     category: str | None = sqlmodel.Field(default=None)
     programming_languages: str | None = sqlmodel.Field(default=None)
diff --git a/atr/routes/projects.py b/atr/routes/projects.py
index a0f1558..02c1d87 100644
--- a/atr/routes/projects.py
+++ b/atr/routes/projects.py
@@ -278,6 +278,9 @@ async def _add_project(form: AddFormProtocol, asf_id: str) -> response.Response:
         if not base_project:
             # This should not happen
             raise RuntimeError(f"Base project {base_project_name} not found")
+        if base_project.super_project_name:
+            await quart.flash(f"Project {base_project.name} is already a derived project", "error")
+            return quart.redirect(util.as_url(add_project, project_name=base_project.name))
 
         # Construct the new label
         derived_label = _generate_label(derived_project_name)
@@ -313,6 +316,7 @@ async def _add_project(form: AddFormProtocol, asf_id: str) -> response.Response:
             full_name=new_project_full_name,
             is_podling=base_project.is_podling,
             is_retired=base_project.is_retired,
+            super_project_name=base_project.name,
             description=base_project.description,
             category=base_project.category,
             programming_languages=base_project.programming_languages,
diff --git a/atr/templates/index-committer.html b/atr/templates/index-committer.html
index 17cc52c..f54416e 100644
--- a/atr/templates/index-committer.html
+++ b/atr/templates/index-committer.html
@@ -85,8 +85,13 @@
           <a href="{{ as_url(routes.projects.view, name=project.name) }}"
              class="text-decoration-none me-2">About this project</a>
           <span class="text-muted me-2">/</span>
-          <a href="{{ as_url(routes.projects.add_project, project_name=project.name) }}"
-             class="text-decoration-none me-2">Create a sub-project</a>
+          {% if project.super_project_name %}
+            <a href="{{ as_url(routes.projects.view, name=project.super_project_name) }}"
+               class="text-decoration-none me-2">View super-project</a>
+          {% else %}
+            <a href="{{ as_url(routes.projects.add_project, project_name=project.name) }}"
+               class="text-decoration-none me-2">Create a sub-project</a>
+          {% endif %}
           {% if completed_releases %}
             <span class="text-muted me-2">/</span>
             <a href="{{ as_url(routes.release.completed, project_name=project.name) }}"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org