/
update-diffpatches.sh
132 lines (103 loc) · 3.82 KB
/
update-diffpatches.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env bash
#
# This script assumes a linux environment
# ORIGINAL SOURCE FROM: https://github.com/uBlockOrigin/uAssets/blob/master/tools/update-diffpatches.sh
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
PATCHES_DIR=$1
if [[ -z $PATCHES_DIR ]]; then
echo "Error: patches directory is not provided, aborting"
exit 1
fi
FILTER_FILES=$2
if [[ -z $FILTER_FILES ]]; then
echo "Error: filter lists are not provided, aborting"
exit 1
fi
FILTER_FILES=( "$FILTER_FILES" )
SKIP_PUSH_DEL_TAG=$3
DELETED_VERSIONS=''
# Keep only the most recent 20 patches
OBSOLETE_PATCHES=( $(ls -1v "$PATCHES_DIR"/*.patch | head -n -20) )
for FILE in "${OBSOLETE_PATCHES[@]}"; do
echo "Removing obsolete patch $FILE"
# Extract tag from patch file name
[[ ${FILE} =~ ^$PATCHES_DIR/([0-9]+)\.patch$ ]] && \
DEL_VERSION=${BASH_REMATCH[1]}
if [ "$DELETED_VERSION" == '' ]; then
DELETED_VERSIONS=$DEL_VERSION
else
DELETED_VERSIONS="$DELETED_VERSIONS $DEL_VERSION"
fi
git rm "$FILE"
done
NEW_PATCH_FILE=$(mktemp)
DIFF_FILE=$(mktemp)
ALL_VERSION=$(git tag --list)
PATCH_FILES=( $(ls -1v "$PATCHES_DIR"/*.patch | head -n -1) )
for PATCH_FILE in "${PATCH_FILES[@]}"; do
# Extract tag from patch file name
[[ ${PATCH_FILE} =~ ^$PATCHES_DIR/([0-9]+)\.patch$ ]] && \
PREVIOUS_VERSION=${BASH_REMATCH[1]}
# Skip if version doesn't exist
if [[ "$ALL_VERSION" != *"$PREVIOUS_VERSION"* ]]; then
echo "Skip version $PREVIOUS_VERSION because does not exist"
continue;
fi
# This will receive a clone of an old version of the current repo to another git work tree
echo "Checkout repo at version $PREVIOUS_VERSION"
OLD_REPO=$(mktemp -d)
git worktree add -f "$OLD_REPO" "$PREVIOUS_VERSION"
: > "$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
git worktree prune
rm -f "$DIFF_FILE"
rm -f "$NEW_PATCH_FILE"
if [ "$DELETED_VERSIONS" != '' ]; then
if [ "$SKIP_PUSH_DEL_TAG" != 'true' ]; then
git push -d origin $DELETED_VERSIONS
else
echo "These tag should be delete manualy: '$DELETED_VERSIONS'"
fi
fi