backports: move legacy and SmPL patch application into helper
authorLuis R. Rodriguez <mcgrof@suse.com>
Fri, 31 Oct 2014 18:16:05 +0000 (18:16 +0000)
committerLuis R. Rodriguez <mcgrof@do-not-panic.com>
Fri, 14 Nov 2014 21:47:15 +0000 (13:47 -0800)
This allows us to extend how backports uses patches for
different types of applications. This will later be used
for kernel integration support, for example.

This should have no functional change.

Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
gentree.py

index 9b4db98ea4a380a6417920d52d4601bf59ec2731..59ae19d6f996f46342f107e7b89b2ca60f0b4a58 100755 (executable)
@@ -438,6 +438,149 @@ def upload_release(args, rel_prep, logwrite=lambda x:None):
         kup_cmd = "kup put /\n\t\t%s /\n\t\t%s /\n\t\t%s" % (gzip_name, tar_name + '.asc', korg_path)
         logwrite("kup-test: skipping cmd: %s" % kup_cmd)
 
+def apply_patches(args, desc, source_dir, patch_src, target_dir, logwrite=lambda x:None):
+    """
+    Given a path of a directories of patches and SmPL patches apply
+    them on the target directory. If requested refresh patches, or test
+    a specific SmPL patch.
+    """
+    logwrite('Applying patches from %s to %s ...' % (patch_src, target_dir))
+    test_cocci = args.test_cocci or args.profile_cocci
+    test_cocci_found = False
+    patches = []
+    sempatches = []
+    for root, dirs, files in os.walk(os.path.join(source_dir, patch_src)):
+        for f in files:
+            if not test_cocci and f.endswith('.patch'):
+                patches.append(os.path.join(root, f))
+            if f.endswith('.cocci'):
+                if test_cocci:
+                    if f not in test_cocci:
+                        continue
+                    test_cocci_found = True
+                    if args.test_cocci:
+                        logwrite("Testing Coccinelle SmPL patch: %s" % test_cocci)
+                    elif args.profile_cocci:
+                        logwrite("Profiling Coccinelle SmPL patch: %s" % test_cocci)
+                sempatches.append(os.path.join(root, f))
+    patches.sort()
+    prefix_len = len(os.path.join(source_dir, patch_src)) + 1
+    for pfile in patches:
+        print_name = pfile[prefix_len:]
+        # read the patch file
+        p = patch.fromfile(pfile)
+        # complain if it's not a patch
+        if not p:
+            raise Exception('No patch content found in %s' % print_name)
+        # leading / seems to be stripped?
+        if 'dev/null' in p.items[0].source:
+            raise Exception('Patches creating files are not supported (in %s)' % print_name)
+        # check if the first file the patch touches exists, if so
+        # assume the patch needs to be applied -- otherwise continue
+        patched_file = '/'.join(p.items[0].source.split('/')[1:])
+        fullfn = os.path.join(target_dir, patched_file)
+        if not os.path.exists(fullfn):
+            if args.verbose:
+                logwrite("Not applying %s, not needed" % print_name)
+            continue
+        if args.verbose:
+            logwrite("Applying patch %s" % print_name)
+
+        if args.refresh:
+            # but for refresh, of course look at all files the patch touches
+            for patchitem in p.items:
+                patched_file = '/'.join(patchitem.source.split('/')[1:])
+                fullfn = os.path.join(target_dir, patched_file)
+                shutil.copyfile(fullfn, fullfn + '.orig_file')
+
+        process = subprocess.Popen(['patch', '-p1'], stdout=subprocess.PIPE,
+                                   stderr=subprocess.STDOUT, stdin=subprocess.PIPE,
+                                   close_fds=True, universal_newlines=True,
+                                   cwd=target_dir)
+        output = process.communicate(input=open(pfile, 'r').read())[0]
+        output = output.split('\n')
+        if output[-1] == '':
+            output = output[:-1]
+        if args.verbose:
+            for line in output:
+                logwrite('> %s' % line)
+        if process.returncode != 0:
+            if not args.verbose:
+                logwrite("Failed to apply changes from %s" % print_name)
+                for line in output:
+                    logwrite('> %s' % line)
+            raise Exception('Patch failed')
+
+        if args.refresh:
+            pfilef = open(pfile + '.tmp', 'a')
+            pfilef.write(p.top_header)
+            pfilef.flush()
+            for patchitem in p.items:
+                patched_file = '/'.join(patchitem.source.split('/')[1:])
+                fullfn = os.path.join(target_dir, patched_file)
+                process = subprocess.Popen(['diff', '-p', '-u', patched_file + '.orig_file', patched_file,
+                                            '--label', 'a/' + patched_file,
+                                            '--label', 'b/' + patched_file],
+                                           stdout=pfilef, close_fds=True,
+                                           universal_newlines=True, cwd=target_dir)
+                process.wait()
+                os.unlink(fullfn + '.orig_file')
+                if not process.returncode in (0, 1):
+                    logwrite("Failed to diff to refresh %s" % print_name)
+                    pfilef.close()
+                    os.unlink(pfile + '.tmp')
+                    raise Exception('Refresh failed')
+            pfilef.close()
+            os.rename(pfile + '.tmp', pfile)
+
+        # remove orig/rej files that patch sometimes creates
+        for root, dirs, files in os.walk(target_dir):
+            for f in files:
+                if f[-5:] == '.orig' or f[-4:] == '.rej':
+                    os.unlink(os.path.join(root, f))
+        git_debug_snapshot(args, "apply %s patch %s" % (desc, print_name))
+
+    sempatches.sort()
+    prefix_len = len(os.path.join(source_dir, patch_src)) + 1
+
+    for cocci_file in sempatches:
+        # Until Coccinelle picks this up
+        pycocci = os.path.join(source_dir, 'devel/pycocci')
+        cmd = [pycocci, cocci_file]
+        extra_spatch_args = []
+        if args.profile_cocci:
+            cmd.append('--profile-cocci')
+        cmd.append(os.path.abspath(target_dir))
+        print_name = cocci_file[prefix_len:]
+        if args.verbose:
+            logwrite("Applying SmPL patch %s" % print_name)
+        sprocess = subprocess.Popen(cmd,
+                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+                                    close_fds=True, universal_newlines=True,
+                                    cwd=target_dir)
+        output = sprocess.communicate()[0]
+        sprocess.wait()
+        if sprocess.returncode != 0:
+            logwrite("Failed to process SmPL patch %s" % print_name)
+            raise Exception('SmPL patch failed')
+        output = output.split('\n')
+        if output[-1] == '':
+            output = output[:-1]
+        if args.verbose:
+            for line in output:
+                logwrite('> %s' % line)
+
+        # remove cocci_backup files
+        for root, dirs, files in os.walk(target_dir):
+            for f in files:
+                if f.endswith('.cocci_backup'):
+                    os.unlink(os.path.join(root, f))
+        git_debug_snapshot(args, "apply %s SmPL patch %s" % (desc, print_name))
+
+    if test_cocci and test_cocci_found:
+        logwrite('Done!')
+        sys.exit(0)
+
 def _main():
     # Our binary requirements go here
     req = reqs.Req()
