~sircmpwn/sr.ht-dev

lists.sr.ht: Remove unidiff in favor of pygit2 v1 PROPOSED

Siva Mahadevan: 1
 Remove unidiff in favor of pygit2

 5 files changed, 30 insertions(+), 36 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/sr.ht-dev/patches/8211/mbox | git am -3
Learn more about email & git

[PATCH lists.sr.ht] Remove unidiff in favor of pygit2 Export this patch

Closes https://todo.sr.ht/~sircmpwn/lists.sr.ht/101
---
 listssrht/blueprints/patches.py | 12 ++++--------
 listssrht/filters.py            | 24 ++++++++++--------------
 listssrht/process.py            |  9 ++++-----
 listssrht/types/email.py        | 20 ++++++++++++--------
 setup.py                        |  1 -
 5 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/listssrht/blueprints/patches.py b/listssrht/blueprints/patches.py
index 1de8ada..d37050d 100644
--- a/listssrht/blueprints/patches.py
+++ b/listssrht/blueprints/patches.py
@@ -84,14 +84,10 @@ def gen_cover_letter(patches):
        insertions = deletions = 0
        for email in patches:
            cover += f" {email.patch_subject}\n"
            patch = email.patch()
            nfiles += (len(patch.added_files)
                    + len(patch.modified_files)
                    + len(patch.removed_files))
            insertions += sum(f.added for
                    f in patch.added_files + patch.modified_files)
            deletions += sum(f.removed
                    for f in patch.removed_files + patch.modified_files)
            stats = email.patch().stats
            nfiles += stats.files_changed
            insertions += stats.insertions
            deletions += stats.deletions
    cover += f"\n {nfiles} files changed, {insertions} insertions(+), {deletions} deletions(-)\n"
    return cover

diff --git a/listssrht/filters.py b/listssrht/filters.py
index d604c5a..63e3f18 100644
--- a/listssrht/filters.py
+++ b/listssrht/filters.py
@@ -21,18 +21,15 @@ def _format_patch(msg, limit=None):
    text = Markup("")
    is_diff = False

    def get_path(f):
        # [2:] to remove a/ or b/
        return f.target_file[2:].strip()

    # Predict the starting lines of each file name
    patch = msg.patch()
    old_files = {delta.old_file.path for delta in patch.deltas}
    new_files = {delta.new_file.path for delta in patch.deltas}
    file_lines = {
        f" {get_path(f)} ": f
        for f in patch.added_files + patch.modified_files + patch.removed_files
        f" {p} ": p for p in old_files | new_files
    }

    line_no = 0

    for line in msg.body.replace("\r", "").split("\n"):
        line_no += 1
        if line_no == limit:
@@ -48,8 +45,7 @@ def _format_patch(msg, limit=None):
            if f != None:
                f = file_lines[f]
                text += Markup(" <a href='#{}'>{}</a>".format(
                    escape(msg.message_id) + "+" + escape(get_path(f)),
                    escape(get_path(f))))
                    escape(msg.message_id) + "+" + escape(f), escape(f)))
                try:
                    stat = line[line.rindex(" ") + 1:]
                    line = line[:line.rindex(" ") + 1]
@@ -71,7 +67,7 @@ def _format_patch(msg, limit=None):
                        stat = escape(stat)
                except ValueError:
                    stat = Markup("")
                text += escape(line[len(get_path(f)) + 1:])
                text += escape(line[len(f) + 1:])
                text += escape(stat)
                text += Markup("\n")
            else:
@@ -143,9 +139,9 @@ def format_body(msg, limit=None):
            text += Markup(urlize(escape(line), rel="noopener nofollow")) + "\n"
    return text.rstrip()

def diffstat(patch):
    p = patch.patch()
def diffstat(patch_email):
    stats = patch_email.patch().stats
    return type("diffstat", tuple(), {
        "added": sum(f.added for f in p.added_files + p.modified_files),
        "removed": sum(f.removed for f in p.removed_files + p.modified_files),
        "added": stats.insertions,
        "removed": stats.deletions,
    })
diff --git a/listssrht/process.py b/listssrht/process.py
index 13e0a2d..eb1eedd 100644
--- a/listssrht/process.py
+++ b/listssrht/process.py
@@ -168,11 +168,10 @@ def _archive(dest, envelope):
            # TODO: should we consider multiple text parts?
            mail.body = part.get_payload(decode=True).decode(charset)
            break
    try:
        patch = pygit2.Diff.parse_diff(mail.body.replace("\r\n", "\n"))
        mail.is_patch = len(patch) > 0
    except:
        mail.is_patch = False

    # force lazy parse of patch (if it exists) after msg body is set
    mail.patch()

    mail.is_request_pull = False # TODO: Detect git request-pull
    reply_to = envelope["In-Reply-To"]

diff --git a/listssrht/types/email.py b/listssrht/types/email.py
index c4d7ff1..2f75120 100644
--- a/listssrht/types/email.py
+++ b/listssrht/types/email.py
@@ -1,9 +1,8 @@
import email
import io
import pygit2
import sqlalchemy as sa
from email import policy
from srht.database import Base
from unidiff import PatchSet

class Email(Base):
    __tablename__ = 'email'
@@ -100,11 +99,16 @@ class Email(Base):
        self._parsed._email = self
        return self._parsed

    # libgit2 Diff object parsed from message body (if it exists)
    def patch(self):
        if not self.is_patch:
            return None
        if hasattr(self, "_patch"):
        if not hasattr(self, "_patch"):
            try:
                self._patch = pygit2.Diff.parse_diff(self.body.replace("\r\n", "\n"))
                self.is_patch = len(self._patch) > 0
            except:
                self.is_patch = False

        if self.is_patch:
            return self._patch
        with io.StringIO(self.body) as f:
            self._patch = PatchSet(f)
        return self._patch

        return None
diff --git a/setup.py b/setup.py
index 9ac7ce2..0ddbb6c 100755
--- a/setup.py
+++ b/setup.py
@@ -57,7 +57,6 @@ setup(
      'flask-login',
      'aiosmtpd',
      'asyncpg',
      'unidiff',
  ],
  license = 'AGPL-3.0',
  package_data={
-- 
2.23.0