#!/usr/bin/env bash set -euo pipefail usage() { cat <<'USAGE' Usage: tools/release/generate-release-lock.sh [options] Generates webui/package-lock.release.json from webui/package.release.json in a temporary workspace. The normal development package.json and package-lock.json are left untouched. Run this after the module git tags referenced by package.release.json exist and are reachable, and before tagging the core release commit that should contain the regenerated release lockfile. Options: --npm npm executable to use. --core-root govoplan-core checkout. Defaults to ../govoplan-core. -h, --help Show this help. USAGE } fail() { echo "error: $*" >&2 exit 1 } META_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" CORE_ROOT="${GOVOPLAN_CORE_ROOT:-$META_ROOT/../govoplan-core}" CORE_ROOT="$(cd "$CORE_ROOT" && pwd)" WEBUI="$CORE_ROOT/webui" NPM_BIN="${NPM:-}" NODE_BIN="${NODE:-}" if [[ -z "$NPM_BIN" ]]; then if [[ -x "/home/zemion/.nvm/versions/node/v22.22.3/bin/npm" ]]; then NPM_BIN="/home/zemion/.nvm/versions/node/v22.22.3/bin/npm" else NPM_BIN="npm" fi fi if [[ -z "$NODE_BIN" ]]; then if [[ -x "$(dirname "$NPM_BIN")/node" ]]; then NODE_BIN="$(dirname "$NPM_BIN")/node" else NODE_BIN="node" fi fi while [[ $# -gt 0 ]]; do case "$1" in --npm) [[ $# -ge 2 ]] || fail "missing value for $1" NPM_BIN="$2" shift 2 ;; --core-root) [[ $# -ge 2 ]] || fail "missing value for $1" CORE_ROOT="$(cd "$2" && pwd)" WEBUI="$CORE_ROOT/webui" shift 2 ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 2 ;; esac done [[ -f "$WEBUI/package.release.json" ]] || fail "missing $WEBUI/package.release.json" command -v "$NPM_BIN" >/dev/null 2>&1 || fail "npm executable not found: $NPM_BIN" command -v "$NODE_BIN" >/dev/null 2>&1 || fail "node executable not found: $NODE_BIN" TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/govoplan-release-lock.XXXXXXXX")" cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT cp "$WEBUI/package.release.json" "$TMP_DIR/package.json" if [[ -f "$WEBUI/package-lock.release.json" ]]; then cp "$WEBUI/package-lock.release.json" "$TMP_DIR/package-lock.json" fi echo "Generating release lockfile from $WEBUI/package.release.json" echo "Temporary workspace: $TMP_DIR" ( cd "$TMP_DIR" PATH="$(dirname "$NPM_BIN"):$PATH" "$NPM_BIN" install --package-lock-only --ignore-scripts mapfile -t GIT_PACKAGES < <( PATH="$(dirname "$NODE_BIN"):$PATH" "$NODE_BIN" <<'NODE' const fs = require("fs"); const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); for (const group of ["dependencies", "devDependencies", "optionalDependencies"]) { for (const [name, spec] of Object.entries(pkg[group] || {})) { if (typeof spec === "string" && spec.startsWith("git+")) { console.log(name); } } } NODE ) if [[ "${#GIT_PACKAGES[@]}" -gt 0 ]]; then echo "Refreshing git package lock entries: ${GIT_PACKAGES[*]}" PATH="$(dirname "$NPM_BIN"):$PATH" "$NPM_BIN" update --package-lock-only --ignore-scripts "${GIT_PACKAGES[@]}" fi ) cp "$TMP_DIR/package-lock.json" "$WEBUI/package-lock.release.json" echo "Updated $WEBUI/package-lock.release.json"