diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index dc0dcbb..5b3e2bc 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,8 @@ sandbox/benchmark/results/ sandbox/benchmark/datasets/ sandbox/benchmark/.venv/ sandbox/playground/.venv/ + +# Nix devshell (opt-in; see flake.nix) +.direnv/ +.pgrx/ +.nix-cargo/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b59eb90..5c88032 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,9 +15,41 @@ cargo test --features pg17 cargo pgrx test pg17 ``` +`cargo pgrx init` with no arguments builds PostgreSQL from source and needs +ICU, pkg-config, bison, flex, readline, zlib, openssl, and perl on the host. +On macOS the typical prerequisites are: + +```bash +brew install icu4c pkg-config bison flex readline zlib openssl@3 +export PKG_CONFIG_PATH="$(brew --prefix icu4c)/lib/pkgconfig:$PKG_CONFIG_PATH" +``` + +To skip the source build entirely, point pgrx at an existing PostgreSQL +install: + +```bash +cargo pgrx init --pg17 $(brew --prefix postgresql@17)/bin/pg_config +``` + Use PostgreSQL 13 through 18 when validating compatibility-sensitive changes. The default local feature is `pg17`. +### Nix devshell (optional) + +A `flake.nix` is provided for contributors who use Nix. It pins the Rust +toolchain, `cargo-pgrx`, and a Postgres major matching the pgrx feature +flag, and initializes `cargo pgrx` against the nix-provided Postgres on +first entry — no system deps to install. + +```bash +nix develop # default shell: pg17 +nix develop .#pg16 # switch majors +cd graph && cargo test --features pg17 +``` + +With direnv installed, `direnv allow` activates the shell automatically. +The Nix path is opt-in; the brew/apt paths above remain fully supported. + ## Pull Request Bar - Keep SQL APIs aligned with `docs/user_guide/api-reference.mdx`. diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..902b4db --- /dev/null +++ b/flake.nix @@ -0,0 +1,90 @@ +{ + description = "pgGraph dev environment (optional, opt-in)."; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, flake-utils, rust-overlay }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ rust-overlay.overlays.default ]; + }; + + # Toolchain pinned to the rust-version in graph/Cargo.toml. + rust = pkgs.rust-bin.stable."1.95.0".default.override { + extensions = [ "rust-src" "rust-analyzer" "clippy" "rustfmt" ]; + }; + + # cargo-pgrx version is pinned in graph/Cargo.toml as `pgrx = "=0.18.0"`. + # nixpkgs' cargo-pgrx may drift from that, so we install the exact + # version into a project-local CARGO_INSTALL_ROOT on first shell entry. + # This keeps the host's global ~/.cargo/bin untouched. + pgrxVersion = "0.18.0"; + + commonBuildInputs = with pkgs; [ + icu + openssl + zlib + readline + libxml2 + libxslt + pkg-config + ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ + libiconv + ]; + + mkShell = pg: pkgs.mkShell { + packages = [ + rust + pg + pkgs.cacert + ] ++ commonBuildInputs; + + shellHook = '' + export PGRX_HOME="$PWD/.pgrx" + export CARGO_INSTALL_ROOT="$PWD/.nix-cargo" + export PATH="$CARGO_INSTALL_ROOT/bin:$PATH" + export PG_CONFIG="${pg}/bin/pg_config" + + mkdir -p "$PGRX_HOME" "$CARGO_INSTALL_ROOT" + + # Install the pinned cargo-pgrx if not already present. + if ! "$CARGO_INSTALL_ROOT/bin/cargo-pgrx" --version 2>/dev/null | grep -q '${pgrxVersion}'; then + echo "Installing cargo-pgrx ${pgrxVersion} into $CARGO_INSTALL_ROOT ..." + cargo install --locked cargo-pgrx --version ${pgrxVersion} + fi + + # Initialize pgrx against the nix-provided Postgres on first entry. + pg_major="$("$PG_CONFIG" --version | awk '{print $2}' | cut -d. -f1)" + if [ ! -d "$PGRX_HOME/$pg_major.''${pg_major}" ] && [ ! -f "$PGRX_HOME/config.toml" ]; then + echo "Running cargo pgrx init --pg$pg_major=$PG_CONFIG ..." + (cd "$PWD/graph" && cargo pgrx init --pg$pg_major="$PG_CONFIG") + fi + + echo "pgGraph devshell: PG $pg_major @ $PG_CONFIG" + echo "Try: (cd graph && cargo test --features pg$pg_major)" + ''; + }; + in { + devShells = { + default = mkShell pkgs.postgresql_17; + pg13 = mkShell pkgs.postgresql_13; + pg14 = mkShell pkgs.postgresql_14; + pg15 = mkShell pkgs.postgresql_15; + pg16 = mkShell pkgs.postgresql_16; + pg17 = mkShell pkgs.postgresql_17; + # pg18 lands in nixpkgs once it's released upstream; uncomment then: + # pg18 = mkShell pkgs.postgresql_18; + }; + + formatter = pkgs.nixpkgs-fmt; + }); +}