From f72e6a0d6e09caf403dbfe2f75ede04c85086648 Mon Sep 17 00:00:00 2001
From: Jacob Champion <jchampion@timescale.com>
Date: Tue, 26 Jul 2022 16:40:49 -0700
Subject: [PATCH 1/2] Add a "Returned: Needs more interest" close code

Reduce the indecision in the case where a patch has received no feedback
in a long time (and so Rejected is too harsh, and Returned with Feedback
seems like a lie) by adding a "Needs more interest" close option.

This is meant to signal to a patch author that they should try drumming
up interest next, whether by gaining consensus, reworking the patchset
for easier review, or otherwise.
---
 .../0006_alter_patchoncommitfest_status.py    | 24 +++++++++++++++++++
 pgcommitfest/commitfest/models.py             |  3 +++
 .../static/commitfest/js/commitfest.js        |  5 +++-
 .../commitfest/templates/patch_commands.inc   |  3 ++-
 pgcommitfest/commitfest/views.py              |  3 +++
 pgcommitfest/urls.py                          |  2 +-
 6 files changed, 37 insertions(+), 3 deletions(-)
 create mode 100644 pgcommitfest/commitfest/migrations/0006_alter_patchoncommitfest_status.py

diff --git a/pgcommitfest/commitfest/migrations/0006_alter_patchoncommitfest_status.py b/pgcommitfest/commitfest/migrations/0006_alter_patchoncommitfest_status.py
new file mode 100644
index 0000000..b749907
--- /dev/null
+++ b/pgcommitfest/commitfest/migrations/0006_alter_patchoncommitfest_status.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.2.13 on 2022-07-26 19:54
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('commitfest', '0005_history_dateindex'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='patchoncommitfest',
+            name='status',
+            field=models.IntegerField(choices=[(1, 'Needs review'), (2, 'Waiting on Author'), (3, 'Ready for Committer'), (4, 'Committed'), (5, 'Moved to next CF'), (6, 'Rejected'), (7, 'Returned with feedback'), (8, 'Withdrawn'), (9, 'Returned: Needs more interest')], default=1),
+        ),
+        migrations.RunSQL("""
+            INSERT INTO commitfest_patchstatus (status, statusstring, sortkey)
+                 VALUES (9, 'Returned: Needs more interest', 50)
+            """,
+            reverse_sql="DELETE FROM commitfest_patchstatus WHERE status = 9",
+        ),
+    ]
diff --git a/pgcommitfest/commitfest/models.py b/pgcommitfest/commitfest/models.py
index 28722f0..433eb4a 100644
--- a/pgcommitfest/commitfest/models.py
+++ b/pgcommitfest/commitfest/models.py
@@ -175,6 +175,7 @@ class PatchOnCommitFest(models.Model):
     STATUS_REJECTED = 6
     STATUS_RETURNED = 7
     STATUS_WITHDRAWN = 8
+    STATUS_RETURNED_INTEREST = 9
     _STATUS_CHOICES = (
         (STATUS_REVIEW, 'Needs review'),
         (STATUS_AUTHOR, 'Waiting on Author'),
@@ -184,6 +185,7 @@ class PatchOnCommitFest(models.Model):
         (STATUS_REJECTED, 'Rejected'),
         (STATUS_RETURNED, 'Returned with feedback'),
         (STATUS_WITHDRAWN, 'Withdrawn'),
+        (STATUS_RETURNED_INTEREST, 'Returned: Needs more interest'),
     )
     _STATUS_LABELS = (
         (STATUS_REVIEW, 'default'),
@@ -194,6 +196,7 @@ class PatchOnCommitFest(models.Model):
         (STATUS_REJECTED, 'danger'),
         (STATUS_RETURNED, 'danger'),
         (STATUS_WITHDRAWN, 'danger'),
+        (STATUS_RETURNED_INTEREST, 'danger'),
     )
     OPEN_STATUSES = [STATUS_REVIEW, STATUS_AUTHOR, STATUS_COMMITTER]
 
