aboutsummaryrefslogtreecommitdiffstats
path: root/bin/common/srtool_patcher.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/common/srtool_patcher.py')
-rwxr-xr-xbin/common/srtool_patcher.py190
1 files changed, 154 insertions, 36 deletions
diff --git a/bin/common/srtool_patcher.py b/bin/common/srtool_patcher.py
index ccf93060..bda941fc 100755
--- a/bin/common/srtool_patcher.py
+++ b/bin/common/srtool_patcher.py
@@ -59,12 +59,17 @@ import json
# Setup:
verbose = False
+INPLACE_TAG = 'INPLACE'
+DISABLE_TAG = 'DISABLE'
#################################
# extract_custom_patch
#
+# Extract a clean version of the file without the the custom sections,
+# and generate a patch file of those sections
+#
-def extract_custom_patch(custom_file,clean_file,patch_file,label,patcher_dir):
+def extract_custom_patch(custom_file,clean_file,patch_file,label,patcher_dir,options):
tag_begin = "%s_EXTENSION_BEGIN" % label
tag_end = "%s_EXTENSION_END" % label
ret = 0
@@ -108,18 +113,32 @@ def extract_custom_patch(custom_file,clean_file,patch_file,label,patcher_dir):
# Did we end cleanly?
if state != "find":
print("ERROR: START not STOPPED (%s)" % state)
- os.system("diff -u %s %s > %s" % (clean_file,custom_file,patch_file))
- print("Custom File: %s" % (custom_file))
- print("Clean File: %s" % (clean_file))
- print("Patch File: %s" % (patch_file))
+ if INPLACE_TAG in options:
+ cmd = "git diff %s > %s" % (custom_file,patch_file)
+ print(cmd)
+ os.system(cmd)
+ print("In-place File: %s" % (clean_file))
+ else:
+ os.system("diff -u %s %s > %s" % (clean_file,custom_file,patch_file))
+ print("Custom File: %s" % (custom_file))
+ print("Clean File: %s" % (clean_file))
+ print("Patch File: %s" % (patch_file))
return(ret,clean_file,patch_file)
#################################
# merge_original
#
+# Merge any changes in the original upstream file into the
+# custom file and reapply the custom patches, so that general upstream
+# changes be be included in the local custom file
+#
+
+def merge_original(custom_file,original_file,patch_file,label,patcher_dir,options):
+ # Skip if in-place
+ if INPLACE_TAG in options:
+ return 0
-def merge_original(custom_file,original_file,patch_file,label,patcher_dir):
- ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir)
+ ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir,options)
custom_saved = os.path.join(os.path.dirname(patch_file),os.path.basename(custom_file) + '.saved')
if 0 == ret:
print("* Preserving custom file as '%s'" % custom_saved)
@@ -143,9 +162,16 @@ def merge_original(custom_file,original_file,patch_file,label,patcher_dir):
#################################
# merge_custom
#
+# Merge any changes in the normal non-custom sections of the custom file back into
+# original file, so that general fixes can be shared upstream
+#
+
+def merge_custom(custom_file,original_file,patch_file,label,patcher_dir,options):
+ # Skip if in-place
+ if INPLACE_TAG in options:
+ return 0
-def merge_custom(custom_file,original_file,patch_file,label,patcher_dir):
- ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir)
+ ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir,options)
if 0 == ret:
print("== Copying clean version of custom file to '%s' ===" % original_file)
cmd = "cp -f %s %s" % (clean_file, original_file)
@@ -156,14 +182,102 @@ def merge_custom(custom_file,original_file,patch_file,label,patcher_dir):
#################################
# diff_original
#
+# Show how the general sections of the custom file compare to the
+# original file, so that the user can (a) see might be shared upstream,
+# and/or (b) insure the custom sections are correct and complete
+#
-def diff_original(custom_file,original_file,patch_file,label,patcher_dir):
- ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir)
+def diff_original(custom_file,original_file,patch_file,label,patcher_dir,options):
+ # Skip if in-place
+ if INPLACE_TAG in options:
+ return 0
+
+ ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir,options)
if 0 == ret:
print("== DIFF from '%s' to clean version of custom file ===" % original_file)
os.system("diff -u %s %s" % (original_file,clean_file))
return(ret)
+
+#################################
+# clean_inplace
+#
+# Stash the customized general file and replace it with a clean version
+# without the custom sections, so that general fixes can be shared upstream
+#
+
+def clean_inplace(custom_file,original_file,patch_file,label,patcher_dir,options):
+ print("FOO1:%s,%s" % (INPLACE_TAG,options))
+ # Skip if not in-place
+ if not INPLACE_TAG in options:
+ return 0
+
+ print("FOO2")
+ # Only continue if 'original' file has custom patches, in case this
+ # command is run multiple times by accident
+ cmd = "grep %s %s" % (label,original_file)
+ ret = os.system(cmd)
+ if 0 != ret:
+ print("ERROR:SKIP: original file '%s' does not have custom tags '%s'" % (original_file,label))
+ return ret
+
+ print("* Backup customized in-place file")
+ try:
+ os.makedirs(os.path.dirname(custom_file))
+ except:
+ pass
+ cmd = "cp --force %s %s" % (original_file,custom_file)
+ print(cmd)
+ os.system(cmd)
+
+ print("* Extract patch file (via 'git diff')")
+ clean_file = custom_file + '.clean'
+ patch_file = custom_file + '.patch'
+ ret,clean_file,patch_file = extract_custom_patch(original_file,clean_file,patch_file,label,'',options)
+ if 0 != ret:
+ return(ret)
+
+ print("* Copy cleaned version back to in-place location")
+ cmd = "cp --force %s %s" % (clean_file,original_file)
+ print(cmd)
+ ret = os.system(cmd)
+ return(ret)
+
+#################################
+# patch_inplace
+#
+# Re-apply the custom patches on top of the general file, so that general fixes can be adopted
+# from upstream together with the customized patches applied on top
+#
+
+def patch_inplace(custom_file,original_file,patch_file,label,patcher_dir,options):
+ # Skip if not in-place
+ if not INPLACE_TAG in options:
+ return 0
+
+ ret = 0
+ patch_file = custom_file + '.patch'
+ if not os.path.isfile(patch_file):
+ # No patch file found, do a simple copy-over of custom file
+ if not os.path.isfile(custom_file):
+ print("ERROR:SKIP: neither the patch file '%s' nor the custom file '%s' can be found" % (patch_file,custom_file))
+ return 1
+ print("* No patch file found, copying custom file over in-place file")
+ cmd = "cp -f %s %s" % (custom_file,original_file)
+ print(cmd)
+ ret = os.system(cmd)
+ else:
+ print("* Patching the in-place file with custom patch")
+ cmd = "patch %s %s" % (original_file,patch_file)
+ print(cmd)
+ ret = os.system(cmd)
+ if 0 != ret:
+ print("* ERROR: Merge failed, restoring previous custom file")
+ cmd = "cp %s %s" % (custom_saved,custom_file)
+ print(cmd)
+ os.system(cmd)
+ return(ret)
+
#################################
# load_json_list
#
@@ -182,7 +296,7 @@ def load_json_list(json_file):
patcher_dir = dct['patcher_dir']
if 'patch_set' in dct:
for patch in dct['patch_set']:
- if 'DISABLE' in patch['options']:
+ if DISABLE_TAG in patch['options']:
continue
file_list.append([patch['custom'],patch['original'],patch['patch'],patch['options']])
return file_list,patcher_dir,label
@@ -197,13 +311,17 @@ def main(argv):
# setup
parser = argparse.ArgumentParser(description='srtool_sanity_test.py: SRTool common sanity tests')
- parser.add_argument('--merge-original', '-O', action='store_const', const='merge_original', dest='command', help='Copy the (updated) original file, merge the custom patches')
- parser.add_argument('--merge-custom', '-C', action='store_const', const='merge_custom', dest='command', help='Copy the (updated) file to the original, without custom patches')
+ parser.add_argument('--merge-original', '-o', action='store_const', const='merge_original', dest='command', help='Copy the (updated) original file, merge the custom patches')
+ parser.add_argument('--merge-custom', '-c', action='store_const', const='merge_custom', dest='command', help='Copy the (updated) file to the original, without custom patches')
- parser.add_argument('--custom', '-c', help='Custom file')
- parser.add_argument('--original', '-o', help='Original file')
- parser.add_argument('--label', '-l', help='Custom label tag (default="CUSTOM")')
- parser.add_argument('--json', '-j', help='Use JSON file for file list')
+ parser.add_argument('--clean-inplace', '-i', action='store_const', const='clean_inplace', dest='command', help='Stash the customized file, leaving the clean mainline version inline')
+ parser.add_argument('--patch-inplace', '-I', action='store_const', const='patch_inplace', dest='command', help='Restore the customized file in place of the mainline version inline')
+
+ parser.add_argument('--json', '-J', help='Use JSON file for file list')
+ parser.add_argument('--custom', '-C', help='Custom file')
+ parser.add_argument('--original', '-O', help='Original file')
+ parser.add_argument('--label', '-L', help='Custom label tag (default="CUSTOM")')
+ parser.add_argument('--options', '-P', help='Options, for example "INPLACE", "DISABLE"')
parser.add_argument('--extract-custom-patch', '-e', action='store_const', const='extract_custom_patch', dest='command', help='Extract a patch of the custom content')
parser.add_argument('--patch', '-p', help='Patch file')
@@ -224,40 +342,40 @@ def main(argv):
validate_file(args.json,"JSON")
file_list,patcher_dir,label = load_json_list(args.json)
else:
- custom_file = ''
- if args.custom:
- custom_file = args.custom
- original_file = ''
- if args.original:
- original_file = args.original
- patch_file = ''
- if args.patch:
- patch_file = args.patch
- options = ''
+ original_file = args.original if args.original else ''
+ custom_file = args.custom if args.custom else ''
+ patch_file = args.patch if args.patch else ''
+ label = args.label if args.label else 'CUSTOM'
+ options = args.options if args.options else ''
file_list.append([custom_file,original_file,patch_file,options])
- label = 'CUSTOM'
- if args.label:
- label = args.label
patcher_dir = os.path.join(os.path.dirname(custom_file),'patcher')
ret = 0
for custom_file,original_file,patch_file,options in file_list:
- #print("PATCH_FILE:%s,%s,%s,%s,%s" % (custom_file,original_file,patch_file,options,patcher_dir))
+ #print("PATCH_FILE:%s,%s,%s,%s,%s,%s" % (custom_file,original_file,patch_file,options,patcher_dir,options))
if 'merge_original' == args.command:
validate_file(custom_file,'Custom')
validate_file(original_file,'Original')
- ret = merge_original(custom_file,original_file,patch_file,label,patcher_dir)
+ ret = merge_original(custom_file,original_file,patch_file,label,patcher_dir,options)
elif 'merge_custom' == args.command:
validate_file(custom_file,'Custom')
validate_file(original_file,'Original')
- ret = merge_custom(custom_file,original_file,patch_file,label,patcher_dir)
+ ret = merge_custom(custom_file,original_file,patch_file,label,patcher_dir,options)
+ elif 'clean_inplace' == args.command:
+ validate_file(custom_file,'Custom')
+ validate_file(original_file,'Original')
+ ret = clean_inplace(custom_file,original_file,patch_file,label,patcher_dir,options)
+ elif 'patch_inplace' == args.command:
+ validate_file(custom_file,'Custom')
+ validate_file(original_file,'Original')
+ ret = patch_inplace(custom_file,original_file,patch_file,label,patcher_dir,options)
elif 'extract_custom_patch' == args.command:
validate_file(custom_file,'Custom')
- ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir)
+ ret,clean_file,patch_file = extract_custom_patch(custom_file,'',patch_file,label,patcher_dir,options)
elif 'diff_original' == args.command:
validate_file(custom_file,'Custom')
validate_file(original_file,'Original')
- ret = diff_original(custom_file,original_file,patch_file,label,patcher_dir)
+ ret = diff_original(custom_file,original_file,patch_file,label,patcher_dir,options)
else:
print("Command not found '%s'" % args.command)
ret = 1