{ description = "beefy-player — a flashy terminal player for internet radio"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; outputs = { self, nixpkgs }: let systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); # Things the app shells out to at runtime: mpv for audio, ffmpeg for the # spectrum capture, and parec/pactl from PulseAudio for the monitor source # (PipeWire speaks the same protocol). runtimeDeps = pkgs: with pkgs; [ mpv ffmpeg ] ++ lib.optionals stdenv.hostPlatform.isLinux [ pulseaudio ]; beefy-player = pkgs: let py = pkgs.python3Packages; in py.buildPythonApplication { pname = "beefy-player"; version = "1.2.2"; pyproject = true; src = self; build-system = [ py.hatchling ]; dependencies = with py; [ textual rich httpx numpy pillow ] ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ dbus-next ]; nativeBuildInputs = [ pkgs.makeWrapper ]; nativeCheckInputs = with py; [ pytestCheckHook pytest-asyncio ]; # The suite is offline (catalogues are cached fixtures). doCheck = true; pythonImportsCheck = [ "beefy_player" ]; makeWrapperArgs = [ "--prefix" "PATH" ":" (pkgs.lib.makeBinPath (runtimeDeps pkgs)) ]; meta = { description = "Flashy terminal player for internet radio, with a live spectrum analyser"; homepage = "https://tildeforge.dev/beefcarver/beefy-player"; license = pkgs.lib.licenses.wtfpl; mainProgram = "beefy-player"; platforms = pkgs.lib.platforms.unix; }; }; # One module body, two install targets: a NixOS system adds the package # to environment.systemPackages, Home Manager to home.packages. mkModule = install: { config, lib, pkgs, ... }: let cfg = config.programs.beefy-player; in { options.programs.beefy-player = { enable = lib.mkEnableOption "beefy-player, a terminal radio player"; package = lib.mkOption { type = lib.types.package; default = self.packages.${pkgs.stdenv.hostPlatform.system}.default; defaultText = lib.literalMD "the `beefy-player` package from this flake"; description = "The beefy-player package to use."; }; }; config = lib.mkIf cfg.enable (lib.setAttrByPath install [ cfg.package ]); }; in { packages = forAllSystems ( pkgs: let pkg = beefy-player pkgs; in { default = pkg; beefy-player = pkg; } ); apps = forAllSystems (pkgs: { default = { type = "app"; program = "${beefy-player pkgs}/bin/beefy-player"; meta.description = "Flashy terminal player for internet radio"; }; }); checks = forAllSystems (pkgs: { beefy-player = beefy-player pkgs; }); devShells = forAllSystems ( pkgs: let inherit (pkgs) lib; in { # No FHS needed here: `nix develop` puts libstdc++ on LD_LIBRARY_PATH # so uv's manylinux wheels load, unlike the plain `nix-shell` case in # shell.nix. default = pkgs.mkShell { packages = runtimeDeps pkgs ++ [ pkgs.python3 pkgs.uv pkgs.ruff pkgs.git pkgs.cacert ]; env = { UV_PYTHON = "${pkgs.python3}/bin/python3"; UV_PYTHON_DOWNLOADS = "never"; UV_PROJECT_ENVIRONMENT = "${toString ./.}/.venv"; UV_LINK_MODE = "copy"; SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; }; LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.stdenv.cc.cc.lib pkgs.zlib ]; shellHook = '' echo "beefy-player dev shell — uv sync, uv run pytest, uv run beefy-player" ''; }; } ); nixosModules.default = mkModule [ "environment" "systemPackages" ]; nixosModules.beefy-player = self.nixosModules.default; homeModules.default = mkModule [ "home" "packages" ]; homeModules.beefy-player = self.homeModules.default; formatter = forAllSystems (pkgs: pkgs.nixfmt); overlays.default = final: _prev: { beefy-player = beefy-player final; }; }; }