コード例 #1
0
 def __init__(self, root='/', logpipe=True, rpmloglevel=logging.INFO):
     self.root = root
     self.ts = None
     self.logpipe = None
     rpm.setVerbosity(logging_to_rpm[rpmloglevel])
     if logpipe:
         self.logpipe = self.openpipe()
コード例 #2
0
ファイル: rpmUtils.py プロジェクト: ncounter/uyuni
def setDebugVerbosity():
    """Set rpm's verbosity mode
    """
    try:
        rpm.setVerbosity(rpm.RPMLOG_DEBUG)
    except AttributeError:
        print "extra verbosity not supported in this version of rpm"
コード例 #3
0
 def __init__(self, root='/', logpipe=True, rpmloglevel=logging.INFO):
     self.root = root
     self.ts = None
     self.logpipe = None
     rpm.setVerbosity(logging_to_rpm[rpmloglevel])
     if logpipe:
         self.logpipe = self.openpipe()
コード例 #4
0
ファイル: rpmUtils.py プロジェクト: NehaRawat/spacewalk
def setDebugVerbosity():
    """Set rpm's verbosity mode
    """
    try:
        rpm.setVerbosity(rpm.RPMLOG_DEBUG)
    except AttributeError:
        print "extra verbosity not supported in this version of rpm"
コード例 #5
0
ファイル: rpmtrans.py プロジェクト: IMFTC/dnf
 def _shutdownOutputLogging(self):
     # reset rpm bits from reording output
     rpm.setVerbosity(rpm.RPMLOG_NOTICE)
     rpm.setLogFile(sys.stderr)
     try:
         self._writepipe.close()
     except:
         pass
コード例 #6
0
 def _shutdownOutputLogging(self):
     # reset rpm bits from reording output
     rpm.setVerbosity(rpm.RPMLOG_NOTICE)
     rpm.setLogFile(sys.stderr)
     try:
         self._writepipe.close()
     except:
         pass
コード例 #7
0
 def closepipe(self):
     log.debug("closing log pipe")
     rpm.setVerbosity(rpm.RPMLOG_WARNING)
     rpm.setLogFile(None)
     if self.ts:
         self.ts.scriptFd = None
     self.logpipe.close()
     os.remove(self.logpipe.name)
     self.logpipe = None
コード例 #8
0
 def closepipe(self):
     log.debug("closing log pipe")
     rpm.setVerbosity(rpm.RPMLOG_WARNING)
     rpm.setLogFile(None)
     if self.ts:
         self.ts.scriptFd = None
     self.logpipe.close()
     os.remove(self.logpipe.name)
     self.logpipe = None
コード例 #9
0
ファイル: rhncli.py プロジェクト: bjmingyang/spacewalk
 def __setDebugLevel(level):
     cfg = config.initUp2dateConfig()
     # figure out the debug level
     cfg["debug"] = cfg["debug"] + level 
     if cfg["debug"] > 2:
         # Set rpm's verbosity mode
         try:
             rpm.setVerbosity(rpm.RPMLOG_DEBUG)
         except AttributeError:
             print "extra verbosity not supported in this version of rpm"
コード例 #10
0
ファイル: rpmtrans.py プロジェクト: rossonet/Strumenti-RCloud
 def _setupOutputLogging(self):
     # UGLY... set up the transaction to record output from scriptlets
     (r, w) = os.pipe()
     # need fd objects, and read should be non-blocking
     self._readpipe = os.fdopen(r, 'r')
     self._fdSetNonblock(self._readpipe.fileno())
     self._writepipe = os.fdopen(w, 'w')
     self.base.ts.scriptFd = self._writepipe.fileno()
     rpm.setVerbosity(rpm.RPMLOG_INFO)
     rpm.setLogFile(self._writepipe)
コード例 #11
0
ファイル: rpmtrans.py プロジェクト: IMFTC/dnf
 def _setupOutputLogging(self, rpmverbosity="info"):
     # UGLY... set up the transaction to record output from scriptlets
     io_r = tempfile.NamedTemporaryFile()
     self._readpipe = io_r
     self._writepipe = open(io_r.name, 'w+b')
     self.base.ts.setScriptFd(self._writepipe)
     rpmverbosity = {'critical' : 'crit',
                     'emergency' : 'emerg',
                     'error' : 'err',
                     'information' : 'info',
                     'warn' : 'warning'}.get(rpmverbosity, rpmverbosity)
     rpmverbosity = 'RPMLOG_' + rpmverbosity.upper()
     if not hasattr(rpm, rpmverbosity):
         rpmverbosity = 'RPMLOG_INFO'
     rpm.setVerbosity(getattr(rpm, rpmverbosity))
     rpm.setLogFile(self._writepipe)
