diff options
-rwxr-xr-x | patch.py | 90 |
1 files changed, 71 insertions, 19 deletions
@@ -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 |