platform-tooling/scripts/node-modules-lock.sh

81 lines
2.1 KiB
Bash
Executable file

#!/bin/bash
# node-modules-lock.sh - Manage node_modules write protection
#
# PURPOSE: Enforce that node_modules is read-only to prevent accidental edits.
# Packages should be modified at ~/Code/@packages/, not in node_modules.
#
# USAGE:
# ./tooling/scripts/node-modules-lock.sh lock # Make read-only (postinstall)
# ./tooling/scripts/node-modules-lock.sh unlock # Make writable (preinstall)
# ./tooling/scripts/node-modules-lock.sh status # Show current state
#
# Called automatically by package.json preinstall/postinstall hooks.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
NODE_MODULES="$ROOT_DIR/node_modules"
usage() {
echo "Usage: $0 {lock|unlock|status}"
echo ""
echo "Commands:"
echo " lock - Make node_modules read-only (run after pnpm install)"
echo " unlock - Make node_modules writable (run before pnpm install)"
echo " status - Show current protection status"
exit 1
}
status() {
if [ ! -d "$NODE_MODULES" ]; then
echo "node_modules: does not exist"
return 0
fi
# Check if .bin directory is writable (indicator of lock state)
if [ -w "$NODE_MODULES/.bin" ]; then
echo "node_modules: UNLOCKED (writable)"
else
echo "node_modules: LOCKED (read-only)"
fi
}
lock() {
if [ ! -d "$NODE_MODULES" ]; then
echo "node_modules does not exist, skipping lock"
return 0
fi
# Lock all top-level entries EXCEPT .pnpm* (pnpm's internal state files)
# pnpm needs to write to .pnpm-workspace-state-v1.json after postinstall
find "$NODE_MODULES" -mindepth 1 -maxdepth 1 ! -name '.pnpm*' -exec chmod -R a-w {} +
echo "node_modules: LOCKED"
}
unlock() {
if [ ! -d "$NODE_MODULES" ]; then
echo "node_modules does not exist, skipping unlock"
return 0
fi
chmod -R u+w "$NODE_MODULES"
echo "node_modules: UNLOCKED"
}
case "${1:-}" in
lock)
lock
;;
unlock)
unlock
;;
status)
status
;;
*)
usage
;;
esac