diff mbox

[3/5] parsemail: Add '--hash' argument

Message ID 1479430492-22646-4-git-send-email-stephen@that.guru
State Superseded
Headers show

Commit Message

Stephen Finucane Nov. 18, 2016, 12:54 a.m. UTC
This allows us to replace the functionality previously provided by the
'parser' executable.

Signed-off-by: Stephen Finucane <stephen@that.guru>
Cc: Paul Jakma <paul@jakma.org>
---
 patchwork/management/commands/parsemail.py | 14 ++++++++++++++
 patchwork/parser.py                        | 17 +++++++++++++++++
 patchwork/tests/test_management.py         |  9 +++++++++
 3 files changed, 40 insertions(+)

Comments

Stephen Finucane Nov. 19, 2016, 4:36 p.m. UTC | #1
On Fri, 2016-11-18 at 17:58 +0000, Paul Jakma wrote:
> Hi Stephen,
> 
> That seems to work for me. Thanks!
> 
> regards,
> 
> Paul
> 

Good stuff. OK for me to stick on a 'Tested-by' tag from you?

Stephen
diff mbox

Patch

diff --git a/patchwork/management/commands/parsemail.py b/patchwork/management/commands/parsemail.py
index fd85763..02a84e7 100644
--- a/patchwork/management/commands/parsemail.py
+++ b/patchwork/management/commands/parsemail.py
@@ -26,6 +26,7 @@  import django
 from django.core.management import base
 from django.utils import six
 
+from patchwork.parser import hash_mail
 from patchwork.parser import parse_mail
 from patchwork.management.commands import configure_logging
 
@@ -42,6 +43,10 @@  class Command(base.BaseCommand):
                 '--list-id',
                 help='mailing list ID. If not supplied, this will be '
                 'extracted from the mail headers.'),
+            make_option(
+                '--hash',
+                action='store_true',
+                help='show hash for parsed patch without storing it.'),
         )
     else:
         def add_arguments(self, parser):
@@ -55,6 +60,10 @@  class Command(base.BaseCommand):
                 '--list-id',
                 help='mailing list ID. If not supplied, this will be '
                 'extracted from the mail headers.')
+            parser.add_argument(
+                '--hash',
+                action='store_true',
+                help='show hash for parsed patch without storing it.')
 
     def handle(self, *args, **options):
         infile = args[0] if args else options['infile']
@@ -76,6 +85,11 @@  class Command(base.BaseCommand):
                 mail = email.message_from_binary_file(sys.stdin.buffer)
             else:
                 mail = email.message_from_file(sys.stdin)
+
+        if options['hash']:
+            self.stdout.write(hash_mail(mail))
+            sys.exit(0)
+
         try:
             result = parse_mail(mail, options['list_id'])
             if result:
diff --git a/patchwork/parser.py b/patchwork/parser.py
index fd7ec82..0432b52 100644
--- a/patchwork/parser.py
+++ b/patchwork/parser.py
@@ -907,6 +907,23 @@  def parse_mail(mail, list_id=None):
     return comment
 
 
+def hash_mail(mail):
+    """Parse a mail and generate the hash for it.
+
+    Args:
+        mail (`mbox.Mail`): Mail to parse and add.
+
+    Returns:
+        None
+    """
+    diff, content = find_content(mail)
+
+    if not diff:
+        return  # nothing to work with
+
+    return Patch.hash_diff(diff).hexdigest()
+
+
 def find_filenames(diff):
     """Find files changes in a given diff."""
     # normalise spaces
diff --git a/patchwork/tests/test_management.py b/patchwork/tests/test_management.py
index f916673..d61c5b1 100644
--- a/patchwork/tests/test_management.py
+++ b/patchwork/tests/test_management.py
@@ -112,6 +112,15 @@  class ParsemailTest(TestCase):
         count = models.Patch.objects.filter(project=project.id).count()
         self.assertEqual(count, 1)
 
+    def test_hash(self):
+        out = StringIO()
+        path = os.path.join(TEST_MAIL_DIR, '0013-with-utf8-body.mbox')
+        with self.assertRaises(SystemExit) as exc:
+            call_command('parsemail', infile=path, hash=True, stdout=out)
+
+        self.assertEqual(exc.exception.code, 0)
+        self.assertIn('4df3c62e1', out.getvalue())
+
 
 class ParsearchiveTest(TestCase):
     def test_invalid_path(self):