#!/usr/bin/env python # vim: set fileencoding=UTF-8: # Copyright 2013 Red Hat, Inc. # Author: Jan Pokorný # Licensed under MIT license import sys import re import getopt from os import environ from subprocess import Popen, PIPE # svn checkout http://python-patch.googlecode.com/svn/trunk/ python-patch # pushd python-patch # patch <../python-patch-allow-for-externalizing-hunk-again.patch # popd # ln -s python-patch/patch . import patch re_h = re.compile( r'^Hunk \#(\d+) succeeded at (\d+)(?: with fuzz (\d+))? \(offset (-?\d+) lines?\)\.$', re.MULTILINE ) def adjustment(ret, stderrdata): #print >>sys.stderr, "ret = {0}\nstderrdata = {1}".format(ret, stderrdata) for match in re_h.finditer(stderrdata): #print >>sys.stderr, match.groups() ret = int(match.groups()[3]) break else: ret = 0 return ret def proceed(opts, args): null = open('/dev/null', 'a') if not args: args.append('-') cmd_args = reduce(lambda a, x: a + list(x), opts, []) #print >>sys.stderr, "cmdargs: {0}, opts: {1}".format(cmd_args, opts) for arg in args: arg = arg if arg != '-' else '/dev/stdin' ps = patch.fromfile(arg) if not ps: print >>sys.stderr, "Bad patch file: {0}".format(arg) continue for p in ps.items: header = '{0}--- {1}\n+++ {2}'.format('\n'.join(p.header), p.source, p.target) print header for hunk in p.hunks: cmd = (lambda *a: a)('/usr/bin/patch', '-o-', *cmd_args) e = dict(LC='C') for name, value in environ.iteritems(): if name in ('TMPDIR', 'TMP', 'TEMP'): e[name] = value proc = Popen(cmd, stdin=PIPE, stdout=null, stderr=PIPE, env=e) str_hunk = str(hunk) partial_patch = header + '\n' + str_hunk _, stderrdata = proc.communicate(partial_patch) delta = adjustment(proc.wait(), stderrdata) if delta: hunk.startsrc += delta hunk.starttgt += delta str_hunk = str(hunk) print str_hunk, null.close() if __name__ == '__main__': # see PATCH(1) opts, args = getopt.getopt(sys.argv[1:], 'p:f:h', ['strip=', 'fuzz=']) if ('-h', '') in opts: print >>sys.stderr, "Usage: {0} {{[-p|-f]}} [patch-or-stdin]" \ .format(sys.argv[0]) sys.exit(0) sys.exit(proceed(opts, args))