Files
yushanhe f097f5bc21
designops-gateway / build (push) Failing after 20m0s
chore: bootstrap DesignOps monorepo (5 subprojects + OKF + annotations)
- merge openpencil/penpot/excalidraw/style-dictionary/storybook as native
  monorepo code (upstream .git removed; origins in okf/manifest.md)
- add project-level okf/ (manifest + memory/rule/skill/decision/lesson)
- add AGENTS.md (OKF annotation standard) + monorepo .gitignore
- annotate 9 entry files with @module/@skill/@rule headers
- add GitOps deploy bundle (infra/gitops/) + Gitea CI (.gitea/workflows/)
2026-09-27 21:28:44 +08:00

92 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Remove node_modules directories across the monorepo's pnpm workspaces:
# the repo root, all module workspaces, and all workspace member packages.
#
# Use it when node_modules are stale or corrupted and a clean reinstall is
# cheaper than debugging. Reinstall afterwards with `pnpm install` in each
# workspace root (root, backend, common, docs, exporter, frontend, library,
# mcp, media-processor, plugins, render-wasm).
#
# external/ (vendored dependency trees) and .opencode/ are always ignored.
# The pnpm content-addressable store lives at <repo>/.pnpm-store, outside
# node_modules, and survives a default clean. `--store` removes it too;
# the next install re-downloads what it held.
set -euo pipefail
usage() {
cat <<'EOF'
Usage: scripts/clean-node-modules [options]
Remove every node_modules directory in the pnpm workspaces: the repo root,
all module workspaces, and all workspace member packages.
Options:
-n, --dry-run Print what would be removed without deleting anything.
--store Also delete the shared pnpm store at <repo>/.pnpm-store.
The next install re-downloads everything it held.
-h, --help Show this help.
external/ (vendored dependency trees) and .opencode/ are always ignored.
EOF
}
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DRY_RUN=0
WITH_STORE=0
while [[ $# -gt 0 ]]; do
case "$1" in
-n | --dry-run) DRY_RUN=1 ;;
--store) WITH_STORE=1 ;;
-h | --help) usage; exit 0 ;;
*) {
echo "error: unknown option: $1" >&2
usage >&2
exit 64
} ;;
esac
shift
done
cd "$ROOT"
if [[ $WITH_STORE -eq 1 && -d .pnpm-store ]]; then
size="$(du -sh .pnpm-store | cut -f1)"
if [[ $DRY_RUN -eq 1 ]]; then
echo "would remove: ./.pnpm-store (pnpm store, $size)"
else
echo "removing pnpm store: $ROOT/.pnpm-store ($size); the next install re-downloads it"
rm -rf .pnpm-store
fi
fi
# -prune stops the descent, so only the top-most node_modules of each tree
# matches; nested dependency copies inside it die with their parent.
mapfile -t dirs < <(
find . \( -name .git -o -name external -o -name .opencode \) -type d -prune \
-o \( -name node_modules -type d -prune -print \)
)
if [[ ${#dirs[@]} -eq 0 ]]; then
echo "no node_modules directories found"
exit 0
fi
cleaned=0
for dir in "${dirs[@]}"; do
if [[ $DRY_RUN -eq 1 ]]; then
echo "would remove: $dir"
else
rm -rf "$dir"
echo "removed: $dir"
fi
cleaned=$((cleaned + 1))
done
if [[ $DRY_RUN -eq 1 ]]; then
echo "$cleaned node_modules directories found"
else
echo "$cleaned node_modules directories cleaned"
fi