コード例 #12
0
 def _setupOutputLogging(self, rpmverbosity="info"):
     # UGLY... set up the transaction to record output from scriptlets
     io_r = tempfile.NamedTemporaryFile()
     self._readpipe = io_r
     self._writepipe = open(io_r.name, 'w+b')
     self.base._ts.setScriptFd(self._writepipe)
     rpmverbosity = {'critical' : 'crit',
                     'emergency' : 'emerg',
                     'error' : 'err',
                     'information' : 'info',
                     'warn' : 'warning'}.get(rpmverbosity, rpmverbosity)
     rpmverbosity = 'RPMLOG_' + rpmverbosity.upper()
     if not hasattr(rpm, rpmverbosity):
         rpmverbosity = 'RPMLOG_INFO'
     rpm.setVerbosity(getattr(rpm, rpmverbosity))
     rpm.setLogFile(self._writepipe)
コード例 #13
0
ファイル: rpmtrans.py プロジェクト: zde/dnf
 def _setupOutputLogging(self, rpmverbosity="info"):
     # UGLY... set up the transaction to record output from scriptlets
     io_r = tempfile.NamedTemporaryFile()
     self._readpipe = io_r
     self._writepipe = open(io_r.name, "w+b")
     self.base.ts.setScriptFd(self._writepipe)
     rpmverbosity = {
         "critical": "crit",
         "emergency": "emerg",
         "error": "err",
         "information": "info",
         "warn": "warning",
     }.get(rpmverbosity, rpmverbosity)
     rpmverbosity = "RPMLOG_" + rpmverbosity.upper()
     if not hasattr(rpm, rpmverbosity):
         rpmverbosity = "RPMLOG_INFO"
     rpm.setVerbosity(getattr(rpm, rpmverbosity))
     rpm.setLogFile(self._writepipe)
コード例 #14
0
ファイル: pluginbase.py プロジェクト: sledges/mic
class BackendPlugin(_Plugin):
    mic_plugin_type = "backend"

    # suppress the verbose rpm warnings
    if msger.get_loglevel() != 'debug':
        import rpm
        rpm.setVerbosity(rpm.RPMLOG_ERR)

    def addRepository(self):
        pass
コード例 #15
0
ファイル: __init__.py プロジェクト: rossonet/Strumenti-RCloud
            tserrors = yum.YumBase.runTransaction(
                self, yum.rpmtrans.RPMTransaction(self, display=tsprog))
        except (yum.Errors.YumBaseError, PirutError), err:
            rpm.setLogFile(sys.stderr)
            rpm.setVerbosity(rpm.RPMLOG_NOTICE)
            wf.close()
            tsprog.destroy()

            # FIXME: these errors are actually pretty bad and should be
            # formatted better
            transactionErrors(err)
            raise PirutError

        # reset rpm bits and get the output
        rpm.setLogFile(sys.stderr)
        rpm.setVerbosity(rpm.RPMLOG_NOTICE)
        del self.ts
        wf.close()

        tsprog.destroy()
        return tsprog.getOutput()

    def applyChanges(self, mainwin, downloadonly=False):
        """Apply all of the packaging changes requested."""
        # do depsolve.  determine if we've added anything or not.
        self.checkDeps(mainwin)
        self.depDetails(mainwin)

        # download and verify packages
        dlpkgs = self.downloadPackages(mainwin)
        self.checkSignatures(dlpkgs, mainwin)
コード例 #16
0
__author__ = 'pussbb'

__AVAILABLE = True

import os

from sx.package.base import AbstractPackagerBase, AbstractPackageFile
from sx.exceptions import ScalixUnresolvedDependencies, ScalixPackageProblems
import sx.logger
from sx.package import *

__all__ = ["RPM"]

try:
    import rpm
    rpm.setVerbosity(0)
    _TS = rpm.ts()
    _TS.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
except ImportError as _:
    __AVAILABLE = False


