summaryrefslogtreecommitdiffstats
path: root/uAssets/tools/update-diffpatches.sh
diff options
context:
space:
mode:
Diffstat (limited to 'uAssets/tools/update-diffpatches.sh')
-rwxr-xr-xuAssets/tools/update-diffpatches.sh115
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"