Add a field to each patch for target version
authorMagnus Hagander <[email protected]>
Wed, 6 Feb 2019 20:05:06 +0000 (21:05 +0100)
committerMagnus Hagander <[email protected]>
Wed, 6 Feb 2019 20:05:06 +0000 (21:05 +0100)
This is particularly interesting towards the end of a cycle where it can
be used to flag patches that are not intended for the current version
but still needs review.

pgcommitfest/commitfest/admin.py
pgcommitfest/commitfest/forms.py
pgcommitfest/commitfest/migrations/0004_target_version.py [new file with mode: 0644]
pgcommitfest/commitfest/models.py
pgcommitfest/commitfest/templates/commitfest.html
pgcommitfest/commitfest/templates/patch.html
pgcommitfest/commitfest/views.py

index a8ac7185fddcd11244f53a0968f6b1dab69da32c..0f7ffda8c216a3cb7b79c78d02e8550972b6a969 100644 (file)
@@ -26,6 +26,7 @@ admin.site.register(CommitFest)
 admin.site.register(Topic)
 admin.site.register(Patch, PatchAdmin)
 admin.site.register(PatchHistory)
+admin.site.register(TargetVersion)
 
 admin.site.register(MailThread)
 admin.site.register(MailThreadAttachment, MailThreadAttachmentAdmin)
index 85cec79211aa5d201f35b4e925b206e6b8ddfef4..a3e5807ae0773c01dc6d205da7d0e03ced6fbac5 100644 (file)
@@ -7,7 +7,7 @@ from django.http import Http404
 
 from selectable.forms.widgets import AutoCompleteSelectMultipleWidget
 
-from .models import Patch, MailThread, PatchOnCommitFest
+from .models import Patch, MailThread, PatchOnCommitFest, TargetVersion
 from .lookups import UserLookup
 from .widgets import ThreadPickWidget
 from .ajax import _archivesAPI
@@ -16,6 +16,7 @@ from .ajax import _archivesAPI
 class CommitFestFilterForm(forms.Form):
     text = forms.CharField(max_length=50, required=False)
     status = forms.ChoiceField(required=False)
+    targetversion = forms.ChoiceField(required=False)
     author = forms.ChoiceField(required=False)
     reviewer = forms.ChoiceField(required=False)
     sortkey = forms.IntegerField(required=False)
@@ -30,6 +31,7 @@ class CommitFestFilterForm(forms.Form):
 
         q = Q(patch_author__commitfests=cf) | Q(patch_reviewer__commitfests=cf)
         userchoices = [(-1, '* All'), (-2, '* None'), (-3, '* Yourself')] + [(u.id, '%s %s (%s)' % (u.first_name, u.last_name, u.username)) for u in User.objects.filter(q).distinct().order_by('first_name', 'last_name')]
+        self.fields['targetversion'] = forms.ChoiceField(choices=[('-1', '* All'), ('-2', '* None')] + [(v.id, v.version) for v in TargetVersion.objects.all()], required=False, label="Target version")
         self.fields['author'] = forms.ChoiceField(choices=userchoices, required=False)
         self.fields['reviewer'] = forms.ChoiceField(choices=userchoices, required=False)
 
diff --git a/pgcommitfest/commitfest/migrations/0004_target_version.py b/pgcommitfest/commitfest/migrations/0004_target_version.py
new file mode 100644 (file)
index 0000000..b307883
--- /dev/null
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.17 on 2019-02-06 19:43
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('commitfest', '0003_withdrawn_status'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='TargetVersion',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('version', models.CharField(max_length=8, unique=True)),
+            ],
+            options={
+                'ordering': ['-version', ],
+            },
+        ),
+        migrations.AddField(
+            model_name='patch',
+            name='targetversion',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='commitfest.TargetVersion', verbose_name='Target version'),
+        ),
+    ]
index c9c9abe83a57ada6c77d1cf8817a1e6e1220ff43..cb1c1dc786765f5fb5d1ea15c659647c64fd76a3 100644 (file)
@@ -75,6 +75,16 @@ class Topic(models.Model):
         return self.topic
 
 
+class TargetVersion(models.Model):
+    version = models.CharField(max_length=8, blank=False, null=False, unique=True)
+
+    class Meta:
+        ordering = ['-version', ]
+
+    def __str__(self):
+        return self.version
+
+
 class Patch(models.Model, DiffableModel):
     name = models.CharField(max_length=500, blank=False, null=False, verbose_name='Description')
     topic = models.ForeignKey(Topic, blank=False, null=False)
@@ -88,6 +98,9 @@ class Patch(models.Model, DiffableModel):
     # If there is a git repo about this patch
     gitlink = models.URLField(blank=True, null=False, default='')
 
