From c818e6452e216fa217fe1cdd41b0688379ad4bf7 Mon Sep 17 00:00:00 2001 From: Konstantin Fickel Date: Fri, 13 Feb 2026 20:44:12 +0100 Subject: [PATCH] feat: add nix flake with uv2nix packaging and pytest checks --- .gitignore | 3 + flake.lock | 99 ++++++++++++++++++++++++++++++++ flake.nix | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 4 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore index 133722d..dd97230 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ wheels/ # bulkgen state .bulkgen.state.yaml + +# Nix +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..daa2c07 --- /dev/null +++ b/flake.lock @@ -0,0 +1,99 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1770841267, + "narHash": "sha256-9xejG0KoqsoKEGp2kVbXRlEYtFFcDTHjidiuX8hGO44=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ec7c70d12ce2fc37cb92aff673dcdca89d187bae", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pyproject-build-systems": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "pyproject-nix": [ + "pyproject-nix" + ], + "uv2nix": [ + "uv2nix" + ] + }, + "locked": { + "lastModified": 1763662255, + "narHash": "sha256-4bocaOyLa3AfiS8KrWjZQYu+IAta05u3gYZzZ6zXbT0=", + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "rev": "042904167604c681a090c07eb6967b4dd4dae88c", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "build-system-pkgs", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769936401, + "narHash": "sha256-kwCOegKLZJM9v/e/7cqwg1p/YjjTAukKPqmxKnAZRgA=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "b0d513eeeebed6d45b4f2e874f9afba2021f7812", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "pyproject-build-systems": "pyproject-build-systems", + "pyproject-nix": "pyproject-nix", + "uv2nix": "uv2nix" + } + }, + "uv2nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "pyproject-nix": [ + "pyproject-nix" + ] + }, + "locked": { + "lastModified": 1770770348, + "narHash": "sha256-A2GzkmzdYvdgmMEu5yxW+xhossP+txrYb7RuzRaqhlg=", + "owner": "pyproject-nix", + "repo": "uv2nix", + "rev": "5d1b2cb4fe3158043fbafbbe2e46238abbc954b0", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "uv2nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..91fa7db --- /dev/null +++ b/flake.nix @@ -0,0 +1,152 @@ +{ + description = "bulkgen - Bulk-Generate Images with Generative AI"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + pyproject-nix = { + url = "github:pyproject-nix/pyproject.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + uv2nix = { + url = "github:pyproject-nix/uv2nix"; + inputs.pyproject-nix.follows = "pyproject-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + pyproject-build-systems = { + url = "github:pyproject-nix/build-system-pkgs"; + inputs.pyproject-nix.follows = "pyproject-nix"; + inputs.uv2nix.follows = "uv2nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { + nixpkgs, + pyproject-nix, + uv2nix, + pyproject-build-systems, + ... + }: + let + inherit (nixpkgs) lib; + forAllSystems = lib.genAttrs lib.systems.flakeExposed; + + workspace = uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; }; + + overlay = workspace.mkPyprojectOverlay { + sourcePreference = "wheel"; + }; + + editableOverlay = workspace.mkEditablePyprojectOverlay { + root = "$REPO_ROOT"; + }; + + pythonSets = forAllSystems ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + inherit (pkgs) stdenv; + + baseSet = pkgs.callPackage pyproject-nix.build.packages { + python = pkgs.python313; + }; + + pyprojectOverrides = _final: prev: { + bulkgen = prev.bulkgen.overrideAttrs (old: { + passthru = old.passthru // { + tests = (old.passthru.tests or { }) // { + pytest = stdenv.mkDerivation { + name = "${_final.bulkgen.name}-pytest"; + inherit (_final.bulkgen) src; + nativeBuildInputs = [ + (_final.mkVirtualEnv "bulkgen-pytest-env" { + bulkgen = [ "dev" ]; + }) + ]; + dontConfigure = true; + buildPhase = '' + runHook preBuild + # Exit code 5 means no tests collected — allow it so the + # check succeeds on an empty test suite. + pytest || [ $? -eq 5 ] + runHook postBuild + ''; + installPhase = '' + runHook preInstall + touch $out + runHook postInstall + ''; + }; + }; + }; + }); + }; + + in + baseSet.overrideScope ( + lib.composeManyExtensions [ + pyproject-build-systems.overlays.default + overlay + pyprojectOverrides + ] + ) + ); + + in + { + packages = forAllSystems ( + system: + let + pythonSet = pythonSets.${system}; + pkgs = nixpkgs.legacyPackages.${system}; + inherit (pkgs.callPackages pyproject-nix.build.util { }) mkApplication; + in + { + default = mkApplication { + venv = pythonSet.mkVirtualEnv "bulkgen-env" workspace.deps.default; + package = pythonSet.bulkgen; + }; + } + ); + + checks = forAllSystems ( + system: + let + pythonSet = pythonSets.${system}; + in + { + inherit (pythonSet.bulkgen.passthru.tests) pytest; + } + ); + + devShells = forAllSystems ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + pythonSet = pythonSets.${system}.overrideScope editableOverlay; + virtualenv = pythonSet.mkVirtualEnv "bulkgen-dev-env" workspace.deps.all; + in + { + default = pkgs.mkShell { + packages = [ + virtualenv + pkgs.uv + ]; + env = { + UV_NO_SYNC = "1"; + UV_PYTHON = pythonSet.python.interpreter; + UV_PYTHON_DOWNLOADS = "never"; + }; + shellHook = '' + unset PYTHONPATH + export REPO_ROOT=$(git rev-parse --show-toplevel) + ''; + }; + } + ); + }; +} diff --git a/pyproject.toml b/pyproject.toml index ad9dcc5..44bd1bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ dependencies = [ ] [project.scripts] -bulkgen = "main:main" +bulkgen = "bulkgen.cli:app" [build-system] requires = ["hatchling"]