class RpmFile(AbstractPackageFile):
    def __init__(self, rpm_file):
        AbstractPackageFile.__init__(self, rpm_file)
        self.header = None
        fdno = os.open(rpm_file, os.O_RDONLY)
        try:
            self.header = _TS.hdrFromFdno(fdno)
        except rpm.error as _:
            pass
コード例 #17
0
 def _init_rpm(self):
     rpm.addMacro("_topdir", self.tmp_dir)
     rpm.addMacro("_tmppath", self.tmp_dir)
     rpm.addMacro("_dbpath", self.tmp_dir)
     # rpm.setVerbosity(rpm.RPMLOG_DEBUG)
     rpm.setVerbosity(rpm.RPMLOG_CRIT)
コード例 #18
0
ファイル: cmd_create.py プロジェクト: tizenpdk/mic
def main(parser, args, argv):
    """mic create entry point."""
    #args is argparser namespace, argv is the input cmd line
    if args is None:
        raise errors.Usage("Invalid arguments")

    if not os.path.exists(args.ksfile):
        raise errors.CreatorError("Can't find the file: %s" % args.ksfile)

    if os.geteuid() != 0:
        msger.error("Root permission is required, abort")

    try:
        w = pwd.getpwuid(os.geteuid())
    except KeyError:
        msger.warning("Might fail in compressing stage for undetermined user")

    abspath = lambda pth: os.path.abspath(os.path.expanduser(pth))
    if args.logfile:
        logfile_abs_path = abspath(args.logfile)
        if os.path.isdir(logfile_abs_path):
            raise errors.Usage("logfile's path %s should be file" %
                               args.logfile)
        configmgr.create['logfile'] = logfile_abs_path
        configmgr.set_logfile()

    if args.subcommand == "auto":
        do_auto(parser, args.ksfile, argv)
        return

    if args.interactive:
        msger.enable_interactive()
    else:
        msger.disable_interactive()

    if args.verbose:
        msger.set_loglevel('VERBOSE')

    if args.debug:
        try:
            import rpm
            rpm.setVerbosity(rpm.RPMLOG_NOTICE)
        except ImportError:
            pass

        msger.set_loglevel('DEBUG')

    #check the imager type
    createrClass = None
    for subcmd, klass in pluginmgr.get_plugins('imager').iteritems():
        if subcmd == args.subcommand and hasattr(klass, 'do_create'):
            createrClass = klass

    if createrClass is None:
        raise errors.CreatorError("Can't support subcommand %s" %
                                  args.subcommand)

    if args.config:
        configmgr.reset()
        configmgr._siteconf = args.config

    if args.outdir is not None:
        configmgr.create['outdir'] = abspath(args.outdir)
    if args.cachedir is not None:
        configmgr.create['cachedir'] = abspath(args.cachedir)
    os.environ['ZYPP_LOCKFILE_ROOT'] = configmgr.create['cachedir']

    for cdir in ('outdir', 'cachedir'):
        if os.path.exists(configmgr.create[cdir]) \
          and not os.path.isdir(configmgr.create[cdir]):
            raise errors.Usage('Invalid directory specified: %s' \
                               % configmgr.create[cdir])
        if not os.path.exists(configmgr.create[cdir]):
            os.makedirs(configmgr.create[cdir])
            if os.getenv('SUDO_UID', '') and os.getenv('SUDO_GID', ''):
                os.chown(configmgr.create[cdir], int(os.getenv('SUDO_UID')),
                         int(os.getenv('SUDO_GID')))

    if args.local_pkgs_path is not None:
        if not os.path.exists(args.local_pkgs_path):
            raise errors.Usage('Local pkgs directory: \'%s\' not exist' \
                          % args.local_pkgs_path)
        configmgr.create['local_pkgs_path'] = args.local_pkgs_path

    if args.release:
        configmgr.create['release'] = args.release.rstrip('/')

    if args.record_pkgs:
        configmgr.create['record_pkgs'] = []
        for infotype in args.record_pkgs.split(','):
            if infotype not in ('name', 'content', 'license', 'vcs'):
                raise errors.Usage('Invalid pkg recording: %s, valid ones:'
                                   ' "name", "content", "license", "vcs"' \
                                   % infotype)

            configmgr.create['record_pkgs'].append(infotype)

    if args.strict_mode:
        configmgr.create['strict_mode'] = args.strict_mode
    if args.arch is not None:
        supported_arch = sorted(rpmmisc.archPolicies.keys(), reverse=True)
        if args.arch in supported_arch:
            configmgr.create['arch'] = args.arch
        else:
            raise errors.Usage('Invalid architecture: "%s".\n'
                               '  Supported architectures are: \n'
                               '  %s' % (args.arch, ', '.join(supported_arch)))

    if args.pkgmgr is not None:
        configmgr.create['pkgmgr'] = args.pkgmgr

    if args.runtime:
        configmgr.set_runtime(args.runtime)

    if args.pack_to is not None:
        configmgr.create['pack_to'] = args.pack_to

    if args.copy_kernel:
        configmgr.create['copy_kernel'] = args.copy_kernel

    if args.install_pkgs:
        configmgr.create['install_pkgs'] = []
        for pkgtype in args.install_pkgs.split(','):
            if pkgtype not in ('source', 'debuginfo', 'debugsource'):
                raise errors.Usage('Invalid parameter specified: "%s", '
                                   'valid values: source, debuginfo, '
                                   'debusource' % pkgtype)

            configmgr.create['install_pkgs'].append(pkgtype)

    if args.check_pkgs:
        for pkg in args.check_pkgs.split(','):
            configmgr.create['check_pkgs'].append(pkg)

    if args.enabletmpfs:
        configmgr.create['enabletmpfs'] = args.enabletmpfs

    if args.repourl:
        for item in args.repourl:
            try:
                key, val = item.split('=')
            except:
                continue
            configmgr.create['repourl'][key] = val

    if args.repo:
        for optvalue in args.repo:
            repo = {}
            for item in optvalue.split(';'):
                try:
                    key, val = item.split('=')
                except:
                    continue
                repo[key.strip()] = val.strip()
            if 'name' in repo:
                configmgr.create['extrarepos'][repo['name']] = repo

    if args.ignore_ksrepo:
        configmgr.create['ignore_ksrepo'] = args.ignore_ksrepo
    if args.run_script:
        configmgr.create['run_script'] = args.run_script
    if args.tpk_install:
        configmgr.create['tpk_install'] = args.tpk_install

    creater = createrClass()
    creater.do_create(args)
