From 6cbd7c879af77d66d9012c829123ec8321f6ef8c Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Sun, 4 Aug 2024 20:17:22 +0100 Subject: [PATCH] Added new merging script and updated build scripts accordingly 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. --- .gitignore | 3 +- Makefile.in | 18 +- meson.build | 23 +-- tools/heap_merge.sh | 409 -------------------------------------------- tools/repl.sed | 25 +++ tools/tool.py | 198 +++++++++++++++++++++ 6 files changed, 247 insertions(+), 429 deletions(-) delete mode 100644 tools/heap_merge.sh create mode 100644 tools/repl.sed create mode 100644 tools/tool.py diff --git a/.gitignore b/.gitignore index 5f9bebe5dab..684ce2426e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ *.so *.o +__pycache__ /config.cache /config.log /config.status /Makefile /autom4te.cache -/configure~ \ No newline at end of file +/configure~ diff --git a/Makefile.in b/Makefile.in index 5b4d98bfb68..2ac378cbe71 100644 --- a/Makefile.in +++ b/Makefile.in @@ -24,16 +24,16 @@ TAP_TESTS = 1 OBJS = src/encryption/enc_tde.o \ src/encryption/enc_aes.o \ src/access/pg_tde_slot.o \ -src/access/pg_tde_io.o \ -src/access/pg_tdeam_visibility.o \ src/access/pg_tde_tdemap.o \ -src/access/pg_tdeam.o \ -src/access/pg_tdetoast.o \ -src/access/pg_tde_prune.o \ -src/access/pg_tde_vacuumlazy.o \ -src/access/pg_tde_visibilitymap.o \ -src/access/pg_tde_rewrite.o \ -src/access/pg_tdeam_handler.o \ +src$(MAJORVERSION)/access/pg_tde_io.o \ +src$(MAJORVERSION)/access/pg_tdeam_visibility.o \ +src$(MAJORVERSION)/access/pg_tdeam.o \ +src$(MAJORVERSION)/access/pg_tdetoast.o \ +src$(MAJORVERSION)/access/pg_tde_prune.o \ +src$(MAJORVERSION)/access/pg_tde_vacuumlazy.o \ +src$(MAJORVERSION)/access/pg_tde_visibilitymap.o \ +src$(MAJORVERSION)/access/pg_tde_rewrite.o \ +src$(MAJORVERSION)/access/pg_tdeam_handler.o \ src/access/pg_tde_ddl.o \ src/access/pg_tde_xlog.o \ src/transam/pg_tde_xact_handler.o \ diff --git a/meson.build b/meson.build index 6445442dcc2..b217ebae9cb 100644 --- a/meson.build +++ b/meson.build @@ -13,20 +13,23 @@ conf_data.set_quoted('PACKAGE_TARNAME', 'pg_tde') configure_file(output : 'config.h', configuration : conf_data) +pg_version = meson.project_version().substring(0,2) +src_version = 'src' + pg_version + pg_tde_sources = files( 'src/pg_tde.c', 'src/transam/pg_tde_xact_handler.c', 'src/access/pg_tde_tdemap.c', 'src/access/pg_tde_slot.c', - 'src/access/pg_tdeam.c', - 'src/access/pg_tdeam_handler.c', - 'src/access/pg_tdeam_visibility.c', - 'src/access/pg_tdetoast.c', - 'src/access/pg_tde_io.c', - 'src/access/pg_tde_prune.c', - 'src/access/pg_tde_rewrite.c', - 'src/access/pg_tde_vacuumlazy.c', - 'src/access/pg_tde_visibilitymap.c', + src_version / 'access/pg_tdeam.c', + src_version / 'access/pg_tdeam_handler.c', + src_version / 'access/pg_tdeam_visibility.c', + src_version / 'access/pg_tdetoast.c', + src_version / 'access/pg_tde_io.c', + src_version / 'access/pg_tde_prune.c', + src_version / 'access/pg_tde_rewrite.c', + src_version / 'access/pg_tde_vacuumlazy.c', + src_version / 'access/pg_tde_visibilitymap.c', 'src/access/pg_tde_ddl.c', 'src/access/pg_tde_xlog.c', @@ -51,7 +54,7 @@ pg_tde_sources = files( 'src/pg_tde_event_capture.c', ) -incdir = include_directories('src/include', '.') +incdir = include_directories(src_version / 'include', 'src/include', '.') deps_update = {'dependencies': contrib_mod_args.get('dependencies') + [curldep]} diff --git a/tools/heap_merge.sh b/tools/heap_merge.sh deleted file mode 100644 index ad305e3569b..00000000000 --- a/tools/heap_merge.sh +++ /dev/null @@ -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 diff --git a/tools/repl.sed b/tools/repl.sed new file mode 100644 index 00000000000..2cac8e82899 --- /dev/null +++ b/tools/repl.sed @@ -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 \ No newline at end of file diff --git a/tools/tool.py b/tools/tool.py new file mode 100644 index 00000000000..a66b0efb589 --- /dev/null +++ b/tools/tool.py @@ -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 +# +# Copies the required heapam source files from the postgres repo, +# to the specified 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 +# +# Runs diff on the tdeheap files between and , and places +# the results into +# +# The assumption is that contains the copied, but not TDEfied +# version of the files, while 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 +# +# Applies the diffs created by the diff command from the to the +# 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 ") + 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 ") + 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 ") + 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 ") + exit() + rm_things(sys.argv[2]) \ No newline at end of file