From d6109d438a78c6fb64759a784d702f8f0d843eaf Mon Sep 17 00:00:00 2001 From: Anthony Mallet Date: Mon, 9 Mar 2020 14:29:13 +0100 Subject: [PATCH] Detect plain diffs in e-mail submitted issues and map to attachments Diffs sent as plain/text message (as with git format-patch + git send-email) in issues tend to be textilized, which messes up the display. Also, the original patch file is not easily downloadable for processing. With this patch, when a diff file is detected in a plain text message without attachment, the whole e-mail message is converted into a proper attachment (that is suitable for git am) and only the diff comment is stored in the issue description. The diff detection is based on the following heuristics: - body contains three consecutive lines starting with "---", "+++" and "@@" - and body contains a line starting with "---", "diff -" or "Index: " The message body is split before this detected separator. --- app/models/mail_handler.rb | 19 ++++++++++++++++++- app/models/mailer.rb | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git app/models/mail_handler.rb app/models/mail_handler.rb index 750383c..579cccb 100644 --- app/models/mail_handler.rb +++ app/models/mail_handler.rb @@ -504,7 +504,12 @@ class MailHandler < ActionMailer::Base # If there is still no body found, and there are no mime-parts defined, # we use the whole raw mail body - @plain_text_body ||= email_parts_to_text([email]).presence if email.all_parts.empty? + if email.all_parts.empty? + @plain_text_body ||= email_parts_to_text([email]).presence + + # map patch to attachment + patch_to_attachement + end # As a fallback we return an empty plain text body (e.g. if we have only # empty text parts but a non-text attachment) @@ -640,4 +645,16 @@ class MailHandler < ActionMailer::Base def find_assignee_from_keyword(keyword, issue) Principal.detect_by_keyword(issue.assignable_users, keyword) end + + # patch to attachement + def patch_to_attachement + return unless @plain_text_body =~ /^--- .*\n[+][+][+] .*\n@@/ + return unless @plain_text_body =~ /^(---$|diff -|Index: )/ + + @plain_text_body = $` + email.attachments['patch.diff'] = { + :mime_type => 'text/x-diff', + :content => email.to_s + } + end end -- 2.17.1