From 639f864f003adf3fa3a8a94cab42d5813f85b476 Mon Sep 17 00:00:00 2001 From: Jan Pokorný Date: Tue, 8 Oct 2013 22:38:45 +0200 Subject: Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan Pokorný --- LICENSE | 21 ++++++ fix-offsets.py | 80 ++++++++++++++++++++++ ...-patch-allow-for-externalizing-hunk-again.patch | 41 +++++++++++ 3 files changed, 142 insertions(+) create mode 100644 LICENSE create mode 100755 fix-offsets.py create mode 100644 python-patch-allow-for-externalizing-hunk-again.patch diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..419b648 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Red Hat, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/fix-offsets.py b/fix-offsets.py new file mode 100755 index 0000000..75b08f9 --- /dev/null +++ b/fix-offsets.py @@ -0,0 +1,80 @@ +#!/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)) diff --git a/python-patch-allow-for-externalizing-hunk-again.patch b/python-patch-allow-for-externalizing-hunk-again.patch new file mode 100644 index 0000000..a1ccec1 --- /dev/null +++ b/python-patch-allow-for-externalizing-hunk-again.patch @@ -0,0 +1,41 @@ +Index: patch.py +=================================================================== +--- patch.py (revision 203) ++++ patch.py (working copy) +@@ -166,17 +166,27 @@ + self.desc='' + self.text=[] + +-# def apply(self, estream): +-# """ write hunk data into enumerable stream +-# return strings one by one until hunk is +-# over +-# +-# enumerable stream are tuples (lineno, line) +-# where lineno starts with 0 +-# """ +-# pass ++ def apply(self, estream): ++ """ write hunk data into enumerable stream ++ return strings one by one until hunk is ++ over + ++ enumerable stream are tuples (lineno, line) ++ where lineno starts with 0 ++ """ ++ if type(estream) is not type([]): ++ return estream ++ header = "@@ -{0},{1} +{2},{3} @@{4}".format(self.startsrc, self.linessrc, ++ self.starttgt, self.linestgt, ++ self.desc) ++ estream.append((0, header + '\n')) ++ estream.extend(enumerate(self.text, 1)) ++ return estream + ++ def __str__(self): ++ return ''.join([line for _, line in self.apply([])]) ++ ++ + class Patch(object): + """ Patch for a single file """ + def __init__(self): -- cgit