#!/usr/bin/env python """ Patch utility to apply unified diffs Brute-force line-by-line non-recursive parsing Copyright (c) 2008-2014 anatoly techtonik Available under the terms of MIT license Project home: http://code.google.com/p/python-patch/ $Id: patch.py 245 2014-03-03 07:57:12Z techtonik $ $HeadURL: http://python-patch.googlecode.com/svn/trunk/patch.py $ """ __author__ = "anatoly techtonik " __version__ = "1.14dev" from optparse import OptionParser import os.path import sys import copy import logging import re from cStringIO import StringIO import urllib2 import os import patchlib def _main() opt = OptionParser(usage="1. %prog [options] unified.diff\n" " 2. %prog [options] -- < unified.diff", version="python-patch %s" % __version__) opt.add_option("-q", "--quiet", action="store_const", dest="verbosity", const=0, help="print only warnings and errors", default=1) opt.add_option("-v", "--verbose", action="store_const", dest="verbosity", const=2, help="be verbose") opt.add_option("--debug", action="store_true", dest="debugmode", help="debug mode") opt.add_option("--diffstat", action="store_true", dest="diffstat", help="print diffstat and exit") opt.add_option("-d", "--directory", metavar='DIR', help="specify root directory for applying patch") opt.add_option("-p", "--strip", type="int", metavar='N', default=0, help="strip N path components from filenames") opt.add_option("--revert", action="store_true", help="apply patch in reverse order (unpatch)") (options, args) = opt.parse_args() if not args and sys.argv[-1:] != ['--']: opt.print_version() opt.print_help() sys.exit() readstdin = (sys.argv[-1:] == ['--'] and not args) patchlib.debugmode = options.debugmode verbosity_levels = {0:logging.WARNING, 1:logging.INFO, 2:logging.DEBUG} loglevel = verbosity_levels[options.verbosity] logformat = "%(message)s" if debugmode: loglevel = logging.DEBUG logformat = "%(levelname)8s %(message)s" patchlib.logger.setLevel(loglevel) loghandler = logging.StreamHandler() loghandler.setFormatter(logging.Formatter(logformat)) patchlib.logger.addHandler(loghandler) if readstdin: patch = pachlib.PatchSet(sys.stdin) else: patchfile = args[0] if not os.path.exists(patchfile) or not os.path.isfile(patchfile): sys.exit("patch file does not exist - %s" % patchfile) patch = patchlib.fromfile(patchfile) if options.diffstat: print patch.diffstat() elif options.revert: patch.revert(options.strip, root=options.directory) or sys.exit(-1) else: patch.apply(options.strip, root=options.directory) or sys.exit(-1) if __name__ == "__main__": _main()