@@ -620,141 +763,7 @@ def process(kerneldir, outdir, copy_list_file, git_revision=None,
         bpcfg.disable_symbols(disable_list)
     git_debug_snapshot(args, 'Add automatic backports')
 
-    test_cocci = args.test_cocci or args.profile_cocci
-
-    logwrite('Apply patches ...')
-    patches = []
-    sempatches = []
-    for root, dirs, files in os.walk(os.path.join(source_dir, 'patches')):
-        for f in files:
-            if not test_cocci and f.endswith('.patch'):
-                patches.append(os.path.join(root, f))
-            if f.endswith('.cocci'):
-                if test_cocci:
-                    if f not in test_cocci:
-                        continue
-                    if args.test_cocci:
-                        logwrite("Testing Coccinelle SmPL patch: %s" % test_cocci)
-                    elif args.profile_cocci:
-                        logwrite("Profiling Coccinelle SmPL patch: %s" % test_cocci)
-                sempatches.append(os.path.join(root, f))
-    patches.sort()
-    prefix_len = len(os.path.join(source_dir, 'patches')) + 1
-    for pfile in patches:
-        print_name = pfile[prefix_len:]
-        # read the patch file
-        p = patch.fromfile(pfile)
-        # complain if it's not a patch
-        if not p:
-            raise Exception('No patch content found in %s' % print_name)
-        # leading / seems to be stripped?
-        if 'dev/null' in p.items[0].source:
-            raise Exception('Patches creating files are not supported (in %s)' % print_name)
-        # check if the first file the patch touches exists, if so
-        # assume the patch needs to be applied -- otherwise continue
-        patched_file = '/'.join(p.items[0].source.split('/')[1:])
-        fullfn = os.path.join(args.outdir, patched_file)
-        if not os.path.exists(fullfn):
-            if args.verbose:
-                logwrite("Not applying %s, not needed" % print_name)
-            continue
-        if args.verbose:
-            logwrite("Applying patch %s" % print_name)
-
-        if args.refresh:
-            # but for refresh, of course look at all files the patch touches
-            for patchitem in p.items:
-                patched_file = '/'.join(patchitem.source.split('/')[1:])
-                fullfn = os.path.join(args.outdir, patched_file)
-                shutil.copyfile(fullfn, fullfn + '.orig_file')
-
-        process = subprocess.Popen(['patch', '-p1'], stdout=subprocess.PIPE,
-                                   stderr=subprocess.STDOUT, stdin=subprocess.PIPE,
-                                   close_fds=True, universal_newlines=True,
-                                   cwd=args.outdir)
-        output = process.communicate(input=open(pfile, 'r').read())[0]
-        output = output.split('\n')
-        if output[-1] == '':
-            output = output[:-1]
-        if args.verbose:
-            for line in output:
-                logwrite('> %s' % line)
-        if process.returncode != 0:
-            if not args.verbose:
-                logwrite("Failed to apply changes from %s" % print_name)
-                for line in output:
-                    logwrite('> %s' % line)
-            return 2
-
-        if args.refresh:
-            pfilef = open(pfile + '.tmp', 'a')
-            pfilef.write(p.top_header)
-            pfilef.flush()
-            for patchitem in p.items:
-                patched_file = '/'.join(patchitem.source.split('/')[1:])
-                fullfn = os.path.join(args.outdir, patched_file)
-                process = subprocess.Popen(['diff', '-p', '-u', patched_file + '.orig_file', patched_file,
-                                            '--label', 'a/' + patched_file,
-                                            '--label', 'b/' + patched_file],
-                                           stdout=pfilef, close_fds=True,
-                                           universal_newlines=True, cwd=args.outdir)
-                process.wait()
-                os.unlink(fullfn + '.orig_file')
-                if not process.returncode in (0, 1):
-                    logwrite("Failed to diff to refresh %s" % print_name)
-                    pfilef.close()
-                    os.unlink(pfile + '.tmp')
-                    return 3
-            pfilef.close()
-            os.rename(pfile + '.tmp', pfile)
-
-        # remove orig/rej files that patch sometimes creates
-        for root, dirs, files in os.walk(args.outdir):
-            for f in files:
-                if f[-5:] == '.orig' or f[-4:] == '.rej':
-                    os.unlink(os.path.join(root, f))
-        git_debug_snapshot(args, "apply backport patch %s" % print_name)
-
-    sempatches.sort()
-    prefix_len = len(os.path.join(source_dir, 'patches')) + 1
-
-    for cocci_file in sempatches:
-        # Until Coccinelle picks this up
-        pycocci = os.path.join(source_dir, 'devel/pycocci')
-        cmd = [pycocci, cocci_file]
-        extra_spatch_args = []
-        if args.profile_cocci:
-            cmd.append('--profile-cocci')
-        cmd.append(os.path.abspath(args.outdir))
-        print_name = cocci_file[prefix_len:]
-        if args.verbose:
-            logwrite("Applying SmPL patch %s" % print_name)
-        sprocess = subprocess.Popen(cmd,
-                                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
-                                    close_fds=True, universal_newlines=True,
-                                    cwd=args.outdir)
-        output = sprocess.communicate()[0]
-        sprocess.wait()
-        if sprocess.returncode != 0:
-            logwrite("Failed to process SmPL patch %s" % print_name)
-            return 3
-        output = output.split('\n')
-        if output[-1] == '':
-            output = output[:-1]
-        if args.verbose:
-            for line in output:
-                logwrite('> %s' % line)
-
-        # remove cocci_backup files
-        for root, dirs, files in os.walk(args.outdir):
-            for f in files:
-                if f.endswith('.cocci_backup'):
-                    os.unlink(os.path.join(root, f))
-        git_debug_snapshot(args, "apply backport SmPL patch %s" % print_name)
-
-    if test_cocci:
-        logwrite('Done!')
-        return 0
+    apply_patches(args, "backport", source_dir, 'patches', args.outdir, logwrite)
 
     # some post-processing is required
     configtree = kconfig.ConfigTree(os.path.join(args.outdir, 'Kconfig'))