#!/usr/bin/env bash set -Eeuo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$ROOT" MODE="debug" ACTION="run" INSTALL_DEPS=1 RESET_DB=0 HOST="" PORT="" usage() { cat <<'TXT' GREE Controller - development environment Usage: ./dev.sh install missing tools, build and run ./dev.sh --release run an optimized build ./dev.sh --check formatting, tests, build and API smoke test ./dev.sh --reset remove the local database before startup ./dev.sh --no-install do not install system packages or Rust ./dev.sh --host 0.0.0.0 --port 8787 TXT } while [[ $# -gt 0 ]]; do case "$1" in --release) MODE="release"; shift ;; --check) ACTION="check"; shift ;; --reset) RESET_DB=1; shift ;; --no-install) INSTALL_DEPS=0; shift ;; --host) HOST="${2:?missing value for --host}"; shift 2 ;; --port) PORT="${2:?missing value for --port}"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "Unknown argument: $1" >&2; usage; exit 2 ;; esac done say() { printf '\033[1;32m==>\033[0m %s\n' "$*"; } warn() { printf '\033[1;33mWARNING:\033[0m %s\n' "$*" >&2; } fail() { printf '\033[1;31mERROR:\033[0m %s\n' "$*" >&2; exit 1; } run_privileged() { if [[ ${EUID:-$(id -u)} -eq 0 ]]; then "$@" elif command -v sudo >/dev/null 2>&1; then sudo "$@" else fail "Root/sudo privileges are required to install dependencies: $*" fi } install_build_tools() { [[ "$INSTALL_DEPS" -eq 1 ]] || return 0 local missing=0 command -v curl >/dev/null 2>&1 || missing=1 command -v cc >/dev/null 2>&1 || missing=1 if [[ "$missing" -eq 0 ]]; then return 0; fi if command -v apt-get >/dev/null 2>&1; then say "Installing build packages (Debian/Ubuntu/LXC)" run_privileged apt-get update run_privileged apt-get install -y --no-install-recommends build-essential curl ca-certificates pkg-config elif command -v dnf >/dev/null 2>&1; then say "Installing build packages (Fedora/RHEL)" run_privileged dnf install -y gcc gcc-c++ make curl ca-certificates pkgconf-pkg-config elif command -v apk >/dev/null 2>&1; then say "Installing build packages (Alpine)" run_privileged apk add --no-cache build-base curl ca-certificates pkgconf else fail "Unsupported package manager. Install a C compiler, make, curl and CA certificates." fi } install_rust() { if command -v cargo >/dev/null 2>&1; then return 0; fi [[ "$INSTALL_DEPS" -eq 1 ]] || fail "Cargo is not installed and --no-install was requested" command -v curl >/dev/null 2>&1 || fail "curl is required to install Rust" say "Installing stable Rust with rustup" curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal # shellcheck disable=SC1090 source "$HOME/.cargo/env" } install_build_tools install_rust command -v cargo >/dev/null 2>&1 || fail "Cargo is still unavailable" if [[ ! -f .env ]]; then cp .env.example .env say "Created .env from the example configuration" fi mkdir -p data if [[ "$RESET_DB" -eq 1 ]]; then rm -f data/gree-controller.db data/gree-controller.db-shm data/gree-controller.db-wal say "Removed the local database" fi # Export simple KEY=VALUE entries from .env. set -a # shellcheck disable=SC1091 source ./.env set +a if [[ -n "$HOST" || -n "$PORT" ]]; then current="${GREE_CONTROLLER_BIND:-0.0.0.0:8787}" current_host="${current%:*}" current_port="${current##*:}" export GREE_CONTROLLER_BIND="${HOST:-$current_host}:${PORT:-$current_port}" fi if [[ "$ACTION" == "check" ]]; then say "Checking formatting" cargo fmt --all -- --check say "Running Rust tests" cargo test --all-targets say "Building the application" cargo build say "Running HTTP/API smoke test" ./scripts/smoke.sh say "All checks passed" exit 0 fi if [[ "$MODE" == "release" ]]; then say "Building release version" cargo build --release BINARY="$ROOT/target/release/gree-controller" else say "Building debug version" cargo build BINARY="$ROOT/target/debug/gree-controller" fi bind="${GREE_CONTROLLER_BIND:-0.0.0.0:8787}" display_host="${bind%:*}" [[ "$display_host" == "0.0.0.0" ]] && display_host="127.0.0.1" say "Panel: http://${display_host}:${bind##*:}" say "Stop: Ctrl+C" exec "$BINARY"