#!/usr/bin/env bash # Local development setup for gc_index_relay. # Safe to run multiple times — all steps are idempotent. # # Requirements: # - Docker must already be installed (https://docs.docker.com/engine/install/) # - sudo access for apt-get # # Usage: # chmod +x setup.sh # ./setup.sh set -euo pipefail # --------------------------------------------------------------------------- # Configuration # --------------------------------------------------------------------------- ERLANG_VERSION="28.4.1" ELIXIR_VERSION="1.19.5-otp-28" POSTGRES_HOST="localhost" POSTGRES_PORT="5455" POSTGRES_USER="postgres" POSTGRES_PASSWORD="postgres" POSTGRES_DB="gc_index_relay_dev" DOCKER_CONTAINER_NAME="gc_age_db" AGE_IMAGE="apache/age:release_PG17_1.6.0" ASDF_DIR="$HOME/.asdf" ASDF_VERSION="v0.15.0" PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' log() { echo -e "${GREEN}[setup]${NC} $*"; } warn() { echo -e "${YELLOW}[ warn]${NC} $*"; } err() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; } require_cmd() { command -v "$1" &>/dev/null || err "'$1' is not installed or not on PATH. $2" } # --------------------------------------------------------------------------- # 1. Pre-flight checks # --------------------------------------------------------------------------- log "Starting gc_index_relay local setup..." echo require_cmd docker "Install Docker first: https://docs.docker.com/engine/install/" docker info &>/dev/null || err "Docker daemon is not running. Start it and try again." log "Docker: $(docker --version)" # --------------------------------------------------------------------------- # 2. System build dependencies (Debian/Ubuntu/Mint) # --------------------------------------------------------------------------- if command -v apt-get &>/dev/null; then log "Installing system build dependencies via apt-get..." sudo apt-get update -qq sudo apt-get install -y \ build-essential \ autoconf \ libtool \ inotify-tools \ git \ curl else warn "apt-get not found — skipping system package install." warn "Make sure these are installed manually: build-essential autoconf libtool inotify-tools git curl" fi # --------------------------------------------------------------------------- # 3. asdf version manager # --------------------------------------------------------------------------- if [ ! -d "$ASDF_DIR" ]; then log "Installing asdf $ASDF_VERSION..." git clone https://github.com/asdf-vm/asdf.git "$ASDF_DIR" --branch "$ASDF_VERSION" else log "asdf already installed at $ASDF_DIR" fi # Source asdf for this script session # shellcheck source=/dev/null source "$ASDF_DIR/asdf.sh" # Persist asdf sourcing to the user's shell rc (idempotent) add_asdf_to_rc() { local rc="$1" local line='. "$HOME/.asdf/asdf.sh"' if [ -f "$rc" ] && ! grep -qF 'asdf/asdf.sh' "$rc"; then echo "" >> "$rc" echo "# asdf version manager" >> "$rc" echo "$line" >> "$rc" log "Added asdf to $rc (will take effect in new shells)" fi } add_asdf_to_rc "$HOME/.bashrc" add_asdf_to_rc "$HOME/.zshrc" 2>/dev/null || true # --------------------------------------------------------------------------- # 4. Erlang # --------------------------------------------------------------------------- asdf plugin add erlang 2>/dev/null || true if asdf list erlang 2>/dev/null | grep -qF "$ERLANG_VERSION"; then log "Erlang $ERLANG_VERSION already installed" else log "Installing Erlang $ERLANG_VERSION (compiles from source — takes a few minutes)..." asdf install erlang "$ERLANG_VERSION" fi asdf global erlang "$ERLANG_VERSION" # --------------------------------------------------------------------------- # 5. Elixir # --------------------------------------------------------------------------- asdf plugin add elixir 2>/dev/null || true if asdf list elixir 2>/dev/null | grep -qF "$ELIXIR_VERSION"; then log "Elixir $ELIXIR_VERSION already installed" else log "Installing Elixir $ELIXIR_VERSION..." asdf install elixir "$ELIXIR_VERSION" fi asdf global elixir "$ELIXIR_VERSION" log "$(elixir --version | grep 'Elixir')" # --------------------------------------------------------------------------- # 6. Apache AGE database (Docker) # --------------------------------------------------------------------------- if docker ps -q --filter "name=^${DOCKER_CONTAINER_NAME}$" | grep -q .; then log "Database container '$DOCKER_CONTAINER_NAME' is already running" elif docker ps -aq --filter "name=^${DOCKER_CONTAINER_NAME}$" | grep -q .; then log "Restarting existing database container '$DOCKER_CONTAINER_NAME'..." docker start "$DOCKER_CONTAINER_NAME" else log "Starting Apache AGE database container..." docker run -d \ --name "$DOCKER_CONTAINER_NAME" \ -p "${POSTGRES_PORT}:5432" \ -e POSTGRES_USER="$POSTGRES_USER" \ -e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \ -e POSTGRES_DB="$POSTGRES_DB" \ "$AGE_IMAGE" fi log "Waiting for database to accept connections..." until docker exec "$DOCKER_CONTAINER_NAME" pg_isready -U "$POSTGRES_USER" &>/dev/null; do sleep 1 done log "Database is ready" # --------------------------------------------------------------------------- # 7. .env file # --------------------------------------------------------------------------- ENV_FILE="$PROJECT_DIR/.env" if [ ! -f "$ENV_FILE" ]; then log "Writing .env with database credentials..." cat > "$ENV_FILE" <