# Packages bridge.py + web/ as a standalone executable. bridge.py's own # shebang (`uv run --script`) is only for `devbox run serve`; here it runs # under a plain interpreter with aiohttp from nixpkgs, so no network access # or uv is needed at build or run time — required for the Nix sandbox anyway. { lib, stdenvNoCC, makeWrapper, python3, nix-gitignore # A server this deployment pre-pins for every first-time visitor (the NixOS # module's `presetServer`). Both or neither — see web/js/config.js. Baking a # config value into the served JS is a build-time concern, not something # bridge.py — "one file, no keys" — should gain runtime logic to do. , serverHost ? null , serverPublicKey ? null }: let pythonEnv = python3.withPackages (ps: [ ps.aiohttp ]); hasPreset = serverHost != null && serverPublicKey != null; presetLine = "export const PRESET_SERVER = " + builtins.toJSON { host = serverHost; publicKey = serverPublicKey; } + ";"; in assert lib.assertMsg ((serverHost == null) == (serverPublicKey == null)) "gsmol-bridge: serverHost and serverPublicKey must be set together, or not at all"; stdenvNoCC.mkDerivation { pname = "gsmol-bridge"; version = "0.2.0"; # Respects the repo's own .gitignore, so .venv/.devbox/.jj never enter the # store path even when building from an unclean local checkout. src = nix-gitignore.gitignoreSource [ ] ../.; nativeBuildInputs = [ makeWrapper ]; dontBuild = true; # The copied bridge.py is run as an argument to python3 (below), never via # its own shebang — but fixupPhase mangles that shebang anyway, silently # replacing "uv run --script" with a broken command. Harmless as shipped, # but a landmine for anyone who later runs the store copy directly. dontPatchShebangs = true; installPhase = '' runHook preInstall mkdir -p $out/share/gsmol cp bridge.py $out/share/gsmol/bridge.py cp -r web $out/share/gsmol/web ${lib.optionalString hasPreset '' printf '%s\n' ${lib.escapeShellArg presetLine} > $out/share/gsmol/web/js/config.js ''} makeWrapper ${pythonEnv}/bin/python3 $out/bin/gsmol-bridge \ --add-flags "$out/share/gsmol/bridge.py" \ --add-flags "--dir $out/share/gsmol/web" runHook postInstall ''; meta = { description = "Static file server and WebSocket-to-TCP relay for the gsmol Smol Mail client"; homepage = "https://code.randogoth.com/randogoth/gsmol"; mainProgram = "gsmol-bridge"; platforms = lib.platforms.unix; }; }