#!/usr/bin/env bash # installSaltcorn.sh -- reproduce this Saltcorn dev environment from scratch. # # Layout created: # / # saltcorn/ upstream saltcorn checkout (cloned + built) # .dev-state/ per-instance state (sqlite, files, env.sh, sessions) # startServer.sh launcher # # After this, `cd && ./startServer.sh` boots Saltcorn on # http://localhost:3000/. # # Usage: ./installSaltcorn.sh [destination] (default: ./saltcorn) set -euo pipefail DEST="${1:-./saltcorn}" REPO_URL="https://github.com/saltcorn/saltcorn.git" ADMIN_EMAIL="admin@local" ADMIN_PASSWORD="AdminP@ss1" # --- prerequisites --- for cmd in git curl; do command -v "$cmd" >/dev/null || { echo "$cmd not found in PATH"; exit 1; } done # Use a user-local nvm at ~/.nvm rather than system node, matching this dev # environment. The .dev-state/env.sh written below sources the same nvm, so # `saltcorn` keeps working in fresh shells without further setup. export NVM_DIR="$HOME/.nvm" NVM_VERSION="v0.40.1" if [ ! -s "$NVM_DIR/nvm.sh" ]; then echo "==> nvm not found at $NVM_DIR -- installing $NVM_VERSION" curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash if [ ! -s "$NVM_DIR/nvm.sh" ]; then echo "nvm install did not produce $NVM_DIR/nvm.sh" exit 1 fi fi # nvm.sh references some unset variables on load; relax 'set -u' while sourcing. set +u # shellcheck source=/dev/null . "$NVM_DIR/nvm.sh" set -u echo "==> Ensuring node 20 is installed and active" nvm install 20 nvm use 20 NODE_MAJOR=$(node -p 'process.versions.node.split(".")[0]') if [ "$NODE_MAJOR" -lt 18 ]; then echo "node >= 18 required, found $(node --version)" exit 1 fi # Refuse to clobber an existing saltcorn subfolder, but allow $DEST itself to # pre-exist (it might already contain dev-deploy/ or other user work). if [ -e "$DEST/saltcorn" ]; then echo "$DEST/saltcorn already exists; refusing to overwrite" exit 1 fi # --- clone + build --- mkdir -p "$DEST" DEST_ABS="$(cd "$DEST" && pwd)" echo "==> Cloning $REPO_URL into $DEST_ABS/saltcorn" git clone "$REPO_URL" "$DEST_ABS/saltcorn" echo "==> npm install (resolves workspaces; takes several minutes)" (cd "$DEST_ABS/saltcorn" && npm install) echo "==> npm run tsc" (cd "$DEST_ABS/saltcorn" && npm run tsc) # --- .dev-state/ with generated session secret --- DEV_DIR="$DEST_ABS/.dev-state" mkdir -p "$DEV_DIR/files" SECRET=$(node -e 'console.log(require("crypto").randomBytes(32).toString("hex"))') cat > "$DEV_DIR/env.sh" </saltcorn/. __SC_DEV_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)" __SC_REPO_DIR="\$(dirname "\$__SC_DEV_DIR")" export NVM_DIR="\$HOME/.nvm" # shellcheck disable=SC1091 [ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" export SQLITE_FILEPATH="\$__SC_DEV_DIR/saltcorn.sqlite" export SALTCORN_FILE_STORE="\$__SC_DEV_DIR/files" export SALTCORN_SESSION_SECRET="$SECRET" # Put the in-tree CLI on PATH so \`saltcorn ...\` resolves to this checkout. case ":\$PATH:" in *":\$__SC_REPO_DIR/saltcorn/packages/saltcorn-cli/bin:"*) ;; *) export PATH="\$__SC_REPO_DIR/saltcorn/packages/saltcorn-cli/bin:\$PATH" ;; esac unset __SC_DEV_DIR __SC_REPO_DIR EOF chmod +x "$DEV_DIR/env.sh" # --- initialize schema and admin user --- # shellcheck source=/dev/null source "$DEV_DIR/env.sh" echo "==> Initializing SQLite schema at $SQLITE_FILEPATH" saltcorn reset-schema -f echo "==> Creating admin user $ADMIN_EMAIL" saltcorn create-user -a -e "$ADMIN_EMAIL" -p "$ADMIN_PASSWORD" # --- startServer.sh --- cat > "$DEST_ABS/startServer.sh" <<'EOF' #!/usr/bin/env bash set -e cd "$(dirname "$0")" source .dev-state/env.sh # Pick up any local plugin source changes before booting the server. # install-plugin copies ./dev-deploy into Saltcorn's # plugins_folder/.../localversion/, so source edits go live on each restart. # Failures here are non-fatal: the previously-installed version still loads. saltcorn install-plugin -d ./dev-deploy 2>&1 | tail -2 || true # Saltcorn's SQLite session store writes sessions.sqlite at process cwd # (packages/server/routes/utils.js). Run from inside .dev-state/ so each # instance gets its own sessions.sqlite alongside its saltcorn.sqlite. cd .dev-state exec saltcorn serve "$@" EOF chmod +x "$DEST_ABS/startServer.sh" echo echo "Done." echo " cd $DEST_ABS && ./startServer.sh" echo " -> http://localhost:3000/ (login: $ADMIN_EMAIL / $ADMIN_PASSWORD)"