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

91 lines
2.7 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 [dir] # Make read-only (postinstall)
# ./tooling/scripts/node-modules-lock.sh unlock [dir] # Make writable (preinstall)
# ./tooling/scripts/node-modules-lock.sh status [dir] # Show current state
# ./tooling/scripts/node-modules-lock.sh lock-all # Lock all node_modules in monorepo
#
# Called automatically by package.json preinstall/postinstall hooks.
# [dir] defaults to current working directory if not specified.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Target directory: use argument if provided, else current working directory
TARGET_DIR="${2:-$(pwd)}"
NODE_MODULES="$TARGET_DIR/node_modules"
usage() {
echo "Usage: $0 {lock|unlock|status|lock-all|unlock-all|status-all} [dir]"
echo ""
echo "Commands:"
echo " lock [dir] - Make node_modules read-only (run after pnpm install)"
echo " unlock [dir] - Make node_modules writable (run before pnpm install)"
echo " status [dir] - Show current protection status"
echo " lock-all - Lock ALL node_modules in monorepo"
echo " unlock-all - Unlock ALL node_modules in monorepo"
echo " status-all - Show status of ALL node_modules in monorepo"
echo ""
echo "[dir] defaults to current working directory"
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