{ lib, stdenvNoCC, fetchFromGitHub, fetchurl, symlinkJoin, makeBinaryWrapper, pkg-config, openssl, cargo-leptos, dart-sass, rustPlatform, wasm-bindgen-cli_0_2_100, binaryen, inkscape, mkShell, clangStdenv, rust-analyzer, rustc, rustfmt, leptosfmt, cargo, clippy, writers, ast-grep, nix-prefetch-github, }: let cargoMetadata = lib.pipe ./Cargo.toml [ builtins.readFile builtins.fromTOML ]; sass-dependencies = { bulma = stdenvNoCC.mkDerivation (drv: { pname = "bulma"; version = "1.0.4"; src = fetchFromGitHub { owner = "jgthms"; repo = "bulma"; rev = drv.version; hash = "sha256-hlejqBI6ayzhm15IymrzhTevkl3xffMfdTasZ2CmAas="; }; installPhase = '' mkdir -p $out/node_modules/bulma/ cp -r ./sass $out/node_modules/bulma/ ''; }); fontsource-scss = stdenvNoCC.mkDerivation { pname = "fontsource-scss"; version = "0.2.2"; src = fetchurl { url = "https://registry.npmjs.org/@fontsource-utils/scss/-/scss-0.2.2.tgz"; hash = "sha256-2BkCBhh01kZfMHhjHMMLDtUeesi7Uy7eMoeM1BAqX38="; }; installPhase = '' mkdir -p $out/node_modules/@fontsource-utils/scss/ cp -r . $out/node_modules/@fontsource-utils/scss/ ''; }; fontsource-nunito = stdenvNoCC.mkDerivation { pname = "fontsource-nunito"; version = "5.2.7"; src = fetchurl { url = "https://registry.npmjs.org/@fontsource-variable/nunito/-/nunito-5.2.7.tgz"; hash = "sha256-xSt1sDpVL/hVYzffKTgN/t7uLI3JadDWtTfWow2jiPM="; }; outputs = [ "out" "assets" ]; installPhase = '' mkdir -p $out/node_modules/@fontsource-variable/nunito/ cp -r . $out/node_modules/@fontsource-variable/nunito/ mkdir -p $assets/@fontsource-variable/ cp -r files/ $assets/@fontsource-variable/nunito ''; }; fontsource-arimo = stdenvNoCC.mkDerivation { pname = "fontsource-nunito"; version = "5.2.8"; src = fetchurl { url = "https://registry.npmjs.org/@fontsource-variable/arimo/-/arimo-5.2.8.tgz"; hash = "sha256-jD1IGqy02j4bqMRAwbCgiIz/h97WPrTSd3eZ09nptHA="; }; outputs = [ "out" "assets" ]; installPhase = '' mkdir -p $out/node_modules/@fontsource-variable/arimo/ cp -r . $out/node_modules/@fontsource-variable/arimo/ mkdir -p $assets/@fontsource-variable/ cp -r files/ $assets/@fontsource-variable/arimo ''; }; }; other-dependencies = { hack-font = stdenvNoCC.mkDerivation (drv: { pname = "hack-font"; version = "3.003"; src = fetchFromGitHub { owner = "source-foundry"; repo = "Hack"; rev = "v${drv.version}"; hash = "sha256-qGDtBvKecdfsleUBfXFezllz9Op679a030Qcj/oBs1o="; }; dontBuild = true; installPhase = '' mkdir -p $out cp -r build/web/fonts $out/hack-font/ ''; }); }; icons = stdenvNoCC.mkDerivation { pname = "tlaternet-icons"; version = "1.0"; src = ./public/icon.svg; dontUnpack = true; nativeBuildInputs = [ inkscape ]; buildPhase = '' inkscape -w 48 -h 48 $src --export-filename=favicon-48.png ''; installPhase = '' mkdir -p $out cp $src $out/icon.svg cp favicon-48.png $out/ ''; }; assets = symlinkJoin { name = "assets-${cargoMetadata.package.name}"; paths = [ sass-dependencies.fontsource-arimo.assets sass-dependencies.fontsource-nunito.assets other-dependencies.hack-font icons ]; }; # Hack to allow importing sass *without* resorting to using `npm` # and dealing with the insanity that is `package.json` files. # # dart-sass *in theory* supports completely arbitrary logic for # package importing via the `pkg:` url prefix, but unfortunately # currently the only implementation of it that is available in the # upstream binary *requires* using a `node_modules` file in the # repository root. See here: # https://sass-lang.com/documentation/at-rules/use/#node-js-package-importer # # This wouldn't be so bad if it supported an environment variable or # command line arg to specify what the repo root should be, but it # doesn't; so instead we use the load-path to specify a package # import root. # # As a consequence, we cannot use the `pkg:` prefix, so package # imports are indistinguishable from relative path imports. This # isn't the end of the world, but: # # TODO(tlater): See if we can talk to upstream about an # implementation better suited for use with nix, perhaps in # dart-sass (add an env variable?) or in cargo-leptos (add a config # option that can also be set with an env variable, and use the sass # protocol instead of the raw exe?). dart-sass-with-packages = let packages = symlinkJoin { name = "sass-packages"; paths = lib.attrValues sass-dependencies; stripPrefix = "/node_modules"; }; in symlinkJoin { inherit (dart-sass) version; pname = "dart-sass-with-packages"; paths = [ dart-sass ]; nativeBuildInputs = [ makeBinaryWrapper ]; postBuild = '' wrapProgram $out/bin/sass \ --add-flag --load-path=${packages} ''; }; in rustPlatform.buildRustPackage (drv: { inherit (cargoMetadata.package) version; pname = cargoMetadata.package.name; cargoLock.lockFile = drv.src + /Cargo.lock; src = lib.fileset.toSource { root = ./.; fileset = lib.fileset.fromSource (lib.sources.cleanSource ./.); }; nativeBuildInputs = [ cargo-leptos rustc.llvmPackages.lld dart-sass-with-packages makeBinaryWrapper pkg-config wasm-bindgen-cli_0_2_100 binaryen ]; buildInputs = [ openssl ]; LEPTOS_ASSETS_DIR = assets.outPath; buildPhase = '' runHook preBuild cargo leptos build --release runHook postBuild ''; installPhase = '' runHook preInstall mkdir -p $out/bin $out/share cp target/release/tlaternet-webserver $out/bin cp -r target/site $out/share wrapProgram $out/bin/tlaternet-webserver \ --set LEPTOS_SITE_ROOT $out/share/site \ --set LEPTOS_ASSETS_DIR ${assets.outPath} runHook postInstall ''; meta.mainProgram = "tlaternet-webserver"; passthru = { dependencies = sass-dependencies; devShell = mkShell.override { stdenv = clangStdenv; } { packages = [ pkg-config openssl cargo-leptos dart-sass-with-packages # lld is exposed as ld by the clangStdenv, adding it # explicitly with bintools makes it work rustc.llvmPackages.lld rust-analyzer rustc rustfmt leptosfmt cargo clippy ]; LEPTOS_ASSETS_DIR = assets.outPath; }; updateScript = writers.writeNuBin "update-${cargoMetadata.package.name}" { makeWrapperArgs = [ "--prefix" "PATH" ":" (lib.makeBinPath [ ast-grep nix-prefetch-github ]) ]; } ./update.nu; }; })