+    # Version targeted by this patch
+    targetversion = models.ForeignKey(TargetVersion, blank=True, null=True, verbose_name="Target version")
+
     authors = models.ManyToManyField(User, related_name='patch_author', blank=True)
     reviewers = models.ManyToManyField(User, related_name='patch_reviewer', blank=True)
 
index c9d1e91e96c279b09b1a4fe65b7f1b97b2574aaf..cf826331773be79b268077d16b1a41de25feb3dc 100644 (file)
@@ -62,6 +62,7 @@
   <tr>
    <th>{%if p.is_open%}<a href="#" style="color:#333333;" onclick="return sortpatches(0);">Patch</a>{%if sortkey == 0%}<div style="float:right;"><i class="glyphicon glyphicon-arrow-down"></i></div>{%endif%}{%endif%}</th>
    <th>Status</th>
+   <th>Ver</th>
    <th>Author</th>
    <th>Reviewers</th>
    <th>Committer</th>
@@ -84,6 +85,7 @@
   <tr>
    <td><a href="{{p.id}}/">{{p.name}}</a></td>
    <td><span class="label label-{{p.status|patchstatuslabel}}">{{p.status|patchstatusstring}}</span></td>
+   <td>{%if p.targetversion%}<span class="label label-primary">{{p.targetversion}}</span>{%endif%}</td>
    <td>{{p.author_names|default:''}}</td>
    <td>{{p.reviewer_names|default:''}}</td>
    <td>{{p.committer|default:''}}</td>
index 74da209d923005d329115446d7245fddd828a3d8..dede74fdfd27e33a742d82d3abc8efe17c924b0c 100644 (file)
        {%endfor%}
       </td>
     </tr>
+    <tr>
+      <th>Target version</th>
+      <td>{%if patch.targetversion%}<span class="label label-primary">{{patch.targetversion}}</span>{%endif%}
+    </tr>
     <tr>
       <th>Authors</th>
       <td>{{patch.authors_string}}</td>
index d8abd55538a228c4945d0a920215d759a8bb04f1..0c9591bd67e5ff53c9d17f0bc9585baf2b79651b 100644 (file)
@@ -117,6 +117,13 @@ def commitfest(request, cfid):
             # int() failed -- so just ignore this filter
             pass
 
+    if request.GET.get('targetversion', '-1') != '-1':
+        if request.GET['targetversion'] == '-2':
+            whereclauses.append("targetversion_id IS NULL")
+        else:
+            whereparams['verid'] = int(request.GET['targetversion'])
+            whereclauses.append("targetversion_id=%(verid)s")
+
     if request.GET.get('author', '-1') != '-1':
         if request.GET['author'] == '-2':
             whereclauses.append("NOT EXISTS (SELECT 1 FROM commitfest_patch_authors cpa WHERE cpa.patch_id=p.id)")
@@ -193,7 +200,7 @@ def commitfest(request, cfid):
 
     # Let's not overload the poor django ORM
     curs = connection.cursor()
-    curs.execute("""SELECT p.id, p.name, poc.status, p.created, p.modified, p.lastmail, committer.username AS committer, t.topic,
+    curs.execute("""SELECT p.id, p.name, poc.status, v.version AS targetversion, p.created, p.modified, p.lastmail, committer.username AS committer, t.topic,
 (poc.status=ANY(%(openstatuses)s)) AS is_open,
 (SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_authors cpa ON cpa.user_id=auth_user.id WHERE cpa.patch_id=p.id) AS author_names,
 (SELECT string_agg(first_name || ' ' || last_name || ' (' || username || ')', ', ') FROM auth_user INNER JOIN commitfest_patch_reviewers cpr ON cpr.user_id=auth_user.id WHERE cpr.patch_id=p.id) AS reviewer_names,
@@ -202,8 +209,9 @@ FROM commitfest_patch p
 INNER JOIN commitfest_patchoncommitfest poc ON poc.patch_id=p.id
 INNER JOIN commitfest_topic t ON t.id=p.topic_id
 LEFT JOIN auth_user committer ON committer.id=p.committer_id
+LEFT JOIN commitfest_targetversion v ON p.targetversion_id=v.id
 WHERE poc.commitfest_id=%(cid)s {0}
-GROUP BY p.id, poc.id, committer.id, t.id
+GROUP BY p.id, poc.id, committer.id, t.id, v.version
 ORDER BY is_open DESC, {1}""".format(where_str, orderby_str), params)
     patches = [dict(zip([col[0] for col in curs.description], row)) for row in curs.fetchall()]