コード例 #19
0
            os.close(fdno)
            del hdr
            value = 4
        else:
            del hdr

    # Don't perform the payload check if the header check failed, otherwise we
    # could mask the reason stored in "value" (we only return one integer from
    # this function and shouldn't change that).
    if payload and value == 0:
        os.lseek(fdno, 0, 0)
        # We don't want the OK message to pollute the output but we do want the
        # BAD message (verbose version) in case of a failure, which is only
        # possible by running _verifySigs() twice (temporary hack until we have
        # the proper API for payload verification in RPM).
        rpm.setVerbosity(rpm.RPMLOG_WARNING)
        valid = ts._verifySigs(fdno, package)
        if not valid:
            value = 2
            os.lseek(fdno, 0, 0)
            rpm.setVerbosity(rpm.RPMLOG_INFO)
            ts._verifySigs(fdno, package)
        rpm.setVerbosity(rpm.RPMLOG_NOTICE)

    try:
        os.close(fdno)
    except OSError, e: # if we're not opened, don't scream about it
        pass

    ts.setVSFlags(currentflags) # put things back like they were before
    return value
コード例 #20
0
ファイル: rpm.py プロジェクト: pussbb/sx-installer
__author__ = 'pussbb'

__AVAILABLE = True

import os

from sx.package.base import AbstractPackagerBase, AbstractPackageFile
from sx.exceptions import ScalixUnresolvedDependencies, ScalixPackageProblems
import sx.logger
from sx.package import *

__all__ = ["RPM"]

try:
    import rpm
    rpm.setVerbosity(0)
    _TS = rpm.ts()
    _TS.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
except ImportError as _:
    __AVAILABLE = False

class RpmFile(AbstractPackageFile):

    def __init__(self, rpm_file):
        AbstractPackageFile.__init__(self, rpm_file)
        self.header = None
        fdno = os.open(rpm_file, os.O_RDONLY)
        try:
            self.header = _TS.hdrFromFdno(fdno)
        except rpm.error as _:
            pass
コード例 #21
0
"""Wrapper module for librpm"""

import tempfile

import gbp.log
from gbp.rpm.policy import RpmPkgPolicy

try:
    # Try to load special RPM lib to be used for GBP (only)
    librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name)
