flake.nix 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. {
  2. description = "CDK Flake";
  3. inputs = {
  4. nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
  5. rust-overlay = {
  6. url = "github:oxalica/rust-overlay";
  7. inputs = {
  8. nixpkgs.follows = "nixpkgs";
  9. };
  10. };
  11. fenix = {
  12. url = "github:nix-community/fenix";
  13. inputs.nixpkgs.follows = "nixpkgs";
  14. inputs.rust-analyzer-src.follows = "";
  15. };
  16. flake-utils.url = "github:numtide/flake-utils";
  17. crane = {
  18. url = "github:ipetkov/crane";
  19. };
  20. pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
  21. };
  22. outputs =
  23. { self
  24. , nixpkgs
  25. , rust-overlay
  26. , flake-utils
  27. , pre-commit-hooks
  28. , crane
  29. , ...
  30. }@inputs:
  31. flake-utils.lib.eachDefaultSystem (
  32. system:
  33. let
  34. overlays = [ (import rust-overlay) ];
  35. lib = pkgs.lib;
  36. stdenv = pkgs.stdenv;
  37. isDarwin = stdenv.isDarwin;
  38. libsDarwin =
  39. with pkgs;
  40. lib.optionals isDarwin [
  41. # Additional darwin specific inputs can be set here
  42. darwin.apple_sdk.frameworks.Security
  43. darwin.apple_sdk.frameworks.SystemConfiguration
  44. ];
  45. # Dependencies
  46. pkgs = import nixpkgs {
  47. inherit system overlays;
  48. };
  49. # Toolchains
  50. # latest stable
  51. stable_toolchain = pkgs.rust-bin.stable."1.91.1".default.override {
  52. targets = [ "wasm32-unknown-unknown" ]; # wasm
  53. extensions = [
  54. "rustfmt"
  55. "clippy"
  56. "rust-analyzer"
  57. ];
  58. };
  59. # MSRV stable
  60. msrv_toolchain = pkgs.rust-bin.stable."1.85.0".default.override {
  61. targets = [ "wasm32-unknown-unknown" ]; # wasm
  62. extensions = [
  63. "rustfmt"
  64. "clippy"
  65. "rust-analyzer"
  66. ];
  67. };
  68. # Nightly used for formatting
  69. nightly_toolchain = pkgs.rust-bin.selectLatestNightlyWith (
  70. toolchain:
  71. toolchain.default.override {
  72. extensions = [
  73. "rustfmt"
  74. "clippy"
  75. "rust-analyzer"
  76. "rust-src"
  77. ];
  78. targets = [ "wasm32-unknown-unknown" ]; # wasm
  79. }
  80. );
  81. # ========================================
  82. # Crane setup for cached builds
  83. # ========================================
  84. craneLib = (crane.mkLib pkgs).overrideToolchain stable_toolchain;
  85. craneLibMsrv = (crane.mkLib pkgs).overrideToolchain msrv_toolchain;
  86. # Source for crane builds
  87. src = builtins.path {
  88. path = ./.;
  89. name = "cdk-source";
  90. };
  91. # Source for MSRV builds - uses Cargo.lock.msrv with MSRV-compatible deps
  92. srcMsrv = pkgs.runCommand "cdk-source-msrv" { } ''
  93. cp -r ${src} $out
  94. chmod -R +w $out
  95. cp $out/Cargo.lock.msrv $out/Cargo.lock
  96. '';
  97. # Common args for all Crane builds
  98. commonCraneArgs = {
  99. inherit src;
  100. pname = "cdk";
  101. version = "0.14.0";
  102. nativeBuildInputs = with pkgs; [
  103. pkg-config
  104. protobuf
  105. ];
  106. buildInputs = with pkgs; [
  107. openssl
  108. sqlite
  109. zlib
  110. ] ++ libsDarwin;
  111. # Environment variables
  112. PROTOC = "${pkgs.protobuf}/bin/protoc";
  113. PROTOC_INCLUDE = "${pkgs.protobuf}/include";
  114. };
  115. # Common args for MSRV builds - uses srcMsrv with pinned deps
  116. commonCraneArgsMsrv = commonCraneArgs // {
  117. src = srcMsrv;
  118. };
  119. # Build ALL dependencies once - this is what gets cached by Cachix
  120. # Note: We exclude swagger feature as it tries to download assets during build
  121. workspaceDeps = craneLib.buildDepsOnly (commonCraneArgs // {
  122. pname = "cdk-deps";
  123. # Build deps for workspace - swagger excluded (downloads during build)
  124. cargoExtraArgs = "--workspace";
  125. });
  126. # MSRV dependencies (separate cache due to different toolchain)
  127. workspaceDepsMsrv = craneLibMsrv.buildDepsOnly (commonCraneArgsMsrv // {
  128. pname = "cdk-deps-msrv";
  129. cargoExtraArgs = "--workspace";
  130. });
  131. # Helper function to create clippy checks
  132. mkClippy = name: cargoArgs: craneLib.cargoClippy (commonCraneArgs // {
  133. pname = "cdk-clippy-${name}";
  134. cargoArtifacts = workspaceDeps;
  135. cargoClippyExtraArgs = "${cargoArgs} -- -D warnings";
  136. });
  137. # Helper function to create example checks (compile only, no network access in sandbox)
  138. mkExample = name: craneLib.mkCargoDerivation (commonCraneArgs // {
  139. pname = "cdk-example-${name}";
  140. cargoArtifacts = workspaceDeps;
  141. buildPhaseCargoCommand = "cargo build --example ${name}";
  142. # Examples are compiled but not run (no network in Nix sandbox)
  143. installPhaseCommand = "mkdir -p $out";
  144. });
  145. # Helper function to create example packages (outputs binary for running outside sandbox)
  146. mkExamplePackage = name: craneLib.mkCargoDerivation (commonCraneArgs // {
  147. pname = "cdk-example-${name}";
  148. cargoArtifacts = workspaceDeps;
  149. buildPhaseCargoCommand = "cargo build --release --example ${name}";
  150. installPhaseCommand = ''
  151. mkdir -p $out/bin
  152. cp target/release/examples/${name} $out/bin/
  153. '';
  154. });
  155. # Helper function to create MSRV build checks
  156. mkMsrvBuild = name: cargoArgs: craneLibMsrv.cargoBuild (commonCraneArgsMsrv // {
  157. pname = "cdk-msrv-${name}";
  158. cargoArtifacts = workspaceDepsMsrv;
  159. cargoExtraArgs = cargoArgs;
  160. });
  161. # Helper function to create WASM build checks
  162. # WASM builds don't need native libs like openssl
  163. mkWasmBuild = name: cargoArgs: craneLib.cargoBuild ({
  164. inherit src;
  165. pname = "cdk-wasm-${name}";
  166. version = "0.14.0";
  167. cargoArtifacts = workspaceDeps;
  168. cargoExtraArgs = "${cargoArgs} --target wasm32-unknown-unknown";
  169. # WASM doesn't need native build inputs
  170. nativeBuildInputs = with pkgs; [ pkg-config ];
  171. buildInputs = [ ];
  172. # Disable tests for WASM (can't run in sandbox)
  173. doCheck = false;
  174. });
  175. # Doc tests check
  176. docTests = craneLib.cargoTest (commonCraneArgs // {
  177. pname = "cdk-doc-tests";
  178. cargoArtifacts = workspaceDeps;
  179. cargoTestExtraArgs = "--doc";
  180. });
  181. # Strict docs check - build docs with warnings as errors
  182. # Uses mkCargoDerivation for custom RUSTDOCFLAGS
  183. strictDocs = craneLib.mkCargoDerivation (commonCraneArgs // {
  184. pname = "cdk-strict-docs";
  185. cargoArtifacts = workspaceDeps;
  186. buildPhaseCargoCommand = ''
  187. export RUSTDOCFLAGS="-D warnings"
  188. cargo doc --no-deps \
  189. -p cashu \
  190. -p cdk-common \
  191. -p cdk-sql-common \
  192. -p cdk \
  193. -p cdk-redb \
  194. -p cdk-sqlite \
  195. -p cdk-axum \
  196. -p cdk-cln \
  197. -p cdk-lnd \
  198. -p cdk-lnbits \
  199. -p cdk-fake-wallet \
  200. -p cdk-mint-rpc \
  201. -p cdk-payment-processor \
  202. -p cdk-signatory \
  203. -p cdk-cli \
  204. -p cdk-mintd
  205. '';
  206. installPhaseCommand = "mkdir -p $out";
  207. });
  208. # FFI Python tests
  209. ffiTests = craneLib.mkCargoDerivation (commonCraneArgs // {
  210. pname = "cdk-ffi-tests";
  211. cargoArtifacts = workspaceDeps;
  212. nativeBuildInputs = commonCraneArgs.nativeBuildInputs ++ [
  213. pkgs.python311
  214. ];
  215. buildPhaseCargoCommand = ''
  216. # Build the FFI library
  217. cargo build --release --package cdk-ffi --features postgres
  218. # Generate Python bindings
  219. cargo run --bin uniffi-bindgen generate \
  220. --library target/release/libcdk_ffi.so \
  221. --language python \
  222. --out-dir target/bindings/python
  223. # Copy library to bindings directory
  224. cp target/release/libcdk_ffi.so target/bindings/python/
  225. # Run Python tests
  226. python3 crates/cdk-ffi/tests/test_transactions.py
  227. '';
  228. installPhaseCommand = "mkdir -p $out";
  229. });
  230. # ========================================
  231. # Example definitions - single source of truth
  232. # ========================================
  233. exampleChecks = [
  234. "mint-token"
  235. "melt-token"
  236. "p2pk"
  237. "proof-selection"
  238. "wallet"
  239. ];
  240. # ========================================
  241. # Clippy check definitions - single source of truth
  242. # ========================================
  243. clippyChecks = {
  244. # Core crate: cashu
  245. "cashu" = "-p cashu";
  246. "cashu-no-default" = "-p cashu --no-default-features";
  247. "cashu-wallet" = "-p cashu --no-default-features --features wallet";
  248. "cashu-mint" = "-p cashu --no-default-features --features mint";
  249. "cashu-auth" = "-p cashu --no-default-features --features auth";
  250. # Core crate: cdk-common
  251. "cdk-common" = "-p cdk-common";
  252. "cdk-common-no-default" = "-p cdk-common --no-default-features";
  253. "cdk-common-wallet" = "-p cdk-common --no-default-features --features wallet";
  254. "cdk-common-mint" = "-p cdk-common --no-default-features --features mint";
  255. "cdk-common-auth" = "-p cdk-common --no-default-features --features auth";
  256. # Core crate: cdk
  257. "cdk" = "-p cdk";
  258. "cdk-no-default" = "-p cdk --no-default-features";
  259. "cdk-wallet" = "-p cdk --no-default-features --features wallet";
  260. "cdk-mint" = "-p cdk --no-default-features --features mint";
  261. "cdk-auth" = "-p cdk --no-default-features --features auth";
  262. # SQL crates
  263. "cdk-sql-common" = "-p cdk-sql-common";
  264. "cdk-sql-common-wallet" = "-p cdk-sql-common --no-default-features --features wallet";
  265. "cdk-sql-common-mint" = "-p cdk-sql-common --no-default-features --features mint";
  266. # Database crates
  267. "cdk-redb" = "-p cdk-redb";
  268. "cdk-sqlite" = "-p cdk-sqlite";
  269. "cdk-sqlite-sqlcipher" = "-p cdk-sqlite --features sqlcipher";
  270. # HTTP/API layer
  271. # Note: swagger feature excluded - downloads assets during build, incompatible with Nix sandbox
  272. "cdk-axum" = "-p cdk-axum";
  273. "cdk-axum-no-default" = "-p cdk-axum --no-default-features";
  274. "cdk-axum-redis" = "-p cdk-axum --no-default-features --features redis";
  275. # Lightning backends
  276. "cdk-cln" = "-p cdk-cln";
  277. "cdk-lnd" = "-p cdk-lnd";
  278. "cdk-lnbits" = "-p cdk-lnbits";
  279. "cdk-fake-wallet" = "-p cdk-fake-wallet";
  280. "cdk-payment-processor" = "-p cdk-payment-processor";
  281. "cdk-ldk-node" = "-p cdk-ldk-node";
  282. # Other crates
  283. "cdk-signatory" = "-p cdk-signatory";
  284. "cdk-mint-rpc" = "-p cdk-mint-rpc";
  285. "cdk-prometheus" = "-p cdk-prometheus";
  286. "cdk-ffi" = "-p cdk-ffi";
  287. # Binaries: cdk-cli
  288. "bin-cdk-cli" = "--bin cdk-cli";
  289. "bin-cdk-cli-sqlcipher" = "--bin cdk-cli --features sqlcipher";
  290. "bin-cdk-cli-redb" = "--bin cdk-cli --features redb";
  291. # Binaries: cdk-mintd
  292. "bin-cdk-mintd" = "--bin cdk-mintd";
  293. "bin-cdk-mintd-redis" = "--bin cdk-mintd --features redis";
  294. "bin-cdk-mintd-sqlcipher" = "--bin cdk-mintd --features sqlcipher";
  295. "bin-cdk-mintd-lnd-sqlite" = "--bin cdk-mintd --no-default-features --features lnd,sqlite";
  296. "bin-cdk-mintd-cln-postgres" = "--bin cdk-mintd --no-default-features --features cln,postgres";
  297. "bin-cdk-mintd-lnbits-sqlite" = "--bin cdk-mintd --no-default-features --features lnbits,sqlite";
  298. "bin-cdk-mintd-fakewallet-sqlite" = "--bin cdk-mintd --no-default-features --features fakewallet,sqlite";
  299. "bin-cdk-mintd-grpc-processor-sqlite" = "--bin cdk-mintd --no-default-features --features grpc-processor,sqlite";
  300. "bin-cdk-mintd-management-rpc-lnd-sqlite" = "--bin cdk-mintd --no-default-features --features management-rpc,lnd,sqlite";
  301. "bin-cdk-mintd-cln-sqlite" = "--bin cdk-mintd --no-default-features --features cln,sqlite";
  302. "bin-cdk-mintd-lnd-postgres" = "--bin cdk-mintd --no-default-features --features lnd,postgres";
  303. "bin-cdk-mintd-lnbits-postgres" = "--bin cdk-mintd --no-default-features --features lnbits,postgres";
  304. "bin-cdk-mintd-fakewallet-postgres" = "--bin cdk-mintd --no-default-features --features fakewallet,postgres";
  305. "bin-cdk-mintd-grpc-processor-postgres" = "--bin cdk-mintd --no-default-features --features grpc-processor,postgres";
  306. "bin-cdk-mintd-management-rpc-cln-postgres" = "--bin cdk-mintd --no-default-features --features management-rpc,cln,postgres";
  307. "bin-cdk-mintd-auth-sqlite-fakewallet" = "--bin cdk-mintd --no-default-features --features auth,sqlite,fakewallet";
  308. "bin-cdk-mintd-auth-postgres-lnd" = "--bin cdk-mintd --no-default-features --features auth,postgres,lnd";
  309. # Binaries: cdk-mint-cli
  310. "bin-cdk-mint-cli" = "--bin cdk-mint-cli";
  311. };
  312. # ========================================
  313. # MSRV build check definitions
  314. # ========================================
  315. msrvChecks = {
  316. # Core library with all features (except swagger which breaks MSRV)
  317. "cdk-all-features" = "-p cdk --features \"mint,wallet,auth\"";
  318. # Mintd with all backends, databases, and features (no swagger)
  319. "cdk-mintd-all" = "-p cdk-mintd --no-default-features --features \"cln,lnd,lnbits,fakewallet,ldk-node,grpc-processor,sqlite,postgres,auth,redis,management-rpc\"";
  320. # CLI - default features (excludes redb which breaks MSRV)
  321. "cdk-cli" = "-p cdk-cli";
  322. # Minimal builds to ensure no-default-features works
  323. "cdk-wallet-only" = "-p cdk --no-default-features --features wallet";
  324. };
  325. # ========================================
  326. # WASM build check definitions
  327. # ========================================
  328. wasmChecks = {
  329. "cdk" = "-p cdk";
  330. "cdk-no-default" = "-p cdk --no-default-features";
  331. "cdk-wallet" = "-p cdk --no-default-features --features wallet";
  332. };
  333. # Common inputs
  334. envVars = {
  335. # rust analyzer needs NIX_PATH for some reason.
  336. NIX_PATH = "nixpkgs=${inputs.nixpkgs}";
  337. };
  338. buildInputs =
  339. with pkgs;
  340. [
  341. # Add additional build inputs here
  342. git
  343. pkg-config
  344. curl
  345. just
  346. protobuf
  347. nixpkgs-fmt
  348. typos
  349. lnd
  350. clightning
  351. bitcoind
  352. sqlx-cli
  353. mprocs
  354. cargo-outdated
  355. cargo-mutants
  356. # Needed for github ci
  357. libz
  358. ]
  359. ++ libsDarwin;
  360. # PostgreSQL configuration
  361. postgresConf = {
  362. pgUser = "cdk_user";
  363. pgPassword = "cdk_password";
  364. pgDatabase = "cdk_mint";
  365. pgPort = "5432";
  366. };
  367. # Script to start PostgreSQL
  368. startPostgres = pkgs.writeShellScriptBin "start-postgres" ''
  369. set -e
  370. PGDATA="$PWD/.pg_data"
  371. PGPORT="${postgresConf.pgPort}"
  372. PGUSER="${postgresConf.pgUser}"
  373. PGPASSWORD="${postgresConf.pgPassword}"
  374. PGDATABASE="${postgresConf.pgDatabase}"
  375. # Stop any existing instance first
  376. if [ -d "$PGDATA" ] && ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" status > /dev/null 2>&1; then
  377. echo "Stopping existing PostgreSQL instance..."
  378. ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" stop > /dev/null 2>&1
  379. fi
  380. if [ ! -d "$PGDATA" ]; then
  381. echo "Initializing PostgreSQL database..."
  382. ${pkgs.postgresql_16}/bin/initdb -D "$PGDATA" --auth=trust --no-locale --encoding=UTF8
  383. # Configure PostgreSQL
  384. echo "listen_addresses = 'localhost'" >> "$PGDATA/postgresql.conf"
  385. echo "port = $PGPORT" >> "$PGDATA/postgresql.conf"
  386. echo "unix_socket_directories = '$PGDATA'" >> "$PGDATA/postgresql.conf"
  387. # Start temporarily to create user and database
  388. ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" -l "$PGDATA/logfile" start
  389. sleep 2
  390. # Create user and database
  391. ${pkgs.postgresql_16}/bin/createuser -h localhost -p $PGPORT -s "$PGUSER" || true
  392. ${pkgs.postgresql_16}/bin/psql -h localhost -p $PGPORT -c "ALTER USER $PGUSER WITH PASSWORD '$PGPASSWORD';" postgres
  393. ${pkgs.postgresql_16}/bin/createdb -h localhost -p $PGPORT -O "$PGUSER" "$PGDATABASE" || true
  394. ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" stop
  395. echo "PostgreSQL initialized."
  396. fi
  397. echo "Starting PostgreSQL on port $PGPORT..."
  398. ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" -l "$PGDATA/logfile" start
  399. echo "PostgreSQL started. Connection URL: postgresql://$PGUSER:$PGPASSWORD@localhost:$PGPORT/$PGDATABASE"
  400. '';
  401. # Script to stop PostgreSQL
  402. stopPostgres = pkgs.writeShellScriptBin "stop-postgres" ''
  403. PGDATA="$PWD/.pg_data"
  404. if [ -d "$PGDATA" ]; then
  405. echo "Stopping PostgreSQL..."
  406. ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" stop || echo "PostgreSQL was not running."
  407. else
  408. echo "No PostgreSQL data directory found."
  409. fi
  410. '';
  411. # Script to check PostgreSQL status
  412. pgStatus = pkgs.writeShellScriptBin "pg-status" ''
  413. PGDATA="$PWD/.pg_data"
  414. if [ -d "$PGDATA" ]; then
  415. ${pkgs.postgresql_16}/bin/pg_ctl -D "$PGDATA" status
  416. else
  417. echo "No PostgreSQL data directory found. Run 'start-postgres' first."
  418. fi
  419. '';
  420. # Script to connect to PostgreSQL
  421. pgConnect = pkgs.writeShellScriptBin "pg-connect" ''
  422. ${pkgs.postgresql_16}/bin/psql "postgresql://${postgresConf.pgUser}:${postgresConf.pgPassword}@localhost:${postgresConf.pgPort}/${postgresConf.pgDatabase}"
  423. '';
  424. # Common arguments can be set here to avoid repeating them later
  425. nativeBuildInputs = [
  426. #Add additional build inputs here
  427. ]
  428. ++ lib.optionals isDarwin [
  429. # Additional darwin specific native inputs can be set here
  430. ];
  431. in
  432. {
  433. # Expose deps for explicit cache warming
  434. packages = {
  435. deps = workspaceDeps;
  436. deps-msrv = workspaceDepsMsrv;
  437. }
  438. # Example packages (binaries that can be run outside sandbox with network access)
  439. // (builtins.listToAttrs (map (name: { name = "example-${name}"; value = mkExamplePackage name; }) exampleChecks));
  440. checks =
  441. # Generate clippy checks from clippyChecks attrset
  442. (builtins.mapAttrs (name: args: mkClippy name args) clippyChecks)
  443. # Generate MSRV build checks (prefixed with msrv-)
  444. // (builtins.listToAttrs (map (name: { name = "msrv-${name}"; value = mkMsrvBuild name msrvChecks.${name}; }) (builtins.attrNames msrvChecks)))
  445. # Generate WASM build checks (prefixed with wasm-)
  446. // (builtins.listToAttrs (map (name: { name = "wasm-${name}"; value = mkWasmBuild name wasmChecks.${name}; }) (builtins.attrNames wasmChecks)))
  447. # Generate example checks from exampleChecks list
  448. // (builtins.listToAttrs (map (name: { name = "example-${name}"; value = mkExample name; }) exampleChecks))
  449. // {
  450. # Doc tests
  451. doc-tests = docTests;
  452. # Strict docs check
  453. strict-docs = strictDocs;
  454. # FFI Python tests
  455. ffi-tests = ffiTests;
  456. # Pre-commit checks
  457. pre-commit-check =
  458. let
  459. # this is a hack based on https://github.com/cachix/pre-commit-hooks.nix/issues/126
  460. # we want to use our own rust stuff from oxalica's overlay
  461. _rust = pkgs.rust-bin.stable.latest.default;
  462. rust = pkgs.buildEnv {
  463. name = _rust.name;
  464. inherit (_rust) meta;
  465. buildInputs = [ pkgs.makeWrapper ];
  466. paths = [ _rust ];
  467. pathsToLink = [
  468. "/"
  469. "/bin"
  470. ];
  471. postBuild = ''
  472. for i in $out/bin/*; do
  473. wrapProgram "$i" --prefix PATH : "$out/bin"
  474. done
  475. '';
  476. };
  477. in
  478. pre-commit-hooks.lib.${system}.run {
  479. src = ./.;
  480. hooks = {
  481. rustfmt = {
  482. enable = true;
  483. entry = lib.mkForce "${rust}/bin/cargo-fmt fmt --all -- --config format_code_in_doc_comments=true --check --color always";
  484. };
  485. nixpkgs-fmt.enable = true;
  486. typos.enable = true;
  487. commitizen.enable = true; # conventional commits
  488. };
  489. };
  490. };
  491. devShells =
  492. let
  493. # pre-commit-checks
  494. _shellHook = (self.checks.${system}.pre-commit-check.shellHook or "");
  495. # devShells
  496. msrv = pkgs.mkShell (
  497. {
  498. shellHook = "
  499. cargo update
  500. cargo update home --precise 0.5.11
  501. cargo update typed-index-collections --precise 3.3.0
  502. ${_shellHook}
  503. ";
  504. buildInputs = buildInputs ++ [ msrv_toolchain ];
  505. inherit nativeBuildInputs;
  506. }
  507. // envVars
  508. );
  509. stable = pkgs.mkShell (
  510. {
  511. shellHook = ''
  512. ${_shellHook}
  513. # Needed for github ci
  514. export LD_LIBRARY_PATH=${
  515. pkgs.lib.makeLibraryPath [
  516. pkgs.zlib
  517. ]
  518. }:$LD_LIBRARY_PATH
  519. # PostgreSQL environment variables
  520. export CDK_MINTD_DATABASE_URL="postgresql://${postgresConf.pgUser}:${postgresConf.pgPassword}@localhost:${postgresConf.pgPort}/${postgresConf.pgDatabase}"
  521. echo ""
  522. echo "PostgreSQL commands available:"
  523. echo " start-postgres - Initialize and start PostgreSQL"
  524. echo " stop-postgres - Stop PostgreSQL (run before exiting)"
  525. echo " pg-status - Check PostgreSQL status"
  526. echo " pg-connect - Connect to PostgreSQL with psql"
  527. echo ""
  528. '';
  529. buildInputs = buildInputs ++ [
  530. stable_toolchain
  531. pkgs.postgresql_16
  532. startPostgres
  533. stopPostgres
  534. pgStatus
  535. pgConnect
  536. ];
  537. inherit nativeBuildInputs;
  538. }
  539. // envVars
  540. );
  541. nightly = pkgs.mkShell (
  542. {
  543. shellHook = ''
  544. ${_shellHook}
  545. # Needed for github ci
  546. export LD_LIBRARY_PATH=${
  547. pkgs.lib.makeLibraryPath [
  548. pkgs.zlib
  549. ]
  550. }:$LD_LIBRARY_PATH
  551. '';
  552. buildInputs = buildInputs ++ [ nightly_toolchain ];
  553. inherit nativeBuildInputs;
  554. }
  555. // envVars
  556. );
  557. # Shell with Docker for integration tests
  558. integration = pkgs.mkShell (
  559. {
  560. shellHook = ''
  561. ${_shellHook}
  562. # Ensure Docker is available
  563. if ! command -v docker &> /dev/null; then
  564. echo "Docker is not installed or not in PATH"
  565. echo "Please install Docker to run integration tests"
  566. exit 1
  567. fi
  568. echo "Docker is available at $(which docker)"
  569. echo "Docker version: $(docker --version)"
  570. '';
  571. buildInputs = buildInputs ++ [
  572. stable_toolchain
  573. pkgs.docker-client
  574. pkgs.python311
  575. ];
  576. inherit nativeBuildInputs;
  577. }
  578. // envVars
  579. );
  580. # Shell for FFI development (Python bindings)
  581. ffi = pkgs.mkShell (
  582. {
  583. shellHook = ''
  584. ${_shellHook}
  585. echo "FFI development shell"
  586. echo " just ffi-test - Run Python FFI tests"
  587. echo " just ffi-dev-python - Launch Python REPL with CDK FFI"
  588. '';
  589. buildInputs = buildInputs ++ [
  590. stable_toolchain
  591. pkgs.python311
  592. ];
  593. inherit nativeBuildInputs;
  594. }
  595. // envVars
  596. );
  597. in
  598. {
  599. inherit
  600. msrv
  601. stable
  602. nightly
  603. integration
  604. ffi
  605. ;
  606. default = stable;
  607. };
  608. }
  609. );
  610. }