{ lib, stdenv, buildGoModule, rustPlatform, fetchgit, fetchurl, fetchzip, linkFarm, runCommandLocal, symlinkJoin, writeShellScriptBin, cmake, perl, tailwindcss, }: # Tangled (https://tangled.org) without its flake: the appview, knot 2 # (knot-rs) and knotmirror, built the way its nix/pkgs files do. tap and goat # come from nixpkgs (tap, atproto-goat). let version = "0-unstable-2026-10-18"; src = fetchgit { url = "https://tangled.org/tangled.org/core"; rev = "dad751949f865d6189f7602e1409c5f951e75771"; hash = "sha256-pehXSw17JRgWA/d4t/x9ZcdxOHJaY3I0+H+3p1hVZxk="; }; # The *-src inputs of the flake at that rev, generated by update.sh from # its flake.lock; the hashes are the lock's narHashes. assets = lib.mapAttrs ( name: a: { file = fetchurl { inherit name; inherit (a) url hash; recursiveHash = true; }; tarball = fetchzip { inherit name; inherit (a) url hash; # flake tarballs only drop a single top-level directory stripRoot = name != "inter-fonts-src"; }; git = fetchgit { inherit (a) url rev hash; }; } .${a.type} ) (lib.importJSON ./assets.json); # The Go programs share the root go.mod, so one vendor directory. buildTangledGo = pname: args: buildGoModule ( { inherit pname version src; vendorHash = "sha256-6eDNOcnMHMpdQS7M7A8O+wZOnP2/968Re7Iqn8XgGNM="; overrideModAttrs = _: { name = "tangled-${version}-go-modules"; }; subPackages = [ "cmd/${pname}" ]; doCheck = false; meta.mainProgram = pname; } // args ); sqlite-lib = stdenv.mkDerivation { name = "sqlite-lib"; src = assets.sqlite-lib-src; buildPhase = '' $CC -c sqlite3.c $AR rcs libsqlite3.a sqlite3.o $RANLIB libsqlite3.a ''; installPhase = '' mkdir -p $out/include $out/lib cp *.h $out/include cp libsqlite3.a $out/lib ''; }; dolly-unwrapped = buildTangledGo "dolly" { }; dolly = writeShellScriptBin "dolly" '' exec ${dolly-unwrapped}/bin/dolly \ -template ${src}/appview/pages/templates/fragments/dolly \ "$@" ''; tailwindcss-plugins = linkFarm "tailwindcss-plugins" [ { name = "tailwindcss-animated"; path = assets.tailwindcss-animated-src; } ]; static-files = runCommandLocal "appview-static-files" { } '' mkdir -p $out/{fonts,icons,logos} && cd $out cp -f ${assets.htmx-src} htmx.min.js cp -f ${assets.htmx-ws-src} htmx-ext-ws.min.js cp -f ${assets.mermaid-src} mermaid.min.js cp -f ${assets.hls-src} hls.min.js cp -f ${assets.mathjax-src} mathjax.min.js cp -rf ${assets.lucide-src}/*.svg icons/ cp -rf ${src}/icons/*.svg icons/ cp -f ${assets.inter-fonts-src}/web/InterVariable*.woff2 fonts/ cp -f ${assets.inter-fonts-src}/web/InterDisplay*.woff2 fonts/ cp -f ${assets.inter-fonts-src}/InterVariable*.ttf fonts/ cp -f ${assets.ibm-plex-mono-src}/fonts/complete/woff2/IBMPlexMono*.woff2 fonts/ cp -f ${assets.actor-typeahead-src}/actor-typeahead.js . cp -rf ${src}/appview/pages/profile-fx . ${dolly}/bin/dolly -output logos/dolly.png -size 180 ${dolly}/bin/dolly -output logos/dolly.ico -size 48 ${dolly}/bin/dolly -output logos/dolly.svg -color currentColor -favicon export NODE_PATH=${tailwindcss-plugins} cd ${src} && ${tailwindcss}/bin/tailwindcss -i input.css -o $out/tw.css ''; appview = buildTangledGo "appview" { # knot2 wants the knot's did:web as listMembers subject, not its hostname patches = [ ./appview-knot-members-did-web.patch ]; postUnpack = '' mkdir -p $sourceRoot/appview/pages/static cp -fr ${static-files}/* $sourceRoot/appview/pages/static ''; tags = [ "libsqlite3" ]; env = { CGO_ENABLED = 1; CGO_CFLAGS = "-I ${sqlite-lib}/include "; CGO_LDFLAGS = "-L ${sqlite-lib}/lib"; }; }; knotmirror = buildTangledGo "knotmirror" { }; knot-rs = rustPlatform.buildRustPackage { pname = "knot-server"; inherit version src; cargoHash = "sha256-3YPqGQS1yVF+Pmj0Xe2z6yITLl7RgwPMPY389MB8lw8="; nativeBuildInputs = [ cmake perl ]; dontUseCmakeConfigure = true; cargoBuildFlags = [ "--bin" "knot-server" "--package" "knot-server" ]; doCheck = false; meta.mainProgram = "knot-server"; }; in symlinkJoin { pname = "tangled"; inherit version; paths = [ appview knot-rs knotmirror ]; passthru = { inherit src assets sqlite-lib dolly static-files appview knot-rs knotmirror ; updateScript = ./update.sh; }; meta = { description = "Git collaboration platform on atproto: appview, knot and knotmirror"; homepage = "https://tangled.org/tangled.org/core"; license = lib.licenses.mit; platforms = lib.platforms.linux; }; }