generated from boboko/starter
Feat: Adding core-mode and deploy scripts
This commit is contained in:
Executable
+146
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
# Switch how this app consumes boboko-core, then restart the dev stack so the
|
||||
# entrypoints re-resolve it.
|
||||
#
|
||||
# bin/core-mode local ../boboko-core checkout (Composer path repo + npm file:)
|
||||
# bin/core-mode repo tagged releases from the forge (Composer VCS repo + npm git+semver)
|
||||
# bin/core-mode print the current mode
|
||||
#
|
||||
# Running it for the mode you're already in skips the file edits but still
|
||||
# restarts the stack — that's how repo mode picks up a newly pushed tag.
|
||||
#
|
||||
# The toggle lives in composer.json ("repositories" <-> "_repositories") and
|
||||
# package.json (@boboko/core in "dependencies" <-> "_dependencies"). The dev
|
||||
# entrypoints run `composer update boboko/*` and `npm update @boboko/core` on
|
||||
# every boot, which rewrites composer.lock / package-lock.json for the mode.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
fail() { echo "!!! $*" >&2; exit 1; }
|
||||
|
||||
# Escape a string for use as a sed regex / replacement with "|" as delimiter.
|
||||
sed_pattern() { printf '%s' "$1" | sed 's/[][\.*^$|]/\\&/g'; }
|
||||
sed_replacement() { printf '%s' "$1" | sed 's/[\&|]/\\&/g'; }
|
||||
|
||||
current_mode() {
|
||||
local composer_type npm_dep composer_mode npm_mode
|
||||
# The live block is "repositories" — the leading quote keeps "_repositories" out.
|
||||
composer_type=$(sed -n '/"repositories": \[/,/"type"/p' composer.json | grep -o '"type": "[a-z]*"' | head -1)
|
||||
npm_dep=$(sed -n '/"dependencies": {/,/}/p' package.json | grep -o '"@boboko/core": "[^"]*"' | head -1)
|
||||
|
||||
case "$composer_type" in
|
||||
*'"path"') composer_mode=local ;;
|
||||
*'"vcs"') composer_mode=repo ;;
|
||||
*) fail "Can't tell the mode from composer.json's \"repositories\" block." ;;
|
||||
esac
|
||||
case "$npm_dep" in
|
||||
*'"file:'*) npm_mode=local ;;
|
||||
*'"git+'*) npm_mode=repo ;;
|
||||
*) fail "Can't tell the mode from package.json's @boboko/core dependency." ;;
|
||||
esac
|
||||
[ "$composer_mode" = "$npm_mode" ] ||
|
||||
fail "composer.json ($composer_mode) and package.json ($npm_mode) disagree — fix by hand first."
|
||||
|
||||
echo "$composer_mode"
|
||||
}
|
||||
|
||||
swap_files() {
|
||||
# composer.json: swap the key names, values stay where they are.
|
||||
sed -i \
|
||||
-e 's/"_repositories":/"__core_mode_swap__":/' \
|
||||
-e 's/"repositories":/"_repositories":/' \
|
||||
-e 's/"__core_mode_swap__":/"repositories":/' \
|
||||
composer.json
|
||||
|
||||
# package.json: swap the two @boboko/core values (live and parked).
|
||||
local a b
|
||||
a=$(grep -o '"@boboko/core": "[^"]*"' package.json | sed -n 1p)
|
||||
b=$(grep -o '"@boboko/core": "[^"]*"' package.json | sed -n 2p)
|
||||
[ -n "$a" ] && [ -n "$b" ] || fail "Expected two @boboko/core entries in package.json."
|
||||
sed -i \
|
||||
-e "s|$(sed_pattern "$a")|__core_mode_swap__|" \
|
||||
-e "s|$(sed_pattern "$b")|$(sed_replacement "$a")|" \
|
||||
-e "s|__core_mode_swap__|$(sed_replacement "$b")|" \
|
||||
package.json
|
||||
}
|
||||
|
||||
wrapper_for() {
|
||||
if [ "$1" = local ]; then echo bin/dc-core.sh; else echo bin/dc; fi
|
||||
}
|
||||
|
||||
# The app healthcheck (php-fpm -t) passes before the entrypoint finishes, so
|
||||
# wait on the entrypoints' own log lines instead: the app's composer block is
|
||||
# done once it clears caches, the vite container's npm block once Vite is up.
|
||||
wait_for_log() {
|
||||
local dc=$1 service=$2 pattern=$3 label=$4 waited=0
|
||||
printf '>>> Waiting for %s' "$label"
|
||||
until $dc logs --no-color "$service" 2>&1 | grep -q "$pattern"; do
|
||||
if [ -z "$($dc ps -q --status running "$service")" ]; then
|
||||
echo
|
||||
$dc logs --no-color --tail 40 "$service"
|
||||
fail "$service stopped before finishing (logs above)."
|
||||
fi
|
||||
if [ "$waited" -ge 600 ]; then
|
||||
echo
|
||||
$dc logs --no-color --tail 40 "$service"
|
||||
fail "Timed out after 600s waiting for $service (logs above)."
|
||||
fi
|
||||
printf '.'
|
||||
sleep 3
|
||||
waited=$((waited + 3))
|
||||
done
|
||||
echo " done"
|
||||
}
|
||||
|
||||
mode=$(current_mode)
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "$mode"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
target=$1
|
||||
[ "$target" = local ] || [ "$target" = repo ] || fail "Usage: bin/core-mode [local|repo]"
|
||||
if [ "$target" = local ] && [ ! -d ../boboko-core ]; then
|
||||
fail "../boboko-core not found — local mode needs the core checkout next to this repo."
|
||||
fi
|
||||
|
||||
old_dc=$(wrapper_for "$mode")
|
||||
new_dc=$(wrapper_for "$target")
|
||||
|
||||
echo ">>> Stopping stack ($mode mode)..."
|
||||
$old_dc down
|
||||
|
||||
if [ "$mode" != "$target" ]; then
|
||||
echo ">>> Switching composer.json / package.json: $mode -> $target"
|
||||
swap_files
|
||||
[ "$(current_mode)" = "$target" ] || fail "Switch didn't take — check composer.json / package.json."
|
||||
else
|
||||
echo ">>> Already in $target mode, restarting to re-resolve boboko-core"
|
||||
fi
|
||||
|
||||
# The entrypoints run `composer install` / `npm install` from the lockfiles
|
||||
# BEFORE re-resolving core. Local-mode lockfiles point at ../boboko-core,
|
||||
# which isn't mounted in repo mode, so the install fails. The committed
|
||||
# lockfiles are always repo mode — restore those and let the entrypoints bump
|
||||
# them to the newest tag.
|
||||
if [ "$target" = repo ]; then
|
||||
if grep -A14 '"name": "boboko/core"' composer.lock | grep -q '"type": "path"' ||
|
||||
grep -A6 '"node_modules/@boboko/core": {' package-lock.json | grep -q '"link": true'; then
|
||||
echo ">>> Lockfiles still point at ../boboko-core — restoring the committed ones"
|
||||
git checkout HEAD -- composer.lock package-lock.json
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ">>> Starting stack ($target mode)..."
|
||||
if ! $new_dc up -d; then
|
||||
$new_dc logs --no-color --tail 40 app
|
||||
fail "Stack failed to start (app logs above)."
|
||||
fi
|
||||
|
||||
wait_for_log "$new_dc" app '\[entrypoint\] Caches cleared' "composer to re-resolve boboko/core"
|
||||
wait_for_log "$new_dc" vite 'ready in' "npm to re-resolve @boboko/core"
|
||||
|
||||
version=$(grep -A1 '"name": "boboko/core"' composer.lock | grep -o '"version": "[^"]*"' | cut -d'"' -f4)
|
||||
echo ">>> Now in $target mode — boboko/core $version"
|
||||
Reference in New Issue
Block a user