#!/usr/bin/env bash set -euo pipefail BASE_DIR="${OPENCODE_DEV_HOME:-$HOME/dev/opencode-dev}" PROJECTS_DIR="$BASE_DIR/projects" IMAGE_REPO="${IMAGE_REPO:-localhost/opencode-dev}" OPENCODE_VERSION="${OPENCODE_VERSION:-1.18.32}" IMAGE_TAG="${IMAGE_TAG:-${OPENCODE_VERSION}}" IMAGE="${IMAGE_REPO}:${IMAGE_TAG}" mkdir -p \ "$BASE_DIR/opencode-config" \ "$BASE_DIR/opencode-data" \ "$BASE_DIR/opencode-cache" \ "$BASE_DIR/m2" \ "$BASE_DIR/npm-cache" \ "$BASE_DIR/pip-cache" \ "$BASE_DIR/certs" \ "$BASE_DIR/bash" \ "$PROJECTS_DIR" if [[ ! -f "$HOME/.gitconfig" ]]; then echo "WARNING: $HOME/.gitconfig does not exist; Git will use container defaults." >&2 fi if ! podman image exists "$IMAGE"; then echo "Image $IMAGE does not exist. Build it first with ./build.sh" >&2 exit 1 fi START_DIR="${1:-$PROJECTS_DIR}" shift || true if [[ "$START_DIR" = /* ]]; then if [[ "$START_DIR" == "$PROJECTS_DIR"* ]]; then REL="${START_DIR#"$PROJECTS_DIR"}" START_DIR="/workspace${REL}" else echo "Absolute paths outside $PROJECTS_DIR require --mount and are not accepted as the initial directory." >&2 exit 2 fi else START_DIR="/workspace/${START_DIR#./}" fi if [[ ! -d "$PROJECTS_DIR" ]]; then echo "Project directory missing: $PROJECTS_DIR" >&2 exit 1 fi ARGS=( run --rm -it --name opencode-dev --userns=keep-id --security-opt=no-new-privileges --network=default --tz=local -e "HOST_LANG=${LANG:-C.UTF-8}" -e "HOST_LC_ALL=${LC_ALL:-}" -e "START_DIR=${START_DIR}" -v "$BASE_DIR/opencode-config:/home/dev/.config/opencode:rw" -v "$BASE_DIR/opencode-data:/home/dev/.local/share/opencode:rw" -v "$BASE_DIR/opencode-cache:/home/dev/.cache/opencode:rw" -v "$BASE_DIR/m2:/home/dev/.m2:rw" -v "$BASE_DIR/npm-cache:/home/dev/.npm:rw" -v "$BASE_DIR/pip-cache:/home/dev/.cache/pip:rw" -v "$BASE_DIR/certs:/host-certs:ro" -v "$PROJECTS_DIR:/workspace:rw" -v "$HOME/.gitconfig:/home/dev/.gitconfig:ro" -v "$HOME/.ssh:/home/dev/.ssh:ro" -v "$BASE_DIR/bash:/host-bash:ro" ) if [[ -n "${SSH_AUTH_SOCK:-}" && -S "$SSH_AUTH_SOCK" ]]; then ARGS+=( -e SSH_AUTH_SOCK=/tmp/ssh-agent.sock -v "$SSH_AUTH_SOCK:/tmp/ssh-agent.sock" ) fi # Additional bind mounts: # ./dev.sh /project --mount "$HOME/other:/extra" while (($#)); do case "$1" in --mount) [[ $# -ge 2 ]] || { echo "--mount requires host:container[:ro|rw]" >&2; exit 2; } ARGS+=(-v "$2") shift 2 ;; *) echo "Unknown option: $1" >&2 exit 2 ;; esac done # Load user Bash configuration after the image defaults, without persisting history. BASH_RC="${BASE_DIR}/bash/bashrc" if [[ -f "$BASH_RC" ]]; then ARGS+=(-e BASH_ENV=/host-bash/bashrc) fi exec podman "${ARGS[@]}" "$IMAGE" bash