1{ 2 # nix provisions toolchains and Postgres; buck2 owns the target 3 # graph. Same division of labour as deizel/buck2-cakeml. 4 description = "postjevsql: a Rust Postgres extension for TypeSafe's Jev"; 5 6 inputs = { 7 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 8 # The estate package set (buck2, see below); nixpkgs follows ours. 9 nix-pkgs.url = "git+ssh://git@github.com/deizel/nix-pkgs"; 10 nix-pkgs.inputs.nixpkgs.follows = "nixpkgs"; 11 # third-party/jevcrates is a git submodule; without this the flake's 12 # source omits it and the sandbox build cannot find the jev crates. 13 self.submodules = true; 14 }; 15 16 outputs = 17 { 18 self, 19 nixpkgs, 20 nix-pkgs, 21 }: 22 let 23 system = "x86_64-linux"; 24 pkgs = nixpkgs.legacyPackages.${system}; 25 inherit (nixpkgs) lib; 26 # The supported majors (PG_MAJORS in build/defs.bzl). The devshell's 27 # Postgres is the default, the one buck's graph builds against. 28 majors = import ./nix/majors.nix { inherit lib; }; 29 postgresql = pkgs."postgresql_${majors.default}"; 30 # Every supported major's server and pg_config, for targets 31 # configured for //platforms:pgNN (build/defs.bzl's 32 # pg_major_select); PATH and PGRX_PG_CONFIG_PATH carry only the 33 # default's. 34 perMajor = lib.concatMapStringsSep "\n" ( 35 m: 36 let 37 pg = pkgs."postgresql_${m}"; 38 in 39 "postgres_bin_${m} = ${pg}/bin\npg_config_${m} = ${pg.pg_config}/bin/pg_config" 40 ) majors.all; 41 # buck2 2026-08-22 drops its own gRPC connections under bursts of 42 # tiny messages (h2's small-DATA-frame budget; tests/CLAUDE.md): 43 # the forkserver exits and every later local action fails. Fixed in 44 # facebook/buck2 1cc3e05f85, first released in 2026-09-15. nix-pkgs 45 # carries that release for the whole estate, and its package throws 46 # once nixpkgs catches up (header there has the full account). 47 buck2 = nix-pkgs.packages.${system}.buck2; 48 in 49 { 50 # The extension per supported major (contract §3, nix/package.nix), 51 # as nixpkgs names its sets: postgresqlNNPackages.postjevsql. 52 legacyPackages.${system} = lib.listToAttrs ( 53 map (major: { 54 name = "postgresql${major}Packages"; 55 value.postjevsql = pkgs."postgresql_${major}".pkgs.callPackage ./nix/package.nix { inherit buck2; }; 56 }) majors.all 57 ); 58 packages.${system} = { 59 default = self.legacyPackages.${system}."postgresql${majors.default}Packages".postjevsql; 60 # The sidecar CLI (nix/sidecar-cli.nix), the one engine behind 61 # every sidecar launcher. 62 postjevsql-sidecar = pkgs.callPackage ./nix/sidecar-cli.nix { 63 postjevsql = self.packages.${system}.default; 64 }; 65 # The sidecar as a `docker load`-able image (nix/sidecar-image.nix). 66 postjevsql-sidecar-image = pkgs.callPackage ./nix/sidecar-image.nix { 67 extension = ps: ps.callPackage ./nix/package.nix { inherit buck2; }; 68 cli = self.packages.${system}.postjevsql-sidecar; 69 }; 70 };
Sidecar mode (CLAUDE.md Deployment); nix/sidecar.nix. The flake's module builds the extension with the pinned buck2.
The module booted against a loopback target (nix/sidecar-test.nix).
84 checks.${system} = { 85 sidecar = import ./nix/sidecar-test.nix { 86 inherit pkgs; 87 sidecar = self.nixosModules.sidecar; 88 }; 89 # The image booted in docker against the same target (nix/sidecar-image-test.nix). 90 sidecar-image = import ./nix/sidecar-image-test.nix { 91 inherit pkgs; 92 image = self.packages.${system}.postjevsql-sidecar-image; 93 }; 94 };
96 devShells.${system}.default = pkgs.mkShell { 97 packages = [ 98 buck2 99 pkgs.reindeer 100 pkgs.rustc 101 pkgs.cargo 102 pkgs.clippy 103 pkgs.rustfmt 104 pkgs.python3 105 # The prelude's system_cxx_toolchain drives clang/clang++. 106 pkgs.clang 107 pkgs.lld 108 # pgrx-pg-sys runs bindgen against the server headers; the hook 109 # sets LIBCLANG_PATH and the libc include flags libclang lacks. 110 # Buck's local actions inherit the daemon's environment. 111 pkgs.rustPlatform.bindgenHook 112 postgresql 113 postgresql.pg_config 114 postgresql.dev 115 ]; 116 PGRX_PG_CONFIG_PATH = "${postgresql.pg_config}/bin/pg_config"; 117 # Buck execs tools by absolute path (the prelude's cc shim uses 118 # os.execl, which never searches PATH), so the toolchain cell reads 119 # store paths from here rather than trusting the environment. 120 # Written only when it changes, and by rename: buck logs any write as a 121 # changed file, and would read a half-written one as a changed config. 122 shellHook = '' 123 local_cfg="$(git rev-parse --show-toplevel)/.buckconfig.local" 124 cat > "$local_cfg.tmp" <<EOF 125 [nix] 126 cc = ${pkgs.clang}/bin/clang 127 cxx = ${pkgs.clang}/bin/clang++ 128 ar = ${pkgs.clang}/bin/ar 129 python = ${pkgs.python3}/bin/python3 130 [rust] 131 rustc_identity = ${pkgs.rustc} 132 [postjevsql] 133 postgres_bin = ${postgresql}/bin 134 ${perMajor} 135 EOF 136 if cmp -s "$local_cfg.tmp" "$local_cfg"; then 137 rm "$local_cfg.tmp" 138 else 139 mv "$local_cfg.tmp" "$local_cfg" 140 fi 141 ''; 142 }; 143 }; 144}