83 lines
3.1 KiB
Bash
Executable File
83 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
#
|
||
# Check if we need to copy node_modules.
|
||
# (e.g. in case it has been modified after last copy)
|
||
#
|
||
# The reasoning for a (mostly) read-only node_modules folder:
|
||
# ideally we’d symlink the folder directly to the Nix store
|
||
# so that we’re guaranteed to have a reproducible source.
|
||
# Unfortunately react-native wants to build some stuff after the fact
|
||
# and this is incompatible with the concept of a pure Nix package.
|
||
# Therefore we copy the whole source to the repo directory,
|
||
# allow writing only on the folders where it is absolutely required,
|
||
# and therefore we still keep some peace of mind that the rest
|
||
# of node_modules is unchanged the rest of the time.
|
||
#
|
||
|
||
set -Eeuo pipefail
|
||
|
||
function replaceNodeModules() {
|
||
local deps="$1"
|
||
local targetNodeModules="$2"
|
||
local needCopyModules=1
|
||
local sentinelFilePath="$targetNodeModules/.copied~"
|
||
|
||
# Check if node_modules exists and is valid
|
||
if [ -d "$targetNodeModules" ]; then
|
||
if [ -f "$sentinelFilePath" ]; then
|
||
existingPath="$(cat $sentinelFilePath)"
|
||
if [ "${existingPath}" != "${deps}" ]; then
|
||
echo "Yarn modules changed, copying new version over"
|
||
else
|
||
echo "Checking for modifications in node_modules..."
|
||
modifiedFiles=(
|
||
$(find $targetNodeModules -writable -type f -newer $sentinelFilePath \
|
||
-not \( -path "$targetNodeModules/react-native/ReactAndroid/build/*" -prune \
|
||
-o -path "$targetNodeModules/*/android/build/*" -prune \) -print) )
|
||
if [ ${#modifiedFiles[@]} -eq 0 ]; then
|
||
needCopyModules=0
|
||
echo "No modifications detected."
|
||
else
|
||
echo "Modifications detected in ${#modifiedFiles[@]} files:"
|
||
for f in ${modifiedFiles[@]}; do
|
||
echo "- $(realpath --relative-to=$STATUS_REACT_HOME $f)"
|
||
done
|
||
fi
|
||
fi
|
||
fi
|
||
if [ $needCopyModules -eq 1 ] && [ -d $targetNodeModules ]; then
|
||
chmod u+w -R $targetNodeModules
|
||
rm -rf $targetNodeModules
|
||
fi
|
||
fi
|
||
|
||
# Replace node_modules if necessary
|
||
if [ ! -d "$targetNodeModules" ]; then
|
||
local tmpNodeModules=$(mktemp -d)
|
||
echo "Copying node_modules from Nix store:"
|
||
echo " - ${deps}"
|
||
export TIMEFORMAT="Done in: %Es"
|
||
trap "[ -d \"${tmpNodeModules}\" ] && chmod -R u+w \"${tmpNodeModules}\" && rm -rf \"${tmpNodeModules}\"" ERR INT HUP
|
||
# WARNING: The -L here is crucial to let Metro find modules.
|
||
time cp -LRf ${deps}/node_modules/. "${tmpNodeModules}"
|
||
chmod -R u+w "${tmpNodeModules}"
|
||
# WARNING: We can't de-reference .bin symlinks
|
||
cp -Rf ${deps}/node_modules/.bin/. "${tmpNodeModules}/.bin/"
|
||
mv -f "${tmpNodeModules}" "${targetNodeModules}"
|
||
|
||
echo -n "${deps}" > "${sentinelFilePath}"
|
||
trap - ERR INT HUP
|
||
fi
|
||
}
|
||
|
||
deps="$1"
|
||
[ -d $deps ] || exit 1
|
||
|
||
nodeModulesDir="$STATUS_REACT_HOME/node_modules"
|
||
|
||
export -f replaceNodeModules
|
||
mkdir -p "$nodeModulesDir/"
|
||
# Leverage flock (file lock) utility to create an exclusive lock on node_modules/ while running replaceNodeModules
|
||
flock "$nodeModulesDir/" sh -c "replaceNodeModules $deps $nodeModulesDir"
|