Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ web-build:

# Local dev = standalone: the server with every role (serve, maintain, events) at
# https://walgit.localhost:$PORT (default 8080) against local rustfs. Self-contained: starts rustfs (+ bucket) if
# it is not answering on :9000 and builds the SPA if web/dist is missing, then runs the server.
# it is not answering on :9000 and builds the SPA if web/dist holds no Vite output, then runs the server.
# `config` defaults to walgit.standalone.toml; point it at a real bucket by editing [store] there. The rustfs
# keys come from the environment (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY; compose.yaml fixes them).
# Optional: export WALGIT__SERVER__AUTH__* (OIDC client, session secret) to try browser sign-in locally.
Expand All @@ -30,8 +30,10 @@ dev-local config="walgit.standalone.toml":
echo "rustfs not running on :9000 — starting it (just dev-store)"
just dev-store
fi
if [ ! -f web/dist/index.html ]; then
echo "web/dist missing — building the SPA (just web-build)"
# crates/walgit-server/build.rs:19 writes a placeholder index.html on any cargo build, so only
# repos.js proves a real Vite build (the same file Containerfile:23 checks).
if [ ! -f web/dist/repos.js ]; then
echo "web/dist SPA is unbuilt; building it (just web-build)"
just web-build
fi
cargo build --release --bin walgit-server
Expand All @@ -41,22 +43,31 @@ dev-local config="walgit.standalone.toml":

# Start rustfs (S3-compatible) for local dev via podman compose (rootless, no daemon group needed;
# `podman compose` drives compose.yaml through the docker-compose binary dev.yml installs).
# `podman compose` talks to the podman API socket; rootless nix podman has no systemd unit for it, so
# `podman system service` is started (detached, idle-timeout 0) when the socket is missing.
# `podman compose` talks to the podman API socket; on Linux rootless nix podman has no systemd unit
# for it, so `podman system service` is started (detached, idle-timeout 0) when the socket is missing.
# Elsewhere (macOS, the BSDs) the socket belongs to the podman machine VM: the recipe only checks that
# podman answers and tells you to start it if it does not.
dev-store:
#!/usr/bin/env bash
set -euo pipefail
# nix podman ships no /etc/containers: give the user a signature policy + registry search list once.
cdir="${XDG_CONFIG_HOME:-$HOME/.config}/containers"; mkdir -p "$cdir"
[ -f "$cdir/policy.json" ] || printf '{"default":[{"type":"insecureAcceptAnything"}]}\n' > "$cdir/policy.json"
[ -f "$cdir/registries.conf" ] || printf 'unqualified-search-registries = ["docker.io"]\n' > "$cdir/registries.conf"
sock="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/podman/podman.sock"
if [ ! -S "$sock" ]; then
echo "starting rootless podman API socket at $sock"
mkdir -p "$(dirname "$sock")"
setsid nohup podman system service --time=0 "unix://$sock" >/tmp/walgit-podman-service.log 2>&1 < /dev/null &
for _ in $(seq 1 50); do [ -S "$sock" ] && break; sleep 0.2; done
[ -S "$sock" ] || { echo "podman API socket did not appear; see /tmp/walgit-podman-service.log"; exit 1; }
# The rootless socket bootstrap is Linux-only: XDG_RUNTIME_DIR and /run/user do not exist on
# macOS or the BSDs, and setsid is util-linux. There the socket lives in the podman machine VM.
if [ "$(uname -s)" = Linux ]; then
# nix podman ships no /etc/containers: give the user a signature policy + registry search list once.
cdir="${XDG_CONFIG_HOME:-$HOME/.config}/containers"; mkdir -p "$cdir"
[ -f "$cdir/policy.json" ] || printf '{"default":[{"type":"insecureAcceptAnything"}]}\n' > "$cdir/policy.json"
[ -f "$cdir/registries.conf" ] || printf 'unqualified-search-registries = ["docker.io"]\n' > "$cdir/registries.conf"
sock="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/podman/podman.sock"
if [ ! -S "$sock" ]; then
echo "starting rootless podman API socket at $sock"
mkdir -p "$(dirname "$sock")"
nohup podman system service --time=0 "unix://$sock" >/tmp/walgit-podman-service.log 2>&1 < /dev/null &
for _ in $(seq 1 50); do [ -S "$sock" ] && break; sleep 0.2; done
[ -S "$sock" ] || { echo "podman API socket did not appear; see /tmp/walgit-podman-service.log"; exit 1; }
fi
elif ! podman info >/dev/null 2>&1; then
echo "podman is not answering: start the container runtime first (macOS: podman machine start)"
exit 1
fi
podman compose up -d rustfs
echo "Waiting for rustfs to be healthy..."
Expand Down
16 changes: 11 additions & 5 deletions tests/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@ if [[ -n "${WALGIT_E2E_BASE_URL:-}" ]]; then
walgit_auth_setup "$WALGIT_E2E_BASE_URL" || exit 1
fi

# ${ARR[@]+"${ARR[@]}"}: bash 3.2 (macOS /bin/bash) calls an empty array expansion an unbound
# variable under set -u. "${ARR[@]:-}" would pass a blank argument, which curl and git reject.
# Wrapper for curl that adds auth headers.
curl_auth() { curl "${AUTH_CURL_ARGS[@]}" "$@"; }
curl_auth() { curl ${AUTH_CURL_ARGS[@]+"${AUTH_CURL_ARGS[@]}"} "$@"; }
# Wrapper for git that adds auth headers.
git_auth() { git "${GIT_AUTH_ARGS[@]}" "$@"; }
git_auth() { git ${GIT_AUTH_ARGS[@]+"${GIT_AUTH_ARGS[@]}"} "$@"; }

wait_http() {
local url="$1" max="${2:-30}"
for ((i=0; i<max; i++)); do
if curl -sf "${AUTH_CURL_ARGS[@]}" "$url" >/dev/null 2>&1; then return 0; fi
if curl -sf ${AUTH_CURL_ARGS[@]+"${AUTH_CURL_ARGS[@]}"} "$url" >/dev/null 2>&1; then return 0; fi
sleep 1
done
return 1
Expand All @@ -70,7 +72,9 @@ fi

TMP="$(mktemp -d)"
PIDS=()
cleanup() { for p in "${PIDS[@]}"; do kill "$p" 2>/dev/null || true; done; wait 2>/dev/null || true; rm -rf "$TMP"; }
# "${PIDS[@]:-}": bash 3.2 (macOS /bin/bash) calls an empty array expansion an unbound variable
# under set -u, which aborts the EXIT trap before rm -rf. Same guard as tests/git-bundle-filter.sh:24.
cleanup() { for p in "${PIDS[@]:-}"; do kill "$p" 2>/dev/null || true; done; wait 2>/dev/null || true; rm -rf "$TMP"; }
trap cleanup EXIT

PORT="$(rand_port)"
Expand Down Expand Up @@ -123,7 +127,9 @@ fi

step "synth: generate synthetic repo (size s, seed 12345)"
SYNTH_DIR="$TMP/synth"
"$WALGIT" --config "$TMP/walgit.toml" synth --out "$SYNTH_DIR" --size s --seed 12345
# synth reads nothing from the config (walgit-cli/src/lib.rs:493 passes only out/size/seed) and
# $TMP/walgit.toml exists in local mode only, so ask for defaults the way the CLI documents.
"$WALGIT" --config /dev/null synth --out "$SYNTH_DIR" --size s --seed 12345
pass "synth completed"

# Verify with git fsck.
Expand Down