style(nix): run the repo's own nix fmt (nixfmt-rfc-style) over the flake

flake.nix, packaging/nix/packages.nix and packaging/nix/nixos-module.nix had
drifted from the formatter the flake itself declares (`formatter =
nixfmt-rfc-style`). Pure reformat — no expression changes — split out so the
bun2nix migration that follows is reviewable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 927b27c4fade6d646e3ef822678b6738f1e2f28a)
This commit is contained in:
2026-07-28 17:01:59 +02:00
parent 347c106498
commit 0d8862457b
3 changed files with 281 additions and 177 deletions
+53 -19
View File
@@ -26,7 +26,9 @@
# The workspace version is the single source of truth (crates/*/Cargo.toml inherit it).
version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version;
pkgsFor = system: import nixpkgs {
pkgsFor =
system:
import nixpkgs {
inherit system;
overlays = [ (import rust-overlay) ];
};
@@ -38,7 +40,8 @@
craneLibFor = pkgs: (crane.mkLib pkgs).overrideToolchain toolchainFor;
packagesFor = system:
packagesFor =
system:
let
pkgs = pkgsFor system;
in
@@ -49,17 +52,30 @@
};
in
{
packages = forAllSystems (system:
let pf = packagesFor system;
in {
inherit (pf) punktfunk-host punktfunk-client punktfunk-web punktfunk-scripting punktfunk-tray;
packages = forAllSystems (
system:
let
pf = packagesFor system;
in
{
inherit (pf)
punktfunk-host
punktfunk-client
punktfunk-web
punktfunk-scripting
punktfunk-tray
;
default = pf.punktfunk-host;
});
}
);
# `nix run .#punktfunk-host -- serve` / `nix run .#punktfunk-client`.
apps = forAllSystems (system:
let pf = packagesFor system;
in {
apps = forAllSystems (
system:
let
pf = packagesFor system;
in
{
punktfunk-host = {
type = "app";
program = "${pf.punktfunk-host}/bin/punktfunk-host";
@@ -80,19 +96,30 @@
program = "${pf.punktfunk-scripting}/bin/punktfunk-scripting";
};
default = self.apps.${system}.punktfunk-host;
});
}
);
# `nix flake check` builds every package (web included — needs its deps hash filled in, see
# packaging/nix/README.md).
checks = forAllSystems (system:
let pf = packagesFor system;
in {
inherit (pf) punktfunk-host punktfunk-client punktfunk-web punktfunk-scripting;
});
checks = forAllSystems (
system:
let
pf = packagesFor system;
in
{
inherit (pf)
punktfunk-host
punktfunk-client
punktfunk-web
punktfunk-scripting
;
}
);
# `nix develop` — the pinned toolchain plus every system lib the workspace links, wired so
# `cargo build` (all crates, host + client) works out of the box.
devShells = forAllSystems (system:
devShells = forAllSystems (
system:
let
pkgs = pkgsFor system;
toolchain = toolchainFor pkgs;
@@ -134,9 +161,16 @@
PF_FFVK_VULKAN_INCLUDE = "${pkgs.vulkan-headers}/include";
# CMake ≥ 4 rejects the pre-3.5 minimums some vendored C libs (libopus) still declare.
CMAKE_POLICY_VERSION_MINIMUM = "3.5";
LD_LIBRARY_PATH = "/run/opengl-driver/lib:${pkgs.lib.makeLibraryPath [ pkgs.vulkan-loader pkgs.libGL gbm ]}";
LD_LIBRARY_PATH = "/run/opengl-driver/lib:${
pkgs.lib.makeLibraryPath [
pkgs.vulkan-loader
pkgs.libGL
gbm
]
}";
};
});
}
);
formatter = forAllSystems (system: (pkgsFor system).nixfmt-rfc-style);
+67 -21
View File
@@ -21,22 +21,36 @@
# for a session with `systemctl --user enable --now punktfunk-host` (or set `autoStart = true` for a
# headless appliance with `users.users.<u>.linger = true`).
self:
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkEnableOption mkOption mkIf mkMerge mkDefault types
optional optionals optionalString literalExpression
concatStringsSep mapAttrsToList genAttrs;
mkEnableOption
mkOption
mkIf
mkMerge
mkDefault
types
optional
optionals
optionalString
literalExpression
concatStringsSep
mapAttrsToList
genAttrs
;
cfg = config.services.punktfunk;
system = pkgs.stdenv.hostPlatform.system;
# host.env rendering: booleans → 1/0 (what PUNKTFUNK_* knobs expect), everything else verbatim.
renderVal = v:
if lib.isBool v then (if v then "1" else "0")
else toString v;
renderEnv = attrs:
concatStringsSep "\n" (mapAttrsToList (k: v: "${k}=${renderVal v}") attrs) + "\n";
renderVal = v: if lib.isBool v then (if v then "1" else "0") else toString v;
renderEnv =
attrs: concatStringsSep "\n" (mapAttrsToList (k: v: "${k}=${renderVal v}") attrs) + "\n";
hostSettingsFile = pkgs.writeText "punktfunk-host.env" (renderEnv cfg.host.settings);
@@ -44,10 +58,21 @@ let
# ephemeral per-session UDP port the host hole-punches, so nothing fixed to open (see
# packaging/linux/punktfunk.ufw).
nativeTCP = [ 47990 ]; # mgmt/library REST API (HTTPS + mTLS)
nativeUDP = [ 9777 5353 ]; # QUIC control plane + mDNS
nativeUDP = [
9777
5353
]; # QUIC control plane + mDNS
# GameStream/Moonlight-compat fixed ports (opt-in with `host.gamestream`).
gamestreamTCP = [ 47984 47989 48010 ];
gamestreamUDP = [ 47998 47999 48000 ];
gamestreamTCP = [
47984
47989
48010
];
gamestreamUDP = [
47998
47999
48000
];
in
{
options.services.punktfunk = {
@@ -93,7 +118,13 @@ in
};
settings = mkOption {
type = types.attrsOf (types.oneOf [ types.str types.int types.bool ]);
type = types.attrsOf (
types.oneOf [
types.str
types.int
types.bool
]
);
default = { };
example = literalExpression ''
{
@@ -233,10 +264,12 @@ in
config = mkMerge [
# --- shared: whenever either half is enabled -----------------------------------------------
(mkIf (cfg.host.enable || cfg.client.enable) {
assertions = [{
assertions = [
{
assertion = system == "x86_64-linux";
message = "services.punktfunk is x86_64-linux only (desktop NVENC host; no aarch64 build).";
}];
}
];
# The GPU driver libs the binaries dlopen at runtime (libcuda / libnvidia-encode / libEGL /
# the Vulkan ICD) live under /run/opengl-driver/lib — provided by hardware.graphics.
hardware.graphics.enable = mkDefault true;
@@ -257,11 +290,17 @@ in
services.udev.path = [ pkgs.coreutils ];
# uinput/uhid: the virtual X360 + DualSense nodes. vhci-hcd: the usbip transport that makes
# the virtual Steam Deck a real USB device (Steam Input only adopts USB pads).
boot.kernelModules = [ "uinput" "uhid" "vhci-hcd" ];
boot.kernelModules = [
"uinput"
"uhid"
"vhci-hcd"
];
# `input` group membership for the virtual-gamepad nodes (mirrors the RPM's usermod hint).
users.groups.input = { };
users.users = genAttrs cfg.host.users (_: { extraGroups = [ "input" ]; });
users.users = genAttrs cfg.host.users (_: {
extraGroups = [ "input" ];
});
# Status-tray autostart entry (self-gating: `--autostart` exits unless this user runs a host).
environment.etc."xdg/autostart/io.unom.Punktfunk.Tray.desktop".source =
@@ -281,10 +320,14 @@ in
wantedBy = optional cfg.host.autoStart "default.target";
# The host may exec external helpers (pw-dump, sh, and — for the gamescope/kwin backends —
# the compositor). Extend this in your config for a headless gamescope/KWin appliance.
path = [ pkgs.bash pkgs.coreutils pkgs.pipewire ];
path = [
pkgs.bash
pkgs.coreutils
pkgs.pipewire
];
serviceConfig = {
ExecStart = "${cfg.host.package}/bin/punktfunk-host serve"
+ optionalString cfg.host.gamestream " --gamestream";
ExecStart =
"${cfg.host.package}/bin/punktfunk-host serve" + optionalString cfg.host.gamestream " --gamestream";
Restart = "on-failure";
RestartSec = 2;
EnvironmentFile =
@@ -339,7 +382,10 @@ in
systemd.user.services.punktfunk-web = {
description = "punktfunk management web console";
documentation = [ "https://git.unom.io/unom/punktfunk" ];
after = [ "punktfunk-web-init.service" "punktfunk-host.service" ];
after = [
"punktfunk-web-init.service"
"punktfunk-host.service"
];
wants = [ "punktfunk-web-init.service" ];
wantedBy = optional cfg.web.autoStart "default.target";
environment = {
+37 -13
View File
@@ -103,7 +103,10 @@ let
meta = {
homepage = "https://git.unom.io/unom/punktfunk";
license = with lib.licenses; [ mit asl20 ];
license = with lib.licenses; [
mit
asl20
];
platforms = [ "x86_64-linux" ]; # NVENC desktop host; matches the RPM's ExclusiveArch: x86_64
maintainers = [ ];
};
@@ -115,7 +118,9 @@ let
# runtime (see crates/punktfunk-tray/Cargo.toml), so a tokio-flavoured zbus panics at startup:
# "there is no reactor running, must be called from the context of a Tokio 1.x runtime". A separate
# invocation keeps the tray's zbus on async-io. (The host package copies this binary into its $out.)
punktfunk-tray = craneLib.buildPackage (commonArgs // {
punktfunk-tray = craneLib.buildPackage (
commonArgs
// {
pname = "punktfunk-tray";
cargoExtraArgs = "--locked -p punktfunk-tray";
PUNKTFUNK_BUILD_VERSION = buildVersion;
@@ -125,17 +130,19 @@ let
description = "punktfunk host status tray (Linux StatusNotifierItem)";
mainProgram = "punktfunk-tray";
};
});
}
);
in
{
inherit punktfunk-tray;
punktfunk-host = craneLib.buildPackage (commonArgs // {
punktfunk-host = craneLib.buildPackage (
commonArgs
// {
pname = "punktfunk-host";
# HOST ONLY — the tray is a separate derivation (see the note above; co-building crashes it).
cargoExtraArgs =
"--locked -p punktfunk-host "
+ "--features punktfunk-host/nvenc,punktfunk-host/vulkan-encode";
"--locked -p punktfunk-host " + "--features punktfunk-host/nvenc,punktfunk-host/vulkan-encode";
PUNKTFUNK_BUILD_VERSION = buildVersion;
@@ -201,9 +208,12 @@ in
description = "Low-latency desktop/game streaming host (Moonlight-compatible + native punktfunk/1)";
mainProgram = "punktfunk-host";
};
});
}
);
punktfunk-client = craneLib.buildPackage (commonArgs // {
punktfunk-client = craneLib.buildPackage (
commonArgs
// {
pname = "punktfunk-client";
# The session's default `ui` feature pulls skia-safe, whose build DOWNLOADS a prebuilt Skia
# (rust-skia releases) — impossible in Nix's network-less build sandbox, and a from-source Skia
@@ -264,7 +274,8 @@ in
description = "Native Linux punktfunk/1 streaming client (GTK4 shell + Vulkan session)";
mainProgram = "punktfunk-client";
};
});
}
);
# --- management web console (punktfunk-web) ------------------------------------------------------
# The browser console every client needs for SPAKE2 PIN pairing + host status: a TanStack Start /
@@ -291,7 +302,10 @@ in
pname = "punktfunk-web-deps";
inherit version;
src = src + "/web";
nativeBuildInputs = [ bun cacert ];
nativeBuildInputs = [
bun
cacert
];
dontConfigure = true;
buildPhase = ''
runHook preBuild
@@ -322,7 +336,11 @@ in
# nodejs: the JS build tools' `.bin` shims are `#!/usr/bin/env node`; patchShebangs (below)
# repoints them at this node so they run in the sandbox. bun is still the RUNTIME (the launcher
# execs it); node is build-time only, for orval/paraglide/vite.
nativeBuildInputs = [ bun nodejs makeWrapper ];
nativeBuildInputs = [
bun
nodejs
makeWrapper
];
# No cross-derivation dep cache: codegen + the vite build are fully offline (every input is in
# the vendored node_modules, the checked-in api/openapi.json, and web/project.inlang).
@@ -401,7 +419,10 @@ in
pname = "punktfunk-scripting-deps";
inherit version;
src = src + "/sdk";
nativeBuildInputs = [ bun cacert ];
nativeBuildInputs = [
bun
cacert
];
dontConfigure = true;
buildPhase = ''
runHook preBuild
@@ -427,7 +448,10 @@ in
stdenvNoCC.mkDerivation {
pname = "punktfunk-scripting";
inherit src version;
nativeBuildInputs = [ bun makeWrapper ];
nativeBuildInputs = [
bun
makeWrapper
];
# `bun build --target=bun` bundles the runner CLI to ONE self-contained JS: effect + the SDK
# are inlined, and the runner's dynamic `import()` of the operator's plugin files is left as a