commit 90f9c58e7de29b29fbaf7e78989184ddaaf9a41d
parent 30a754d8c211a76539f1a742d6a5b008c02e8678
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 15 Mar 2021 23:00:38 +0100
replaced install script with general do.sh and implemented handling of no newline at EOF as well as patch prefix
Diffstat:
4 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/TODO b/TODO
@@ -1,2 +0,0 @@
-add handling of lines with:
-\ No newline at end of file
diff --git a/do.sh b/do.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+BINDIR=${BINDIR:-/usr/bin}
+
+set -e
+
+if [ "$1" == "install" ]; then
+ cp patch.py "$DESTDIR/$BINDIR/spatch"
+ chmod +x "$DESTDIR/$BINDIR/spatch"
+elif [ "$1" == "uninstall" ]; then
+ rm "$DESTDIR/$BINDIR/spatch"
+else
+ echo "USAGE: do.sh (install|uninstall)"
+ exit 1
+fi
diff --git a/install b/install
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-sudo ln -sf $PWD/patch.py /usr/bin/spatch
diff --git a/patch.py b/patch.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import sys, os, re
+from os import path
file_header = """\
--- ([^\n ]*)( [^\n]*)?
@@ -21,8 +22,9 @@ def patch_file(src_filename, dst_filename, content):
chunks = list()
next_header_match = True # for do_while loop
- while (next_header_match):
- next_header_match = chunk_header_pattern.search(content, prev_header_match.span()[1])
+ while next_header_match:
+ next_header_match = chunk_header_pattern\
+ .search(content, prev_header_match.span()[1])
chunks.append(prev_header_match)
prev_header_match = next_header_match
@@ -47,17 +49,33 @@ def patch_file(src_filename, dst_filename, content):
chunk_content = content[start_pos:end_pos].split("\n")
valid_lines = 0
for l in chunk_content:
- if len(l) == 0 or l[0] not in (' ', '+', '-'):
+ if len(l) == 0 or l[0] not in (' ', '+', '-', '\\'):
break
valid_lines += 1
+
chunk_content = chunk_content[:valid_lines]
src_lines = "\n".join([l[1:] for l in chunk_content if l[0] in (' ', '-')])
dst_lines = "\n".join([l[1:] for l in chunk_content if l[0] in (' ', '+')])
+ if src_lines == 0 and dst_lines == 0:
+ print("[ERROR] Chunk has no valid lines")
+ sys.exit(1)
+
+ src_nl = dst_nl = True
+ for i,l in enumerate(chunk_content):
+ if i != 0 and l == '\ No newline at end of file':
+ if chunk_content[i-1][0] == '+':
+ src_nl = False
+ elif chunk_content[i-1][0] == '-':
+ dst_nl = False
+ src_lines += "\n" if src_nl else ""
+ dst_lines += "\n" if dst_nl else ""
+
try:
replace_start = src_content.index(src_lines)
- src_content = src_content[:replace_start] + dst_lines + src_content[replace_start+len(src_lines):]
+ src_content = src_content[:replace_start] \
+ + dst_lines + src_content[replace_start+len(src_lines):]
except Exception as e:
print("[ERROR] Failed to find corresponding lines for chunk, exiting..")
sys.exit(1)
@@ -68,13 +86,18 @@ def main():
if len(sys.argv) < 2:
print("Supply the path of a unified diff file as argument")
return 1
+ elif len(sys.argv) == 3:
+ targetdir = sys.argv[2]
+ else:
+ targetdir = None
+ noprompt = (os.getenv("NOPROMPT") != None)
diff_file = sys.argv[1]
content = open(diff_file).read()
prev_header_match = file_header_pattern.search(content)
if prev_header_match == None:
- print("Not a unified diff file!")
+ print("[ERROR] Not a unified diff file!")
return 1
header_matches = list()
next_header_match = True # for do_while loop
@@ -94,6 +117,21 @@ def main():
src_file = header_matches[i].group(1)
dst_file = header_matches[i].group(2)
+ if src_file.split("/",1)[0] == "a" and dst_file.split("/",1)[0] == "b" \
+ and not path.isdir("a") and not path.isdir("b"):
+ if path.isfile(src_file.split("/",1)[1]):
+ src_file = src_file.split("/",1)[1]
+ dst_file = dst_file.split("/",1)[1]
+ else:
+ if not targetdir:
+ if noprompt:
+ print("[ERROR] Unknown patch prefix")
+ sys.exit(1)
+ else:
+ targetdir = input("patch prefix: ")
+ src_file = targetdir + "/" + src_file.split("/",1)[1]
+ dst_file = targetdir + "/" + dst_file.split("/",1)[1]
+
print("[PATCH] Applying patch from {} to {}".format(src_file, dst_file))
startpos = header_matches[i].span()[1]