mirror of https://github.com/postgres/postgres
Recent commits in the PG17 code added additional API changes, making the "single src directory with ifdefs" approach inpractical. This commit adds a new python based script (documented with comments in the file) to help with version specific merges, where the copied heap files reside in srcXX directories, where XX is the version.pull/209/head
parent
f9ed3ce2ca
commit
6cbd7c879a
@ -1,9 +1,10 @@ |
||||
*.so |
||||
*.o |
||||
__pycache__ |
||||
|
||||
/config.cache |
||||
/config.log |
||||
/config.status |
||||
/Makefile |
||||
/autom4te.cache |
||||
/configure~ |
||||
/configure~ |
||||
|
@ -1,409 +0,0 @@ |
||||
#!/bin/bash |
||||
|
||||
# SCRIPT: patch_generator.sh |
||||
#----------------------------- |
||||
# This script generates patch between two PG commits and applies it to |
||||
# the TDE extension source. |
||||
|
||||
set -o pipefail |
||||
|
||||
## GLOBAL VARIABLES |
||||
export TDE="tde" |
||||
export SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" |
||||
|
||||
export WORKING_DIR="${WORKING_DIR:-$(mktemp -d -t $TDE)}" |
||||
export TDE_DIR="${WORKING_DIR}/tde" |
||||
export USER_TDE_DIR="" |
||||
export PG_COMMIT_BASE="${PG_COMMIT_BASE}" |
||||
export PG_COMMIT_LATEST="${PG_COMMIT_BASE}" |
||||
export TDE_COMMIT="${TDE_COMMIT}" |
||||
|
||||
export FILES_BASE_DIR="pg_base" |
||||
export FILES_LATEST_DIR="pg_latest" |
||||
export FILES_PATCH_DIR="pg_patches" |
||||
export TDE_DRY_RUN="--dry-run" |
||||
export APPLY_PATCHES_FORCE=0 |
||||
|
||||
# Script variables |
||||
total_patches=0 |
||||
total_patches_failed=0 |
||||
|
||||
declare -a patch_list_unclean=() |
||||
|
||||
declare -a pg_header_file_map=("visibilitymap.h" "rewriteheap.h" "heapam_xlog.h" "hio.h" "heapam.h" "heaptoast.h") |
||||
declare -a tde_header_file_map=("pg_tde_visibilitymap.h" "pg_tde_rewrite.h" "pg_tdeam_xlog.h" "pg_tde_io.h" "pg_tdeam.h" "pg_tdetoast.h") |
||||
|
||||
declare -a pg_c_file_map=("heapam.c" "heapam_handler.c" "heapam_visibility.c" "heaptoast.c" "hio.c" "pruneheap.c" "rewriteheap.c" "vacuumlazy.c" "visibilitymap.c") |
||||
declare -a tde_c_file_map=("pg_tdeam.c" "pg_tdeam_handler.c" "pg_tdeam_visibility.c" "pg_tdetoast.c" "pg_tde_io.c" "pg_tde_prune.c" "pg_tde_rewrite.c" "pg_tde_vacuumlazy.c" "pg_tde_visibilitymap.c") |
||||
|
||||
|
||||
## USAGE |
||||
usage() |
||||
{ |
||||
errorCode=${1:-0} |
||||
|
||||
cat << EOF |
||||
|
||||
usage: $0 OPTIONS |
||||
|
||||
This script generates file-wise patches between two PG commits and applies it to |
||||
the TDE extension source. |
||||
|
||||
By default, it only performs a dry run of the patch application. See the usage |
||||
options below for applying clean patches or forcefully applying all patches. |
||||
|
||||
It clones both PG and TDE repositories in the working directory. If TDE path is |
||||
specified either with its usage option or via the environment variable, then |
||||
the script will use the given TDE source code. |
||||
|
||||
* All working folders folders created will carry "$TDE" as part of the folder name. |
||||
* This simplies the manual cleanup process. |
||||
|
||||
OPTIONS can be: |
||||
|
||||
-h Show this message |
||||
|
||||
-a The patches are not applied by default. Specify this to |
||||
apply the generated patches. Otherwise, the script will |
||||
only perform a dryrun. |
||||
|
||||
-f Force apply patches. |
||||
|
||||
-b [PG_COMMIT_BASE] PG base commit hash/branch/tag for patch [REQUIRED] |
||||
-l [PG_COMMIT_LATEST] PG lastest commit hash/branch/tag for patch [REQUIRED] |
||||
-x [TDE_COMMIT] TDE commit hash/branch/tag to apply patch on [REQUIRED] |
||||
|
||||
-t [USER_TDE_DIR] Source directory for TDE [Default: Cloned under WORKING_DIR] |
||||
-w [WORKING_DIR] Script working folder [Default: $WORKING_DIR] |
||||
* a folder where patches and relevant log |
||||
files may be created. This folder will not be removed |
||||
by the script, so better to keep it in the temp folder. |
||||
|
||||
EOF |
||||
|
||||
if [[ $errorCode -ne 0 ]]; |
||||
then |
||||
exit_script $errorCode |
||||
fi |
||||
} |
||||
|
||||
# Perform any required cleanup and exit with the given error/success code |
||||
exit_script() |
||||
{ |
||||
# Reminder of manual cleanup |
||||
if [[ -d $WORKING_DIR ]]; |
||||
then |
||||
printf "\n%20s\n" | tr " " "-" |
||||
printf "The following folder was created by the script and may require manual removal.\n" |
||||
printf "* %s\n" $WORKING_DIR |
||||
printf "%20s\n" | tr " " "-" |
||||
fi |
||||
|
||||
# Exit with a given return code or 0 if none are provided. |
||||
exit ${1:-0} |
||||
} |
||||
|
||||
# Raise the error for a failure to checkout required source |
||||
checkout_validate() |
||||
{ |
||||
commit=$1 |
||||
retval=$2 |
||||
|
||||
if [[ $rteval -ne 0 ]]; |
||||
then |
||||
printf "%s is not a valid commit hash/branch/tag.\n" $commit |
||||
exit_script $retval |
||||
fi |
||||
} |
||||
|
||||
# Vaildate arguments to ensure that we can safely run the benchmark |
||||
validate_args() |
||||
{ |
||||
local USAGE_TEXT="See usage for details." |
||||
local PATH_ERROR_TEXT="path is not a valid directory." |
||||
|
||||
if [[ ! -z "$USER_TDE_DIR" ]]; |
||||
then |
||||
if [[ ! -d "$USER_TDE_DIR" ]]; |
||||
then |
||||
printf "TDE %s %s\n" $PATH_ERROR_TEXT $USAGE_TEXT >&2 |
||||
usage 1 |
||||
fi |
||||
elif [[ -z "$TDE_COMMIT" ]]; |
||||
then |
||||
printf "TDE_COMMIT is not specified. %s\n" $USAGE_TEXT >&2 |
||||
usage 1 |
||||
fi |
||||
|
||||
|
||||
if [[ ! -d "$WORKING_DIR" ]]; |
||||
then |
||||
printf "Working folder %s %s\n" $PATH_ERROR_TEXT $USAGE_TEXT >&2 |
||||
usage 1 |
||||
fi |
||||
|
||||
if [[ -z "$PG_COMMIT_BASE" ]]; |
||||
then |
||||
printf "PG_COMMIT_BASE is not specified. %s\n" $USAGE_TEXT >&2 |
||||
usage 1 |
||||
fi |
||||
|
||||
if [[ -z "$PG_COMMIT_LATEST" ]]; |
||||
then |
||||
printf "PG_COMMIT_LATEST is not specified. %s\n" $USAGE_TEXT >&2 |
||||
usage 1 |
||||
fi |
||||
} |
||||
|
||||
# Print the file mapping between PG and TDE |
||||
print_map() |
||||
{ |
||||
printf "\n" |
||||
printf "%50s\n" | tr " " "=" |
||||
printf "%s\n" "Heap Access to TDE File Map" |
||||
printf "%50s\n\n" | tr " " "=" |
||||
|
||||
printf "%s\n" "--- Header Files ---" |
||||
for (( i=0; i < ${#pg_header_file_map[@]}; i++ )); |
||||
do |
||||
printf "* %-20s --> %s\n" ${pg_header_file_map[$i]} ${tde_header_file_map[$i]} |
||||
done |
||||
|
||||
printf "\n" |
||||
printf "%s\n" "--- C Files ---" |
||||
for (( i=0; i < ${#pg_c_file_map[@]}; i++ )); |
||||
do |
||||
printf "* %-20s --> %s\n" ${pg_c_file_map[$i]} ${tde_c_file_map[$i]} |
||||
done |
||||
|
||||
printf "\n\n" |
||||
} |
||||
|
||||
# Copy files from the PG source to the a separate folder. |
||||
# This function expects that we don't have duplicate file names. |
||||
copy_files() |
||||
{ |
||||
local dest_folder=$1 |
||||
shift |
||||
local file_list=("$@") |
||||
retval=0 |
||||
|
||||
for f in "${file_list[@]}"; |
||||
do |
||||
find * -name $f -exec cp -rpv {} $dest_folder \; |
||||
retval=$? |
||||
|
||||
if [[ $retval -ne 0 ]]; |
||||
then |
||||
exit_script $retval |
||||
fi |
||||
done |
||||
} |
||||
|
||||
# Compare two files and generate a patch |
||||
generate_file_patch() |
||||
{ |
||||
f_base=$1 |
||||
f_latest=$2 |
||||
f_patch=$3 |
||||
|
||||
diff -u $f_base $f_latest > $f_patch |
||||
|
||||
if [[ ! -s $f_patch ]]; |
||||
then |
||||
rm -fv $f_patch |
||||
else |
||||
total_patches=$(expr $total_patches + 1) |
||||
fi |
||||
} |
||||
|
||||
# Apply a given patch on a given file |
||||
apply_file_patch() |
||||
{ |
||||
local file_to_patch=$1 |
||||
local patch_file=$2 |
||||
local apply_patch=${APPLY_PATCHES_FORCE} |
||||
|
||||
echo "===> $APPLY_PATCHES_FORCE ==> $apply_patch" |
||||
|
||||
if [[ -f $patch_file ]]; |
||||
then |
||||
find * -name $file_to_patch | xargs -I{} echo "patch -p1 -t --dry-run {} $patch_file" | sh |
||||
|
||||
if [[ $? -ne 0 ]]; |
||||
then |
||||
total_patches_failed=$(expr $total_patches_failed + 1) |
||||
patch_list_unclean+=($(basename $patch_file)) |
||||
patch_list_unclean+=($(basename $file_to_patch)) |
||||
elif [[ -z "$TDE_DRY_RUN" ]]; |
||||
then |
||||
apply_patch=1 |
||||
fi |
||||
|
||||
echo "ABOUT TO APPLY PATCH" |
||||
|
||||
if [[ $apply_patch -eq 1 ]]; |
||||
then |
||||
echo "APPLYING PACH" |
||||
find * -name $file_to_patch | xargs -I{} echo "patch -p1 -t {} $patch_file" | sh |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
# Generate file-wise patches using the |
||||
generate_pg_patches() |
||||
{ |
||||
retval=0 |
||||
|
||||
mkdir $FILES_BASE_DIR |
||||
mkdir $FILES_LATEST_DIR |
||||
mkdir $FILES_PATCH_DIR |
||||
|
||||
git clone https://github.com/postgres/postgres.git |
||||
|
||||
# go into the postgres directory |
||||
pushd postgres |
||||
|
||||
# safety net to ensure that any changes introduced due to git configuration are cleaned up |
||||
git checkout . |
||||
|
||||
#checkout base source code |
||||
git checkout $PG_COMMIT_BASE |
||||
checkout_validate $PG_COMMIT_BASE $? |
||||
copy_files "$WORKING_DIR/$FILES_BASE_DIR" "${pg_header_file_map[@]}" |
||||
copy_files "$WORKING_DIR/$FILES_BASE_DIR" "${pg_c_file_map[@]}" |
||||
|
||||
# safety net to ensure that any changes introduced due to git configuration are cleaned up |
||||
git checkout . |
||||
|
||||
# do the latest checkout |
||||
git checkout $PG_COMMIT_LATEST |
||||
checkout_validate $PG_COMMIT_LATEST $? |
||||
copy_files "$WORKING_DIR/$FILES_LATEST_DIR" "${pg_header_file_map[@]}" |
||||
copy_files "$WORKING_DIR/$FILES_LATEST_DIR" "${pg_c_file_map[@]}" |
||||
|
||||
# go back to the old directory |
||||
popd |
||||
|
||||
# generate patches for the header files |
||||
for f in "${pg_header_file_map[@]}"; |
||||
do |
||||
generate_file_patch "$FILES_BASE_DIR/$f" "$FILES_LATEST_DIR/$f" "$FILES_PATCH_DIR/$f.patch" |
||||
done |
||||
|
||||
# generate patches for the c files |
||||
for f in "${pg_c_file_map[@]}"; |
||||
do |
||||
generate_file_patch "$FILES_BASE_DIR/$f" "$FILES_LATEST_DIR/$f" "$FILES_PATCH_DIR/$f.patch" |
||||
done |
||||
} |
||||
|
||||
# Apply patches to the TDE sources |
||||
tde_apply_patches() |
||||
{ |
||||
# check if the $TDE folder exists. If not, then we have to clone it |
||||
if [[ ! -d "$TDE_DIR" ]]; |
||||
then |
||||
t="$(basename $TDE_DIR)" |
||||
git clone https://github.com/Percona-Lab/pg_tde.git $t |
||||
fi |
||||
|
||||
pushd $TDE_DIR |
||||
|
||||
# do the required checkout |
||||
git checkout $TDE_COMMIT |
||||
checkout_validate $TDE_COMMIT $? |
||||
|
||||
# apply patches to the header files |
||||
for (( i=0; i < ${#pg_header_file_map[@]}; i++ )); |
||||
do |
||||
patch_file=$WORKING_DIR/$FILES_PATCH_DIR/${pg_header_file_map[$i]}.patch |
||||
apply_file_patch ${tde_header_file_map[$i]} $patch_file |
||||
done |
||||
|
||||
# apply patches to the header files |
||||
for (( i=0; i < ${#pg_c_file_map[@]}; i++ )); |
||||
do |
||||
patch_file=$WORKING_DIR/$FILES_PATCH_DIR/${pg_c_file_map[$i]}.patch |
||||
apply_file_patch ${tde_c_file_map[$i]} $patch_file |
||||
done |
||||
} |
||||
|
||||
# Check options passed in. |
||||
while getopts "haf t:b:l:w:x:" OPTION |
||||
do |
||||
case $OPTION in |
||||
h) |
||||
usage |
||||
exit_script 1 |
||||
;; |
||||
|
||||
a) |
||||
TDE_DRY_RUN="" |
||||
;; |
||||
|
||||
f) |
||||
APPLY_PATCHES_FORCE=1 |
||||
;; |
||||
b) |
||||
PG_COMMIT_BASE=$OPTARG |
||||
;; |
||||
l) |
||||
PG_COMMIT_LATEST=$OPTARG |
||||
;; |
||||
t) |
||||
TDE_DIR=$OPTARG |
||||
;; |
||||
w) |
||||
WORK_DIR=$OPTARG |
||||
;; |
||||
x) |
||||
TDE_COMMIT=$OPTARG |
||||
;; |
||||
|
||||
?) |
||||
usage |
||||
exit_script |
||||
;; |
||||
esac |
||||
done |
||||
|
||||
# Validate and update setup |
||||
validate_args |
||||
|
||||
# print the file map |
||||
print_map |
||||
|
||||
# Let's move to the working directory |
||||
pushd $WORKING_DIR |
||||
|
||||
# generate pg patches between the two commits |
||||
generate_pg_patches |
||||
|
||||
# apply patches |
||||
tde_apply_patches |
||||
|
||||
# We're done... |
||||
printf "\nJob completed!\n" |
||||
|
||||
printf "\n\n" |
||||
printf "%50s\n" | tr " " "=" |
||||
printf "RESULT SUMMARY\n" |
||||
printf "%50s\n" | tr " " "=" |
||||
printf "Patches Generated = %s\n" $total_patches |
||||
printf "Patches Applied = %s\n" $(expr $total_patches - $total_patches_failed) |
||||
printf "Patches Failed = %s\n" $total_patches_failed |
||||
|
||||
if [[ ${#patch_list_unclean[@]} -gt 0 ]]; |
||||
then |
||||
printf "=> Failed Patch List\n" |
||||
fi |
||||
|
||||
for (( i=0; i < ${#patch_list_unclean[@]}; i++ )); |
||||
do |
||||
printf "* %s --> %s\n" ${patch_list_unclean[$i]} ${patch_list_unclean[$(expr $i + 1)]} |
||||
i=$(expr $i + 1) |
||||
done |
||||
|
||||
# Perform clean up and exit. |
||||
exit_script 0 |
@ -0,0 +1,25 @@ |
||||
# These first few lines are only for the initial run, but should be harmless in later runs |
||||
s/\theap_/\ttdeheap_/g |
||||
s/\t\*heap_/\t*tdeheap_/g |
||||
s/ heap_/ tdeheap_/g |
||||
s/ \*heap_/ *tdeheap_/g |
||||
s/(heap_/ (tdeheap_/g |
||||
s/^heap_/tdeheap_/g |
||||
s/_heap_/_tdeheap_/g |
||||
s/-heap_/-tdeheap_/g |
||||
s/+heap_/+tdeheap_/g |
||||
s/!heap_/!tdeheap_/g |
||||
s/heapam_/pg_tdeam_/g |
||||
s/heap2_/tdeheap2_/g |
||||
s/heapgettup/tdeheapgettup/g |
||||
s/heapgetpage/tdeheapgetpage/g |
||||
s/visibilitymap_/tdeheap_visibilitymap_/g |
||||
s/RelationPutHeapTuple/tdeheap_RelationPutHeapTuple/g |
||||
s/RelationGetBufferForTuple/tdeheap_RelationGetBufferForTuple/g |
||||
s/TTSOpsBufferHeapTuple/TTSOpsTDEBufferHeapTuple/g |
||||
s/TTS_IS_BUFFERTUPLE/TTS_IS_TDE_BUFFERTUPLE/g |
||||
s/toast_tuple_externalize/tdeheap_toast_tuple_externalize/g |
||||
# Repairing error by earlier rule |
||||
s/num_tdeheap_tuples/num_heap_tuples/g |
||||
s/pgstat_update_tdeheap_dead_tuples/pgstat_update_heap_dead_tuples/g |
||||
s/tdeheap_xlog_deserialize_prune_and_freeze/heap_xlog_deserialize_prune_and_freeze/g |
@ -0,0 +1,198 @@ |
||||
# Simple helper script for upstream merges to the copied heap code |
||||
# It implements a few simple steps which can be used to automate |
||||
# most operations |
||||
# |
||||
# Generally this script assumes that pg_tde is checked out as a |
||||
# submodule inside postgres, in the contrib/pg_tde directory. |
||||
# |
||||
# Most methods interact with the currently checked out version |
||||
# of postgres, this part is not automated at all. Select the |
||||
# correct commit before executing functions! |
||||
# |
||||
# == copy <dst_folder> |
||||
# |
||||
# Copies the required heapam source files from the postgres repo, |
||||
# to the specified <dst_folder> inside the pg_tde repo. Also |
||||
# renames the files, places them in the correct directory, and |
||||
# runs the automatic sed replacement script. |
||||
# |
||||
# The sed replacements only cover the name changes, mainly changing "heap" |
||||
# to "tdeheap". It doesn't apply the actual encryption changes! |
||||
# |
||||
# It also creates a file named "COMMIT" in the directory, which contains the |
||||
# commit hash used. |
||||
# |
||||
# == diff <folder1> <folder2> <diff_folder> |
||||
# |
||||
# Runs diff on the tdeheap files between <folder1> and <folder2>, and places |
||||
# the results into <diff_folder> |
||||
# |
||||
# The assumption is that <folder1> contains the copied, but not TDEfied |
||||
# version of the files, while <folder2> is the actual current TDEfied code, |
||||
# and that way this command creates the "tde patch" for the given commit. |
||||
# |
||||
# For example, assuming that we have the PG16 tde sources in the src16 |
||||
# directory, these steps create a diff for the current sources: |
||||
# 1. check out the src16/COMMIT commit |
||||
# 2. run `copy tmp_16dir` |
||||
# 3. run `diff tmp_16dir src16 diff16` |
||||
# 4. delete the tmp_16dir directory |
||||
# |
||||
# == apply <target_folder> <diff_folder> |
||||
# |
||||
# Applies the diffs created by the diff command from the <diff_folder> to the |
||||
# <target_folder> source directory. |
||||
# |
||||
# When the diff can't be applied cleanly, and there are conflicts, it still |
||||
# writes the file with conflicts, using the diff3 format (usual git conflict |
||||
# markers). which can be resolved manually. |
||||
# |
||||
# The recommended action in this case is to first create a commit with the |
||||
# conflicts as-is, and then create a separate commit with the conflicts |
||||
# resolved and the code working. |
||||
# |
||||
# This is mainly intended for version upgrades. |
||||
# For example, if the current version is 16, and the goal is creating the 17 |
||||
# version: |
||||
# 1. create the src16 diff using the steps described in the `diff` section |
||||
# 2. checkout the 17 version in the postgres repo |
||||
# 3. use the copy command to create a base directory for the 17 version |
||||
# 4. create a commit with the src17 basefiles |
||||
# 5. use the apply command to apply the patches |
||||
# 6. commit things with conflicts |
||||
# 7. resolve the conflicts as needed |
||||
# 8. commit resolved/working sources |
||||
|
||||
|
||||
import shutil |
||||
import os |
||||
import subprocess |
||||
import sys |
||||
|
||||
tools_directory = os.path.dirname(os.path.realpath(__file__)) |
||||
|
||||
pg_root = tools_directory + "/../../../" |
||||
heapam_src_dir = pg_root + "src/backend/access/heap/" |
||||
heapam_inc_dir = pg_root + "src/include/access/" |
||||
|
||||
tde_root = tools_directory + "/../" |
||||
|
||||
heapam_headers = { |
||||
"visibilitymap.h": "pg_tde_visibilitymap.h", |
||||
"rewriteheap.h": "pg_tde_rewrite.h", |
||||
"heapam_xlog.h": "pg_tdeam_xlog.h", |
||||
"hio.h": "pg_tde_io.h", |
||||
"heapam.h": "pg_tdeam.h", |
||||
"heaptoast.h": "pg_tdetoast.h" |
||||
} |
||||
|
||||
heapam_sources = { |
||||
"heapam.c": "pg_tdeam.c", |
||||
"heapam_handler.c": "pg_tdeam_handler.c", |
||||
"heapam_visibility.c": "pg_tdeam_visibility.c", |
||||
"heaptoast.c": "pg_tdetoast.c", |
||||
"hio.c": "pg_tde_io.c", |
||||
"pruneheap.c": "pg_tde_prune.c", |
||||
"rewriteheap.c": "pg_tde_rewrite.c", |
||||
"vacuumlazy.c": "pg_tde_vacuumlazy.c", |
||||
"visibilitymap.c": "pg_tde_visibilitymap.c", |
||||
} |
||||
|
||||
def copy_and_sed_things(files, src, dst): |
||||
os.makedirs(dst, exist_ok=True) |
||||
for original,copy in files.items(): |
||||
print(" - ", original, "=>", copy) |
||||
shutil.copyfile(src+original, dst+copy) |
||||
subprocess.call(["sed", "-i", "-f", tools_directory + "/repl.sed", dst+copy]) |
||||
|
||||
def copy_upstream_things(dstdir): |
||||
print("Processing headers") |
||||
copy_and_sed_things(heapam_headers, heapam_inc_dir, tde_root + dstdir + "/include/access/") |
||||
print("Processing sources") |
||||
copy_and_sed_things(heapam_sources, heapam_src_dir, tde_root + dstdir + "/access/") |
||||
# Also create a commit file |
||||
cwd = os.getcwd() |
||||
os.chdir(pg_root) |
||||
commit_hash = subprocess.check_output(["git", "rev-parse", "HEAD"]) |
||||
os.chdir(cwd) |
||||
f = open(tde_root + dstdir + "/COMMIT", "w") |
||||
f.write(commit_hash.decode("utf-8")) |
||||
f.close() |
||||
|
||||
|
||||
def save_diffs(files, src, dst, diffdir): |
||||
os.makedirs(tde_root + "/" + diffdir, exist_ok=True) |
||||
for _,copy in files.items(): |
||||
print(" - ", copy + ".patch") |
||||
diff = subprocess.run(["diff", "-u", tde_root+src+"/"+copy, tde_root+dst+"/"+copy], stdout = subprocess.PIPE, stderr=subprocess.PIPE, check=False) |
||||
f = open(tde_root + "/" + diffdir + "/" + copy + ".patch", "w") |
||||
f.write(diff.stdout.decode("utf-8")) |
||||
f.close() |
||||
|
||||
def diff_things(src, dst, diffdir): |
||||
print("Processing headers") |
||||
save_diffs(heapam_headers, src + "/include/access/", dst + "/include/access/", diffdir) |
||||
print("Processing sources") |
||||
save_diffs(heapam_sources, src + "/access/", dst + "/access/", diffdir) |
||||
|
||||
def apply_diffs(files, dst, diffdir): |
||||
for _,copy in files.items(): |
||||
print(" - ", copy + ".patch") |
||||
patch = subprocess.run(["patch", "--merge=diff3", "-l", "--no-backup-if-mismatch", tde_root+dst+"/"+copy, tde_root+"/"+diffdir+"/"+copy+".patch"], stdout = subprocess.PIPE, stderr=subprocess.PIPE, check=False) |
||||
print(patch.stdout.decode("utf-8")) |
||||
print(patch.stderr.decode("utf-8")) |
||||
|
||||
def apply_things(dst, diffdir): |
||||
print("Processing headers") |
||||
apply_diffs(heapam_headers, dst + "/include/access/", diffdir) |
||||
print("Processing sources") |
||||
apply_diffs(heapam_sources, dst + "/access/", diffdir) |
||||
|
||||
def rm_files(files, src): |
||||
for _,copy in files.items(): |
||||
print(" - RM ", copy) |
||||
os.remove(tde_root+src+"/"+copy) |
||||
|
||||
def rm_things(srcdir): |
||||
print("Processing headers") |
||||
rm_files(heapam_headers, srcdir + "/include/access/") |
||||
print("Processing sources") |
||||
rm_files(heapam_sources, srcdir + "/access/") |
||||
|
||||
if len(sys.argv) < 2: |
||||
print("No command given! Commands:") |
||||
print(" - copy") |
||||
print(" - diff") |
||||
print(" - ppply") |
||||
print(" - rm ") |
||||
exit() |
||||
|
||||
if sys.argv[1] == "copy": |
||||
if len(sys.argv) < 3: |
||||
print("No target directory given!") |
||||
print("Usage: tool.py copy <dstdir>") |
||||
exit() |
||||
copy_upstream_things(sys.argv[2]) |
||||
|
||||
if sys.argv[1] == "diff": |
||||
if len(sys.argv) < 5: |
||||
print("Not enough parameters!") |
||||
print("Usage: tool.py diff <copied_dir> <current_dir> <diff_dir>") |
||||
exit() |
||||
diff_things(sys.argv[2], sys.argv[3], sys.argv[4]) |
||||
|
||||
if sys.argv[1] == "apply": |
||||
if len(sys.argv) < 4: |
||||
print("Not enough parameters!") |
||||
print("Usage: tool.py patch <src_dir> <diff_dir>") |
||||
exit() |
||||
apply_things(sys.argv[2], sys.argv[3]) |
||||
|
||||
|
||||
|
||||
if sys.argv[1] == "rm": |
||||
if len(sys.argv) < 3: |
||||
print("No target directory given!") |
||||
print("Usage: tool.py rm <dstdir>") |
||||
exit() |
||||
rm_things(sys.argv[2]) |
Loading…
Reference in new issue