summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xpatch.py90
1 files changed, 71 insertions, 19 deletions
diff --git a/patch.py b/patch.py
index 5b1a1dd..e466fb5 100755
--- a/patch.py
+++ b/patch.py
@@ -388,24 +388,46 @@ class Patch(object):
return path
return os.path.join(basedir, path)
+ (
+ NEW_FILE,
+ DELETE_FILE,
+ MODIFY_FILE
+ ) = range(3)
+
total = len(self.source)
for fileno, filename in enumerate(self.source):
+ devnull = '/dev/null'
- f2patch = strippath(filename, basedir, strip)
- if not exists(f2patch):
- f2patch = strippath(self.target[fileno], basedir, strip)
+ target = self.target[fileno]
+ f2patch = filename
+ if devnull not in [filename, target]:
+ f2patch = strippath(f2patch, basedir, strip)
if not exists(f2patch):
- warning("source/target file does not exist\n--- %s\n+++ %s" % (filename, self.target[fileno]))
+ f2patch = strippath(target, basedir, strip)
+ if not exists(f2patch):
+ warning("source/target file does not exist\n--- %s\n+++ %s" % (filename, target))
+ continue
+ if not isfile(f2patch):
+ warning("not a file - %s" % f2patch)
continue
- if not isfile(f2patch):
- warning("not a file - %s" % f2patch)
- continue
+ action = MODIFY_FILE
+ else:
+ if filename == devnull:
+ f2patch = strippath(target, basedir, strip)
+ action = NEW_FILE
+ else:
+ f2patch = strippath(filename, basedir, strip)
+ action = DELETE_FILE
+
filename = f2patch
debug("processing %d/%d:\t %s" % (fileno+1, total, filename))
# validate before patching
- f2fp = open(filename)
+ if exists(filename):
+ f2fp = open(filename)
+ else:
+ f2fp = StringIO()
hunkno = 0
hunk = self.hunks[fileno][hunkno]
hunkfind = []
@@ -450,12 +472,32 @@ class Patch(object):
canpatch = True
break
else:
- if hunkno < len(self.hunks[fileno]):
+ if action == NEW_FILE:
+ canpatch = True
+ elif action != DELETE_FILE and hunkno < len(self.hunks[fileno]):
warning("premature end of source file %s at hunk %d" % (filename, hunkno+1))
f2fp.close()
- if validhunks < len(self.hunks[fileno]):
+ if action == NEW_FILE:
+ if exists(filename):
+ srccont = file(filename, 'rb').read()
+ src = StringIO()
+ tgtcont = ''.join(self.patch_stream(src, self.hunks[fileno]))
+ src.close()
+ if srccont == tgtcont:
+ warning("already patched %s" % filename)
+ else:
+ warning("file is already exists %s" % filename)
+ canpatch = False
+ elif action == DELETE_FILE:
+ if not exists(filename):
+ warning("already patched %s" % filename)
+ elif self._match_file_hunks(filename, self.hunks[fileno]):
+ warning("already patched %s" % filename)
+ else:
+ warning("source file is different - %s" % filename)
+ elif validhunks < len(self.hunks[fileno]):
if self._match_file_hunks(filename, self.hunks[fileno]):
warning("already patched %s" % filename)
else:
@@ -466,16 +508,26 @@ class Patch(object):
warning("can't backup original file to %s - aborting" % backupname)
else:
import shutil
- shutil.move(filename, backupname)
- if self.write_hunks(backupname, filename, self.hunks[fileno]):
- info("successfully patched %d/%d:\t %s" % (fileno+1, total, filename))
- unlink(backupname)
+ if action == NEW_FILE:
+ src = StringIO()
+ tgt = open(filename, 'wb')
+ tgt.writelines(self.patch_stream(src, self.hunks[fileno]))
+ tgt.close()
+ src.close()
else:
- warning("error patching file %s" % filename)
- shutil.copy(filename, filename+".invalid")
- warning("invalid version is saved to %s" % filename+".invalid")
- # todo: proper rejects
- shutil.move(backupname, filename)
+ shutil.move(filename, backupname)
+
+ if self.write_hunks(backupname, filename, self.hunks[fileno]):
+ info("successfully patched %d/%d:\t %s" % (fileno+1, total, filename))
+ unlink(backupname)
+ if action == DELETE_FILE:
+ unlink(filename)
+ else:
+ warning("error patching file %s" % filename)
+ shutil.copy(filename, filename+".invalid")
+ warning("invalid version is saved to %s" % filename+".invalid")
+ # todo: proper rejects
+ shutil.move(backupname, filename)
# todo: check for premature eof