1import subprocess
2import os
3import stat
4from pathlib import Path
5import logging
6
7
8def apply_patch(patch_file, dest_path):
9    """Apply patch and report error if any"""
10    cmd = (
11        "git",
12        "apply",
13        "--recount",
14        "--reject",
15        patch_file,
16    )
17    log_path = dest_path / str(Path(patch_file).name + ".log")
18    with open(log_path, "w") as output_log:
19        if subprocess.call(cmd, stderr=output_log, cwd=dest_path):
20            logging.error(
21                "##########################  "
22                + "ERROR when applying patch to zephyr: "
23                + "###########################\n"
24                + f"           see {str(log_path)}\n"
25                + f"patch file:{patch_file}"
26            )
27
28            # Print list of conflicting file
29            conflict = "Potential merge conflict:\n"
30
31            with open(str(log_path), "r", encoding="utf8", errors="ignore") as f:
32                # ignore lines with non UTF-8 characters
33                previous_conflict_file = ""
34                for line in f:
35                    if line.startswith("error: patch failed:"):
36                        conflict_file = line.split(":")[2]
37                        if conflict_file != previous_conflict_file:
38                            previous_conflict_file = conflict_file
39                            conflict = f"{conflict}               {conflict_file}\n"
40            logging.error(conflict)
41
42
43def remove_readonly(func, path, _):
44    """Remove read only protection"""
45    os.chmod(path, stat.S_IWRITE)
46    func(path)
47