A social internet radio platform built on AT Protocol. atradio.fm
atproto radio
7

Configure Feed

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

fix(nix): drop path:./cli input that broke nix build in CI

A relative `path:./cli` flake input can't be locked inside a git repo, so
`nix build` failed with "lock file contains unlocked input". Extract the
crane build into a shared cli/package.nix imported by both flakes:
- cli/flake.nix builds it with src = ./.
- the root flake builds it with src = ./cli (default package)
Neither uses a path input now; both locks contain only GitHub inputs.

Tsiry Sandratraina (Jul 17, 2026, 2:12 AM +0300) bb344b2d 2feba31b

+148 -213
-22
cli/flake.lock
··· 31 31 "type": "github" 32 32 } 33 33 }, 34 - "fenix": { 35 - "inputs": { 36 - "nixpkgs": [ 37 - "nixpkgs" 38 - ], 39 - "rust-analyzer-src": [] 40 - }, 41 - "locked": { 42 - "lastModified": 1784190100, 43 - "narHash": "sha256-cE4wAMa3MDhnx+mH5Y72tM/VTSh5cS5S2q0w56XurJU=", 44 - "owner": "nix-community", 45 - "repo": "fenix", 46 - "rev": "010b0647f8ebce9cd9e185773a7f9e422af1154a", 47 - "type": "github" 48 - }, 49 - "original": { 50 - "owner": "nix-community", 51 - "repo": "fenix", 52 - "type": "github" 53 - } 54 - }, 55 34 "flake-utils": { 56 35 "inputs": { 57 36 "systems": "systems" ··· 90 69 "inputs": { 91 70 "advisory-db": "advisory-db", 92 71 "crane": "crane", 93 - "fenix": "fenix", 94 72 "flake-utils": "flake-utils", 95 73 "nixpkgs": "nixpkgs" 96 74 }
+10 -125
cli/flake.nix
··· 3 3 4 4 inputs = { 5 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 6 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 7 flake-utils.url = "github:numtide/flake-utils"; 17 - 18 8 advisory-db = { 19 9 url = "github:rustsec/advisory-db"; 20 10 flake = false; 21 11 }; 22 12 }; 23 13 24 - outputs = { self, nixpkgs, crane, fenix, flake-utils, advisory-db, ... }: 14 + outputs = { self, nixpkgs, crane, flake-utils, advisory-db, ... }: 25 15 flake-utils.lib.eachDefaultSystem (system: 26 16 let 27 17 pkgs = import nixpkgs { inherit system; }; 28 - 29 - inherit (pkgs) lib; 30 - 31 18 craneLib = crane.mkLib pkgs; 32 19 33 - src = craneLib.cleanCargoSource ./.; 34 - 35 - # atradio uses rustls end-to-end, so no openssl. Unlike the web build it 36 - # has NO runtime binary dependency (rockbox-playback decodes in-process), 37 - # so there is no wrapProgram/PATH shim — the binary stands alone. 38 - commonArgs = { 39 - inherit src; 40 - 41 - pname = "atradio"; 42 - version = "0.1.0"; 43 - strictDeps = true; 44 - 45 - # rockbox-playback pulls in rockbox-codecs + rockbox-dsp, whose build 46 - # scripts compile Rockbox's C codec/DSP sources with the `cc` crate — 47 - # so a C compiler must be on PATH. `stdenv.cc` is that toolchain 48 - # (clang on Darwin, gcc on Linux). 49 - nativeBuildInputs = [ 50 - pkgs.pkg-config 51 - pkgs.stdenv.cc 52 - ] ++ lib.optionals pkgs.stdenv.isDarwin [ 53 - # coreaudio-sys generates its CoreAudio bindings with bindgen at 54 - # build time; bindgenHook provides libclang + the Nix Apple SDK. 55 - pkgs.rustPlatform.bindgenHook 56 - ]; 57 - 58 - buildInputs = lib.optionals pkgs.stdenv.isDarwin [ 59 - pkgs.libiconv 60 - ] ++ lib.optionals pkgs.stdenv.isLinux [ 61 - # cpal links against ALSA on Linux for the audio output path. 62 - # MPRIS needs no dbus dev lib: zbus (via mpris-server) is pure Rust. 63 - pkgs.alsa-lib 64 - ]; 65 - 66 - # Single bin target. 67 - cargoExtraArgs = "--locked --bin atradio"; 20 + atradio = import ./package.nix { 21 + inherit craneLib pkgs advisory-db; 22 + inherit (pkgs) lib; 23 + src = craneLib.cleanCargoSource ./.; 68 24 }; 69 - 70 - craneLibLLvmTools = craneLib.overrideToolchain 71 - (fenix.packages.${system}.complete.withComponents [ 72 - "cargo" 73 - "llvm-tools" 74 - "rustc" 75 - ]); 76 - 77 - # Cache the dependency graph separately from the crate source. 78 - cargoArtifacts = craneLib.buildDepsOnly commonArgs; 79 - 80 - atradio = craneLib.buildPackage (commonArgs // { 81 - inherit cargoArtifacts; 82 - doCheck = false; 83 - 84 - meta = { 85 - description = "A TUI radio player on the AT Protocol"; 86 - homepage = "https://github.com/tsirysndr/atradio.fm"; 87 - # Linking rockbox-playback (GPL-2.0) makes the binary GPL-2.0+. 88 - license = lib.licenses.gpl2Plus; 89 - mainProgram = "atradio"; 90 - platforms = lib.platforms.unix; 91 - }; 92 - }); 93 - 94 25 in 95 26 { 96 - checks = { 97 - inherit atradio; 98 - 99 - atradio-clippy = craneLib.cargoClippy (commonArgs // { 100 - inherit cargoArtifacts; 101 - cargoClippyExtraArgs = "--all-targets -- --deny warnings"; 102 - }); 103 - 104 - atradio-fmt = craneLib.cargoFmt { 105 - inherit src; 106 - }; 107 - 108 - atradio-audit = craneLib.cargoAudit { 109 - inherit src advisory-db; 110 - }; 111 - }; 27 + checks = atradio.checks; 112 28 113 29 packages = { 114 - default = atradio; 115 - atradio = atradio; 116 - 117 - atradio-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs // { 118 - inherit cargoArtifacts; 119 - }); 30 + default = atradio.atradio; 31 + atradio = atradio.atradio; 120 32 }; 121 33 122 34 apps.default = flake-utils.lib.mkApp { 123 - drv = atradio; 35 + drv = atradio.atradio; 124 36 name = "atradio"; 125 37 }; 126 38 127 - devShells.default = pkgs.mkShell { 128 - inputsFrom = builtins.attrValues self.checks.${system}; 129 - 130 - # Build-time tools. pkg-config resolves libasound for cpal's build.rs 131 - # on Linux; stdenv.cc supplies the C compiler the rockbox-codecs / 132 - # rockbox-dsp build scripts need for Rockbox's C sources. 133 - nativeBuildInputs = with pkgs; [ 134 - cargo 135 - rustc 136 - rustfmt 137 - clippy 138 - rust-analyzer 139 - pkg-config 140 - stdenv.cc 141 - ]; 142 - 143 - # Link-time libraries. pkg-config only picks up `.pc` files from 144 - # buildInputs, so alsa-lib MUST live here for cpal → ALSA to resolve. 145 - buildInputs = with pkgs; lib.optionals stdenv.isDarwin [ 146 - libiconv 147 - ] ++ lib.optionals stdenv.isLinux [ 148 - alsa-lib 149 - ]; 150 - 151 - shellHook = '' 152 - echo "◈ atradio dev shell — $(cargo --version)" 153 - ''; 154 - }; 39 + devShells.default = atradio.devShell; 155 40 }); 156 41 }
+105
cli/package.nix
··· 1 + # Shared crane build for the atradio CLI, imported by BOTH: 2 + # - cli/flake.nix (standalone: `cd cli && nix build`), src = ./. 3 + # - the root flake (default package), src = ./cli 4 + # 5 + # Kept as a plain importable file (not a flake input) so neither flake needs a 6 + # `path:` input — relative path inputs can't be locked inside a git repo and 7 + # break `nix build` in CI ("unlocked input"). 8 + { craneLib, pkgs, lib, src, advisory-db }: 9 + 10 + let 11 + # atradio uses rustls end-to-end (no openssl) and has NO runtime binary 12 + # dependency (rockbox-playback decodes in-process), so the binary stands 13 + # alone — no wrapProgram / PATH shim. 14 + commonArgs = { 15 + inherit src; 16 + 17 + pname = "atradio"; 18 + version = "0.1.0"; 19 + strictDeps = true; 20 + 21 + # rockbox-playback pulls in rockbox-codecs + rockbox-dsp, whose build 22 + # scripts compile Rockbox's C sources with the `cc` crate — so a C compiler 23 + # must be on PATH. `stdenv.cc` is that toolchain (clang on Darwin, gcc on 24 + # Linux). 25 + nativeBuildInputs = [ 26 + pkgs.pkg-config 27 + pkgs.stdenv.cc 28 + ] ++ lib.optionals pkgs.stdenv.isDarwin [ 29 + # coreaudio-sys generates its CoreAudio bindings with bindgen at build 30 + # time; bindgenHook provides libclang + the Nix Apple SDK. 31 + pkgs.rustPlatform.bindgenHook 32 + ]; 33 + 34 + buildInputs = lib.optionals pkgs.stdenv.isDarwin [ 35 + pkgs.libiconv 36 + ] ++ lib.optionals pkgs.stdenv.isLinux [ 37 + # cpal links against ALSA on Linux. MPRIS needs no dbus dev lib: zbus 38 + # (via mpris-server) is pure Rust. 39 + pkgs.alsa-lib 40 + ]; 41 + 42 + cargoExtraArgs = "--locked --bin atradio"; 43 + }; 44 + 45 + cargoArtifacts = craneLib.buildDepsOnly commonArgs; 46 + 47 + atradio = craneLib.buildPackage (commonArgs // { 48 + inherit cargoArtifacts; 49 + doCheck = false; 50 + 51 + meta = { 52 + description = "A TUI radio player on the AT Protocol"; 53 + homepage = "https://github.com/tsirysndr/atradio.fm"; 54 + # Linking rockbox-playback (GPL-2.0) makes the binary GPL-2.0+. 55 + license = lib.licenses.gpl2Plus; 56 + mainProgram = "atradio"; 57 + platforms = lib.platforms.unix; 58 + }; 59 + }); 60 + 61 + checks = { 62 + inherit atradio; 63 + 64 + atradio-clippy = craneLib.cargoClippy (commonArgs // { 65 + inherit cargoArtifacts; 66 + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; 67 + }); 68 + 69 + atradio-fmt = craneLib.cargoFmt { inherit src; }; 70 + 71 + atradio-audit = craneLib.cargoAudit { inherit src advisory-db; }; 72 + }; 73 + 74 + devShell = pkgs.mkShell { 75 + inputsFrom = builtins.attrValues checks; 76 + 77 + # Build-time tools. pkg-config resolves libasound for cpal's build.rs on 78 + # Linux; stdenv.cc supplies the C compiler the rockbox-codecs / rockbox-dsp 79 + # build scripts need for Rockbox's C sources. 80 + nativeBuildInputs = with pkgs; [ 81 + cargo 82 + rustc 83 + rustfmt 84 + clippy 85 + rust-analyzer 86 + pkg-config 87 + stdenv.cc 88 + ]; 89 + 90 + # Link-time libraries. pkg-config only picks up `.pc` files from 91 + # buildInputs, so alsa-lib MUST live here for cpal → ALSA to resolve. 92 + buildInputs = with pkgs; lib.optionals stdenv.isDarwin [ 93 + libiconv 94 + ] ++ lib.optionals stdenv.isLinux [ 95 + alsa-lib 96 + ]; 97 + 98 + shellHook = '' 99 + echo "◈ atradio dev shell — $(cargo --version)" 100 + ''; 101 + }; 102 + in 103 + { 104 + inherit atradio checks devShell; 105 + }
+2 -47
flake.lock
··· 16 16 "type": "github" 17 17 } 18 18 }, 19 - "cli": { 20 - "inputs": { 21 - "advisory-db": "advisory-db", 22 - "crane": "crane", 23 - "fenix": "fenix", 24 - "flake-utils": [ 25 - "flake-utils" 26 - ], 27 - "nixpkgs": [ 28 - "nixpkgs" 29 - ] 30 - }, 31 - "locked": { 32 - "path": "./cli", 33 - "type": "path" 34 - }, 35 - "original": { 36 - "path": "./cli", 37 - "type": "path" 38 - }, 39 - "parent": [] 40 - }, 41 19 "crane": { 42 20 "locked": { 43 21 "lastModified": 1784172867, ··· 53 31 "type": "github" 54 32 } 55 33 }, 56 - "fenix": { 57 - "inputs": { 58 - "nixpkgs": [ 59 - "cli", 60 - "nixpkgs" 61 - ], 62 - "rust-analyzer-src": [ 63 - "cli" 64 - ] 65 - }, 66 - "locked": { 67 - "lastModified": 1784190100, 68 - "narHash": "sha256-cE4wAMa3MDhnx+mH5Y72tM/VTSh5cS5S2q0w56XurJU=", 69 - "owner": "nix-community", 70 - "repo": "fenix", 71 - "rev": "010b0647f8ebce9cd9e185773a7f9e422af1154a", 72 - "type": "github" 73 - }, 74 - "original": { 75 - "owner": "nix-community", 76 - "repo": "fenix", 77 - "type": "github" 78 - } 79 - }, 80 34 "flake-utils": { 81 35 "inputs": { 82 36 "systems": "systems" ··· 113 67 }, 114 68 "root": { 115 69 "inputs": { 116 - "cli": "cli", 70 + "advisory-db": "advisory-db", 71 + "crane": "crane", 117 72 "flake-utils": "flake-utils", 118 73 "nixpkgs": "nixpkgs" 119 74 }
+31 -19
flake.nix
··· 3 3 4 4 inputs = { 5 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 + crane.url = "github:ipetkov/crane"; 6 7 flake-utils.url = "github:numtide/flake-utils"; 7 - 8 - # The CLI is a self-contained sub-flake; the root re-exports it so 9 - # `nix build`, `nix run`, and `nix profile install github:tsirysndr/atradio.fm` 10 - # all resolve to the CLI. Add more sub-flakes here as the repo grows. 11 - cli = { 12 - url = "path:./cli"; 13 - inputs.nixpkgs.follows = "nixpkgs"; 14 - inputs.flake-utils.follows = "flake-utils"; 8 + advisory-db = { 9 + url = "github:rustsec/advisory-db"; 10 + flake = false; 15 11 }; 16 12 }; 17 13 18 - outputs = { self, nixpkgs, flake-utils, cli, ... }: 19 - flake-utils.lib.eachDefaultSystem (system: { 20 - # Root default = the CLI (only package for now). 21 - packages = { 22 - default = cli.packages.${system}.default; 23 - atradio = cli.packages.${system}.default; 24 - }; 14 + # The root default package IS the CLI. We build it directly from the ./cli 15 + # source (sharing cli/package.nix with cli/flake.nix) rather than importing 16 + # the sub-flake — a `path:./cli` input can't be locked inside a git repo. 17 + outputs = { self, nixpkgs, crane, flake-utils, advisory-db, ... }: 18 + flake-utils.lib.eachDefaultSystem (system: 19 + let 20 + pkgs = import nixpkgs { inherit system; }; 21 + craneLib = crane.mkLib pkgs; 25 22 26 - apps.default = cli.apps.${system}.default; 23 + atradio = import ./cli/package.nix { 24 + inherit craneLib pkgs advisory-db; 25 + inherit (pkgs) lib; 26 + src = craneLib.cleanCargoSource ./cli; 27 + }; 28 + in 29 + { 30 + checks = atradio.checks; 31 + 32 + packages = { 33 + default = atradio.atradio; 34 + atradio = atradio.atradio; 35 + }; 27 36 28 - devShells.default = cli.devShells.${system}.default; 37 + apps.default = flake-utils.lib.mkApp { 38 + drv = atradio.atradio; 39 + name = "atradio"; 40 + }; 29 41 30 - checks = cli.checks.${system}; 31 - }); 42 + devShells.default = atradio.devShell; 43 + }); 32 44 }