{ inputs = { advisory-db = { url = "github:rustsec/advisory-db"; flake = false; }; crane.url = "github:ipetkov/crane"; flake-utils.url = "github:numtide/flake-utils"; nix-filter.url = "github:numtide/nix-filter"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; rust-overlay.url = "github:oxalica/rust-overlay"; treefmt-nix.url = "github:numtide/treefmt-nix"; }; outputs = { self, advisory-db, crane, flake-utils, nix-filter, nixpkgs, rust-overlay, treefmt-nix, }: flake-utils.lib.eachDefaultSystem ( system: let rustVersion = "1.83.0"; overlays = [ (import rust-overlay) (final: prev: { nix-filter = nix-filter.lib; rust-toolchain = pkgs.rust-bin.stable.${rustVersion}.default; rust-dev-toolchain = pkgs.rust-toolchain.override { extensions = [ "rust-analyzer" "rust-src" ]; }; }) ]; pkgs = import nixpkgs { inherit overlays system; }; craneLib = (crane.mkLib pkgs).overrideToolchain pkgs.rust-toolchain; stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.stdenv; nativeBuildInputs = with pkgs; [ clang_18 mold ]; sourceAndFixtures = path: type: (craneLib.filterCargoSources path type); src = pkgs.lib.cleanSourceWith { src = ./.; filter = sourceAndFixtures; }; treefmtEval = treefmt-nix.lib.evalModule pkgs { projectRootFile = "flake.nix"; programs = { nixfmt.enable = true; nixfmt.package = pkgs.nixfmt-rfc-style; shfmt.enable = true; rustfmt.enable = true; }; settings.formatter.rustfmt.command = pkgs.lib.mkForce "${pkgs.rust-toolchain}/bin/rustfmt"; }; commonArgs = { inherit src stdenv nativeBuildInputs; strictDeps = true; LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib"; }; cargoArtifacts = craneLib.buildDepsOnly commonArgs; individualCrateArgs = commonArgs // { inherit cargoArtifacts; inherit (craneLib.crateNameFromCargoToml { inherit src; }) version; doCheck = false; # We use cargo-nextest for all tests }; fileSetForCrate = crate: pkgs.lib.fileset.toSource { root = ./.; fileset = pkgs.lib.fileset.unions [ ./api.json ./Cargo.toml ./Cargo.lock (craneLib.fileset.commonCargoSources ./agent) (craneLib.fileset.commonCargoSources ./controller) (craneLib.fileset.commonCargoSources ./xtask) (craneLib.fileset.commonCargoSources crate) ]; }; patagia-agent = craneLib.buildPackage ( individualCrateArgs // { pname = "patagia-agent"; cargoExtraArgs = "-p patagia-agent"; src = fileSetForCrate ./agent; } ); patagia-controller = craneLib.buildPackage ( individualCrateArgs // { pname = "patagia-controller"; cargoExtraArgs = "-p patagia-controller"; src = fileSetForCrate ./controller; } ); xtask = craneLib.buildPackage ( individualCrateArgs // { pname = "xtask"; cargoExtraArgs = "-p xtask"; src = fileSetForCrate ./xtask; } ); in { # `nix build` packages = { inherit patagia-agent patagia-controller xtask; }; # Tests checks = { inherit patagia-agent patagia-controller xtask; clippy = craneLib.cargoClippy ( commonArgs // { inherit cargoArtifacts; cargoClippyExtraArgs = "--all-targets -- --deny warnings"; } ); fmt = craneLib.cargoFmt (commonArgs // { inherit src; }); audit = craneLib.cargoAudit (commonArgs // { inherit src advisory-db; }); nextest = craneLib.cargoNextest ( commonArgs // { inherit cargoArtifacts; partitions = 1; partitionType = "count"; } ); openapi = pkgs.runCommand "openapi" (commonArgs // { src = fileSetForCrate ./xtask; }) '' ${self.packages.${system}.xtask}/bin/xtask open-api | ${pkgs.diffutils}/bin/diff -u $src/api.json - | tee $out ''; }; # For `nix fmt` formatter = treefmtEval.config.build.wrapper; # `nix develop` devShells.default = pkgs.mkShell { inherit nativeBuildInputs; buildInputs = with pkgs; [ bacon cargo-edit cargo-features-manager cargo-hakari cargo-machete cargo-nextest cargo-watch hyperfine just rust-dev-toolchain watchexec ]; shellHook = '' export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc} # Required for rust-analyzer echo echo "✨ Welcome to the Patagia development environment! ✨" echo "Run 'just' to see available commands." echo ''; }; } ); }