diff options
Diffstat (limited to 'uAssets/tools/update-diffpatches.sh')
-rwxr-xr-x | uAssets/tools/update-diffpatches.sh | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/uAssets/tools/update-diffpatches.sh b/uAssets/tools/update-diffpatches.sh new file mode 100755 index 0000000..406598e --- /dev/null +++ b/uAssets/tools/update-diffpatches.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +# +# This script assumes a linux environment + +set -e + +# To be executed at the root of CDN repo +# +# It's not being hosted at CDN because that +# repo is also used as a website + +REPO_DIR=$1 +if [[ -z $REPO_DIR ]]; then + echo "Error: repo directory is not provided, aborting" + exit 1 +fi + +PATCHES_DIR=$2 +if [[ -z $PATCHES_DIR ]]; then + echo "Error: patches directory is not provided, aborting" + exit 1 +fi + +FILTER_FILES=$3 +if [[ -z $FILTER_FILES ]]; then + echo "Error: filter lists are not provided, aborting" + exit 1 +fi +FILTER_FILES=( "$FILTER_FILES" ) + +PATCH_FILES=( $(ls -1v "$PATCHES_DIR"/*.patch | head -n -1) ) + +# Keep only the most recent (5-day x 4-per-day) patches +OBSOLETE_PATCHES=( $(ls -1v "$PATCHES_DIR"/*.patch | head -n -20) ) +for FILE in "${OBSOLETE_PATCHES[@]}"; do + echo "Removing obsolete patch $FILE" + git rm "$FILE" +done + +NEW_PATCH_FILE=$(mktemp) +DIFF_FILE=$(mktemp) + +for PATCH_FILE in "${PATCH_FILES[@]}"; do + + # Extract tag from patch file name + [[ ${PATCH_FILE} =~ ^$PATCHES_DIR/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.patch$ ]] && \ + PREVIOUS_VERSION=${BASH_REMATCH[1]} + + # This will receive a clone of an old version of the current repo + echo "Fetching repo at $PREVIOUS_VERSION version" + OLD_REPO=$(mktemp -d) + git clone -q --single-branch --branch "$PREVIOUS_VERSION" --depth=1 "https://github.com/$REPO_DIR.git" "$OLD_REPO" 2>/dev/null || true + + # Skip if version doesn't exist + if [ -z "$(ls -A "$OLD_REPO" 2>/dev/null)" ]; then + continue; + fi + + : > "$NEW_PATCH_FILE" + + for FILTER_LIST in ${FILTER_FILES[@]}; do + + if [ ! -f "$OLD_REPO/$FILTER_LIST" ]; then continue; fi + + # Patches are for filter lists supporting differential updates + if ! (head "$OLD_REPO/$FILTER_LIST" | grep -q '^! Diff-Path: '); then + continue + fi + + # Reference: + # https://github.com/ameshkov/diffupdates + + # Extract diff name from `! Diff-Path:` field + DIFF_NAME=$(grep -m 1 -oP '^! Diff-Path: [^#]+#?\K.*' "$FILTER_LIST") + # Fall back to `! Diff-Name:` field if no name found + # Remove once `! Diff-Name:` is no longer needed after transition + if [[ -z $DIFF_NAME ]]; then + DIFF_NAME=$(grep -m 1 -oP '^! Diff-Name: \K.+' "$FILTER_LIST") + fi + + # We need a patch name to generate a valid patch + if [[ -z $DIFF_NAME ]]; then + echo "Info: $FILTER_LIST is missing a patch name, skipping" + continue + fi + + # Compute the RCS diff between current version and new version + diff -n "$OLD_REPO/$FILTER_LIST" "$FILTER_LIST" > "$DIFF_FILE" || true + + FILE_CHECKSUM=$(sha1sum "$FILTER_LIST") + FILE_CHECKSUM=${FILE_CHECKSUM:0:10} + + DIFF_LINE_COUNT=$(wc -l < "$DIFF_FILE") + + # Patch header + DIFF_HEAD="diff name:$DIFF_NAME lines:$DIFF_LINE_COUNT checksum:$FILE_CHECKSUM" + printf "\tAdding diff: %s\n" "$DIFF_HEAD" + echo "$DIFF_HEAD" >> "$NEW_PATCH_FILE" + # Patch data + cat "$DIFF_FILE" >> "$NEW_PATCH_FILE" + + done + + rm -rf "$OLD_REPO" + + # Stage changed patch file + mv -f "$NEW_PATCH_FILE" "$PATCH_FILE" + ls -l "$PATCH_FILE" + echo "Info: Staging ${PATCH_FILE}" + git add -u "$PATCH_FILE" + +done + +rm -f "$DIFF_FILE" +rm -f "$NEW_PATCH_FILE" |