mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
110 lines
2.9 KiB
Bash
110 lines
2.9 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# dc.sh — devcontainer helper for this repo
|
|
#
|
|
# Usage:
|
|
# ./devcontainer.sh <config> <command>
|
|
#
|
|
# Configs: backend | asset_list
|
|
# Commands: up, shell, down, rebuild
|
|
#
|
|
# `shell` auto-runs `up` first if the container isn't already running,
|
|
# so it's safe to call cold.
|
|
#
|
|
# Examples:
|
|
# ./devcontainer.sh backend shell # up + exec bash
|
|
# ./devcontainer.sh asset_list up
|
|
# ./devcontainer.sh backend rebuild
|
|
# ./devcontainer.sh backend down
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
|
REPO_ROOT="${SCRIPT_DIR}"
|
|
|
|
VALID_CONFIGS=(backend asset_list)
|
|
VALID_COMMANDS=(up shell down rebuild)
|
|
|
|
# --- helpers ---------------------------------------------------------------
|
|
|
|
usage() {
|
|
sed -n '3,20p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'
|
|
exit "${1:-0}"
|
|
}
|
|
|
|
die() {
|
|
echo "error: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
in_list() {
|
|
# in_list <needle> <haystack...>
|
|
local needle="$1"
|
|
shift
|
|
local item
|
|
for item in "$@"; do
|
|
[[ "${item}" == "${needle}" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
container_id_for() {
|
|
# Find a running container for the given config path via devcontainer labels.
|
|
local config_path="$1"
|
|
docker ps -q \
|
|
--filter "label=devcontainer.local_folder=${REPO_ROOT}" \
|
|
--filter "label=devcontainer.config_file=${config_path}"
|
|
}
|
|
|
|
# --- argument parsing ------------------------------------------------------
|
|
|
|
[[ $# -eq 2 ]] || usage 1
|
|
|
|
CONFIG_NAME="$1"
|
|
COMMAND="$2"
|
|
|
|
in_list "${CONFIG_NAME}" "${VALID_CONFIGS[@]}" \
|
|
|| die "invalid config '${CONFIG_NAME}' (expected: ${VALID_CONFIGS[*]})"
|
|
in_list "${COMMAND}" "${VALID_COMMANDS[@]}" \
|
|
|| die "invalid command '${COMMAND}' (expected: ${VALID_COMMANDS[*]})"
|
|
|
|
CONFIG_PATH="${REPO_ROOT}/.devcontainer/${CONFIG_NAME}/devcontainer.json"
|
|
[[ -f "${CONFIG_PATH}" ]] || die "config not found: ${CONFIG_PATH}"
|
|
|
|
DC_ARGS=(--workspace-folder "${REPO_ROOT}" --config "${CONFIG_PATH}")
|
|
|
|
# --- dispatch --------------------------------------------------------------
|
|
|
|
case "${COMMAND}" in
|
|
up)
|
|
echo ">> bringing up '${CONFIG_NAME}'"
|
|
devcontainer up "${DC_ARGS[@]}"
|
|
;;
|
|
|
|
shell)
|
|
# Auto-up if not already running. `devcontainer up` is idempotent —
|
|
# it reuses an existing container, so this is cheap on warm starts.
|
|
if [[ -z "$(container_id_for "${CONFIG_PATH}")" ]]; then
|
|
echo ">> '${CONFIG_NAME}' not running, bringing it up first"
|
|
devcontainer up "${DC_ARGS[@]}"
|
|
fi
|
|
echo ">> attaching shell to '${CONFIG_NAME}'"
|
|
devcontainer exec "${DC_ARGS[@]}" bash 2>/dev/null \
|
|
|| devcontainer exec "${DC_ARGS[@]}" sh
|
|
;;
|
|
|
|
down)
|
|
cid="$(container_id_for "${CONFIG_PATH}")"
|
|
if [[ -z "${cid}" ]]; then
|
|
echo ">> '${CONFIG_NAME}' not running, nothing to stop"
|
|
exit 0
|
|
fi
|
|
echo ">> stopping '${CONFIG_NAME}'"
|
|
docker stop "${cid}"
|
|
;;
|
|
|
|
rebuild)
|
|
echo ">> rebuilding '${CONFIG_NAME}' from scratch"
|
|
devcontainer up "${DC_ARGS[@]}" --remove-existing-container --build-no-cache
|
|
;;
|
|
esac
|