should be it
This commit is contained in:
99
external/duckdb/scripts/apply_extension_patches.py
vendored
Normal file
99
external/duckdb/scripts/apply_extension_patches.py
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import glob
|
||||
import subprocess
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
# Get the directory and construct the patch file pattern
|
||||
directory = sys.argv[1]
|
||||
patch_pattern = f"{directory}*.patch"
|
||||
|
||||
# Find patch files matching the pattern
|
||||
patches = glob.glob(patch_pattern)
|
||||
|
||||
|
||||
def raise_error(error_msg):
|
||||
sys.stderr.write(error_msg + '\n')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
patches = sorted(os.listdir(directory))
|
||||
for patch in patches:
|
||||
if not patch.endswith('.patch'):
|
||||
raise_error(
|
||||
f'Patch file {patch} found in directory {directory} does not end in ".patch" - rename the patch file'
|
||||
)
|
||||
|
||||
|
||||
# Exit if no patches are found
|
||||
if not patches:
|
||||
error_message = (
|
||||
f"\nERROR: Extension patching enabled, but no patches found in '{directory}'. "
|
||||
"Please make sure APPLY_PATCHES is only enabled when there are actually patches present. "
|
||||
"See .github/patches/extensions/README.md for more details."
|
||||
)
|
||||
raise_error(error_message)
|
||||
|
||||
|
||||
current_dir = os.getcwd()
|
||||
print(f"Applying patches at '{current_dir}'")
|
||||
print(f"Resetting patches in {directory}\n")
|
||||
|
||||
# capture the current diff
|
||||
diff_proc = subprocess.run(["git", "diff"], capture_output=True, check=True)
|
||||
prev_diff = diff_proc.stdout
|
||||
|
||||
output_proc = subprocess.run(["git", "diff", "--numstat"], capture_output=True, check=True)
|
||||
prev_output_lines = output_proc.stdout.decode('utf8').split('\n')
|
||||
prev_output_lines.sort()
|
||||
|
||||
subprocess.run(["git", "clean", "-f"], check=True)
|
||||
subprocess.run(["git", "reset", "--hard", "HEAD"], check=True)
|
||||
|
||||
|
||||
def apply_patch(patch_file):
|
||||
ARGUMENTS = ["patch", "-p1", "--forward", "-i"]
|
||||
arguments = []
|
||||
arguments.extend(ARGUMENTS)
|
||||
arguments.append(patch_file)
|
||||
try:
|
||||
subprocess.run(arguments, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
except subprocess.CalledProcessError as e:
|
||||
arguments[1:1] = ['-d', current_dir]
|
||||
command = " ".join(arguments)
|
||||
print(f"Failed to apply patch, command to reproduce locally:\n{command}")
|
||||
print("\nError output:")
|
||||
print(e.stderr.decode('utf-8'))
|
||||
print("\nStandard output:")
|
||||
print(e.stdout.decode('utf-8'))
|
||||
print("Exiting")
|
||||
exit(1)
|
||||
|
||||
|
||||
# Apply each patch file using patch
|
||||
for patch in patches:
|
||||
print(f"Applying patch: {patch}\n")
|
||||
apply_patch(os.path.join(directory, patch))
|
||||
|
||||
# all patches have applied - check the current diff
|
||||
output_proc = subprocess.run(["git", "diff", "--numstat"], capture_output=True, check=True)
|
||||
output_lines = output_proc.stdout.decode('utf8').split('\n')
|
||||
output_lines.sort()
|
||||
|
||||
if len(output_lines) <= len(prev_output_lines) and prev_output_lines != output_lines:
|
||||
print("Detected local changes - rolling back patch application")
|
||||
|
||||
subprocess.run(["git", "clean", "-f"], check=True)
|
||||
subprocess.run(["git", "reset", "--hard", "HEAD"], check=True)
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
f.write(prev_diff)
|
||||
apply_patch(f.name)
|
||||
|
||||
print("--------------------------------------------------")
|
||||
print("Generate a patch file using the following command:")
|
||||
print("--------------------------------------------------")
|
||||
print(f"(cd {os.getcwd()} && git diff > {os.path.join(directory, 'fix.patch')})")
|
||||
print("--------------------------------------------------")
|
||||
|
||||
exit(1)
|
||||
Reference in New Issue
Block a user