except ImportError:
    gbp.log.warn("Failed to import '%s' as rpm python module, using host's "
                 "default rpm library instead" %
                 RpmPkgPolicy.python_rpmlib_module_name)
    import rpm as librpm

# Module initialization
_rpmlog = tempfile.NamedTemporaryFile(prefix='gbp_rpmlog')
_rpmlogfd = _rpmlog.file
librpm.setVerbosity(librpm.RPMLOG_INFO)
librpm.setLogFile(_rpmlogfd)


def get_librpm_log(truncate=True):
    """Get rpmlib log output"""
    _rpmlogfd.seek(0)
    log = [line.strip() for line in _rpmlogfd.readlines()]
    if truncate:
        _rpmlogfd.truncate(0)
    return log
コード例 #22
0
import tempfile

import gbp.log
from gbp.rpm.policy import RpmPkgPolicy

try:
    # Try to load special RPM lib to be used for GBP (only)
    librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name)
except ImportError:
    gbp.log.warn("Failed to import '%s' as rpm python module, using host's "
                    "default rpm library instead" %
                    RpmPkgPolicy.python_rpmlib_module_name)
    import rpm as librpm

# Module initialization
_rpmlog = tempfile.NamedTemporaryFile(prefix='gbp_rpmlog')
_rpmlogfd = _rpmlog.file
librpm.setVerbosity(librpm.RPMLOG_INFO)
librpm.setLogFile(_rpmlogfd)


def get_librpm_log(truncate=True):
    """Get rpmlib log output"""
    _rpmlogfd.seek(0)
    log = [line.strip() for line in _rpmlogfd.readlines()]
    if truncate:
        _rpmlogfd.truncate(0)
    return log

コード例 #23
0
ファイル: __init__.py プロジェクト: rossonet/Strumenti-RCloud
    def runTransaction(self, mainwin):
        def transactionErrors(errs):
            d = PirutDetailsDialog(mainwin,
                                   gtk.MESSAGE_ERROR,
                                   buttons=[('gtk-ok', 0)],
                                   text=_("Error updating software"))
            d.format_secondary_text(
                _("There were errors encountered in "
                  "trying to update the software "
                  "you selected"))
            d.set_details("%s" % '\n'.join(map(lambda x: x[0], errs.value)))
            d.run()
            d.destroy()

        def blacklistRemoveWarning(pkgs):
            d = PirutDetailsDialog(mainwin,
                                   gtk.MESSAGE_WARNING,
                                   buttons=[('gtk-cancel',
                                             gtk.RESPONSE_CANCEL),
                                            (_("_Remove anyway"),
                                             gtk.RESPONSE_OK, 'gtk-ok')],
                                   text=_("Removing critical software"))
            d.format_secondary_text(
                _("Some of the software which you are "
                  "removing is either critical software "
                  "for system functionality or required "
                  "by such software.  Are you sure you "
                  "want to continue?"))
            txt = ""
            for po in pkgs:
                txt += "%s\n" % (po, )
            d.set_details(txt)

            rc = d.run()
            d.destroy()
            return rc

        def kernelRemoveWarning(pkgs):
            d = PirutDetailsDialog(mainwin,
                                   gtk.MESSAGE_WARNING,
                                   buttons=[('gtk-cancel',
                                             gtk.RESPONSE_CANCEL),
                                            (_("_Remove anyway"),
                                             gtk.RESPONSE_OK, 'gtk-ok')],
                                   text=_("Removing critical software"))
            d.format_secondary_text(
                _("Removing this could leave you with "
                  "no kernels and thus lead to a "
                  "non-bootable system.  Are you sure "
                  "you want to continue?"))
            rc = d.run()
            d.destroy()
            return rc

        # FIXME: does this belong here?
        blacked = []
        for txmbr in self.tsInfo.removed:
            if (txmbr.po.returnSimple('name') in remove_blacklist and len(
                    self.tsInfo.matchNaevr(name=txmbr.po.returnSimple('name')))
                    == 1):
                blacked.append(txmbr.po)
        if len(blacked) > 0:
            rc = blacklistRemoveWarning(blacked)
            if rc != gtk.RESPONSE_OK:
                raise PirutError

        del self.ts
        self.initActionTs()  # make a new, blank ts to populate
        self.populateTs(keepold=0)
        self.ts.check()  #required for ordering
        self.ts.order()  # order

        # set up the transaction to record output from scriptlets
        # this is pretty ugly...
        rpm.setVerbosity(rpm.RPMLOG_INFO)
        (r, w) = os.pipe()
        rf = os.fdopen(r, 'r')
        wf = os.fdopen(w, 'w')
        self.ts.ts.scriptFd = wf.fileno()
        rpm.setLogFile(wf)

        tsprog = Progress.PirutTransactionCallback(_("Updating software"),
                                                   mainwin)
        tsprog.setReadPipe(rf)
        tsprog.show()
        tsprog.set_markup("<i>%s</i>" % (_("Preparing transaction")))
        try:
            tserrors = yum.YumBase.runTransaction(
                self, yum.rpmtrans.RPMTransaction(self, display=tsprog))
        except (yum.Errors.YumBaseError, PirutError), err:
            rpm.setLogFile(sys.stderr)
            rpm.setVerbosity(rpm.RPMLOG_NOTICE)
            wf.close()
            tsprog.destroy()

            # FIXME: these errors are actually pretty bad and should be
            # formatted better
            transactionErrors(err)
            raise PirutError
