-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathflake.nix
411 lines (383 loc) · 16.2 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
{
description = "interactive systemd flake";
inputs = {
# 24.11 does _not_ contain asciinema_3
# nixpkgs.url = "github:NixOS/nixpkgs/release-24.11";
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";
};
# Supports linux x86_64 and aarch64.
systems.url = "github:nix-systems/default-linux";
nix-filter.url = "github:numtide/nix-filter";
# pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
systemd-nix = {
url = "github:serokell/systemd-nix";
inputs.nixpkgs.follows = "nixpkgs"; # Make sure the nixpkgs version matches
};
nix-appimage = {
url = "github:ralismark/nix-appimage";
# nix-appimage cannot track nixos-unstable until this issue is resolved:
# - <https://github.com/ralismark/nix-appimage/issues/23>
# inputs.nixpkgs.follows = "nixpkgs";
};
};
# Disclaimer: Uv2nix is new and experimental.
# Users are expected to be able to contribute fixes.
#
# Note that uv2nix is _not_ using Nixpkgs buildPythonPackage.
# It's using https://pyproject-nix.github.io/pyproject.nix/build.html
outputs =
{ self, nixpkgs, ... }@inputs:
let
inherit (nixpkgs) lib;
# Load a uv workspace from a workspace root.
# Uv2nix treats all uv projects as workspace projects.
workspace = inputs.uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; };
# Create package overlay from workspace.
overlay = workspace.mkPyprojectOverlay {
# Prefer prebuilt binary wheels as a package source.
# Sdists are less likely to "just work" because of the metadata missing from uv.lock.
# Binary wheels are more likely to, but may still require overrides for library dependencies.
sourcePreference = "wheel"; # or sourcePreference = "sdist";
# Optionally customise PEP 508 environment
# environ = {
# platform_release = "5.10.65";
# };
};
# Extend generated overlay with build fixups
#
# Uv2nix can only work with what it has, and uv.lock is missing essential metadata to perform some builds.
# This is an additional overlay implementing build fixups.
# See:
# - https://pyproject-nix.github.io/uv2nix/FAQ.html
pyprojectOverrides = _final: _prev: {
# Implement build fixups here.
};
eachSystem = nixpkgs.lib.genAttrs (import inputs.systems);
pkgsFor = eachSystem (system: nixpkgs.legacyPackages.${system});
# # This example is only using x86_64-linux
# pkgs = nixpkgs.legacyPackages.x86_64-linux;
# # Use Python 3.13 from nixpkgs
# python = pkgs.python313;
# Construct package set
pythonSet311 = (
pkgs:
let
# injecting cairosvg from upstream nixpkgs, as it is currently not
# supported by the uv2nix_hammer project and is still in the todo list.
# https://pyproject-nix.github.io/pyproject.nix/builders/hacks.html
# python = pkgs.python312;
python = pkgs.python311;
hacks = pkgs.callPackage inputs.pyproject-nix.build.hacks { };
in
# Use base package set from pyproject.nix builders
(pkgs.callPackage inputs.pyproject-nix.build.packages {
inherit python;
}).overrideScope
(
lib.composeManyExtensions [
inputs.pyproject-build-systems.overlays.default
overlay
pyprojectOverrides
(_final: prev: {
cairosvg = hacks.nixpkgsPrebuilt {
from = pkgs.python311Packages.cairosvg;
prev = prev.cairosvg;
};
cairocffi = hacks.nixpkgsPrebuilt {
from = pkgs.python311Packages.cairocffi;
prev = prev.cairocffi;
};
})
# (_final: prev: {
# pythonPkgsBuildHost = prev.pythonPkgsBuildHost.overrideScope pyprojectOverrides;
# })
]
)
);
pythonSet313 = (
pkgs:
let
# injecting cairosvg from upstream nixpkgs, as it is currently not
# supported by the uv2nix_hammer project and is still in the todo list.
# https://pyproject-nix.github.io/pyproject.nix/builders/hacks.html
# pkgs = pkgsFor.${system};
# python = pkgs.python312;
python = pkgs.python313;
hacks = pkgs.callPackage inputs.pyproject-nix.build.hacks { };
in
# Use base package set from pyproject.nix builders
(pkgs.callPackage inputs.pyproject-nix.build.packages {
inherit python;
}).overrideScope
(
lib.composeManyExtensions [
inputs.pyproject-build-systems.overlays.default
overlay
pyprojectOverrides
(_final: prev: {
cairosvg = hacks.nixpkgsPrebuilt {
from = pkgs.python313Packages.cairosvg;
prev = prev.cairosvg;
};
cairocffi = hacks.nixpkgsPrebuilt {
from = pkgs.python313Packages.cairocffi;
prev = prev.cairocffi;
};
})
]
)
);
in
{
formatter = eachSystem (system: pkgsFor.${system}.nixfmt-rfc-style);
checks = eachSystem (
system:
{
# pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
# src = ./.;
# hooks = {
# nixfmt-rfc-style.enable = true;
# trim-trailing-whitespace.enable = true;
# };
# };
}
# { }
// self.packages.${system}
);
# Use the newest python version to build packages
# -> get the benefit of improvements to CPython for free.
packages = eachSystem (
system:
let
# https://pyproject-nix.github.io/uv2nix/patterns/cross/index.html
pkgs = pkgsFor.${system};
# pkgs = pkgsFor.${system}.pkgsCross.aarch64-multiplatform;
pythonSet = pythonSet313 pkgs;
version = (builtins.fromTOML (builtins.readFile ./pyproject.toml)).project.version;
gen_unit =
name:
inputs.systemd-nix.lib.${system}.mkUserService name {
description = name;
documentation = [ "man:python" ];
wants = [ "default.target" ];
after = [ "default.target" ];
serviceConfig = {
Type = "simple"; # or oneshot for multiple ExecStart
# ExecStart = "${lib.getExe' pkgs.coreutils "sleep"} 1m";
ExecStart = "${lib.getExe pythonSet.python} ${./docs/loggen.py} 100";
# --number <number-of-messages>
# --interval <number of seconds loggen will run>
# --rate message per second
RemainAfterExit = true;
};
};
gen_broken_unit =
name:
inputs.systemd-nix.lib.${system}.mkUserService name {
description = name;
documentation = [ "man:python" ];
wants = [ "default.target" ];
after = [ "default.target" ];
serviceConfig = {
Type = "simple"; # or oneshot for multiple ExecStart
# ExecStart = "${lib.getExe' pkgs.coreutils "sleep"} 1m";
ExecStart = "${lib.getExe pythonSet.python} -asdf";
# --number <number-of-messages>
# --interval <number of seconds loggen will run>
# --rate message per second
RemainAfterExit = true;
};
};
in
rec {
default =
let
# Package the virtual environment
# Enable no optional dependencies for production build.
venv = pythonSet.mkVirtualEnv "isd-tui-env" workspace.deps.default;
in
pkgs.stdenvNoCC.mkDerivation {
pname = "isd";
inherit version;
src = venv;
meta = {
mainProgram = "isd";
license = pkgs.lib.getLicenseFromSpdxId "GPL-3.0-or-later";
};
buildPhase = ''
mkdir -p $out/bin
ln -s $src/bin/isd $out/bin/
ln -s $src/share $out/
'';
};
isd = default;
isd-tui = isd;
"isd-AppImage" = inputs.nix-appimage.lib.${system}.mkAppImage {
pname = "isd.${system}";
program = pkgs.lib.getExe (
isd.overrideAttrs (oldAttrs: {
buildInputs = oldAttrs.buildInputs or [ ] ++ [ pkgs.makeBinaryWrapper ];
postInstall =
oldAttrs.postInstall or ""
+ ''
wrapProgram $out/bin/isd --set SYSTEMD_IGNORE_CHROOT yes
'';
})
);
};
player =
let
version = "v3.8.2";
css = builtins.fetchurl {
url = "https://github.com/asciinema/asciinema-player/releases/download/${version}/asciinema-player.css";
sha256 = "sha256:19jl4ps46cmn31lxccvmza9igpqv66hpg60kd4rc9mp0a677nfsc";
};
js = builtins.fetchurl {
url = "https://github.com/asciinema/asciinema-player/releases/download/${version}/asciinema-player.min.js";
sha256 = "sha256:1ganjf704k6hm2pvjxyx7jnppvjyhak16m50wxrfbig61gvri8i2";
};
in
pkgs.runCommand "combine-player" { } ''
mkdir -p $out
cp ${css} $out/asciinema-player.css
cp ${js} $out/asciinema-player.min.js
'';
isd-example-templated-unit =
inputs.systemd-nix.lib.${system}.mkUserService "0-isd-example-unit-template@"
{
description = "isd-example instantiated unit %i";
documentation = [ "man:python" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${lib.getExe' pkgs.coreutils "echo"} 'I am unit %i'";
RemainAfterExit = true;
};
};
generate-integration-test-data = pkgs.writeScriptBin "generate-integration-test-data" ''
set -e
${lib.getExe (gen_unit "0-isd-example-unit-01")}
${lib.getExe (gen_unit "0-isd-example-unit-02")}
${lib.getExe (gen_unit "0-isd-example-unit-03")}
${lib.getExe (gen_broken_unit "0-isd-example-unit-04")}
systemctl --user stop "0-isd-example-unit-02.service"
systemctl --user stop "0-isd-example-unit-03.service"
ln -s /tmp/__wrong_path_that_does_not_exist --force "$HOME/.config/systemd/user/0-isd-example-unit-03.service"
# 4 is broken by default
systemctl --user daemon-reload
# Now generate the sample data from the above generated state.
export _SYSTEMD_USER_MODE=1
export OUT_DIR="$(git rev-parse --show-toplevel)/tests/integration-test/"
${lib.getExe pkgs.bash} ${./tests/test_data_generator.sh} generate_list_data "0-isd*"
${lib.getExe pkgs.bash} ${./tests/test_data_generator.sh} generate_unit_data "0-isd-example-unit-01.service"
${lib.getExe pkgs.bash} ${./tests/test_data_generator.sh} generate_unit_data "0-isd-example-unit-02.service"
${lib.getExe pkgs.bash} ${./tests/test_data_generator.sh} generate_unit_data "0-isd-example-unit-03.service"
${lib.getExe pkgs.bash} ${./tests/test_data_generator.sh} generate_unit_data "0-isd-example-unit-04.service"
'';
generate-doc-test-data = pkgs.writeScriptBin "generate-doc-test-data" ''
set -e
${lib.getExe (gen_unit "0-isd-example-unit-01")}
${lib.getExe (gen_unit "0-isd-example-unit-02")}
${lib.getExe (gen_unit "0-isd-example-unit-03")}
${lib.getExe (gen_broken_unit "0-isd-example-unit-04")}
${lib.getExe (gen_unit "0-isd-example-unit-05")}
${lib.getExe (gen_unit "0-isd-example-unit-06")}
${lib.getExe (gen_unit "0-isd-example-unit-07")}
systemctl --user stop "0-isd-example-unit-02.service"
systemctl --user stop "0-isd-example-unit-03.service"
ln -s /tmp/__wrong_path_that_does_not_exist --force "$HOME/.config/systemd/user/0-isd-example-unit-03.service"
# 4 is broken by default
systemctl --user daemon-reload
'';
}
);
# This example provides two different modes of development:
# - Impurely using uv to manage virtual environments
# - Pure development using uv2nix to manage virtual environments
#
# Use Python311 (oldest supported Python) for local development and testing.
devShells = eachSystem (
system:
let
pkgs = pkgsFor.${system};
pythonSet = pythonSet311 pkgs;
lib = pkgs.lib;
in
{
# It is of course perfectly OK to keep using an impure virtualenv workflow and only use uv2nix to build packages.
# This devShell simply adds Python and undoes the dependency leakage done by Nixpkgs Python infrastructure.
# impure = pkgs.mkShell {
# packages = [
# python
# pkgs.uv
# ];
# shellHook = ''
# unset PYTHONPATH
# export UV_PYTHON_DOWNLOADS=never
# '';
# };
# This devShell uses uv2nix to construct a virtual environment purely from Nix, using the same dependency specification as the application.
# The notable difference is that we also apply another overlay here enabling editable mode ( https://setuptools.pypa.io/en/latest/userguide/development_mode.html ).
#
# This means that any changes done to your local files do not require a rebuild.
default =
let
# Create an overlay enabling editable mode for all local dependencies.
editableOverlay = workspace.mkEditablePyprojectOverlay {
# Use environment variable
root = "$REPO_ROOT";
# Optional: Only enable editable for these packages
# members = [ "hello-world" ];
};
# Override previous set with our overridable overlay.
editablePythonSet = pythonSet.overrideScope editableOverlay;
# Build virtual environment, with local packages being editable.
#
# Enable all optional dependencies for development.
virtualenv = editablePythonSet.mkVirtualEnv "isd-tui-env" workspace.deps.all;
in
pkgs.mkShell {
packages = [
virtualenv
pkgs.uv
pkgs.asciinema_3
pkgs.lnav
pkgs.moar
# pkgs.nushell
pkgs.quickemu
# pkgs.debootstrap
];
shellHook = ''
# Undo dependency propagation by nixpkgs.
unset PYTHONPATH
# Don't create venv using uv
export UV_NO_SYNC=1
# Prevent uv from downloading managed Python's
export UV_PYTHON_DOWNLOADS=never
export VENV=.venv/
# Get repository root using git. This is expanded at runtime by the editable `.pth` machinery.
export REPO_ROOT=$(git rev-parse --show-toplevel)
'';
};
# vms = pkgs.mkShell {
# packages = [
# pkgs.quickemu
# ];
# };
}
);
};
}