{ pkgs, lib, config, inputs, ... }: let # devenv's `languages.rust.import` only builds single root-package crates # (it hardcodes `cargoNix.rootCrate.build`). tora is a virtual workspace with # no root package, so we drive crate2nix directly and select the `torad` member # out of `workspaceMembers`. src = ./. gives crate2nix the whole workspace, so # torad's path-dependency on ../proto (tora-proto) resolves. crate2nixTools = pkgs.callPackage "${inputs.crate2nix}/tools.nix" { }; cargoNix = pkgs.callPackage (crate2nixTools.generatedCargoNix { name = "tora"; src = ./.; }) { # Build with the toolchain configured for this dev environment, # matching what languages.rust.import does internally. buildRustCrateForPkgs = _: pkgs.buildRustCrate.override { rustc = config.languages.rust.toolchainPackage; cargo = config.languages.rust.toolchainPackage; }; }; in { languages.rust.enable = true; git-hooks.hooks = { clippy = { enable = true; settings.allFeatures = true; }; treefmt.enable = true; }; treefmt = { enable = true; config.programs = { nixfmt.enable = true; rustfmt.enable = true; }; }; packages = with pkgs; [ git just protobuf buf grpcurl # Protobuf generators protoc-gen-prost-crate protoc-gen-prost-serde protoc-gen-tonic protoc-gen-prost opencode ]; services.postgres = { enable = true; initialDatabases = [ { name = "toradb"; schema = ./db/schema.sql; } ]; }; env.PGDATABASE = "toradb"; env.DATABASE_URL = "postgresql://${builtins.getEnv "USER"}@localhost/${config.env.PGDATABASE}?host=${config.env.PGHOST}"; env.TORAD_SOCKET = "${config.env.DEVENV_RUNTIME}/torad.sock"; env.TORAD_PID_FILE = "${config.env.DEVENV_RUNTIME}/torad.pid"; processes.torad = { exec = '' ${config.outputs.torad}/bin/torad --socket "$TORAD_SOCKET" --pid-file "$TORAD_PID_FILE" ''; # Waits for postgres's own readiness probe (pg_isready + SELECT 1), not just process start. after = [ "devenv:processes:postgres" ]; # torad speaks gRPC over a Unix socket and does not register reflection, # so grpcurl would need proto files. Instead use the `tora health` CLI # (already knows the proto, reads TORAD_SOCKET env), which exits 0 iff # torad reports SERVING. torad's poll_db_health flips the status to # NotServing when postgres ping fails, so this also gates on a live DB. ready.exec = "${config.outputs.tora}/bin/tora health"; }; outputs = { torad = cargoNix.workspaceMembers.torad.build; tora = cargoNix.workspaceMembers.tora.build; }; }