#!/usr/bin/env bash
# Run a command against this repository inside the capped CI container.
#
#   docker/ci/run cargo check --workspace --all-targets
#   docker/ci/run cargo clippy --workspace --all-targets --keep-going -- -D warnings
#   docker/ci/run bash -c 'cargo fmt --all; cargo fmt --all -- --check | grep -c "^Diff in"'
#
# 🔴 EVERY HEAVY COMMAND GOES THROUGH HERE. A bare `cargo build` on the host is
# unbounded: `CARGO_BUILD_JOBS` caps codegen units, not rustc's own threads, not
# the linker, not the test harness. A full-parallel build has OOM-crashed this
# box, and unbounded host runs have frozen it since. The container is the cap
# that actually holds.
#
# Half the machine, no swap. `--memory-swap` equal to `--memory` means a build
# that would swap is killed instead, which is a fast failure rather than an
# hour of thrashing that takes the desktop with it.
set -euo pipefail

REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
IMAGE="${SYLPH_CI_IMAGE:-sylph-ci:local}"
CPUS="${SYLPH_CI_CPUS:-6}"
MEM_GB="${SYLPH_CI_MEM_GB:-7}"

args=(
  --rm
  --cpus "$CPUS"
  --memory "${MEM_GB}g"
  --memory-swap "${MEM_GB}g"
  --pids-limit 2048
  -v "$REPO:/work"
  # Named volumes, not bind mounts: the host tree keeps a 32 GB `target/` from
  # earlier host-side builds, and mixing the two produces rebuilds that look
  # like cache misses and are actually two toolchains fighting over one directory.
  -v sylph-ci-cargo:/cargo   -e CARGO_HOME=/cargo
  -v sylph-ci-target:/target -e CARGO_TARGET_DIR=/target
  -w /work
)

# The disc, read-only, when a disc-backed test or the exporter needs it.
DISC="${SYLPHEED_DISC:-$REPO/../sylph_extract}"
[ -d "$DISC" ] && args+=(-v "$DISC:/disc:ro" -e SYLPHEED_DISC=/disc)

exec docker run "${args[@]}" "$IMAGE" "$@"
