Skip to content

Instantly share code, notes, and snippets.

@joncardasis
Created July 23, 2019 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joncardasis/da8c8f2fa67b487b23474dc56052c9b5 to your computer and use it in GitHub Desktop.
Save joncardasis/da8c8f2fa67b487b23474dc56052c9b5 to your computer and use it in GitHub Desktop.
Detect if a jsbundle is dirty and needs to be rebuilt or if just the source code needs to be rebuilt
#!/bin/bash -e
# Check if JS code in a provided root folder has been changed.
# **SHOULD BE RUN WITH XCODE ENV VARIABLES**
#
# Creates a 'jsbundle-hashtable' in xcode product build directory to determine if
# the jsBundle needs to be rebuilt based on src directory hash value.
print_usage() {
printf "Usage: "
printf " %-20s %s\n" "--lookup-hash <target_name>" "Return hash value for <target_name> in table. Otherwise nothing is returned."
printf " %-20s %s\n" "--generate-hash-for <root_path>" "Generates and returns a sha1 hash of a <root_path> directory"
printf " %-20s %s\n" "--update-hash-table <target_name> <hash>" "Updates <hash> value for a given <target_name> in hash table"
printf " %-20s %s\n" "--delete-hash-tables" "Delete all js hash table instances in Xcode DerivedData"
}
# Compute a SHA1 hash of an entire directory tree
# Args: $1 - path to folder root
sha_dir() {
DIR="$1"
FILE_CONTENT_SHA=`find ${DIR} -type f -print0 | sort -z | xargs -0 shasum | shasum | awk '{print $1}'`
PERMISSIONS_SHA=`find ${DIR} \( -type f -o -type d \) -print0 | sort -z | xargs -0 stat -f %A | awk '{print $1}'`
(echo $FILE_CONTENT_SHA; echo $PERMISSIONS_SHA) | shasum | awk '{print $1}'
}
# Returns last hash value of directory provided. Otherwise empty string.
# Args: $1 - target name to search for
find_hash_value() {
TARGET_NAME="$1"
while read LINE; do
LINE_TARGET=$(echo "$LINE" | cut -f1 -d":")
LINE_HASH=$(echo "$LINE" | cut -f2 -d":")
if [[ $LINE_TARGET = "${TARGET_NAME}" ]]; then
echo $LINE_HASH
break
fi
done < "${HASH_TABLE_PATH}"
}
# Args: $1 - target name
# $2 - js directory hash
write_to_hash_table() {
FILE="${HASH_TABLE_PATH}"
grep -q "^$1:" "$FILE" && sed -i "" "s/^$1:.*/$1:$2/" "$FILE" || echo "${1}:${2}" >> "$FILE" # Replace instance or append
}
#################
##### MAIN ######
#################
COMMAND="$1"
# Handle delete command
if [[ "$#" = 1 && "$COMMAND" = "--delete-hash-tables" ]]; then
DERIVED_DATA="${HOME}/Library/Developer/Xcode/DerivedData"
HASH_TABLES=`find "$DERIVED_DATA" -type d -name "Tardis*" -maxdepth 1 -exec find {} -name "jsbundle-hashtable" \;`
while read -r TABLE; do
rm "${TABLE}"
done <<< "${HASH_TABLES}"
echo "Removed JSBundle caches"
exit 0
fi
if [ -z $CONFIGURATION_BUILD_DIR ]; then
echo "ERROR: Run from Xcode or export CONFIGURATION_BUILD_DIR environment variable."
exit 1
fi
HASH_TABLE_PATH="${CONFIGURATION_BUILD_DIR}/jsbundle-hashtable"
# Create hash table file if needed
if [ ! -f "$HASH_TABLE_PATH" ]; then
mkdir -p `dirname "$HASH_TABLE_PATH"`
echo "" > "$HASH_TABLE_PATH"
fi
# Handle hash commands
if [[ "$#" = 2 && "$COMMAND" = "--lookup-hash" ]]; then
TARGET_NAME="$2"
find_hash_value "$TARGET_NAME"
elif [[ "$#" = 2 && "$COMMAND" = "--generate-hash-for" ]]; then
HASH=$(sha_dir "$2")
echo "$HASH"
elif [[ "$#" = 3 && "$COMMAND" = "--update-hash-table" ]]; then
TARGET_NAME="$2"
NEW_HASH="$3"
write_to_hash_table "$TARGET_NAME" "$NEW_HASH"
else
print_usage
exit 1
fi
# **Must be run with Xcode build env variables**
# Skip jsbundle creation if no changes have been made to js src directory
JS_SRC_PATH="${APP_DIR}/src"
BUNDLE_CACHE=${APP_DIR}/scripts/ios/jsBundleCache.sh
CACHED_HASH=$(${BUNDLE_CACHE} --lookup-hash $TARGET_NAME)
CURRENT_HASH=$(${BUNDLE_CACHE} --generate-hash-for ${JS_SRC_PATH})
if [ "$CACHED_HASH" == "$CURRENT_HASH" ]; then
echo "***JS source unchanged. Skipping metro bundler***"
exit 0
else
${BUNDLE_CACHE} --update-hash-table ${TARGET_NAME} ${CURRENT_HASH}
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment