a Jellyfin & Subsonic client for the terminal — powered by mpv, Chromecast and UPnP MediaRenderer
mpv chromecast mpris navidrome jellyfin upnp tui
0

Configure Feed

Select the types of activity you want to include in your feed.

fin / flake.nix
4.9 kB 167 lines
1{ 2 description = "fin - a neon-electric Jellyfin TUI client for mpv & Chromecast"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 7 # Current crane doesn't expose a `nixpkgs` input, so we don't follow it. 8 crane.url = "github:ipetkov/crane"; 9 10 fenix = { 11 url = "github:nix-community/fenix"; 12 inputs.nixpkgs.follows = "nixpkgs"; 13 inputs.rust-analyzer-src.follows = ""; 14 }; 15 16 flake-utils.url = "github:numtide/flake-utils"; 17 18 advisory-db = { 19 url = "github:rustsec/advisory-db"; 20 flake = false; 21 }; 22 }; 23 24 outputs = { self, nixpkgs, crane, fenix, flake-utils, advisory-db, ... }: 25 flake-utils.lib.eachDefaultSystem (system: 26 let 27 pkgs = import nixpkgs { 28 inherit system; 29 }; 30 31 inherit (pkgs) lib; 32 33 craneLib = crane.mkLib pkgs; 34 35 src = craneLib.cleanCargoSource ./.; 36 37 # fin uses rustls end-to-end, so no openssl. 38 # mpv is a *runtime* requirement (we spawn it for local playback and 39 # the CLI does a preflight `mpv --version` at startup). We fold it 40 # into PATH via a makeWrapper post-fixup below. 41 commonArgs = { 42 inherit src; 43 44 pname = "fin"; 45 version = "0.2.0"; 46 strictDeps = true; 47 48 # No native TLS or system libs needed — pure Rust deps. 49 # Modern nixpkgs (post-25.05) auto-links the Darwin SDK, so no 50 # framework references here — `darwin.apple_sdk_11_0` was removed 51 # as a legacy compatibility stub. 52 nativeBuildInputs = [ 53 pkgs.pkg-config 54 ]; 55 56 buildInputs = lib.optionals pkgs.stdenv.isDarwin [ 57 pkgs.libiconv 58 ]; 59 60 # Workspace has one bin target — build just that. 61 cargoExtraArgs = "--locked --bin fin"; 62 }; 63 64 craneLibLLvmTools = craneLib.overrideToolchain 65 (fenix.packages.${system}.complete.withComponents [ 66 "cargo" 67 "llvm-tools" 68 "rustc" 69 ]); 70 71 # Cache the dependency graph separately from the crate source. 72 cargoArtifacts = craneLib.buildDepsOnly commonArgs; 73 74 finUnwrapped = craneLib.buildPackage (commonArgs // { 75 inherit cargoArtifacts; 76 doCheck = false; 77 }); 78 79 # Wrap the binary so `mpv` is always discoverable at runtime, even 80 # when installed via `nix profile install`. 81 fin = pkgs.symlinkJoin { 82 name = "fin-${finUnwrapped.version}"; 83 paths = [ finUnwrapped ]; 84 nativeBuildInputs = [ pkgs.makeWrapper ]; 85 postBuild = '' 86 wrapProgram $out/bin/fin \ 87 --prefix PATH : ${lib.makeBinPath [ pkgs.mpv ]} 88 ''; 89 meta = { 90 description = "A neon-electric Jellyfin TUI client for mpv & Chromecast"; 91 homepage = "https://github.com/tsirysndr/fin"; 92 license = lib.licenses.mpl20; 93 mainProgram = "fin"; 94 platforms = lib.platforms.unix; 95 }; 96 }; 97 98 in 99 { 100 checks = { 101 inherit fin; 102 103 fin-clippy = craneLib.cargoClippy (commonArgs // { 104 inherit cargoArtifacts; 105 cargoClippyExtraArgs = "--all-targets -- --deny warnings"; 106 }); 107 108 fin-doc = craneLib.cargoDoc (commonArgs // { 109 inherit cargoArtifacts; 110 }); 111 112 fin-fmt = craneLib.cargoFmt { 113 inherit src; 114 }; 115 116 fin-audit = craneLib.cargoAudit { 117 inherit src advisory-db; 118 }; 119 120 fin-nextest = craneLib.cargoNextest (commonArgs // { 121 inherit cargoArtifacts; 122 partitions = 1; 123 partitionType = "count"; 124 }); 125 } // lib.optionalAttrs (system == "x86_64-linux") { 126 fin-coverage = craneLib.cargoTarpaulin (commonArgs // { 127 inherit cargoArtifacts; 128 }); 129 }; 130 131 packages = { 132 default = fin; 133 fin = fin; 134 fin-unwrapped = finUnwrapped; 135 136 fin-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs // { 137 inherit cargoArtifacts; 138 }); 139 }; 140 141 apps.default = flake-utils.lib.mkApp { 142 drv = fin; 143 name = "fin"; 144 }; 145 146 devShells.default = pkgs.mkShell { 147 inputsFrom = builtins.attrValues self.checks.${system}; 148 149 # Everything you need to `cargo run` and actually play back media. 150 nativeBuildInputs = with pkgs; [ 151 cargo 152 rustc 153 rustfmt 154 clippy 155 rust-analyzer 156 mpv 157 pkg-config 158 ] ++ lib.optionals pkgs.stdenv.isDarwin [ 159 libiconv 160 ]; 161 162 shellHook = '' 163 echo " fin dev shell mpv $(mpv --version | head -n1 | cut -d' ' -f2) ready" 164 ''; 165 }; 166 }); 167}