コード例 #24
0
def main():
    parser = parser = argparse.ArgumentParser(
        description='rediff patches to avoid fuzzy hunks')
    parser.add_argument('spec', type=str, help='spec file name')
    parser.add_argument('-p',
                        '--patches',
                        type=str,
                        help='comma separated list of patch numbers to rediff')
    parser.add_argument(
        '-s',
        '--skip-patches',
        type=str,
        help='comma separated list of patch numbers to skip rediff')
    parser.add_argument('-v',
                        '--verbose',
                        help='increase output verbosity',
                        action='store_true')
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO)
    rpm.setVerbosity(rpm.RPMLOG_ERR)

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
        rpm.setVerbosity(rpm.RPMLOG_DEBUG)

    if args.patches:
        args.patches = [int(x) for x in args.patches.split(',')]

    if args.skip_patches:
        args.skip_patches = [int(x) for x in args.skip_patches.split(',')]

    specfile = args.spec
    appsourcedir = os.path.dirname(os.path.abspath(specfile))

    try:
        tempdir = tempfile.TemporaryDirectory(dir="/dev/shm")
    except FileNotFoundError as e:
        tempdir = tempfile.TemporaryDirectory(dir="/tmp")
    topdir = tempdir.name
    builddir = os.path.join(topdir, 'BUILD')

    rpm.addMacro("_builddir", builddir)

    r = rpm.spec(specfile)

    patches = {}

    for (name, nr, flags) in r.sources:
        if flags & RPMBUILD_ISPATCH:
            patches[nr] = name

    applied_patches = collections.OrderedDict()
    re_patch = re.compile(r'^%patch(?P<patch_number>\d+)\w*(?P<patch_args>.*)')
    for line in r.parsed.split('\n'):
        m = re_patch.match(line)
        if not m:
            continue
        patch_nr = int(m.group('patch_number'))
        patch_args = m.group('patch_args')
        applied_patches[patch_nr] = patch_args

    appbuilddir = rpm.expandMacro("%{_builddir}/%{?buildsubdir}")

    for patch_nr in applied_patches.keys():
        if args.patches and patch_nr not in args.patches:
            continue
        if args.skip_patches and patch_nr in args.skip_patches:
            continue
        patch_name = patches[patch_nr]
        logging.info("*** patch %d: %s" % (patch_nr, patch_name))

        tempspec = prepare_spec(r, patch_nr, before=True)
        unpack(tempspec.name, appsourcedir, builddir)
        tempspec.close()
        os.rename(appbuilddir, appbuilddir + ".org")

        tempspec = prepare_spec(r, patch_nr, before=False)
        unpack(tempspec.name, appsourcedir, builddir)
        tempspec.close()

        patch_comment = patch_comment_get(patch_name)
        diff(
            appbuilddir + ".org", appbuilddir, builddir, patch_comment,
            os.path.join(topdir,
                         os.path.join(appsourcedir, patch_name + ".rediff")))

        diffstat(os.path.join(topdir, os.path.join(appsourcedir, patch_name)))
        diffstat(
            os.path.join(topdir,
                         os.path.join(appsourcedir, patch_name + ".rediff")))

        shutil.rmtree(builddir)
    tempdir.cleanup()