]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
parser: Set the delegate using Delegation rules
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Sat, 28 Nov 2015 12:14:39 +0000 (10:14 -0200)
committerStephen Finucane <stephen.finucane@intel.com>
Tue, 19 Jan 2016 21:22:23 +0000 (21:22 +0000)
v2: Resolve issues with unit tests

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Stephen Finucane <stephen.finucane@intel.com>
patchwork/bin/parsemail.py
patchwork/tests/test_patchparser.py

index 8870f62acab88a031378e528e5b219169c3518ce..db948ea4a9769caf8767256ed2c21f19bcc8b5f8 100755 (executable)
@@ -27,6 +27,7 @@ import datetime
 from email import message_from_file
 from email.header import Header, decode_header
 from email.utils import parsedate_tz, mktime_tz
+from fnmatch import fnmatch
 from functools import reduce
 import logging
 import operator
@@ -40,9 +41,9 @@ from django.utils.log import AdminEmailHandler
 from django.utils import six
 from django.utils.six.moves import map
 
-from patchwork.models import (
-    Patch, Project, Person, Comment, State, get_default_initial_patch_state)
-from patchwork.parser import parse_patch
+from patchwork.models import (Patch, Project, Person, Comment, State,
+                              DelegationRule, get_default_initial_patch_state)
+from patchwork.parser import parse_patch, patch_get_filenames
 
 LOGGER = logging.getLogger(__name__)
 
@@ -249,6 +250,10 @@ def find_content(project, mail):
 
     patch = None
     comment = None
+    filenames = None
+
+    if patchbuf:
+        filenames = patch_get_filenames(patchbuf)
 
     if pullurl or patchbuf:
         name = clean_subject(mail.get('Subject'), [project.linkname])
@@ -265,12 +270,12 @@ def find_content(project, mail):
         else:
             cpatch = find_patch_for_comment(project, mail)
             if not cpatch:
-                return (None, None)
+                return (None, None, None)
             comment = Comment(patch=cpatch, date=mail_date(mail),
                               content=clean_content(commentbuf),
                               headers=mail_headers(mail))
 
-    return (patch, comment)
+    return (patch, comment, filenames)
 
 
 def find_patch_for_comment(project, mail):
@@ -385,6 +390,32 @@ def get_state(state_name):
     return get_default_initial_patch_state()
 
 
+def auto_delegate(project, filenames):
+    if not filenames:
+        return None
+
+    rules = list(DelegationRule.objects.filter(project=project))
+
+    patch_delegate = None
+
+    for filename in filenames:
+        file_delegate = None
+        for rule in rules:
+            if fnmatch(filename, rule.path):
+                file_delegate = rule.user
+                break
+
+        if file_delegate is None:
+            return None
+
+        if patch_delegate is not None and file_delegate != patch_delegate:
+            return None
+
+        patch_delegate = file_delegate
+
+    return patch_delegate
+
+
 def get_delegate(delegate_email):
     """Return the delegate with the given email or None."""
     if delegate_email:
@@ -436,9 +467,13 @@ def parse_mail(mail, list_id=None):
 
     (author, save_required) = find_author(mail)
 
-    (patch, comment) = find_content(project, mail)
+    (patch, comment, filenames) = find_content(project, mail)
 
     if patch:
+        delegate = get_delegate(mail.get('X-Patchwork-Delegate', '').strip())
+        if not delegate:
+            delegate = auto_delegate(project, filenames)
+
         # we delay the saving until we know we have a patch.
         if save_required:
             author.save()
index e526a79db4b116502316f976d8737df3cced604f..f3d9b6bcd11fec5dc735d0587df1700cee28fe0f 100644 (file)
@@ -42,11 +42,13 @@ class PatchTest(TestCase):
 class InlinePatchTest(PatchTest):
     patch_filename = '0001-add-line.patch'
     test_comment = 'Test for attached patch'
+    expected_filenames = ['meep.text']
 
     def setUp(self):
         self.orig_patch = read_patch(self.patch_filename)
         email = create_email(self.test_comment + '\n' + self.orig_patch)
-        (self.patch, self.comment) = find_content(self.project, email)
+        self.patch, self.comment, self.filenames = find_content(
+            self.project, email)
 
     def testPatchPresence(self):
         self.assertTrue(self.patch is not None)
@@ -60,6 +62,9 @@ class InlinePatchTest(PatchTest):
     def testCommentContent(self):
         self.assertEqual(self.comment.content, self.test_comment)
 
+    def testFilenames(self):
+        self.assertEqual(self.filenames, self.expected_filenames)
+
 
 class AttachmentPatchTest(InlinePatchTest):
     patch_filename = '0001-add-line.patch'
