From 3e34201f6a10f5bcbdba7d88d21ce99a2190177e Mon Sep 17 00:00:00 2001 From: fusion44 Date: Fri, 8 May 2026 12:39:33 +0200 Subject: [PATCH] refactor(flake): expose lib.mkBlitzApi for consumer-pkgs builds Extract the Python virtualenv build into `mkBlitzApi { pkgs, python ? null }` and expose it as `lib.mkBlitzApi`. Rewrite `overlays.default` to call the builder against the consumer's `prev` instead of pulling from `self.packages.${system}` (which captured this flake's pinned nixpkgs at flake-eval time and shut consumer overlays out of the build hook). Motivation: NixBlitz pulls blitz-api's flake via `builtins.getFlake` to keep the plugin self-contained. Without a pkgs-agnostic builder, the operator's nixpkgs overlays (Pi 5 jemalloc page-size patch and similar platform fixes) couldn't reach blitz-api's build, so the package would either fail to compile on Pi 5 or silently link against this flake's pinned nixpkgs and pull a second snapshot of glibc / openssl / etc. into the operator's closure. The `packages.${system}.${name}` attribute is preserved as a convenience pre-built using this flake's pinned nixpkgs; consumers that want consumer-pkgs builds should use `overlays.default` or `lib.mkBlitzApi` directly. Co-Authored-By: Claude Opus 4.7 (1M context) --- flake.nix | 78 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/flake.nix b/flake.nix index 0ed157e..58c0eb8 100644 --- a/flake.nix +++ b/flake.nix @@ -35,54 +35,80 @@ }: let name = "blitz-api"; - # Load the uv workspace once; reused across systems. + # Load the uv workspace once. Pure Nix value — independent of + # the consumer's pkgs, only depends on this repo's source tree. workspace = uv2nix.lib.workspace.loadWorkspace {workspaceRoot = ./.;}; - # Pure Nix overlay derived from pyproject.toml + uv.lock. Prefer - # prebuilt wheels — a handful of deps (grpcio, psutil, pyzmq) are - # painful to compile from source and wheels work fine on linux/darwin. - overlay = workspace.mkPyprojectOverlay { + # Pyproject-nix overlay derived from pyproject.toml + uv.lock. + # Prefer prebuilt wheels — a handful of deps (grpcio, psutil, + # pyzmq) are painful to compile from source and wheels work + # fine on linux/darwin. Also pkgs-independent. + pyprojectOverlay = workspace.mkPyprojectOverlay { sourcePreference = "wheel"; }; + # Build the blitz-api Python virtualenv against the CALLER's + # pkgs. Exposed as `lib.mkBlitzApi` so consumers (NixBlitz + # plugin, downstream embedders) can build the package using + # their own nixpkgs — important when the consumer needs a + # platform-specific patch that this flake's pinned + # nixos-unstable doesn't carry yet. + # + # Without this, the package would be built once at THIS flake's + # eval time using THIS flake's pinned nixpkgs, and consumer + # overlays couldn't reach the build hook. + mkBlitzApi = { + pkgs, + python ? null, + }: let + py = + if python != null + then python + else pkgs.python312; + pythonSet = (pkgs.callPackage pyproject-nix.build.packages {python = py;}) + .overrideScope ( + pkgs.lib.composeManyExtensions [ + pyproject-build-systems.overlays.default + pyprojectOverlay + ] + ); + in + pythonSet.mkVirtualEnv "${name}-env" workspace.deps.default; + + # Library output — what callers reach for to build the package + # under their own pkgs. + libOutput = { + lib = {inherit mkBlitzApi;}; + }; + systems = flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; - python = pkgs.python312; - - pythonSet = - (pkgs.callPackage pyproject-nix.build.packages { - inherit python; - }) - .overrideScope ( - nixpkgs.lib.composeManyExtensions [ - pyproject-build-systems.overlays.default - overlay - ] - ); in { packages = { default = self.packages.${system}.${name}; - ${name} = pythonSet.mkVirtualEnv "${name}-env" workspace.deps.default; + # Convenience: a pre-built package using THIS flake's pinned + # nixpkgs. Most consumers should use `overlays.default` or + # `lib.mkBlitzApi` instead so the package builds against + # their pkgs. + ${name} = mkBlitzApi {inherit pkgs;}; }; }); overlays.overlays = { + # Re-runs `mkBlitzApi` against the consumer's `prev` pkgs so the + # consumer's overlays (Pi 5 page-size patch, custom uv pin, etc.) + # are in scope when the package is built. default = final: prev: { - ${name} = self.packages.${prev.stdenv.hostPlatform.system}.${name}; + ${name} = mkBlitzApi {pkgs = prev;}; }; }; module = { - nixosModules.default = { - pkgs, - lib, - config, - ... - }: { + nixosModules.default = {...}: { imports = [./modules/blitz_api.nix]; nixpkgs.overlays = [self.overlays.default]; }; }; in - systems // overlays // module; + systems // overlays // module // libOutput; }