{ description = "Landkreis-Sprints"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; rust-overlay.url = "github:oxalica/rust-overlay"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { nixpkgs, rust-overlay, flake-utils, ... }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = import nixpkgs { inherit system; overlays = [ rust-overlay.overlays.default ]; }; rust = pkgs.rust-bin.stable.latest.default.override { extensions = [ "rustfmt" "clippy" ]; }; # PostgreSQL 17 with PostGIS in the PostgreSQL extension path. postgresql = pkgs.postgresql_17.withPackages ( ps: [ ps.postgis ] ); in { devShells.default = pkgs.mkShell { packages = [ rust # PostgreSQL + PostGIS postgresql # SQLx migrations / CLI pkgs.sqlx-cli # GIS pkgs.gdal pkgs.geos pkgs.proj # Rust native dependencies pkgs.pkg-config pkgs.openssl ]; shellHook = '' set -e # ============================================================ # Environment # ============================================================ export PGDATA="$PWD/.pgdata" export PGHOST="$PWD/.pgsocket" export PGDATABASE="county_sprints" export PGUSER="county_sprints" export RUST_BACKTRACE=1 if [ -z "''${RUST_LOG:-}" ]; then export RUST_LOG="info" fi mkdir -p "$PGHOST" # Use an absolute path for the PostgreSQL Unix socket. PGHOST_ABS="$(cd "$PGHOST" && pwd)" # ============================================================ # Initialise PostgreSQL cluster # ============================================================ if [ ! -f "$PGDATA/PG_VERSION" ]; then echo echo "==> Initialising local PostgreSQL cluster" initdb \ --username="$PGUSER" \ --auth=trust \ --no-locale \ --encoding=UTF8 \ "$PGDATA" \ >/dev/null fi # ============================================================ # Start PostgreSQL # # PostgreSQL is deliberately restricted to the Unix socket. # ============================================================ if ! pg_ctl \ -D "$PGDATA" \ status \ >/dev/null 2>&1 then echo echo "==> Starting local PostgreSQL" pg_ctl \ -D "$PGDATA" \ -l "$PGDATA/postgresql.log" \ -o "-c listen_addresses= -k $PGHOST_ABS" \ start \ >/dev/null fi # ============================================================ # Wait until PostgreSQL is ready # ============================================================ postgres_ready=0 for _ in $(seq 1 50); do if pg_isready \ -h "$PGHOST_ABS" \ -U "$PGUSER" \ >/dev/null 2>&1 then postgres_ready=1 break fi sleep 0.2 done if [ "$postgres_ready" != "1" ]; then echo echo "ERROR: PostgreSQL could not be started." echo echo "PostgreSQL log:" echo "------------------------------------------------------------" if [ -f "$PGDATA/postgresql.log" ]; then cat "$PGDATA/postgresql.log" else echo "No PostgreSQL log found." fi echo "------------------------------------------------------------" echo return 1 fi # ============================================================ # Create application database # ============================================================ if ! psql \ -h "$PGHOST_ABS" \ -U "$PGUSER" \ -d postgres \ -tAc \ "SELECT 1 FROM pg_database WHERE datname = '$PGDATABASE'" | grep -q 1 then echo echo "==> Creating PostgreSQL database '$PGDATABASE'" createdb \ -h "$PGHOST_ABS" \ -U "$PGUSER" \ "$PGDATABASE" fi # ============================================================ # Enable PostGIS # ============================================================ echo echo "==> Checking PostGIS" psql \ -h "$PGHOST_ABS" \ -U "$PGUSER" \ -d "$PGDATABASE" \ -v ON_ERROR_STOP=1 \ -c "CREATE EXTENSION IF NOT EXISTS postgis;" \ >/dev/null # ============================================================ # SQLx / application connection string # # localhost is only the syntactic host. The host query # parameter tells libpq/SQLx to use our Unix socket. # ============================================================ export DATABASE_URL="postgresql://$PGUSER@localhost/$PGDATABASE?host=$PGHOST_ABS" # ============================================================ # Development information # ============================================================ echo echo "============================================================" echo " Landkreis-Sprints development environment" echo "============================================================" echo echo "Rust:" echo " $(rustc --version)" echo echo "PostgreSQL:" echo " $(psql --version)" echo " socket: $PGHOST_ABS" echo " database: $PGDATABASE" echo " user: $PGUSER" echo echo "PostGIS:" psql \ -h "$PGHOST_ABS" \ -U "$PGUSER" \ -d "$PGDATABASE" \ -tAc "SELECT PostGIS_Full_Version();" | sed 's/^/ /' echo echo "DATABASE_URL:" echo " $DATABASE_URL" echo echo "Commands:" echo " sqlx migrate run" echo " cargo check" echo " cargo test" echo " cargo run" echo echo "============================================================" echo set +e ''; }; } ); }