diff --git a/pgcommitfest/commitfest/static/commitfest/js/commitfest.js b/pgcommitfest/commitfest/static/commitfest/js/commitfest.js
index 2f1edda..ec84d3b 100644
--- a/pgcommitfest/commitfest/static/commitfest/js/commitfest.js
+++ b/pgcommitfest/commitfest/static/commitfest/js/commitfest.js
@@ -5,7 +5,10 @@ function verify_withdrawn() {
    return confirm('Are you sure you want to close this patch as Withdrawn?\n\nThis should only be done when the author voluntarily withdraws the patch.\n\nSo - are you sure?');
 }
 function verify_returned() {
-   return confirm('Are you sure you want to close this patch as Returned with Feedback?\n\nThis should be done if the patch is expected to be finished at some future time, but not necessarily in the next commitfest. If work is undergoing and expected in the next commitfest, it should instead be set to "Moved to next CF".\n\nSo - are you sure?');
+   return confirm('Are you sure you want to close this patch as Returned (with feedback)?\n\nThis should be done if the patch is expected to be finished at some future time, but not necessarily in the next commitfest. If work is undergoing and expected in the next commitfest, it should instead be set to "Moved to next CF".\n\nSo - are you sure?');
+}
+function verify_returned_interest() {
+   return confirm('Are you sure you want to close this patch as Returned (needs more interest)?\n\nThis should be done if the patch has stalled waiting for reviews. If work is undergoing and expected in the next commitfest, it should instead be set to "Moved to next CF".\n\nSo - are you sure?');
 }
 function verify_next() {
     return confirm('Are you sure you want to move this patch to the next commitfest?\n\nThis means the patch will be marked as closed in this commitfest, but will automatically be moved to the next one. If no further work is expected on this patch, it should be closed with "Rejected" or "Returned with Feedback" instead.\n\nSo - are you sure?');
diff --git a/pgcommitfest/commitfest/templates/patch_commands.inc b/pgcommitfest/commitfest/templates/patch_commands.inc
index 8f18f71..63e4c1f 100644
--- a/pgcommitfest/commitfest/templates/patch_commands.inc
+++ b/pgcommitfest/commitfest/templates/patch_commands.inc
@@ -20,7 +20,8 @@
   <li role="presentation" class="dropdown-header">Closed statuses</li>
   <li role="presentation"><a href="close/reject/" onclick="return verify_reject()">Rejected</a></li>
   <li role="presentation"><a href="close/withdrawn/" onclick="return verify_withdrawn()">Withdrawn</a></li>
-  <li role="presentation"><a href="close/feedback/" onclick="return verify_returned()">Returned with feedback</a></li>
+  <li role="presentation"><a href="close/feedback/" onclick="return verify_returned()">Returned (with feedback)</a></li>
+  <li role="presentation"><a href="close/interest/" onclick="return verify_returned_interest()">Returned (needs more interest)</a></li>
   <li role="presentation"><a href="close/next/" onclick="return verify_next()">Move to next CF</a></li>
   <li role="presentation"><a href="close/committed/" onclick="return flagCommitted({%if patch.committer%}'{{patch.committer}}'{%elif is_committer%}'{{user.username}}'{%else%}null{%endif%})">Committed</a></li>
  </ul>
diff --git a/pgcommitfest/commitfest/views.py b/pgcommitfest/commitfest/views.py
index 6040c1b..1915aad 100644
--- a/pgcommitfest/commitfest/views.py
+++ b/pgcommitfest/commitfest/views.py
@@ -540,11 +540,14 @@ def close(request, cfid, patchid, status):
         poc.status = PatchOnCommitFest.STATUS_WITHDRAWN
     elif status == 'feedback':
         poc.status = PatchOnCommitFest.STATUS_RETURNED
+    elif status == 'interest':
+        poc.status = PatchOnCommitFest.STATUS_RETURNED_INTEREST
     elif status == 'next':
         # Only some patch statuses can actually be moved.
         if poc.status in (PatchOnCommitFest.STATUS_COMMITTED,
                           PatchOnCommitFest.STATUS_NEXT,
                           PatchOnCommitFest.STATUS_RETURNED,
+                          PatchOnCommitFest.STATUS_RETURNED_INTEREST,
                           PatchOnCommitFest.STATUS_REJECTED):
             # Can't be moved!
             messages.error(request, "A patch in status {0} cannot be moved to next commitfest.".format(poc.statusstring))
diff --git a/pgcommitfest/urls.py b/pgcommitfest/urls.py
index 9e92961..098b858 100644
--- a/pgcommitfest/urls.py
+++ b/pgcommitfest/urls.py
@@ -23,7 +23,7 @@ urlpatterns = [
     url(r'^(\d+)/(\d+)/edit/$', views.patchform),
     url(r'^(\d+)/new/$', views.newpatch),
     url(r'^(\d+)/(\d+)/status/(review|author|committer)/$', views.status),
-    url(r'^(\d+)/(\d+)/close/(reject|withdrawn|feedback|committed|next)/$', views.close),
+    url(r'^(\d+)/(\d+)/close/(reject|withdrawn|feedback|interest|committed|next)/$', views.close),
     url(r'^(\d+)/(\d+)/reviewer/(become|remove)/$', views.reviewer),
     url(r'^(\d+)/(\d+)/committer/(become|remove)/$', views.committer),
     url(r'^(\d+)/(\d+)/(un)?subscribe/$', views.subscribe),
-- 
2.25.1

