]> git.pld-linux.org Git - packages/rpm-build-tools.git/blob - rediff-patches.py
main()
[packages/rpm-build-tools.git] / rediff-patches.py
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
8 # - argparse fro arguments
9 # - cleanup
10
11 import os
12 import re
13 import rpm
14 import shutil
15 import subprocess
16 import sys
17 import tempfile
18
19 RPMBUILD_ISPATCH = (1<<1)
20
21 def unpack(spec, builddir, until_patch=None):
22     cmd = [ 'rpmbuild', '-bp', '--define',  '_builddir %s' % builddir, '--define', '_default_patch_fuzz 2' ]
23     if until_patch is not None:
24         cmd += [ '--define', '%%patch%d exit; #' % until_patch ]
25     cmd += [ spec ]
26     subprocess.check_call(cmd, stdout=sys.stderr, stderr=sys.stderr, timeout=600)
27
28 def diff(diffdir_org, diffdir, builddir, output):
29     diffdir_org = os.path.basename(diffdir_org)
30     diffdir = os.path.basename(diffdir)
31
32     with open(output, 'wt') as f:
33         cmd = [ 'diff', '-urNp', '-x', '*.orig', diffdir_org, diffdir ]
34         try:
35             subprocess.check_call(cmd, cwd=builddir, stdout=f, stderr=sys.stderr, timeout=600)
36         except subprocess.CalledProcessError as err:
37             if err.returncode != 1:
38                 raise
39
40 def main():
41     specfile = sys.argv[1]
42
43     tempdir = tempfile.TemporaryDirectory(dir="/dev/shm")
44     topdir = tempdir.name
45     builddir = os.path.join(topdir, 'BUILD')
46
47     rpm.addMacro("_builddir", builddir)
48
49     r = rpm.spec(specfile)
50
51     patches = {}
52
53     for (name, nr, flags) in r.sources:
54         if flags & RPMBUILD_ISPATCH:
55             patches[nr] = name
56
57     applied_patches = {}
58     re_patch = re.compile(r'^%patch(?P<patch_number>\d+)\w*(?P<patch_args>.*)')
59     for line in r.parsed.split('\n'):
60         m = re_patch.match(line)
61         if not m:
62             continue
63         patch_nr = int(m.group('patch_number'))
64         patch_args = m.group('patch_args')
65         applied_patches[patch_nr] = patch_args
66
67     appsourcedir = rpm.expandMacro("%{_sourcedir}")
68     appbuilddir = rpm.expandMacro("%{_builddir}/%{?buildsubdir}")
69
70     for (patch_nr, patch_name) in sorted(patches.items()):
71         if patch_nr not in applied_patches:
72             continue
73         print("*** patch %d: %s" % (patch_nr, patch_name), file=sys.stderr)
74         unpack(specfile, builddir, patch_nr)
75         os.rename(appbuilddir, appbuilddir + ".org")
76         unpack(specfile, builddir, patch_nr + 1)
77         diff(appbuilddir + ".org", appbuilddir, builddir, os.path.join(topdir, os.path.join(appsourcedir, patch_name + ".rediff")))
78         shutil.rmtree(builddir)
79     tempdir.cleanup()
80
81 if __name__ == '__main__':
82     main()
This page took 0.844367 seconds and 4 git commands to generate.