Files
2026-11-05 12:52:32 +01:00

116 lines
4.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT"
umask 077
if [[ -f .env ]]; then
# Local shell configuration. Do not source untrusted .env files.
set -a
# shellcheck disable=SC1091
source .env
set +a
fi
if ! command -v cargo >/dev/null 2>&1 && [[ -x "$HOME/.cargo/bin/cargo" ]]; then
export PATH="$HOME/.cargo/bin:$PATH"
fi
VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)"
mode="${1:-run}"
if [[ $# -gt 0 ]]; then shift; fi
case "$mode" in
help|-h|--help)
cat <<HELP
ActivePush ${VERSION} - development helper
./dev.sh Build and start the server (ActiveSync + panel) with ./data
./dev.sh run [flags] Same, extra flags go to 'active-push serve'
./dev.sh backends Start throw-away Dovecot + Radicale + SMTP sink (tools/dev)
./dev.sh seed Apply tools/dev/test-settings.json (matches 'backends')
./dev.sh e2e End-to-end test against a running dev server + backends
./dev.sh probe USER ActiveSync smoke test (password prompted)
./dev.sh admin setup-token One-time token for creating the first administrator in the panel
./dev.sh admin init --username NAME
Create the administrator from the shell (hidden password prompt)
./dev.sh admin reset-password [--username NAME]
./dev.sh admin logout-all | status
./dev.sh config get|apply FILE|validate FILE
./dev.sh device list|wipe ID|resync ID|remove ID|block ID|unblock ID
./dev.sh test Unit tests (cargo test)
./dev.sh check cargo check for all targets
./dev.sh lint rustfmt --check + clippy -D warnings + JS syntax check
./dev.sh fmt Format Rust sources
./dev.sh build Debug build only
./dev.sh release Optimised build (target/release/active-push)
./dev.sh deb Build a Debian package into dist/
./dev.sh dist Full release pipeline (build-release.sh)
./dev.sh import-zpush DIR Convert a Z-Push installation's config into settings JSON
./dev.sh doctor Show available tools
Defaults (override in .env): ActiveSync 127.0.0.1:8081, panel 127.0.0.1:9091, data ./data
HELP
exit 0 ;;
run|backends|seed|e2e|probe|admin|config|device|test|check|lint|fmt|build|release|deb|dist|import-zpush|doctor) ;;
*) printf 'Unknown command: %s. Use ./dev.sh help\n' "$mode" >&2; exit 2 ;;
esac
case "$mode" in
doctor)
for tool in cargo rustc cc python3 node dpkg-deb dovecot radicale; do
printf '%-10s ' "$tool"; command -v "$tool" || printf 'NOT FOUND\n'
done
exit 0 ;;
backends) exec tools/dev/test-backends.sh "$@" ;;
import-zpush) exec python3 tools/zpush-import.py "$@" ;;
deb) exec scripts/build-deb.sh "$@" ;;
dist) exec ./build-release.sh "$@" ;;
esac
if ! command -v cargo >/dev/null 2>&1; then
cat >&2 <<'MISSING'
Rust/Cargo is not installed or not in PATH.
Install the stable toolchain from https://rustup.rs and a C linker (build-essential).
This script never installs system software or runs sudo.
MISSING
exit 127
fi
export ACTIVE_PUSH_DATA_DIR="${ACTIVE_PUSH_DATA_DIR:-$ROOT/data}"
export ACTIVE_PUSH_EAS_LISTEN="${ACTIVE_PUSH_EAS_LISTEN:-127.0.0.1:8081}"
export ACTIVE_PUSH_ADMIN_LISTEN="${ACTIVE_PUSH_ADMIN_LISTEN:-127.0.0.1:9091}"
export RUST_LOG="${RUST_LOG:-active_push=info,warn}"
export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$ROOT/target}"
mkdir -p "$ACTIVE_PUSH_DATA_DIR"
case "$mode" in
fmt) exec cargo fmt --all "$@" ;;
check) exec cargo check --all-targets "$@" ;;
test) exec cargo test --lib --bins "$@" ;;
lint)
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
if command -v node >/dev/null; then node --check web/app.js; fi
python3 scripts/check-wbxml-names.py
printf 'Lint: OK\n'
exit 0 ;;
release) exec cargo build --release "$@" ;;
e2e)
export AP_E2E_URL="${AP_E2E_URL:-http://${ACTIVE_PUSH_EAS_LISTEN}}"
exec cargo test --test e2e -- --nocapture --test-threads=1 "$@" ;;
esac
printf 'Building ActivePush %s...\n' "$VERSION" >&2
cargo build
BIN="$CARGO_TARGET_DIR/debug/active-push"
case "$mode" in
build) printf 'Binary: %s\n' "$BIN" ;;
seed) exec "$BIN" config apply tools/dev/test-settings.json ;;
probe)
user="${1:?usage: ./dev.sh probe USER}"
exec "$BIN" probe --url "http://${ACTIVE_PUSH_EAS_LISTEN}/Microsoft-Server-ActiveSync" --user "$user" ;;
admin) exec "$BIN" admin "$@" ;;
config) exec "$BIN" config "$@" ;;
device) exec "$BIN" device "$@" ;;
run)
printf 'ActiveSync: http://%s/Microsoft-Server-ActiveSync\nPanel: http://%s/\n' "$ACTIVE_PUSH_EAS_LISTEN" "$ACTIVE_PUSH_ADMIN_LISTEN" >&2
exec "$BIN" serve "$@" ;;
esac