/ flake.nix
flake.nix
1 { 2 description = "distrox"; 3 inputs = { 4 nixpkgs.url = "nixpkgs/nixos-25.11"; 5 unstable.url = "nixpkgs/nixpkgs-unstable"; 6 flake-utils.url = "github:numtide/flake-utils"; 7 crane.url = "github:ipetkov/crane"; 8 rust-overlay = { 9 url = "github:oxalica/rust-overlay"; 10 inputs.nixpkgs.follows = "nixpkgs"; 11 }; 12 treefmt-nix = { 13 # Update to upstream as soon as https://github.com/numtide/treefmt-nix/pull/414 is merged 14 url = "github:matthiasbeyer/treefmt-nix/configure-sqlfluff"; 15 inputs.nixpkgs.follows = "nixpkgs"; 16 }; 17 18 git-metrics-flake = { 19 url = "github:matthiasbeyer/git-metrics-flake"; 20 inputs = { 21 nixpkgs.follows = "nixpkgs"; 22 flake-utils.follows = "flake-utils"; 23 treefmt-nix.follows = "treefmt-nix"; 24 }; 25 }; 26 27 goyo = { 28 url = "git+https://github.com/hahwul/goyo.git"; 29 flake = false; 30 }; 31 }; 32 33 outputs = 34 inputs@{ 35 self, 36 nixpkgs, 37 crane, 38 flake-utils, 39 rust-overlay, 40 treefmt-nix, 41 ... 42 }: 43 flake-utils.lib.eachSystem [ "x86_64-linux" ] ( 44 system: 45 let 46 pkgs = import nixpkgs { 47 inherit system; 48 overlays = [ (import rust-overlay) ]; 49 }; 50 51 pkgsUnstable = import inputs.unstable { 52 inherit system; 53 }; 54 55 nightlyRustTarget = pkgs.rust-bin.selectLatestNightlyWith ( 56 toolchain: 57 pkgs.rust-bin.fromRustupToolchain { 58 channel = "nightly-2025-10-03"; 59 components = [ "rustfmt" ]; 60 } 61 ); 62 63 rustTarget = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; 64 65 craneLib = (inputs.crane.mkLib pkgs).overrideToolchain rustTarget; 66 67 src = 68 let 69 markdownFilter = path: _type: pkgs.lib.hasSuffix ".md" path; 70 filterPath = 71 path: type: 72 builtins.any (f: f path type) [ 73 markdownFilter 74 craneLib.filterCargoSources 75 pkgs.lib.cleanSourceFilter 76 ]; 77 in 78 pkgs.lib.cleanSourceWith { 79 src = ./.; 80 filter = filterPath; 81 }; 82 83 rustSrc = pkgs.lib.fileset.toSource { 84 root = ./.; 85 fileset = 86 let 87 includeFilesWithExt = ext: (pkgs.lib.fileset.fileFilter (file: file.hasExt ext) ./.); 88 in 89 pkgs.lib.fileset.unions ( 90 [ 91 ./Cargo.lock 92 ./README.md 93 ] 94 ++ (builtins.map includeFilesWithExt [ 95 "rs" 96 "toml" 97 "sql" 98 "snap" 99 ]) 100 ); 101 }; 102 103 rustfmt' = pkgs.writeShellScriptBin "rustfmt" '' 104 exec "${nightlyRustTarget}/bin/rustfmt" "$@" 105 ''; 106 107 formatting = 108 let 109 treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs ./lib/nix/treefmt.nix; 110 in 111 { 112 formatter = treefmtEval.config.build.wrapper; 113 check = treefmtEval.config.build.check src; 114 }; 115 116 commonCrateArgs = { 117 src = rustSrc; 118 strictDeps = true; 119 120 nativeBuildInputs = [ 121 pkgs.pkg-config 122 ]; 123 124 buildInputs = [ 125 pkgs.sqlite 126 ]; 127 }; 128 129 lib = pkgs.callPackage ./lib/nix { 130 inherit 131 craneLib 132 src 133 commonCrateArgs 134 rustTarget 135 inputs 136 ; 137 138 mkMetric = inputs.git-metrics-flake.lib."${system}".mkMetric; 139 distrox-cli = inputs.self.packages."${system}".distrox-cli; 140 iroh-relay = inputs.self.packages."${system}".iroh-relay; 141 }; 142 143 callPackage = pkgs.lib.callPackageWith ( 144 pkgs 145 // { 146 inherit (lib) workspace; 147 inherit craneLib; 148 inherit inputs; 149 150 inherit (lib.config) 151 mkDistroxConfigFile 152 ; 153 154 distrox-cli = inputs.self.packages."${system}".distrox-cli; 155 distrox-cli-no-tracy = inputs.self.packages."${system}".distrox-cli-no-tracy; 156 iroh-relay = inputs.self.packages."${system}".iroh-relay; 157 iroh-relay-module = lib.iroh-relay-module; 158 iroh-doctor = inputs.self.packages."${system}".iroh-doctor; 159 160 mkMetric = inputs.git-metrics-flake.lib."${system}".mkMetric; 161 } 162 // lib.testUtils 163 // { 164 inherit callPackage; 165 } 166 ); 167 168 isNotOverride = name: name != "override" && name != "overrideDerivation"; 169 attrsetWithoutOverrides = pkgs.lib.attrsets.filterAttrs (name: _: isNotOverride name); 170 171 all-endtoend-tests = attrsetWithoutOverrides (callPackage ./tests { }); 172 173 distroxMeta = { 174 description = "The distrox social network"; 175 mainProgram = "distrox-cli"; 176 homepage = "https://distrox.net"; 177 license = pkgs.lib.licenses.gpl2Only; 178 maintainers = with lib.maintainers; [ 179 matthiasbeyer 180 ]; 181 }; 182 183 customCargoMultiplexer = pkgs.writeShellScriptBin "cargo" '' 184 case "$1" in 185 +nightly) 186 shift 187 export PATH="${nightlyRustTarget}/bin/:''$PATH" 188 exec ${nightlyRustTarget}/bin/cargo "$@" 189 ;; 190 *) 191 exec ${rustTarget}/bin/cargo "$@" 192 esac 193 ''; 194 in 195 { 196 inherit (formatting) formatter; 197 198 checks = 199 lib.allCrateTests 200 // all-endtoend-tests 201 // { 202 formatting = formatting.check; 203 distrox-cli = lib.crates.distrox-cli.build; 204 }; 205 206 packages = { 207 distrox-cli = lib.crates.distrox-cli.build.overrideAttrs { meta = distroxMeta; }; 208 distrox-cli-no-tracy = lib.crates.distrox-cli-no-tracy.overrideAttrs { meta = distroxMeta; }; 209 depgraph = lib.depgraph; 210 depgraph-svg = lib.depgraph-svg; 211 manpages = lib.manpages; 212 website = callPackage ./website { 213 inherit (lib) 214 manpages 215 depgraph-svg 216 ; 217 218 inherit (lib.packages) mantohtml; 219 }; 220 221 git-metrics-ci-script = 222 let 223 gmf-lib = inputs.git-metrics-flake.lib."${system}"; 224 in 225 gmf-lib.mkCiScript { 226 inherit pkgs; 227 inherit (inputs.git-metrics-flake.packages."${system}") git-metrics; 228 drv = inputs.self.packages."${system}".distrox-cli; 229 230 metrics = 231 let 232 all-crate-metrics-test-count = pkgs.lib.pipe lib.allCrateNames [ 233 (pkgs.lib.lists.filter ( 234 crateName: lib.filterForCratesWith "build" crateName && lib.filterForCratesWith "test" crateName 235 )) 236 (map (name: lib.mk-metric-test-count lib.crates."${name}")) 237 ]; 238 in 239 all-crate-metrics-test-count 240 ++ [ 241 lib.metric-binary-size 242 lib.metric-derivation-size 243 ]; 244 }; 245 } 246 // attrsetWithoutOverrides lib.packages; 247 248 apps = { 249 distrox-cli = 250 flake-utils.lib.mkApp { 251 drv = self.packages.${pkgs.stdenv.hostPlatform.system}.distrox-cli; 252 name = "distrox-cli"; 253 } 254 // { 255 meta = distroxMeta; 256 }; 257 258 distrox-cli-no-tracy = 259 flake-utils.lib.mkApp { 260 drv = self.packages.${pkgs.stdenv.hostPlatform.system}.distrox-cli-no-tracy; 261 name = "distrox-cli"; 262 } 263 // { 264 meta = distroxMeta; 265 }; 266 267 serve-website = 268 inputs.flake-utils.lib.mkApp { 269 drv = pkgs.writeShellApplication { 270 name = "serve-website"; 271 runtimeInputs = [ pkgs.zola ]; 272 text = '' 273 ln -vsn "${inputs.goyo}" ./website/themes/goyo ||: 274 ln -vsn "${lib.depgraph-svg}/depgraph.svg" ./website/static/depgraph.svg ||: 275 cd website 276 zola serve 277 ''; 278 }; 279 } 280 // { 281 meta = { 282 description = "The distrox social network website"; 283 homepage = "https://distrox.net"; 284 license = pkgs.lib.licenses.gpl2Only; 285 maintainers = with lib.maintainers; [ 286 matthiasbeyer 287 ]; 288 }; 289 }; 290 }; 291 292 devShells = 293 let 294 mkTestInstanceShell = 295 { 296 number, 297 config, 298 }: 299 pkgs.mkShell { 300 buildInputs = [ 301 (pkgs.writeShellApplication { 302 name = "distrox-cli"; 303 runtimeInputs = [ 304 inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.distrox-cli 305 ]; 306 307 text = '' 308 XDG_STATE_HOME="$(pwd)/instance-test/${toString number}/xdg/state/" \ 309 XDG_CONFIG_HOME="$(pwd)/instance-test/${toString number}/xdg/config/" \ 310 XDG_CACHE_HOME="$(pwd)/instance-test/${toString number}/xdg/cache/" \ 311 distrox-cli "$@" 312 ''; 313 }) 314 ]; 315 316 shellHook = 317 let 318 configFile = lib.config.mkDistroxConfigFile config; 319 in 320 '' 321 mkdir -p "$(pwd)/instance-test/${toString number}/xdg/config/distrox" 322 >&2 echo ">>> created: $(pwd)/instance-test/${toString number}/xdg/config/distrox/" 323 324 >&2 cp -v ${configFile} "$(pwd)/instance-test/${toString number}/xdg/config/distrox/config.toml" 325 >&2 echo ">>> config file created: $(pwd)/instance-test/${toString number}/xdg/config/distrox/config.toml" 326 327 export RUST_LOG=debug,pkarr_publish=warn,hickory_proto=warn,actor=info,reportgen-actor=info,run-probe=info,poll=warn 328 >&2 echo ">>> RUST_LOG = ''${RUST_LOG}" 329 330 echo >&2 ">>> Shell for Test instance ${toString number}"; 331 ''; 332 }; 333 in 334 { 335 default = pkgs.mkShell { 336 buildInputs = [ 337 customCargoMultiplexer 338 inputs.git-metrics-flake.packages."${system}".git-metrics 339 pkgs.cargo-depgraph 340 pkgs.cargo-insta 341 pkgs.cargo-nextest 342 pkgs.gitlint 343 pkgs.rainfrog 344 pkgs.sqlite 345 pkgsUnstable.diesel-cli 346 rustTarget 347 rustfmt' 348 ]; 349 }; 350 }; 351 352 website-shell = pkgs.mkShell { 353 buildInputs = [ 354 inputs.git-metrics-flake.packages."${system}".git-metrics 355 pkgs.cargo-depgraph 356 pkgs.cargo-insta 357 pkgs.gitlint 358 pkgs.zola 359 rustTarget 360 rustfmt' 361 ]; 362 363 shellHook = '' 364 ln -vsn "${inputs.goyo}" ./website/themes/goyo 365 ln -vsn "${lib.depgraph-svg}/depgraph.svg" ./website/static/depgraph.svg ||: 366 ''; 367 }; 368 } 369 ); 370 }