|
3 | 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; |
4 | 4 | flake-utils.url = "github:numtide/flake-utils"; |
5 | 5 | flake-parts.url = "github:hercules-ci/flake-parts"; |
6 | | - poetry2nix = { |
7 | | - url = "github:nix-community/poetry2nix"; |
| 6 | + pyproject-nix = { |
| 7 | + url = "github:nix-community/pyproject.nix"; |
| 8 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 9 | + }; |
| 10 | + uv2nix = { |
| 11 | + url = "github:adisbladis/uv2nix"; |
| 12 | + inputs.pyproject-nix.follows = "pyproject-nix"; |
| 13 | + inputs.nixpkgs.follows = "nixpkgs"; |
| 14 | + }; |
| 15 | + pyproject-build-systems = { |
| 16 | + url = "github:pyproject-nix/build-system-pkgs"; |
8 | 17 | inputs = { |
| 18 | + pyproject-nix.follows = "pyproject-nix"; |
| 19 | + uv2nix.follows = "uv2nix"; |
9 | 20 | nixpkgs.follows = "nixpkgs"; |
10 | | - flake-utils.follows = "flake-utils"; |
11 | 21 | }; |
12 | 22 | }; |
13 | 23 | }; |
|
23 | 33 | ]; |
24 | 34 |
|
25 | 35 | perSystem = |
26 | | - { pkgs, self', ... }: |
| 36 | + { |
| 37 | + pkgs, |
| 38 | + lib, |
| 39 | + self', |
| 40 | + ... |
| 41 | + }: |
27 | 42 | let |
28 | | - poetry2nix = import inputs.poetry2nix { inherit pkgs; }; |
29 | | - overrides = poetry2nix.overrides.withDefaults ( |
30 | | - final: prev: { |
31 | | - pygeodesy = prev.pygeodesy.overridePythonAttrs (old: { |
32 | | - nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ final.setuptools ]; |
33 | | - }); |
34 | | - } |
35 | | - ); |
36 | | - devEnv = poetry2nix.mkPoetryEnv { |
37 | | - inherit overrides; |
38 | | - projectDir = ./.; |
39 | | - editablePackageSources = { |
40 | | - mapbuilder = ./.; |
41 | | - }; |
| 43 | + workspace = inputs.uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; }; |
| 44 | + overlay = workspace.mkPyprojectOverlay { |
| 45 | + sourcePreference = "wheel"; |
42 | 46 | }; |
| 47 | + |
| 48 | + python = pkgs.python314; |
| 49 | + |
| 50 | + pythonSet = |
| 51 | + (pkgs.callPackage inputs.pyproject-nix.build.packages { |
| 52 | + inherit python; |
| 53 | + }).overrideScope |
| 54 | + ( |
| 55 | + lib.composeManyExtensions [ |
| 56 | + inputs.pyproject-build-systems.overlays.default |
| 57 | + overlay |
| 58 | + (final: prev: { |
| 59 | + fiona = prev.fiona.overrideAttrs (old: { |
| 60 | + nativeBuildInputs = old.nativeBuildInputs ++ [ |
| 61 | + pkgs.gdal |
| 62 | + (final.resolveBuildSystem { |
| 63 | + setuptools = [ ]; |
| 64 | + cython = [ ]; |
| 65 | + }) |
| 66 | + ]; |
| 67 | + }); |
| 68 | + }) |
| 69 | + ] |
| 70 | + ); |
43 | 71 | in |
44 | 72 | { |
45 | 73 | packages = { |
46 | | - default = poetry2nix.mkPoetryApplication { |
47 | | - inherit overrides; |
48 | | - projectDir = ./.; |
49 | | - checkGroups = [ ]; |
50 | | - }; |
| 74 | + mapbuilder = (pythonSet.mkVirtualEnv "mapbuilder-env" workspace.deps.default); |
51 | 75 |
|
52 | 76 | docker = pkgs.dockerTools.buildLayeredImage { |
53 | 77 | name = "ghcr.io/vatger-nav/mapbuilder"; |
|
56 | 80 | contents = [ |
57 | 81 | pkgs.cacert |
58 | 82 | pkgs.tzdata |
59 | | - self'.packages.default |
| 83 | + self'.packages.mapbuilder |
60 | 84 | ]; |
61 | 85 |
|
62 | 86 | config = { |
|
65 | 89 | "PYTHONDONTWRITEBYTECODE=1" |
66 | 90 | "PYTHONUNBUFFERED=1" |
67 | 91 | ]; |
68 | | - WorkingDir = "/"; |
| 92 | + WorkingDir = "/bin"; |
69 | 93 | Entrypoint = [ "mapbuilder" ]; |
70 | 94 | }; |
71 | 95 | }; |
72 | 96 | }; |
73 | 97 |
|
74 | | - devShells.default = devEnv.env.overrideAttrs (attrs: { |
75 | | - nativeBuildInputs = attrs.nativeBuildInputs ++ [ |
76 | | - pkgs.poetry |
77 | | - pkgs.pyright |
78 | | - ]; |
79 | | - shellHook = '' |
80 | | - export PYTHONPATH=${devEnv}/${devEnv.sitePackages} |
81 | | - ''; |
82 | | - }); |
| 98 | + devShells = |
| 99 | + let |
| 100 | + editableOverlay = workspace.mkEditablePyprojectOverlay { |
| 101 | + root = "$REPO_ROOT"; |
| 102 | + }; |
| 103 | + editablePythonSet = pythonSet.overrideScope ( |
| 104 | + lib.composeManyExtensions [ |
| 105 | + editableOverlay |
| 106 | + (final: prev: { |
| 107 | + mapbuilder = prev.mapbuilder.overrideAttrs (old: { |
| 108 | + # Hatchling (our build system) has a dependency on the `editables` package when building editables. |
| 109 | + # |
| 110 | + # In normal Python flows this dependency is dynamically handled, and doesn't need to be explicitly declared. |
| 111 | + # This behaviour is documented in PEP-660. |
| 112 | + # |
| 113 | + # With Nix the dependency needs to be explicitly declared. |
| 114 | + nativeBuildInputs = |
| 115 | + old.nativeBuildInputs |
| 116 | + ++ final.resolveBuildSystem { |
| 117 | + editables = [ ]; |
| 118 | + }; |
| 119 | + }); |
| 120 | + }) |
| 121 | + ] |
| 122 | + ); |
| 123 | + virtualenv = editablePythonSet.mkVirtualEnv "mapbuilder-dev-env" workspace.deps.all; |
| 124 | + commonPackages = [ |
| 125 | + virtualenv |
| 126 | + pkgs.uv |
| 127 | + ]; |
| 128 | + in |
| 129 | + { |
| 130 | + default = pkgs.mkShell { |
| 131 | + packages = commonPackages; |
| 132 | + env = { |
| 133 | + # Don't create venv using uv |
| 134 | + UV_NO_SYNC = "1"; |
| 135 | + |
| 136 | + # Force uv to use Python interpreter from venv |
| 137 | + UV_PYTHON = "${virtualenv}/bin/python"; |
| 138 | + |
| 139 | + # Prevent uv from downloading managed Python's |
| 140 | + UV_PYTHON_DOWNLOADS = "never"; |
| 141 | + |
| 142 | + PYTHONPATH = ".:${virtualenv}/${python.sitePackages}"; |
| 143 | + }; |
| 144 | + }; |
| 145 | + }; |
83 | 146 |
|
84 | | - formatter = pkgs.nixfmt-rfc-style; |
| 147 | + formatter = pkgs.nixfmt; |
85 | 148 | }; |
86 | 149 | } |
87 | 150 | ); |
|
0 commit comments