File size: 1,098 Bytes
f10d14f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"""Read a git diff or patch into the files the added-line checks take: {filename, status, patch (hunks only), binary}.
The browser page (web/try_checks.js, parseDiff) does the same; eval/try_agreement.py compares the two. Standard library only."""
from __future__ import annotations

import re


def files_of(patch: str) -> list[dict]:
    """The files of a git patch as the checks read them: {filename, status, patch (hunks only)}."""
    out = []
    for block in re.split(r"(?m)^diff --git ", patch)[1:]:
        m = re.match(r"a/(\S+) b/(\S+)", block)
        if not m:
            continue
        hunks = block[block.find("\n@@"):].lstrip("\n") if "\n@@" in block else ""
        hunks = re.split(r"(?m)^-- $", hunks)[0]                  # the trailer of a format-patch mail
        status = "added" if re.search(r"(?m)^new file mode", block) else "removed" if re.search(r"(?m)^deleted file mode", block) else "modified"
        out.append({"filename": m.group(2), "status": status, "patch": hunks, "binary": bool(re.search(r"(?m)^(?:Binary files|GIT binary patch)", block))})
    return out