From: Laurent Pinchart Date: Sat, 28 Nov 2015 12:14:39 +0000 (-0200) Subject: parser: Set the delegate using Delegation rules X-Git-Tag: v1.1.0~78 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6c25e3af355fe5c88efc97230fc2179536b0210;p=thirdparty%2Fpatchwork.git parser: Set the delegate using Delegation rules v2: Resolve issues with unit tests Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Stephen Finucane --- diff --git a/patchwork/bin/parsemail.py b/patchwork/bin/parsemail.py index 8870f62a..db948ea4 100755 --- a/patchwork/bin/parsemail.py +++ b/patchwork/bin/parsemail.py @@ -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() diff --git a/patchwork/tests/test_patchparser.py b/patchwork/tests/test_patchparser.py index e526a79d..f3d9b6bc 100644 --- a/patchwork/tests/test_patchparser.py +++ b/patchwork/tests/test_patchparser.py @@ -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(