@@ -71,7 +76,8 @@ class AttachmentPatchTest(InlinePatchTest):
         email = create_email(self.test_comment, multipart=True)
         attachment = MIMEText(self.orig_patch, _subtype=self.content_subtype)
         email.attach(attachment)
-        (self.patch, self.comment) = find_content(self.project, email)
+        self.patch, self.comment, self.filenames = find_content(
+            self.project, email)
 
 
 class AttachmentXDiffPatchTest(AttachmentPatchTest):
@@ -86,7 +92,8 @@ class UTF8InlinePatchTest(InlinePatchTest):
         self.orig_patch = read_patch(self.patch_filename, self.patch_encoding)
         email = create_email(self.test_comment + '\n' + self.orig_patch,
                              content_encoding=self.patch_encoding)
-        (self.patch, self.comment) = find_content(self.project, email)
+        self.patch, self.comment, self.filenames = find_content(
+            self.project, email)
 
 
 class NoCharsetInlinePatchTest(InlinePatchTest):
@@ -99,7 +106,8 @@ class NoCharsetInlinePatchTest(InlinePatchTest):
         email = create_email(self.test_comment + '\n' + self.orig_patch)
         del email['Content-Type']
         del email['Content-Transfer-Encoding']
-        (self.patch, self.comment) = find_content(self.project, email)
+        self.patch, self.comment, self.filenames = find_content(
+            self.project, email)
 
 
 class SignatureCommentTest(InlinePatchTest):
@@ -111,7 +119,8 @@ class SignatureCommentTest(InlinePatchTest):
         email = create_email(
             self.test_comment + '\n' +
             '-- \nsig\n' + self.orig_patch)
-        (self.patch, self.comment) = find_content(self.project, email)
+        self.patch, self.comment, self.filenames = find_content(
+            self.project, email)
 
 
 class ListFooterTest(InlinePatchTest):
@@ -125,7 +134,8 @@ class ListFooterTest(InlinePatchTest):
             '_______________________________________________\n' +
             'Linuxppc-dev mailing list\n' +
             self.orig_patch)
-        (self.patch, self.comment) = find_content(self.project, email)
+        self.patch, self.comment, self.filenames = find_content(
+            self.project, email)
 
 
 class DiffWordInCommentTest(InlinePatchTest):
@@ -207,7 +217,7 @@ class SubjectEncodingTest(PatchTest):
         self.email = message_from_string(mail)
 
     def testSubjectEncoding(self):
-        (patch, comment) = find_content(self.project, self.email)
+        patch, comment, _ = find_content(self.project, self.email)
         self.assertEqual(patch.name, self.subject)
 
 
@@ -394,7 +404,7 @@ class GitPullTest(MBoxPatchTest):
     mail_file = '0001-git-pull-request.mbox'
 
     def testGitPullRequest(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertTrue(patch.pull_url is not None)
         self.assertTrue(patch.content is None)
@@ -409,7 +419,7 @@ class GitPullWithDiffTest(MBoxPatchTest):
     mail_file = '0003-git-pull-request-with-diff.mbox'
 
     def testGitPullWithDiff(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertEqual('git://git.kernel.org/pub/scm/linux/kernel/git/tip/'
                          'linux-2.6-tip.git x86-fixes-for-linus',
@@ -437,7 +447,7 @@ class GitRenameOnlyTest(MBoxPatchTest):
     mail_file = '0008-git-rename.mbox'
 
     def testGitRename(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertTrue(comment is not None)
         self.assertEqual(patch.content.count("\nrename from "), 2)
@@ -448,7 +458,7 @@ class GitRenameWithDiffTest(MBoxPatchTest):
     mail_file = '0009-git-rename-with-diff.mbox'
 
     def testGitRename(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertTrue(comment is not None)
         self.assertEqual(patch.content.count("\nrename from "), 2)
@@ -460,7 +470,7 @@ class CVSFormatPatchTest(MBoxPatchTest):
     mail_file = '0007-cvs-format-diff.mbox'
 
     def testPatch(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertTrue(comment is not None)
         self.assertTrue(patch.content.startswith('Index'))
@@ -474,7 +484,7 @@ class CharsetFallbackPatchTest(MBoxPatchTest):
     mail_file = '0010-invalid-charset.mbox'
 
     def testPatch(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertTrue(comment is not None)
 
@@ -483,7 +493,7 @@ class NoNewlineAtEndOfFilePatchTest(MBoxPatchTest):
     mail_file = '0011-no-newline-at-end-of-file.mbox'
 
     def testPatch(self):
-        (patch, comment) = find_content(self.project, self.mail)
+        patch, comment, _ = find_content(self.project, self.mail)
         self.assertTrue(patch is not None)
         self.assertTrue(comment is not None)
         self.assertTrue(patch.content.startswith(