]> git.pld-linux.org Git - packages/rpm-build-tools.git/blame - rediff-patches.py
Args parsing and few fixes.
[packages/rpm-build-tools.git] / rediff-patches.py
CommitLineData
7eacbddd
AM
1#!/usr/bin/python3
2
3# rediff-patches.py name.spec
4
5# TODO:
6# - handle rediff of last patch (need some way to terminate build just after that patch is applied)
7# - or maybe apply patches on our own instead of using rpmbuild for that
7eacbddd
AM
8# - cleanup
9
1e57e977
AM
10import argparse
11import collections
12import logging
7eacbddd
AM
13import os
14import re
15import rpm
16import shutil
17import subprocess
18import sys
19import tempfile
20
21RPMBUILD_ISPATCH = (1<<1)
22
23def unpack(spec, builddir, until_patch=None):
2addb8ce 24 cmd = [ 'rpmbuild', '-bp', '--define', '_builddir %s' % builddir, '--define', '_default_patch_fuzz 2' ]
7eacbddd
AM
25 if until_patch is not None:
26 cmd += [ '--define', '%%patch%d exit; #' % until_patch ]
27 cmd += [ spec ]
1e57e977
AM
28 logging.debug("running %s" % repr(cmd))
29 subprocess.check_call(cmd, stdout=sys.stderr, stderr=sys.stderr,
30 env={'LC_ALL': 'C.UTF-8'}, timeout=600)
7eacbddd
AM
31
32def diff(diffdir_org, diffdir, builddir, output):
33 diffdir_org = os.path.basename(diffdir_org)
34 diffdir = os.path.basename(diffdir)
35
36 with open(output, 'wt') as f:
37 cmd = [ 'diff', '-urNp', '-x', '*.orig', diffdir_org, diffdir ]
1e57e977 38 logging.debug("running %s" % repr(cmd))
7eacbddd 39 try:
1e57e977
AM
40 subprocess.check_call(cmd, cwd=builddir, stdout=f, stderr=sys.stderr,
41 env={'LC_ALL': 'C.UTF-8'}, timeout=600)
7eacbddd
AM
42 except subprocess.CalledProcessError as err:
43 if err.returncode != 1:
44 raise
1e57e977
AM
45 logging.info("rediff generated as %s" % output)
46
7eacbddd 47
c65b587f 48def main():
1e57e977
AM
49 parser = parser = argparse.ArgumentParser(description='rediff patches to avoid fuzzy hunks')
50 parser.add_argument('spec', type=str, help='spec file name')
51 parser.add_argument('-p', '--patches', type=str, help='comma separated list of patch numbers to rediff')
52 parser.add_argument('-v', '--verbose', help='increase output verbosity', action='store_true')
53 args = parser.parse_args()
54
55 logging.basicConfig(level=logging.INFO)
56 rpm.setVerbosity(rpm.RPMLOG_ERR)
57
58 if args.verbose:
59 logging.basicConfig(level=logging.DEBUG)
60 rpm.setVerbosity(rpm.RPMLOG_DEBUG)
61
62 if args.patches:
63 args.patches = [int(x) for x in args.patches.split(',')]
64
65 specfile = args.spec
c65b587f
AM
66
67 tempdir = tempfile.TemporaryDirectory(dir="/dev/shm")
68 topdir = tempdir.name
69 builddir = os.path.join(topdir, 'BUILD')
70
71 rpm.addMacro("_builddir", builddir)
72
73 r = rpm.spec(specfile)
74
75 patches = {}
76
77 for (name, nr, flags) in r.sources:
78 if flags & RPMBUILD_ISPATCH:
79 patches[nr] = name
80
1e57e977 81 applied_patches = collections.OrderedDict()
c65b587f
AM
82 re_patch = re.compile(r'^%patch(?P<patch_number>\d+)\w*(?P<patch_args>.*)')
83 for line in r.parsed.split('\n'):
84 m = re_patch.match(line)
85 if not m:
86 continue
87 patch_nr = int(m.group('patch_number'))
88 patch_args = m.group('patch_args')
89 applied_patches[patch_nr] = patch_args
90
91 appsourcedir = rpm.expandMacro("%{_sourcedir}")
92 appbuilddir = rpm.expandMacro("%{_builddir}/%{?buildsubdir}")
93
1e57e977
AM
94 for patch_nr, patch_nr_next in zip(applied_patches.keys(), list(applied_patches.keys())[1:] + [None]):
95 if args.patches and patch_nr not in args.patches:
c65b587f 96 continue
1e57e977
AM
97 if patch_nr_next is None:
98 logging.warning("can't rediff last patch, see TODO")
99 break
100 patch_name = patches[patch_nr]
101 logging.info("*** patch %d: %s" % (patch_nr, patch_name))
c65b587f
AM
102 unpack(specfile, builddir, patch_nr)
103 os.rename(appbuilddir, appbuilddir + ".org")
1e57e977 104 unpack(specfile, builddir, patch_nr_next)
c65b587f
AM
105 diff(appbuilddir + ".org", appbuilddir, builddir, os.path.join(topdir, os.path.join(appsourcedir, patch_name + ".rediff")))
106 shutil.rmtree(builddir)
107 tempdir.cleanup()
108
109if __name__ == '__main__':
110 main()
This page took 0.127881 seconds and 4 git commands to generate.